Skip to content
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

Defer functions enclosed in all contexts. #2666

Merged
merged 1 commit into from
Mar 15, 2017

Conversation

pleath
Copy link
Contributor

@pleath pleath commented Mar 10, 2017

Support deferral of functions enclosed in scopes other than function body and function expression scope -- in particular, ES6-style lexical scopes and parameter scopes. This requires changing ScopeInfo so that it is associated with a single scope rather than a function body. Instead of carrying per-function information for body/var scope, parameter scope, and function expression scope, ScopeInfo will describe one scope, with a value identifying the scope type, a pointer to the FunctionInfo that contains it, and a pointer to the enclosing ScopeInfo. A FunctionProxy will point to the ScopeInfo that is the nearest enclosing scope. At parse time, we will reconstitute the closure environment by walking the list of enclosing ScopeInfo's. The code that allowed redeferral to work around the context limitation of deferring parsing is deleted, and the OptimizeBlockScope feature is off by default, as it doesn't play well with this new logic and isn't required to make (re-)deferral effective. (We will want to revisit it, though, so I've left it there.)

@pleath
Copy link
Contributor Author

pleath commented Mar 13, 2017

@aneeshdk This is the feature work we discussed last week. Can you take a look when you get a chance? (Thanks.)

{
func->bodyScope = this->currentScope;
func = Anew(alloc, FuncInfo, pfi->GetDisplayName(), alloc, nullptr, nullptr, nullptr, pfi);
newFunc = true;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't need it here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry -- can you explain what you mean?

@@ -2023,7 +2041,7 @@ void ByteCodeGenerator::CheckDeferParseHasMaybeEscapedNestedFunc()
else
{
// We have to wait until it is parsed before we populate the stack nested func parent.
FuncInfo * parentFunc = top->GetBodyScope()->GetEnclosingFunc();
FuncInfo * parentFunc = top->GetParamScope() ? top->GetParamScope()->GetEnclosingFunc() : top->GetBodyScope()->GetEnclosingFunc();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

top->GetParamScope()->GetEnclosingFunc() : top->GetBodyScope()->GetEnclosingFunc() [](start = 55, length = 82)

Aren't these two the same?

bool scopeIsEmpty = scope->IsEmpty();
scope->SetIsObject();
scope->SetCapturesAll(true);
scope->SetMustInstantiate(!scopeIsEmpty);
}

if (scope->GetHasOwnLocalInClosure())
{
byteCodeGenerator->ProcessScopeWithCapturedSym(scope);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

byteCodeGenerator->ProcessScopeWithCapturedSym(scope); [](start = 8, length = 54)

Why do we have to do this here? Doesn't this happen when we find the captured symbol itself? Or is it to cover the case where the scope is recreated from the ScopeInfo so we have to mark it again? If that is the case should we do this while Restoring the scope?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've been doing this when we find the capturing reference to the symbol. Now that reference may be deferred, so byte code gen won't see it. It would be great to go through and remove the calls at the points where they're no longer needed, but I'm not doing that cleanup as part of this change.

TRACE_BYTECODE(_u("\nSave ScopeInfo: %s parent: %s #symbols: %d %s\n"),
scope->GetFunc()->name, parent ? parent->GetDisplayName() : _u(""), count,
TRACE_BYTECODE(_u("\nSave ScopeInfo: %s #symbols: %d %s\n"),
scope->GetFunc()->name, /*parent ? parent->GetDisplayName() : _u(""),*/ count,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/parent ? parent->GetDisplayName() : _u(""),/ [](start = 36, length = 47)

Don't need this

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for spotting these.

scopeInfo->isObject ? _u("isObject") : _u(""));

MapSymbolData mapSymbolData = { byteCodeGenerator, scope->GetFunc(), 0 };
MapSymbolData mapSymbolData = { /*byteCodeGenerator,*/ scope->GetFunc(), 0 };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/byteCodeGenerator,/ [](start = 40, length = 22)

Don't need this

}

void ScopeInfo::SaveScopeInfoForDeferParse(ByteCodeGenerator* byteCodeGenerator, FuncInfo* parentFunc, FuncInfo* funcInfo)
void ScopeInfo::SaveEnclosingScopeInfo(ByteCodeGenerator* byteCodeGenerator, /*FuncInfo* parentFunc,*/ FuncInfo* funcInfo)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/FuncInfo parentFunc,*/ [](start = 81, length = 25)

Remove this

@aneeshdk
Copy link
Contributor

:shipit:

…ns enclosed in scopes other than function body and function expression scope -- in particular, ES6-style lexical scopes and parameter scopes. This requires changing ScopeInfo so that it is associated with a single scope rather than a function body. Instead of carrying per-function information for body/var scope, parameter scope, and function expression scope, ScopeInfo will describe one scope, with a value identifying the scope type, a pointer to the FunctionInfo that contains it, and a pointer to the enclosing ScopeInfo.. A FunctionProxy will point to the ScopeInfo that is the nearest enclosing scope. At parse time, we will reconstitute the closure environment by walking the list of enclosing ScopeInfo's. The code that allowed redeferral to work around the context limitation of deferring parsing is deleted, and the OptimizeBlockScope feature is off by default, as it doesn't play well with this new logic and isn't required to make (re-)deferral effective. (We will want to revisit it.)
@chakrabot chakrabot merged commit 61cafb8 into chakra-core:master Mar 15, 2017
chakrabot pushed a commit that referenced this pull request Mar 15, 2017
Merge pull request #2666 from pleath:deferfib

Support deferral of functions enclosed in scopes other than function body and function expression scope -- in particular, ES6-style lexical scopes and parameter scopes. This requires changing ScopeInfo so that it is associated with a single scope rather than a function body. Instead of carrying per-function information for body/var scope, parameter scope, and function expression scope, ScopeInfo will describe one scope, with a value identifying the scope type, a pointer to the FunctionInfo that contains it, and a pointer to the enclosing ScopeInfo. A FunctionProxy will point to the ScopeInfo that is the nearest enclosing scope. At parse time, we will reconstitute the closure environment by walking the list of enclosing ScopeInfo's. The code that allowed redeferral to work around the context limitation of deferring parsing is deleted, and the OptimizeBlockScope feature is off by default, as it doesn't play well with this new logic and isn't required to make (re-)deferral effective. (We will want to revisit it, though, so I've left it there.)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants