summaryrefslogtreecommitdiffstats
path: root/js/src/jit
diff options
context:
space:
mode:
authorMoonchild <moonchild@palemoon.org>2019-12-17 21:47:18 +0000
committerGitHub <noreply@github.com>2019-12-17 21:47:18 +0000
commit07d0bcbf112a4e274905837c6ea0b0212b51e4e3 (patch)
tree3b43cb63b33d82d4965d402aca39028836983bb4 /js/src/jit
parente2de507e0261c9b138cd3cf5356c21eca3e7a28d (diff)
parent6c3e42ac6427fabaf83b5acc7877aa3d15117125 (diff)
downloadUXP-07d0bcbf112a4e274905837c6ea0b0212b51e4e3.tar
UXP-07d0bcbf112a4e274905837c6ea0b0212b51e4e3.tar.gz
UXP-07d0bcbf112a4e274905837c6ea0b0212b51e4e3.tar.lz
UXP-07d0bcbf112a4e274905837c6ea0b0212b51e4e3.tar.xz
UXP-07d0bcbf112a4e274905837c6ea0b0212b51e4e3.zip
Merge pull request #1327 from g4jc/async_iteration
Implement Async Iteration in SpiderMonkey This resolves #1287
Diffstat (limited to 'js/src/jit')
-rw-r--r--js/src/jit/BaselineCompiler.cpp94
-rw-r--r--js/src/jit/BaselineCompiler.h11
-rw-r--r--js/src/jit/BaselineIC.cpp7
-rw-r--r--js/src/jit/BaselineJIT.cpp6
-rw-r--r--js/src/jit/BaselineJIT.h2
-rw-r--r--js/src/jit/CodeGenerator.cpp23
-rw-r--r--js/src/jit/CodeGenerator.h2
-rw-r--r--js/src/jit/Ion.cpp11
-rw-r--r--js/src/jit/IonAnalysis.cpp8
-rw-r--r--js/src/jit/IonBuilder.cpp36
-rw-r--r--js/src/jit/IonBuilder.h2
-rw-r--r--js/src/jit/Lowering.cpp16
-rw-r--r--js/src/jit/Lowering.h2
-rw-r--r--js/src/jit/MIR.h30
-rw-r--r--js/src/jit/MOpcodes.h2
-rw-r--r--js/src/jit/VMFunctions.cpp4
-rw-r--r--js/src/jit/shared/LIR-shared.h26
-rw-r--r--js/src/jit/shared/LOpcodes-shared.h2
18 files changed, 247 insertions, 37 deletions
diff --git a/js/src/jit/BaselineCompiler.cpp b/js/src/jit/BaselineCompiler.cpp
index b2f9d3b23..d254b9826 100644
--- a/js/src/jit/BaselineCompiler.cpp
+++ b/js/src/jit/BaselineCompiler.cpp
@@ -25,6 +25,7 @@
#include "jit/VMFunctions.h"
#include "js/UniquePtr.h"
#include "vm/AsyncFunction.h"
+#include "vm/AsyncIteration.h"
#include "vm/EnvironmentObject.h"
#include "vm/Interpreter.h"
#include "vm/TraceLogging.h"
@@ -43,7 +44,7 @@ using mozilla::AssertedCast;
BaselineCompiler::BaselineCompiler(JSContext* cx, TempAllocator& alloc, JSScript* script)
: BaselineCompilerSpecific(cx, alloc, script),
- yieldOffsets_(cx),
+ yieldAndAwaitOffsets_(cx),
modifiesArguments_(false)
{
}
@@ -210,7 +211,7 @@ BaselineCompiler::compile()
pcMappingIndexEntries.length(),
pcEntries.length(),
bytecodeTypeMapEntries,
- yieldOffsets_.length(),
+ yieldAndAwaitOffsets_.length(),
traceLoggerToggleOffsets_.length()),
JS::DeletePolicy<BaselineScript>(cx->runtime()));
if (!baselineScript) {
@@ -275,7 +276,7 @@ BaselineCompiler::compile()
// searches for the sought entry when queries are in linear order.
bytecodeMap[script->nTypeSets()] = 0;
- baselineScript->copyYieldEntries(script, yieldOffsets_);
+ baselineScript->copyYieldAndAwaitEntries(script, yieldAndAwaitOffsets_);
if (compileDebugInstrumentation_)
baselineScript->setHasDebugInstrumentation();
@@ -3908,6 +3909,50 @@ BaselineCompiler::emit_JSOP_TOASYNC()
return true;
}
+typedef JSObject* (*ToAsyncGenFn)(JSContext*, HandleFunction);
+static const VMFunction ToAsyncGenInfo =
+ FunctionInfo<ToAsyncGenFn>(js::WrapAsyncGenerator, "ToAsyncGen");
+
+bool
+BaselineCompiler::emit_JSOP_TOASYNCGEN()
+{
+ frame.syncStack(0);
+ masm.unboxObject(frame.addressOfStackValue(frame.peek(-1)), R0.scratchReg());
+
+ prepareVMCall();
+ pushArg(R0.scratchReg());
+
+ if (!callVM(ToAsyncGenInfo))
+ return false;
+
+ masm.tagValue(JSVAL_TYPE_OBJECT, ReturnReg, R0);
+ frame.pop();
+ frame.push(R0);
+ return true;
+}
+
+typedef JSObject* (*ToAsyncIterFn)(JSContext*, HandleObject);
+static const VMFunction ToAsyncIterInfo =
+ FunctionInfo<ToAsyncIterFn>(js::CreateAsyncFromSyncIterator, "ToAsyncIter");
+
+bool
+BaselineCompiler::emit_JSOP_TOASYNCITER()
+{
+ frame.syncStack(0);
+ masm.unboxObject(frame.addressOfStackValue(frame.peek(-1)), R0.scratchReg());
+
+ prepareVMCall();
+ pushArg(R0.scratchReg());
+
+ if (!callVM(ToAsyncIterInfo))
+ return false;
+
+ masm.tagValue(JSVAL_TYPE_OBJECT, ReturnReg, R0);
+ frame.pop();
+ frame.push(R0);
+ return true;
+}
+
typedef bool (*ThrowObjectCoercibleFn)(JSContext*, HandleValue);
static const VMFunction ThrowObjectCoercibleInfo =
FunctionInfo<ThrowObjectCoercibleFn>(ThrowObjectCoercible, "ThrowObjectCoercible");
@@ -4174,27 +4219,28 @@ BaselineCompiler::emit_JSOP_GENERATOR()
}
bool
-BaselineCompiler::addYieldOffset()
+BaselineCompiler::addYieldAndAwaitOffset()
{
- MOZ_ASSERT(*pc == JSOP_INITIALYIELD || *pc == JSOP_YIELD);
+ MOZ_ASSERT(*pc == JSOP_INITIALYIELD || *pc == JSOP_YIELD || *pc == JSOP_AWAIT);
- uint32_t yieldIndex = GET_UINT24(pc);
+ uint32_t yieldAndAwaitIndex = GET_UINT24(pc);
- while (yieldIndex >= yieldOffsets_.length()) {
- if (!yieldOffsets_.append(0))
+ while (yieldAndAwaitIndex >= yieldAndAwaitOffsets_.length()) {
+ if (!yieldAndAwaitOffsets_.append(0))
return false;
}
- static_assert(JSOP_INITIALYIELD_LENGTH == JSOP_YIELD_LENGTH,
- "code below assumes INITIALYIELD and YIELD have same length");
- yieldOffsets_[yieldIndex] = script->pcToOffset(pc + JSOP_YIELD_LENGTH);
+ static_assert(JSOP_INITIALYIELD_LENGTH == JSOP_YIELD_LENGTH &&
+ JSOP_INITIALYIELD_LENGTH == JSOP_AWAIT_LENGTH,
+ "code below assumes INITIALYIELD and YIELD and AWAIT have same length");
+ yieldAndAwaitOffsets_[yieldAndAwaitIndex] = script->pcToOffset(pc + JSOP_YIELD_LENGTH);
return true;
}
bool
BaselineCompiler::emit_JSOP_INITIALYIELD()
{
- if (!addYieldOffset())
+ if (!addYieldAndAwaitOffset())
return false;
frame.syncStack(0);
@@ -4204,7 +4250,8 @@ BaselineCompiler::emit_JSOP_INITIALYIELD()
masm.unboxObject(frame.addressOfStackValue(frame.peek(-1)), genObj);
MOZ_ASSERT(GET_UINT24(pc) == 0);
- masm.storeValue(Int32Value(0), Address(genObj, GeneratorObject::offsetOfYieldIndexSlot()));
+ masm.storeValue(Int32Value(0),
+ Address(genObj, GeneratorObject::offsetOfYieldAndAwaitIndexSlot()));
Register envObj = R0.scratchReg();
Address envChainSlot(genObj, GeneratorObject::offsetOfEnvironmentChainSlot());
@@ -4233,7 +4280,7 @@ static const VMFunction NormalSuspendInfo =
bool
BaselineCompiler::emit_JSOP_YIELD()
{
- if (!addYieldOffset())
+ if (!addYieldAndAwaitOffset())
return false;
// Store generator in R0.
@@ -4250,7 +4297,7 @@ BaselineCompiler::emit_JSOP_YIELD()
// generator is in the closing state, see GeneratorObject::suspend.
masm.storeValue(Int32Value(GET_UINT24(pc)),
- Address(genObj, GeneratorObject::offsetOfYieldIndexSlot()));
+ Address(genObj, GeneratorObject::offsetOfYieldAndAwaitIndexSlot()));
Register envObj = R0.scratchReg();
Address envChainSlot(genObj, GeneratorObject::offsetOfEnvironmentChainSlot());
@@ -4282,6 +4329,12 @@ BaselineCompiler::emit_JSOP_YIELD()
return emitReturn();
}
+bool
+BaselineCompiler::emit_JSOP_AWAIT()
+{
+ return emit_JSOP_YIELD();
+}
+
typedef bool (*DebugAfterYieldFn)(JSContext*, BaselineFrame*);
static const VMFunction DebugAfterYieldInfo =
FunctionInfo<DebugAfterYieldFn>(jit::DebugAfterYield, "DebugAfterYield");
@@ -4501,16 +4554,17 @@ BaselineCompiler::emit_JSOP_RESUME()
masm.pushValue(retVal);
if (resumeKind == GeneratorObject::NEXT) {
- // Determine the resume address based on the yieldIndex and the
- // yieldIndex -> native table in the BaselineScript.
+ // Determine the resume address based on the yieldAndAwaitIndex and the
+ // yieldAndAwaitIndex -> native table in the BaselineScript.
masm.load32(Address(scratch1, BaselineScript::offsetOfYieldEntriesOffset()), scratch2);
masm.addPtr(scratch2, scratch1);
- masm.unboxInt32(Address(genObj, GeneratorObject::offsetOfYieldIndexSlot()), scratch2);
+ masm.unboxInt32(Address(genObj, GeneratorObject::offsetOfYieldAndAwaitIndexSlot()),
+ scratch2);
masm.loadPtr(BaseIndex(scratch1, scratch2, ScaleFromElemWidth(sizeof(uintptr_t))), scratch1);
// Mark as running and jump to the generator's JIT code.
- masm.storeValue(Int32Value(GeneratorObject::YIELD_INDEX_RUNNING),
- Address(genObj, GeneratorObject::offsetOfYieldIndexSlot()));
+ masm.storeValue(Int32Value(GeneratorObject::YIELD_AND_AWAIT_INDEX_RUNNING),
+ Address(genObj, GeneratorObject::offsetOfYieldAndAwaitIndexSlot()));
masm.jump(scratch1);
} else {
MOZ_ASSERT(resumeKind == GeneratorObject::THROW || resumeKind == GeneratorObject::CLOSE);
diff --git a/js/src/jit/BaselineCompiler.h b/js/src/jit/BaselineCompiler.h
index 95e0c77ad..a200f7ab9 100644
--- a/js/src/jit/BaselineCompiler.h
+++ b/js/src/jit/BaselineCompiler.h
@@ -196,6 +196,8 @@ namespace jit {
_(JSOP_RUNONCE) \
_(JSOP_REST) \
_(JSOP_TOASYNC) \
+ _(JSOP_TOASYNCGEN) \
+ _(JSOP_TOASYNCITER) \
_(JSOP_TOID) \
_(JSOP_TOSTRING) \
_(JSOP_TABLESWITCH) \
@@ -207,6 +209,7 @@ namespace jit {
_(JSOP_GENERATOR) \
_(JSOP_INITIALYIELD) \
_(JSOP_YIELD) \
+ _(JSOP_AWAIT) \
_(JSOP_DEBUGAFTERYIELD) \
_(JSOP_FINALYIELDRVAL) \
_(JSOP_RESUME) \
@@ -255,9 +258,9 @@ class BaselineCompiler : public BaselineCompilerSpecific
// equivalent positions when debug mode is off.
CodeOffset postDebugPrologueOffset_;
- // For each INITIALYIELD or YIELD op, this Vector maps the yield index
- // to the bytecode offset of the next op.
- Vector<uint32_t> yieldOffsets_;
+ // For each INITIALYIELD or YIELD or AWAIT op, this Vector maps the yield
+ // index to the bytecode offset of the next op.
+ Vector<uint32_t> yieldAndAwaitOffsets_;
// Whether any on stack arguments are modified.
bool modifiesArguments_;
@@ -349,7 +352,7 @@ class BaselineCompiler : public BaselineCompilerSpecific
MOZ_MUST_USE bool addPCMappingEntry(bool addIndexEntry);
- MOZ_MUST_USE bool addYieldOffset();
+ MOZ_MUST_USE bool addYieldAndAwaitOffset();
void getEnvironmentCoordinateObject(Register reg);
Address getEnvironmentCoordinateAddressFromObject(Register objReg, Register reg);
diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp
index 9530f65fa..e65f10aac 100644
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -6600,12 +6600,13 @@ ICCall_IsSuspendedStarGenerator::Compiler::generateStubCode(MacroAssembler& masm
masm.branchTestObjClass(Assembler::NotEqual, genObj, scratch, &StarGeneratorObject::class_,
&returnFalse);
- // If the yield index slot holds an int32 value < YIELD_INDEX_CLOSING,
+ // If the yield index slot holds an int32 value < YIELD_AND_AWAIT_INDEX_CLOSING,
// the generator is suspended.
- masm.loadValue(Address(genObj, GeneratorObject::offsetOfYieldIndexSlot()), argVal);
+ masm.loadValue(Address(genObj, GeneratorObject::offsetOfYieldAndAwaitIndexSlot()), argVal);
masm.branchTestInt32(Assembler::NotEqual, argVal, &returnFalse);
masm.unboxInt32(argVal, scratch);
- masm.branch32(Assembler::AboveOrEqual, scratch, Imm32(StarGeneratorObject::YIELD_INDEX_CLOSING),
+ masm.branch32(Assembler::AboveOrEqual, scratch,
+ Imm32(StarGeneratorObject::YIELD_AND_AWAIT_INDEX_CLOSING),
&returnFalse);
masm.moveValue(BooleanValue(true), R0);
diff --git a/js/src/jit/BaselineJIT.cpp b/js/src/jit/BaselineJIT.cpp
index 5c21926b5..94e018252 100644
--- a/js/src/jit/BaselineJIT.cpp
+++ b/js/src/jit/BaselineJIT.cpp
@@ -760,12 +760,12 @@ BaselineScript::icEntryFromReturnAddress(uint8_t* returnAddr)
}
void
-BaselineScript::copyYieldEntries(JSScript* script, Vector<uint32_t>& yieldOffsets)
+BaselineScript::copyYieldAndAwaitEntries(JSScript* script, Vector<uint32_t>& yieldAndAwaitOffsets)
{
uint8_t** entries = yieldEntryList();
- for (size_t i = 0; i < yieldOffsets.length(); i++) {
- uint32_t offset = yieldOffsets[i];
+ for (size_t i = 0; i < yieldAndAwaitOffsets.length(); i++) {
+ uint32_t offset = yieldAndAwaitOffsets[i];
entries[i] = nativeCodeForPC(script, script->offsetToPC(offset));
}
}
diff --git a/js/src/jit/BaselineJIT.h b/js/src/jit/BaselineJIT.h
index 5e7775a61..b6ccd2ff9 100644
--- a/js/src/jit/BaselineJIT.h
+++ b/js/src/jit/BaselineJIT.h
@@ -397,7 +397,7 @@ struct BaselineScript
void copyICEntries(JSScript* script, const BaselineICEntry* entries, MacroAssembler& masm);
void adoptFallbackStubs(FallbackICStubSpace* stubSpace);
- void copyYieldEntries(JSScript* script, Vector<uint32_t>& yieldOffsets);
+ void copyYieldAndAwaitEntries(JSScript* script, Vector<uint32_t>& yieldAndAwaitOffsets);
PCMappingIndexEntry& pcMappingIndexEntry(size_t index);
CompactBufferReader pcMappingReader(size_t indexEntry);
diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp
index 205812942..2b1c671d1 100644
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -41,6 +41,7 @@
#include "jit/RangeAnalysis.h"
#include "jit/SharedICHelpers.h"
#include "vm/AsyncFunction.h"
+#include "vm/AsyncIteration.h"
#include "vm/MatchPairs.h"
#include "vm/RegExpObject.h"
#include "vm/RegExpStatics.h"
@@ -10213,6 +10214,28 @@ CodeGenerator::visitToAsync(LToAsync* lir)
callVM(ToAsyncInfo, lir);
}
+typedef JSObject* (*ToAsyncGenFn)(JSContext*, HandleFunction);
+static const VMFunction ToAsyncGenInfo =
+ FunctionInfo<ToAsyncGenFn>(js::WrapAsyncGenerator, "ToAsyncGen");
+
+void
+CodeGenerator::visitToAsyncGen(LToAsyncGen* lir)
+{
+ pushArg(ToRegister(lir->unwrapped()));
+ callVM(ToAsyncGenInfo, lir);
+}
+
+typedef JSObject* (*ToAsyncIterFn)(JSContext*, HandleObject);
+static const VMFunction ToAsyncIterInfo =
+ FunctionInfo<ToAsyncIterFn>(js::CreateAsyncFromSyncIterator, "ToAsyncIter");
+
+void
+CodeGenerator::visitToAsyncIter(LToAsyncIter* lir)
+{
+ pushArg(ToRegister(lir->unwrapped()));
+ callVM(ToAsyncIterInfo, lir);
+}
+
typedef bool (*ToIdFn)(JSContext*, HandleScript, jsbytecode*, HandleValue,
MutableHandleValue);
static const VMFunction ToIdInfo = FunctionInfo<ToIdFn>(ToIdOperation, "ToIdOperation");
diff --git a/js/src/jit/CodeGenerator.h b/js/src/jit/CodeGenerator.h
index 12f1238ef..65acfe274 100644
--- a/js/src/jit/CodeGenerator.h
+++ b/js/src/jit/CodeGenerator.h
@@ -286,6 +286,8 @@ class CodeGenerator final : public CodeGeneratorSpecific
void visitTypeOfV(LTypeOfV* lir);
void visitOutOfLineTypeOfV(OutOfLineTypeOfV* ool);
void visitToAsync(LToAsync* lir);
+ void visitToAsyncGen(LToAsyncGen* lir);
+ void visitToAsyncIter(LToAsyncIter* lir);
void visitToIdV(LToIdV* lir);
template<typename T> void emitLoadElementT(LLoadElementT* lir, const T& source);
void visitLoadElementT(LLoadElementT* lir);
diff --git a/js/src/jit/Ion.cpp b/js/src/jit/Ion.cpp
index b8a2d2fba..9337f6150 100644
--- a/js/src/jit/Ion.cpp
+++ b/js/src/jit/Ion.cpp
@@ -2320,7 +2320,9 @@ IonCompile(JSContext* cx, JSScript* script,
static bool
CheckFrame(JSContext* cx, BaselineFrame* frame)
{
- MOZ_ASSERT(!frame->script()->isGenerator());
+ MOZ_ASSERT(!frame->script()->isStarGenerator());
+ MOZ_ASSERT(!frame->script()->isLegacyGenerator());
+ MOZ_ASSERT(!frame->script()->isAsync());
MOZ_ASSERT(!frame->isDebuggerEvalFrame());
MOZ_ASSERT(!frame->isEvalFrame());
@@ -2351,11 +2353,16 @@ CheckScript(JSContext* cx, JSScript* script, bool osr)
return false;
}
- if (script->isGenerator()) {
+ if (script->isStarGenerator() || script->isLegacyGenerator()) {
TrackAndSpewIonAbort(cx, script, "generator script");
return false;
}
+ if (script->isAsync()) {
+ TrackAndSpewIonAbort(cx, script, "async script");
+ return false;
+ }
+
if (script->hasNonSyntacticScope() && !script->functionNonDelazifying()) {
// Support functions with a non-syntactic global scope but not other
// scripts. For global scripts, IonBuilder currently uses the global
diff --git a/js/src/jit/IonAnalysis.cpp b/js/src/jit/IonAnalysis.cpp
index ace6cd81e..a4724bca4 100644
--- a/js/src/jit/IonAnalysis.cpp
+++ b/js/src/jit/IonAnalysis.cpp
@@ -4402,8 +4402,14 @@ jit::AnalyzeArgumentsUsage(JSContext* cx, JSScript* scriptArg)
// direct eval is present.
//
// FIXME: Don't build arguments for ES6 generator expressions.
- if (scriptArg->isDebuggee() || script->isGenerator() || script->bindingsAccessedDynamically())
+ if (scriptArg->isDebuggee() ||
+ script->isStarGenerator() ||
+ script->isLegacyGenerator() ||
+ script->isAsync() ||
+ script->bindingsAccessedDynamically())
+ {
return true;
+ }
if (!jit::IsIonEnabled(cx))
return true;
diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp
index 0c69729a4..1e12f5dbe 100644
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -2130,6 +2130,12 @@ IonBuilder::inspectOpcode(JSOp op)
case JSOP_TOASYNC:
return jsop_toasync();
+ case JSOP_TOASYNCGEN:
+ return jsop_toasyncgen();
+
+ case JSOP_TOASYNCITER:
+ return jsop_toasynciter();
+
case JSOP_TOID:
return jsop_toid();
@@ -3351,7 +3357,7 @@ IonBuilder::whileOrForInLoop(jssrcnote* sn)
unsigned stackPhiCount;
if (SN_TYPE(sn) == SRC_FOR_OF)
- stackPhiCount = 2;
+ stackPhiCount = 3;
else if (SN_TYPE(sn) == SRC_FOR_IN)
stackPhiCount = 1;
else
@@ -13196,6 +13202,34 @@ IonBuilder::jsop_toasync()
}
bool
+IonBuilder::jsop_toasyncgen()
+{
+ MDefinition* unwrapped = current->pop();
+ MOZ_ASSERT(unwrapped->type() == MIRType::Object);
+
+ MToAsyncGen* ins = MToAsyncGen::New(alloc(), unwrapped);
+
+ current->add(ins);
+ current->push(ins);
+
+ return resumeAfter(ins);
+}
+
+bool
+IonBuilder::jsop_toasynciter()
+{
+ MDefinition* unwrapped = current->pop();
+ MOZ_ASSERT(unwrapped->type() == MIRType::Object);
+
+ MToAsyncIter* ins = MToAsyncIter::New(alloc(), unwrapped);
+
+ current->add(ins);
+ current->push(ins);
+
+ return resumeAfter(ins);
+}
+
+bool
IonBuilder::jsop_toid()
{
// No-op if the index is an integer.
diff --git a/js/src/jit/IonBuilder.h b/js/src/jit/IonBuilder.h
index 1f763a4f2..6a3b61232 100644
--- a/js/src/jit/IonBuilder.h
+++ b/js/src/jit/IonBuilder.h
@@ -762,6 +762,8 @@ class IonBuilder
MOZ_MUST_USE bool jsop_globalthis();
MOZ_MUST_USE bool jsop_typeof();
MOZ_MUST_USE bool jsop_toasync();
+ MOZ_MUST_USE bool jsop_toasyncgen();
+ MOZ_MUST_USE bool jsop_toasynciter();
MOZ_MUST_USE bool jsop_toid();
MOZ_MUST_USE bool jsop_iter(uint8_t flags);
MOZ_MUST_USE bool jsop_itermore();
diff --git a/js/src/jit/Lowering.cpp b/js/src/jit/Lowering.cpp
index 22f1d5f70..108450983 100644
--- a/js/src/jit/Lowering.cpp
+++ b/js/src/jit/Lowering.cpp
@@ -1176,6 +1176,22 @@ LIRGenerator::visitToAsync(MToAsync* ins)
}
void
+LIRGenerator::visitToAsyncGen(MToAsyncGen* ins)
+{
+ LToAsyncGen* lir = new(alloc()) LToAsyncGen(useRegisterAtStart(ins->input()));
+ defineReturn(lir, ins);
+ assignSafepoint(lir, ins);
+}
+
+void
+LIRGenerator::visitToAsyncIter(MToAsyncIter* ins)
+{
+ LToAsyncIter* lir = new(alloc()) LToAsyncIter(useRegisterAtStart(ins->input()));
+ defineReturn(lir, ins);
+ assignSafepoint(lir, ins);
+}
+
+void
LIRGenerator::visitToId(MToId* ins)
{
LToIdV* lir = new(alloc()) LToIdV(useBox(ins->input()), tempDouble());
diff --git a/js/src/jit/Lowering.h b/js/src/jit/Lowering.h
index 9342ef471..81e6abbbb 100644
--- a/js/src/jit/Lowering.h
+++ b/js/src/jit/Lowering.h
@@ -121,6 +121,8 @@ class LIRGenerator : public LIRGeneratorSpecific
void visitCompare(MCompare* comp);
void visitTypeOf(MTypeOf* ins);
void visitToAsync(MToAsync* ins);
+ void visitToAsyncGen(MToAsyncGen* ins);
+ void visitToAsyncIter(MToAsyncIter* ins);
void visitToId(MToId* ins);
void visitBitNot(MBitNot* ins);
void visitBitAnd(MBitAnd* ins);
diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h
index 6c376d528..e7186ed30 100644
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -5784,6 +5784,36 @@ class MToAsync
TRIVIAL_NEW_WRAPPERS
};
+class MToAsyncGen
+ : public MUnaryInstruction,
+ public SingleObjectPolicy::Data
+{
+ explicit MToAsyncGen(MDefinition* unwrapped)
+ : MUnaryInstruction(unwrapped)
+ {
+ setResultType(MIRType::Object);
+ }
+
+ public:
+ INSTRUCTION_HEADER(ToAsyncGen)
+ TRIVIAL_NEW_WRAPPERS
+};
+
+class MToAsyncIter
+ : public MUnaryInstruction,
+ public SingleObjectPolicy::Data
+{
+ explicit MToAsyncIter(MDefinition* unwrapped)
+ : MUnaryInstruction(unwrapped)
+ {
+ setResultType(MIRType::Object);
+ }
+
+ public:
+ INSTRUCTION_HEADER(ToAsyncIter)
+ TRIVIAL_NEW_WRAPPERS
+};
+
class MToId
: public MUnaryInstruction,
public BoxInputsPolicy::Data
diff --git a/js/src/jit/MOpcodes.h b/js/src/jit/MOpcodes.h
index 9e460a2ba..589dde077 100644
--- a/js/src/jit/MOpcodes.h
+++ b/js/src/jit/MOpcodes.h
@@ -79,6 +79,8 @@ namespace jit {
_(BitNot) \
_(TypeOf) \
_(ToAsync) \
+ _(ToAsyncGen) \
+ _(ToAsyncIter) \
_(ToId) \
_(BitAnd) \
_(BitOr) \
diff --git a/js/src/jit/VMFunctions.cpp b/js/src/jit/VMFunctions.cpp
index 1ff7adfd1..652c23bf1 100644
--- a/js/src/jit/VMFunctions.cpp
+++ b/js/src/jit/VMFunctions.cpp
@@ -735,7 +735,7 @@ bool
NormalSuspend(JSContext* cx, HandleObject obj, BaselineFrame* frame, jsbytecode* pc,
uint32_t stackDepth)
{
- MOZ_ASSERT(*pc == JSOP_YIELD);
+ MOZ_ASSERT(*pc == JSOP_YIELD || *pc == JSOP_AWAIT);
// Return value is still on the stack.
MOZ_ASSERT(stackDepth >= 1);
@@ -816,7 +816,7 @@ GeneratorThrowOrClose(JSContext* cx, BaselineFrame* frame, Handle<GeneratorObjec
// work. This function always returns false, so we're guaranteed to enter
// the exception handler where we will clear the pc.
JSScript* script = frame->script();
- uint32_t offset = script->yieldOffsets()[genObj->yieldIndex()];
+ uint32_t offset = script->yieldAndAwaitOffsets()[genObj->yieldAndAwaitIndex()];
frame->setOverridePc(script->offsetToPC(offset));
MOZ_ALWAYS_TRUE(DebugAfterYield(cx, frame));
diff --git a/js/src/jit/shared/LIR-shared.h b/js/src/jit/shared/LIR-shared.h
index ecf02816e..ff4915d1a 100644
--- a/js/src/jit/shared/LIR-shared.h
+++ b/js/src/jit/shared/LIR-shared.h
@@ -1606,6 +1606,32 @@ class LToAsync : public LCallInstructionHelper<1, 1, 0>
}
};
+class LToAsyncGen : public LCallInstructionHelper<1, 1, 0>
+{
+ public:
+ LIR_HEADER(ToAsyncGen)
+ explicit LToAsyncGen(const LAllocation& input) {
+ setOperand(0, input);
+ }
+
+ const LAllocation* unwrapped() {
+ return getOperand(0);
+ }
+};
+
+class LToAsyncIter : public LCallInstructionHelper<1, 1, 0>
+{
+ public:
+ LIR_HEADER(ToAsyncIter)
+ explicit LToAsyncIter(const LAllocation& input) {
+ setOperand(0, input);
+ }
+
+ const LAllocation* unwrapped() {
+ return getOperand(0);
+ }
+};
+
class LToIdV : public LInstructionHelper<BOX_PIECES, BOX_PIECES, 1>
{
public:
diff --git a/js/src/jit/shared/LOpcodes-shared.h b/js/src/jit/shared/LOpcodes-shared.h
index e260d7e94..56b98940a 100644
--- a/js/src/jit/shared/LOpcodes-shared.h
+++ b/js/src/jit/shared/LOpcodes-shared.h
@@ -353,6 +353,8 @@
_(Rest) \
_(TypeOfV) \
_(ToAsync) \
+ _(ToAsyncGen) \
+ _(ToAsyncIter) \
_(ToIdV) \
_(Floor) \
_(FloorF) \