diff --git a/src/serializer/ResidualFunctions.js b/src/serializer/ResidualFunctions.js index 210ca83931..7b98e3c7f4 100644 --- a/src/serializer/ResidualFunctions.js +++ b/src/serializer/ResidualFunctions.js @@ -262,14 +262,13 @@ export class ResidualFunctions { // Emit code for ModifiedBindings for additional functions for (let [funcValue, funcInfo] of this.additionalFunctionValueInfos) { + let scopes = new Set(); for (let [, residualBinding] of funcInfo.modifiedBindings) { let scope = residualBinding.scope; - if (scope === undefined) continue; + if (scope === undefined || scopes.has(scope)) continue; + scopes.add(scope); - // TODO #989: This should probably be an invariant once captures work properly - // Currently we don't referentialize bindings in additional functions (but we - // do for bindings nested in additional functions) - if (!residualBinding.referentialized) continue; + invariant(residualBinding.referentialized); // Find the proper prelude to emit to (global vs additional function's prelude) let bodySegment = getModifiedBindingsSegment(funcValue); diff --git a/test/serializer/additional-functions/ModifiedBindingsCapturedScopesCalls.js b/test/serializer/additional-functions/ModifiedBindingsCapturedScopesCalls.js new file mode 100644 index 0000000000..3db22f0d83 --- /dev/null +++ b/test/serializer/additional-functions/ModifiedBindingsCapturedScopesCalls.js @@ -0,0 +1,16 @@ +// add at runtime:var a = 17; +// Copies of \|\|:2 +(function () { + let a, b, c, d; + global.f = function() { + a = 1; + b = 2; + c = 3; + d = 4; + } + if (global.__optimize) __optimize(f); + inspect = function() { + global.f(); + return a + b + c + d; + } +})();