summaryrefslogtreecommitdiffstats
path: root/js/src/vm
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/vm')
-rw-r--r--js/src/vm/GeneratorObject.cpp12
-rw-r--r--js/src/vm/GeneratorObject.h53
-rw-r--r--js/src/vm/Interpreter.cpp2
-rw-r--r--js/src/vm/Opcodes.h14
4 files changed, 47 insertions, 34 deletions
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<GeneratorObject*> genObj(cx, &obj->as<GeneratorObject>());
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<LegacyGeneratorObject>()) {
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) \
/*