Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Use ES 2015 syntax to generate more compact code for blocking functions. #1137

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Aug 16, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Further compactify blocking function context save/restore code.
This change deduplicates variable declaration with restoration from
saved context for blocking functions. This removes a significant source
of duplicated code in each blocking function intro.

We also introduce a helper function $restore to eliminate some
repetitive snippets of generated code.
  • Loading branch information
nevkontakte committed Aug 7, 2022
commit cea2ae1dcb12842f8d884c1e4e9dbd8d89fadaff
28 changes: 19 additions & 9 deletions 28 compiler/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -805,7 +805,7 @@ func translateFunction(typ *ast.FuncType, recv *ast.Ident, body *ast.BlockStmt,

if len(c.Flattened) != 0 {
c.localVars = append(c.localVars, "$s")
prefix = prefix + " $s = 0;"
prefix = prefix + " $s = $s || 0;"
}

if c.HasDefer {
Expand All @@ -816,17 +816,27 @@ func translateFunction(typ *ast.FuncType, recv *ast.Ident, body *ast.BlockStmt,
}
}

localVarDefs := "" // Function-local var declaration at the top.

if len(c.Blocking) != 0 {
c.localVars = append(c.localVars, "$r")
localVars := append([]string{}, c.localVars...)
// $r is sometimes used as a temporary variable to store blocking call result.
// $c indicates that a function is being resumed after a blocking call when set to true.
// $f is an object used to save and restore function context for blocking calls.
localVars = append(localVars, "$r", "$c", "$f")
// If a blocking function is being resumed, initialize local variables from the saved context.
localVarDefs = fmt.Sprintf("var {%s} = $restore(this, {%s});\n", strings.Join(localVars, ", "), strings.Join(params, ", "))
// If the function gets blocked, save local variables for future.
saveContext := fmt.Sprintf("$f = {...$f, $r, %s};", strings.Join(c.localVars, ", "))

if funcRef == "" {
funcRef = "$b"
functionName = " $b"
}
var stores, loads string
loads = fmt.Sprintf("({%s} = $f); ", strings.Join(c.localVars, ", "))
stores = fmt.Sprintf("$f = {...$f, %s};", strings.Join(c.localVars, ", "))
prefix = prefix + " var $f, $c = false; if (this !== undefined && this.$blk !== undefined) { $f = this; $c = true; " + loads + "}"
suffix = " if ($f === undefined) { $f = { $blk: " + funcRef + " }; } " + stores + "return $f;" + suffix
suffix = " if ($f === undefined) { $f = { $blk: " + funcRef + " }; } " + saveContext + "return $f;" + suffix
} else if len(c.localVars) > 0 {
// Non-blocking functions simply declare local variables with no need for restore support.
localVarDefs = fmt.Sprintf("var %s;\n", strings.Join(c.localVars, ", "))
}

if c.HasDefer {
Expand Down Expand Up @@ -863,8 +873,8 @@ func translateFunction(typ *ast.FuncType, recv *ast.Ident, body *ast.BlockStmt,
if suffix != "" {
bodyOutput = bodyOutput + strings.Repeat("\t", c.pkgCtx.indentation+1) + "/* */" + suffix + "\n"
}
if len(c.localVars) != 0 {
bodyOutput = fmt.Sprintf("%svar %s;\n", strings.Repeat("\t", c.pkgCtx.indentation+1), strings.Join(c.localVars, ", ")) + bodyOutput
if localVarDefs != "" {
bodyOutput = strings.Repeat("\t", c.pkgCtx.indentation+1) + localVarDefs + bodyOutput
}

c.pkgCtx.escapingVars = prevEV
Expand Down
15 changes: 15 additions & 0 deletions 15 compiler/prelude/goroutines.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,21 @@ var $block = function() {
$curGoroutine.asleep = true;
};

var $restore = function(context, params) {
if (context !== undefined && context.$blk !== undefined) {
return {
$f: context,
$c: true,
...context,
};
} else {
return {
$c: false,
...params,
};
}
}

var $send = function(chan, value) {
if (chan.$closed) {
$throwRuntimeError("send on closed channel");
Expand Down
Loading
Morty Proxy This is a proxified and sanitized view of the page, visit original site.