diff --git a/js/src/frontend/BytecodeEmitter.cpp b/js/src/frontend/BytecodeEmitter.cpp index 9932a63b58..75d1fbfddb 100644 --- a/js/src/frontend/BytecodeEmitter.cpp +++ b/js/src/frontend/BytecodeEmitter.cpp @@ -7615,11 +7615,43 @@ BytecodeEmitter::emitPropertyList(ListNode* obj, PropertyEmitter& pe, PropListTy { // [stack] CTOR? OBJ + size_t curFieldKeyIndex = 0; for (ParseNode* propdef : obj->contents()) { if (propdef->is()) { - // Skip over class fields and emit them at the end. This is needed - // because they're all emitted into a single array, which is then stored - // into a local variable + MOZ_ASSERT(type == ClassBody); + // Only handle computing field keys here: the .initializers lambda array + // is created elsewhere. + ClassField* field = &propdef->as(); + if (field->name().getKind() == PNK_COMPUTED_NAME) { + if (!emitGetName(cx->names().dotFieldKeys)) { + // [stack] CTOR? OBJ ARRAY + return false; + } + + ParseNode* nameExpr = field->name().as().kid(); + + if (!emitTree(nameExpr)) { + // [stack] ARRAY KEY + return false; + } + + if (!emit1(JSOP_TOID)) { + // [stack] ARRAY KEY + return false; + } + + if (!emitUint32Operand(JSOP_INITELEM_ARRAY, curFieldKeyIndex)) { + // [stack] ARRAY + return false; + } + + if (!emit1(JSOP_POP)) { + // [stack] CTOR? OBJ + return false; + } + + curFieldKeyIndex++; + } continue; } @@ -7903,7 +7935,8 @@ BytecodeEmitter::setupFieldInitializers(ListNode* classMembers) // } // } // -// BytecodeEmitter::emitCreateFieldKeys does `let .fieldKeys = [keyExpr, ...];` +// BytecodeEmitter::emitCreateFieldKeys does `let .fieldKeys = [...];` +// BytecodeEmitter::emitPropertyList fills in the elements of the array. // See Parser::fieldInitializer for the `this[.fieldKeys[0]]` part. bool BytecodeEmitter::emitCreateFieldKeys(ListNode* obj) @@ -7931,34 +7964,6 @@ BytecodeEmitter::emitCreateFieldKeys(ListNode* obj) return false; } - size_t curFieldKeyIndex = 0; - for (ParseNode* propdef : obj->contents()) { - if (propdef->is()) { - ClassField* field = &propdef->as(); - if (field->name().getKind() == PNK_COMPUTED_NAME) { - ParseNode* nameExpr = field->name().as().kid(); - - if (!emitTree(nameExpr)) { - // [stack] ARRAY KEY - return false; - } - - if (!emit1(JSOP_TOID)) { - // [stack] ARRAY KEY - return false; - } - - if (!emitUint32Operand(JSOP_INITELEM_ARRAY, curFieldKeyIndex)) { - // [stack] ARRAY - return false; - } - - curFieldKeyIndex++; - } - } - } - MOZ_ASSERT(curFieldKeyIndex == numFieldKeys); - if (!noe.emitAssignment()) { // [stack] ARRAY return false; @@ -8690,14 +8695,15 @@ BytecodeEmitter::emitClass(ClassNode* classNode) return false; } } + + if (!emitCreateFieldKeys(classMembers)) + return false; + if (!emitPropertyList(classMembers, ce, ClassBody)) { // [stack] CTOR HOMEOBJ return false; } - if (!emitCreateFieldKeys(classMembers)) - return false; - if (!ce.emitEnd(kind)) { // [stack] # class declaration // [stack]