From 3a3de55aadd9d3a2aafc3638c7a9b0c23584cef4 Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Sun, 1 Dec 2019 19:14:11 -0500 Subject: Bug 1343481 - Part 3: Add JSOP_AWAIT and rename {yieldIndex,yieldOffset} to {yieldAndAwaitIndex,yieldAndAwaitOffset}. Tag #1287 --- js/src/vm/GeneratorObject.cpp | 12 ++++++---- js/src/vm/GeneratorObject.h | 53 ++++++++++++++++++++++--------------------- js/src/vm/Interpreter.cpp | 2 +- js/src/vm/Opcodes.h | 14 +++++++++--- 4 files changed, 47 insertions(+), 34 deletions(-) (limited to 'js/src/vm') diff --git a/js/src/vm/GeneratorObject.cpp b/js/src/vm/GeneratorObject.cpp index c0dff8faa..a61d37132 100644 --- a/js/src/vm/GeneratorObject.cpp +++ b/js/src/vm/GeneratorObject.cpp @@ -64,10 +64,14 @@ bool GeneratorObject::suspend(JSContext* cx, HandleObject obj, AbstractFramePtr frame, jsbytecode* pc, Value* vp, unsigned nvalues) { - MOZ_ASSERT(*pc == JSOP_INITIALYIELD || *pc == JSOP_YIELD); + MOZ_ASSERT(*pc == JSOP_INITIALYIELD || *pc == JSOP_YIELD || *pc == JSOP_AWAIT); Rooted genObj(cx, &obj->as()); MOZ_ASSERT(!genObj->hasExpressionStack()); + MOZ_ASSERT_IF(*pc == JSOP_AWAIT, genObj->callee().isAsync()); + MOZ_ASSERT_IF(*pc == JSOP_YIELD, + genObj->callee().isStarGenerator() || + genObj->callee().isLegacyGenerator()); if (*pc == JSOP_YIELD && genObj->isClosing() && genObj->is()) { RootedValue val(cx, ObjectValue(*frame.callee())); @@ -75,8 +79,8 @@ GeneratorObject::suspend(JSContext* cx, HandleObject obj, AbstractFramePtr frame return false; } - uint32_t yieldIndex = GET_UINT24(pc); - genObj->setYieldIndex(yieldIndex); + uint32_t yieldAndAwaitIndex = GET_UINT24(pc); + genObj->setYieldAndAwaitIndex(yieldAndAwaitIndex); genObj->setEnvironmentChain(*frame.environmentChain()); if (nvalues) { @@ -173,7 +177,7 @@ GeneratorObject::resume(JSContext* cx, InterpreterActivation& activation, } JSScript* script = callee->nonLazyScript(); - uint32_t offset = script->yieldOffsets()[genObj->yieldIndex()]; + uint32_t offset = script->yieldAndAwaitOffsets()[genObj->yieldAndAwaitIndex()]; activation.regs().pc = script->offsetToPC(offset); // Always push on a value, even if we are raising an exception. In the diff --git a/js/src/vm/GeneratorObject.h b/js/src/vm/GeneratorObject.h index ca1452b34..beb15f790 100644 --- a/js/src/vm/GeneratorObject.h +++ b/js/src/vm/GeneratorObject.h @@ -21,15 +21,15 @@ class GeneratorObject : public NativeObject public: // Magic values stored in the yield index slot when the generator is // running or closing. See the yield index comment below. - static const int32_t YIELD_INDEX_RUNNING = INT32_MAX; - static const int32_t YIELD_INDEX_CLOSING = INT32_MAX - 1; + static const int32_t YIELD_AND_AWAIT_INDEX_RUNNING = INT32_MAX; + static const int32_t YIELD_AND_AWAIT_INDEX_CLOSING = INT32_MAX - 1; enum { CALLEE_SLOT = 0, ENV_CHAIN_SLOT, ARGS_OBJ_SLOT, EXPRESSION_STACK_SLOT, - YIELD_INDEX_SLOT, + YIELD_AND_AWAIT_INDEX_SLOT, NEWTARGET_SLOT, RESERVED_SLOTS }; @@ -124,47 +124,48 @@ class GeneratorObject : public NativeObject // The yield index slot is abused for a few purposes. It's undefined if // it hasn't been set yet (before the initial yield), and null if the // generator is closed. If the generator is running, the yield index is - // YIELD_INDEX_RUNNING. If the generator is in that bizarre "closing" - // state, the yield index is YIELD_INDEX_CLOSING. + // YIELD_AND_AWAIT_INDEX_RUNNING. If the generator is in that bizarre + // "closing" state, the yield index is YIELD_AND_AWAIT_INDEX_CLOSING. // // If the generator is suspended, it's the yield index (stored as - // JSOP_INITIALYIELD/JSOP_YIELD operand) of the yield instruction that - // suspended the generator. The yield index can be mapped to the bytecode - // offset (interpreter) or to the native code offset (JIT). + // JSOP_INITIALYIELD/JSOP_YIELD/JSOP_AWAIT operand) of the yield + // instruction that suspended the generator. The yield index can be mapped + // to the bytecode offset (interpreter) or to the native code offset (JIT). bool isRunning() const { MOZ_ASSERT(!isClosed()); - return getFixedSlot(YIELD_INDEX_SLOT).toInt32() == YIELD_INDEX_RUNNING; + return getFixedSlot(YIELD_AND_AWAIT_INDEX_SLOT).toInt32() == YIELD_AND_AWAIT_INDEX_RUNNING; } bool isClosing() const { - return getFixedSlot(YIELD_INDEX_SLOT).toInt32() == YIELD_INDEX_CLOSING; + return getFixedSlot(YIELD_AND_AWAIT_INDEX_SLOT).toInt32() == YIELD_AND_AWAIT_INDEX_CLOSING; } bool isSuspended() const { // Note: also update Baseline's IsSuspendedStarGenerator code if this // changes. MOZ_ASSERT(!isClosed()); - static_assert(YIELD_INDEX_CLOSING < YIELD_INDEX_RUNNING, - "test below should return false for YIELD_INDEX_RUNNING"); - return getFixedSlot(YIELD_INDEX_SLOT).toInt32() < YIELD_INDEX_CLOSING; + static_assert(YIELD_AND_AWAIT_INDEX_CLOSING < YIELD_AND_AWAIT_INDEX_RUNNING, + "test below should return false for YIELD_AND_AWAIT_INDEX_RUNNING"); + return getFixedSlot(YIELD_AND_AWAIT_INDEX_SLOT).toInt32() < YIELD_AND_AWAIT_INDEX_CLOSING; } void setRunning() { MOZ_ASSERT(isSuspended()); - setFixedSlot(YIELD_INDEX_SLOT, Int32Value(YIELD_INDEX_RUNNING)); + setFixedSlot(YIELD_AND_AWAIT_INDEX_SLOT, Int32Value(YIELD_AND_AWAIT_INDEX_RUNNING)); } void setClosing() { MOZ_ASSERT(isSuspended()); - setFixedSlot(YIELD_INDEX_SLOT, Int32Value(YIELD_INDEX_CLOSING)); - } - void setYieldIndex(uint32_t yieldIndex) { - MOZ_ASSERT_IF(yieldIndex == 0, getFixedSlot(YIELD_INDEX_SLOT).isUndefined()); - MOZ_ASSERT_IF(yieldIndex != 0, isRunning() || isClosing()); - MOZ_ASSERT(yieldIndex < uint32_t(YIELD_INDEX_CLOSING)); - setFixedSlot(YIELD_INDEX_SLOT, Int32Value(yieldIndex)); + setFixedSlot(YIELD_AND_AWAIT_INDEX_SLOT, Int32Value(YIELD_AND_AWAIT_INDEX_CLOSING)); + } + void setYieldAndAwaitIndex(uint32_t yieldAndAwaitIndex) { + MOZ_ASSERT_IF(yieldAndAwaitIndex == 0, + getFixedSlot(YIELD_AND_AWAIT_INDEX_SLOT).isUndefined()); + MOZ_ASSERT_IF(yieldAndAwaitIndex != 0, isRunning() || isClosing()); + MOZ_ASSERT(yieldAndAwaitIndex < uint32_t(YIELD_AND_AWAIT_INDEX_CLOSING)); + setFixedSlot(YIELD_AND_AWAIT_INDEX_SLOT, Int32Value(yieldAndAwaitIndex)); MOZ_ASSERT(isSuspended()); } - uint32_t yieldIndex() const { + uint32_t yieldAndAwaitIndex() const { MOZ_ASSERT(isSuspended()); - return getFixedSlot(YIELD_INDEX_SLOT).toInt32(); + return getFixedSlot(YIELD_AND_AWAIT_INDEX_SLOT).toInt32(); } bool isClosed() const { return getFixedSlot(CALLEE_SLOT).isNull(); @@ -174,7 +175,7 @@ class GeneratorObject : public NativeObject setFixedSlot(ENV_CHAIN_SLOT, NullValue()); setFixedSlot(ARGS_OBJ_SLOT, NullValue()); setFixedSlot(EXPRESSION_STACK_SLOT, NullValue()); - setFixedSlot(YIELD_INDEX_SLOT, NullValue()); + setFixedSlot(YIELD_AND_AWAIT_INDEX_SLOT, NullValue()); setFixedSlot(NEWTARGET_SLOT, NullValue()); } @@ -187,8 +188,8 @@ class GeneratorObject : public NativeObject static size_t offsetOfArgsObjSlot() { return getFixedSlotOffset(ARGS_OBJ_SLOT); } - static size_t offsetOfYieldIndexSlot() { - return getFixedSlotOffset(YIELD_INDEX_SLOT); + static size_t offsetOfYieldAndAwaitIndexSlot() { + return getFixedSlotOffset(YIELD_AND_AWAIT_INDEX_SLOT); } static size_t offsetOfExpressionStackSlot() { return getFixedSlotOffset(EXPRESSION_STACK_SLOT); diff --git a/js/src/vm/Interpreter.cpp b/js/src/vm/Interpreter.cpp index 030f0f3b6..92bb18b36 100644 --- a/js/src/vm/Interpreter.cpp +++ b/js/src/vm/Interpreter.cpp @@ -1940,7 +1940,6 @@ CASE(JSOP_NOP) CASE(JSOP_NOP_DESTRUCTURING) CASE(JSOP_UNUSED126) CASE(JSOP_UNUSED192) -CASE(JSOP_UNUSED209) CASE(JSOP_UNUSED210) CASE(JSOP_UNUSED211) CASE(JSOP_TRY_DESTRUCTURING_ITERCLOSE) @@ -3994,6 +3993,7 @@ CASE(JSOP_INITIALYIELD) } CASE(JSOP_YIELD) +CASE(JSOP_AWAIT) { MOZ_ASSERT(!cx->isExceptionPending()); MOZ_ASSERT(REGS.fp()->isFunctionFrame()); diff --git a/js/src/vm/Opcodes.h b/js/src/vm/Opcodes.h index 3c4d61a67..b44628080 100644 --- a/js/src/vm/Opcodes.h +++ b/js/src/vm/Opcodes.h @@ -2055,7 +2055,7 @@ * interpretation. * Category: Statements * Type: Generator - * Operands: uint24_t yieldIndex + * Operands: uint24_t yieldAndAwaitIndex * Stack: generator => */ \ macro(JSOP_INITIALYIELD, 202,"initialyield", NULL, 4, 1, 1, JOF_UINT24) \ @@ -2064,7 +2064,7 @@ * returns 'rval1'. Pushes sent value from 'send()' onto the stack. * Category: Statements * Type: Generator - * Operands: uint24_t yieldIndex + * Operands: uint24_t yieldAndAwaitIndex * Stack: rval1, gen => rval2 */ \ macro(JSOP_YIELD, 203,"yield", NULL, 4, 2, 1, JOF_UINT24) \ @@ -2119,7 +2119,15 @@ * Stack: => */ \ macro(JSOP_DEBUGAFTERYIELD, 208, "debugafteryield", NULL, 1, 0, 0, JOF_BYTE) \ - macro(JSOP_UNUSED209, 209, "unused209", NULL, 1, 0, 0, JOF_BYTE) \ + /* + * Pops the generator and the return value 'result', stops interpretation + * and returns 'result'. Pushes resolved value onto the stack. + * Category: Statements + * Type: Generator + * Operands: uint24_t yieldAndAwaitIndex + * Stack: result, gen => resolved + */ \ + macro(JSOP_AWAIT, 209, "await", NULL, 4, 2, 1, JOF_UINT24) \ macro(JSOP_UNUSED210, 210, "unused210", NULL, 1, 0, 0, JOF_BYTE) \ macro(JSOP_UNUSED211, 211, "unused211", NULL, 1, 0, 0, JOF_BYTE) \ /* -- cgit v1.2.3