Closed Bug 1166950 Opened 10 years ago Closed 9 years ago

Generator methods incorrectly restricted from use as constructors

Categories

(Core :: JavaScript Engine, defect)

defect
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla41
Tracking Status
firefox41 --- fixed

People

(Reporter: jugglinmike, Assigned: evilpie)

References

(Blocks 1 open bug)

Details

Attachments

(3 files)

Input: var g = { *g() {} }.g; new g(); Expected: an object is created whose [[Prototype]] internal slot is the generator function defined in the object initializer. Actual: TypeError Demo: $ js -e "var g = { *g() {} }.g; new g();" -e:1:27 TypeError: g is not a constructor "Normal" functions declared within object initializers using the MethodDefinition syntax do not defined a [[Construct]] internal method and cannot be used as constructors. The same is not true for generator functions: > 14.4.13 Runtime Semantics: PropertyDefinitionEvaluation > > GeneratorMethod : * PropertyName ( StrictFormalParameters ) { GeneratorBody } > > [...] > 5. Let closure be GeneratorFunctionCreate(Method, StrictFormalParameters, > GeneratorBody, scope, strict). > 6. Perform MakeMethod(closure, object). > 7. Let prototype be ObjectCreate(%GeneratorPrototype%). > 8. Perform MakeConstructor(closure, true, prototype). > [...] > 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"). > 3. Return FunctionInitialize(F, kind, ParameterList, Body, Scope). > 9.2.3 FunctionAllocate (functionPrototype, strict [,functionKind] ) > > [...] > 3. If functionKind is not present, let functionKind be "normal". > 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. Sources: - https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generator-function-definitions-runtime-semantics-propertydefinitionevaluation - https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorfunctioncreate - https://people.mozilla.org/~jorendorff/es6-draft.html#sec-functionallocate
Blocks: es6
See Also: → 1059908
And Method Definitions except for GeneratorMethod should not have a prototype property: js> ({m(){}}).m.hasOwnProperty("prototype") true // should be false js> ({*g(){}}).g.hasOwnProperty("prototype") true // √ js> (class {constructor(){} static m(){}}).m.hasOwnProperty("prototype") true // should be false js> (class {constructor(){} static *g(){}}).g.hasOwnProperty("prototype") true // √ js> (new (class {constructor(){} m(){}})).m.hasOwnProperty("prototype") true // should be false js> (new (class {constructor(){} *g(){}})).g.hasOwnProperty("prototype") true // √ js> Object.getOwnPropertyDescriptor({set m(_){}}, "m").set.hasOwnProperty("prototype") true // should be false js> Object.getOwnPropertyDescriptor({get m(){}}, "m").get.hasOwnProperty("prototype") true // should be false
See Also: → 1069402
Assignee: nobody → evilpies
Attachment #8609834 - Flags: review?(efaustbmo)
Attachment #8609835 - Flags: review?(efaustbmo)
Attachment #8609836 - Flags: review?(efaustbmo)
Comment on attachment 8609834 [details] [diff] [review] Introduce a new FunctionKind for class-constructors Review of attachment 8609834 [details] [diff] [review]: ----------------------------------------------------------------- Looks fine. ::: js/src/jsfun.h @@ +165,5 @@ > > // Arrow functions store their lexical |this| in the first extended slot. > bool isArrow() const { return kind() == Arrow; } > // Every class-constructor is also a method. > + bool isMethod() const { return kind() == Method || kind() == ClassConstructor; } nit: || isClassConstructor()
Attachment #8609834 - Flags: review?(efaustbmo) → review+
Comment on attachment 8609835 [details] [diff] [review] Make generator methods constructors Review of attachment 8609835 [details] [diff] [review]: ----------------------------------------------------------------- Yup
Attachment #8609835 - Flags: review?(efaustbmo) → review+
Comment on attachment 8609836 [details] [diff] [review] Only give constructor functions a prototype Review of attachment 8609836 [details] [diff] [review]: ----------------------------------------------------------------- Thanks for taking this, too.
Attachment #8609836 - Flags: review?(efaustbmo) → review+
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: