diff --git a/js/src/jit/BaselineCompiler.cpp b/js/src/jit/BaselineCompiler.cpp index 3856fb63f6..38202915a4 100644 --- a/js/src/jit/BaselineCompiler.cpp +++ b/js/src/jit/BaselineCompiler.cpp @@ -3937,6 +3937,28 @@ BaselineCompiler::emit_JSOP_TOASYNCGEN() return true; } +typedef JSObject* (*ToAsyncIterFn)(JSContext*, HandleObject); +static const VMFunction ToAsyncIterInfo = + FunctionInfo(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(ThrowObjectCoercible, "ThrowObjectCoercible"); diff --git a/js/src/jit/BaselineCompiler.h b/js/src/jit/BaselineCompiler.h index 15d0e30645..7b1af092ae 100644 --- a/js/src/jit/BaselineCompiler.h +++ b/js/src/jit/BaselineCompiler.h @@ -198,6 +198,7 @@ namespace jit { _(JSOP_REST) \ _(JSOP_TOASYNC) \ _(JSOP_TOASYNCGEN) \ + _(JSOP_TOASYNCITER) \ _(JSOP_TOID) \ _(JSOP_TOSTRING) \ _(JSOP_TABLESWITCH) \ diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp index 128947e5ed..2b1c671d1b 100644 --- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -10225,6 +10225,17 @@ CodeGenerator::visitToAsyncGen(LToAsyncGen* lir) callVM(ToAsyncGenInfo, lir); } +typedef JSObject* (*ToAsyncIterFn)(JSContext*, HandleObject); +static const VMFunction ToAsyncIterInfo = + FunctionInfo(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(ToIdOperation, "ToIdOperation"); diff --git a/js/src/jit/CodeGenerator.h b/js/src/jit/CodeGenerator.h index d2f24dc043..65acfe2740 100644 --- a/js/src/jit/CodeGenerator.h +++ b/js/src/jit/CodeGenerator.h @@ -287,6 +287,7 @@ class CodeGenerator final : public CodeGeneratorSpecific void visitOutOfLineTypeOfV(OutOfLineTypeOfV* ool); void visitToAsync(LToAsync* lir); void visitToAsyncGen(LToAsyncGen* lir); + void visitToAsyncIter(LToAsyncIter* lir); void visitToIdV(LToIdV* lir); template void emitLoadElementT(LLoadElementT* lir, const T& source); void visitLoadElementT(LLoadElementT* lir); diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index 79214c993d..ac56312894 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -2133,6 +2133,9 @@ IonBuilder::inspectOpcode(JSOp op) case JSOP_TOASYNCGEN: return jsop_toasyncgen(); + case JSOP_TOASYNCITER: + return jsop_toasynciter(); + case JSOP_TOID: return jsop_toid(); @@ -13210,6 +13213,20 @@ IonBuilder::jsop_toasyncgen() 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() { diff --git a/js/src/jit/IonBuilder.h b/js/src/jit/IonBuilder.h index 48388539fd..6a3b61232f 100644 --- a/js/src/jit/IonBuilder.h +++ b/js/src/jit/IonBuilder.h @@ -763,6 +763,7 @@ class IonBuilder 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 ee59b8ae60..1084509833 100644 --- a/js/src/jit/Lowering.cpp +++ b/js/src/jit/Lowering.cpp @@ -1183,6 +1183,14 @@ LIRGenerator::visitToAsyncGen(MToAsyncGen* 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) { diff --git a/js/src/jit/Lowering.h b/js/src/jit/Lowering.h index 1d412040c5..81e6abbbbd 100644 --- a/js/src/jit/Lowering.h +++ b/js/src/jit/Lowering.h @@ -122,6 +122,7 @@ class LIRGenerator : public LIRGeneratorSpecific 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 637c09cfdd..e7186ed305 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -5799,6 +5799,21 @@ class MToAsyncGen 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 59620e4e76..589dde0774 100644 --- a/js/src/jit/MOpcodes.h +++ b/js/src/jit/MOpcodes.h @@ -80,6 +80,7 @@ namespace jit { _(TypeOf) \ _(ToAsync) \ _(ToAsyncGen) \ + _(ToAsyncIter) \ _(ToId) \ _(BitAnd) \ _(BitOr) \ diff --git a/js/src/jit/shared/LIR-shared.h b/js/src/jit/shared/LIR-shared.h index 6c8ff899b5..ff4915d1a7 100644 --- a/js/src/jit/shared/LIR-shared.h +++ b/js/src/jit/shared/LIR-shared.h @@ -1619,6 +1619,19 @@ class LToAsyncGen : public LCallInstructionHelper<1, 1, 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 { public: diff --git a/js/src/jit/shared/LOpcodes-shared.h b/js/src/jit/shared/LOpcodes-shared.h index 9e79f02660..56b98940af 100644 --- a/js/src/jit/shared/LOpcodes-shared.h +++ b/js/src/jit/shared/LOpcodes-shared.h @@ -354,6 +354,7 @@ _(TypeOfV) \ _(ToAsync) \ _(ToAsyncGen) \ + _(ToAsyncIter) \ _(ToIdV) \ _(Floor) \ _(FloorF) \