@@ -805,7 +805,7 @@ func translateFunction(typ *ast.FuncType, recv *ast.Ident, body *ast.BlockStmt,
805
805
806
806
if len (c .Flattened ) != 0 {
807
807
c .localVars = append (c .localVars , "$s" )
808
- prefix = prefix + " $s = 0;"
808
+ prefix = prefix + " $s = $s || 0;"
809
809
}
810
810
811
811
if c .HasDefer {
@@ -816,19 +816,29 @@ func translateFunction(typ *ast.FuncType, recv *ast.Ident, body *ast.BlockStmt,
816
816
}
817
817
}
818
818
819
+ localVarDefs := "" // Function-local var declaration at the top.
820
+
819
821
if len (c .Blocking ) != 0 {
820
- c .localVars = append (c .localVars , "$r" )
821
822
if funcRef == "" {
822
823
funcRef = "$b"
823
824
functionName = " $b"
824
825
}
825
- var stores , loads string
826
- for _ , v := range c .localVars {
827
- loads += fmt .Sprintf ("%s = $f.%s; " , v , v )
828
- stores += fmt .Sprintf ("$f.%s = %s; " , v , v )
829
- }
830
- prefix = prefix + " var $f, $c = false; if (this !== undefined && this.$blk !== undefined) { $f = this; $c = true; " + loads + "}"
831
- suffix = " if ($f === undefined) { $f = { $blk: " + funcRef + " }; } " + stores + "return $f;" + suffix
826
+
827
+ localVars := append ([]string {}, c .localVars ... )
828
+ // There are several special variables involved in handling blocking functions:
829
+ // $r is sometimes used as a temporary variable to store blocking call result.
830
+ // $c indicates that a function is being resumed after a blocking call when set to true.
831
+ // $f is an object used to save and restore function context for blocking calls.
832
+ localVars = append (localVars , "$r" )
833
+ // If a blocking function is being resumed, initialize local variables from the saved context.
834
+ localVarDefs = fmt .Sprintf ("var {%s, $c} = $restore(this, {%s});\n " , strings .Join (localVars , ", " ), strings .Join (params , ", " ))
835
+ // If the function gets blocked, save local variables for future.
836
+ saveContext := fmt .Sprintf ("var $f = {$blk: " + funcRef + ", $c: true, $r, %s};" , strings .Join (c .localVars , ", " ))
837
+
838
+ suffix = " " + saveContext + "return $f;" + suffix
839
+ } else if len (c .localVars ) > 0 {
840
+ // Non-blocking functions simply declare local variables with no need for restore support.
841
+ localVarDefs = fmt .Sprintf ("var %s;\n " , strings .Join (c .localVars , ", " ))
832
842
}
833
843
834
844
if c .HasDefer {
@@ -865,8 +875,8 @@ func translateFunction(typ *ast.FuncType, recv *ast.Ident, body *ast.BlockStmt,
865
875
if suffix != "" {
866
876
bodyOutput = bodyOutput + strings .Repeat ("\t " , c .pkgCtx .indentation + 1 ) + "/* */" + suffix + "\n "
867
877
}
868
- if len ( c . localVars ) != 0 {
869
- bodyOutput = fmt . Sprintf ( "%svar %s; \n " , strings .Repeat ("\t " , c .pkgCtx .indentation + 1 ), strings . Join ( c . localVars , ", " )) + bodyOutput
878
+ if localVarDefs != "" {
879
+ bodyOutput = strings .Repeat ("\t " , c .pkgCtx .indentation + 1 ) + localVarDefs + bodyOutput
870
880
}
871
881
872
882
c .pkgCtx .escapingVars = prevEV
0 commit comments