Comment #1 on issue 4163 by [email protected]: Construct on generator
functions
https://code.google.com/p/v8/issues/detail?id=4163
I think it's correct. Declarations like:
function* g() {}
Are created like this:
14.4.14 Runtime Semantics: Evaluation
GeneratorExpression : function * ( FormalParameters ) { GeneratorBody }
[...]
3. Let closure be GeneratorFunctionCreate(Normal, FormalParameters,
GeneratorBody, scope, strict).
[...]
GeneratorExpression : function * BindingIdentifier ( FormalParameters ) {
GeneratorBody }
[...]
7. Let closure be GeneratorFunctionCreate(Normal, FormalParameters,
GeneratorBody, funcEnv, strict).
[...]
https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generator-function-definitions-runtime-semantics-evaluation
9.2.6 GeneratorFunctionCreate (kind, ParameterList, Body, Scope, Strict)
1. Let functionPrototype be the intrinsic object %Generator%.
2. Let F be FunctionAllocate(functionPrototype, Strict, "generator").
[...]
https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorfunctioncreate
9.2.3 FunctionAllocate (functionPrototype, strict [,functionKind] )
[...]
4. If functionKind is "non-constructor", then
a. Let functionKind be "normal".
b. Let needsConstruct be false.
5. Else let needsConstruct be true.
[...]
9. If needsConstruct is true, then
a. Set F’s [[Construct]] internal method to the definition specified in
9.2.2.
b. If functionKind is "generator", set the [[ConstructorKind]] internal
slot of F to "derived".
c. Else, set the [[ConstructorKind]] internal slot of F to "base".
d. NOTE Generator functions are tagged as "derived" constructors to
prevent [[Construct]] from preallocating a generator instance.
Generator instance objects are allocated when EvaluateBody is
applied
to the GeneratorBody of a generator function.
[...]
https://people.mozilla.org/~jorendorff/es6-draft.html#sec-functionallocate
The [[ConstructorKind]] interal attribute of all generator functions is
therefore "derived". This matters when "instantiating" an iterable by
invoking
a generator function via `new`:
9.2.2 [[Construct]] ( argumentsList, newTarget)
[...]
4. Let kind be F’s [[ConstructorKind]] internal slot.
[...]
6. Let calleeContext be PrepareForOrdinaryCall(F, newTarget).
[...]
8. If kind is "base", perform OrdinaryCallBindThis(F, calleeContext,
thisArgument).
[...]
https://people.mozilla.org/~jorendorff/es6-draft.html#sec-ecmascript-function-objects-construct-argumentslist-newtarget
Step 6 unconditionally sets [[thisBindingStatus]] to "uninitialized" via
NewFunctionEnvironment (see
https://people.mozilla.org/~jorendorff/es6-draft.html#sec-newfunctionenvironment).
Step 8 is *not* taken in this case. That's critical because it is what
ultimately allows the `this` keyword to operate in normal functions:
9.2.1.2 OrdinaryCallBindThis ( F, calleeContext, thisArgument )
[...]
9. Return envRec.BindThisValue(thisValue).
https://people.mozilla.org/~jorendorff/es6-draft.html#sec-ordinarycallbindthis
8.1.1.3.1 BindThisValue(V)
1. Let envRec be the function Environment Record for which the method was
invoked.
2. Assert: envRec.[[thisBindingStatus]] is not "lexical".
3. If envRec.[[thisBindingStatus]] is "initialized", throw a
ReferenceError exception.
4. Set envRec.[[thisValue]] to V.
5. Set envRec.[[thisBindingStatus]] to "initialized".
6. Return V.
https://people.mozilla.org/~jorendorff/es6-draft.html#sec-bindthisvalue
So advancing an iterable created in this way:
iter.next();
begins execution of the function body. A `this` reference looks like:
12.2.1.1 Runtime Semantics: Evaluation
PrimaryExpression : this
1. Return ResolveThisBinding( ) .
https://people.mozilla.org/~jorendorff/es6-draft.html#sec-this-keyword
8.3.3 ResolveThisBinding ( )
1. Let envRec be GetThisEnvironment( ).
2. Return envRec.GetThisBinding().
https://people.mozilla.org/~jorendorff/es6-draft.html#sec-resolvethisbinding
8.1.1.3.4 GetThisBinding ()
1. Let envRec be the function Environment Record for which the method was
invoked.
2. Assert: envRec.[[thisBindingStatus]] is not "lexical".
3. If envRec.[[thisBindingStatus]] is "uninitialized", throw a
ReferenceError exception.
4. Return envRec.[[thisValue]].
https://people.mozilla.org/~jorendorff/es6-draft.html#sec-function-environment-records-getthisbinding
...and there's your ReferenceError!
--
You received this message because this project is configured to send all
issue notifications to this address.
You may adjust your notification preferences at:
https://code.google.com/hosting/settings
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.