diff --git a/js/src/jit/BaselineCompiler.cpp b/js/src/jit/BaselineCompiler.cpp index bef1c7a26c94..dc37c9e4765e 100644 --- a/js/src/jit/BaselineCompiler.cpp +++ b/js/src/jit/BaselineCompiler.cpp @@ -41,8 +41,10 @@ using namespace js::jit; using mozilla::AssertedCast; -BaselineCompiler::BaselineCompiler(JSContext* cx, TempAllocator& alloc, JSScript* script) - : cx(cx), +template +BaselineCodeGen::BaselineCodeGen(JSContext* cx, TempAllocator& alloc, JSScript* script) + : handler(), + cx(cx), script(script), pc(script->code()), ionCompileable_(jit::IsIonEnabled(cx) && CanIonCompileScript(cx, script)), @@ -50,18 +52,23 @@ BaselineCompiler::BaselineCompiler(JSContext* cx, TempAllocator& alloc, JSScript alloc_(alloc), analysis_(alloc, script), frame(script, masm), - pcMappingEntries_(), + traceLoggerToggleOffsets_(cx), icEntryIndex_(0), pushedBeforeCall_(0), #ifdef DEBUG inCall_(false), #endif + modifiesArguments_(false) +{ +} + +BaselineCompiler::BaselineCompiler(JSContext* cx, TempAllocator& alloc, JSScript* script) + : BaselineCodeGen(cx, alloc, script), + pcMappingEntries_(), profilerPushToggleOffset_(), profilerEnterFrameToggleOffset_(), profilerExitFrameToggleOffset_(), - traceLoggerToggleOffsets_(cx), - traceLoggerScriptTextIdOffset_(), - modifiesArguments_(false) + traceLoggerScriptTextIdOffset_() { #ifdef JS_CODEGEN_NONE MOZ_CRASH(); @@ -565,8 +572,9 @@ BaselineCompiler::emitOutOfLinePostBarrierSlot() return true; } +template bool -BaselineCompiler::emitNextIC() +BaselineCodeGen::emitNextIC() { // Emit a call to an IC stored in ICScript. Calls to this must match the // ICEntry order in ICScript: first the non-op IC entries for |this| and @@ -599,8 +607,9 @@ BaselineCompiler::emitNextIC() return true; } +template void -BaselineCompiler::prepareVMCall() +BaselineCodeGen::prepareVMCall() { pushedBeforeCall_ = masm.framePushed(); #ifdef DEBUG @@ -614,8 +623,9 @@ BaselineCompiler::prepareVMCall() masm.Push(BaselineFrameReg); } +template bool -BaselineCompiler::callVM(const VMFunction& fun, CallVMPhase phase) +BaselineCodeGen::callVM(const VMFunction& fun, CallVMPhase phase) { TrampolinePtr code = cx->runtime()->jitRuntime()->getVMWrapper(fun); @@ -858,8 +868,9 @@ typedef bool (*InterruptCheckFn)(JSContext*); static const VMFunction InterruptCheckInfo = FunctionInfo(InterruptCheck, "InterruptCheck"); +template bool -BaselineCompiler::emitInterruptCheck() +BaselineCodeGen::emitInterruptCheck() { frame.syncStack(0); @@ -882,8 +893,9 @@ static const VMFunction IonCompileScriptForBaselineInfo = FunctionInfo(IonCompileScriptForBaseline, "IonCompileScriptForBaseline"); +template bool -BaselineCompiler::emitWarmUpCounterIncrement(bool allowOsr) +BaselineCodeGen::emitWarmUpCounterIncrement(bool allowOsr) { // Emit no warm-up counter increments or bailouts if Ion is not // enabled, or if the script will never be Ion-compileable @@ -1073,8 +1085,10 @@ BaselineCompiler::emitTraceLoggerExit() return true; } +template bool -BaselineCompiler::emitTraceLoggerResume(Register baselineScript, AllocatableGeneralRegisterSet& regs) +BaselineCodeGen::emitTraceLoggerResume(Register baselineScript, + AllocatableGeneralRegisterSet& regs) { Register scriptId = regs.takeAny(); Register loggerReg = regs.takeAny(); @@ -1243,52 +1257,60 @@ OPCODE_LIST(EMIT_OP) return Method_Compiled; } +template bool -BaselineCompiler::emit_JSOP_NOP() +BaselineCodeGen::emit_JSOP_NOP() { return true; } +template bool -BaselineCompiler::emit_JSOP_ITERNEXT() +BaselineCodeGen::emit_JSOP_ITERNEXT() { return true; } +template bool -BaselineCompiler::emit_JSOP_NOP_DESTRUCTURING() +BaselineCodeGen::emit_JSOP_NOP_DESTRUCTURING() { return true; } +template bool -BaselineCompiler::emit_JSOP_TRY_DESTRUCTURING_ITERCLOSE() +BaselineCodeGen::emit_JSOP_TRY_DESTRUCTURING_ITERCLOSE() { return true; } +template bool -BaselineCompiler::emit_JSOP_LABEL() +BaselineCodeGen::emit_JSOP_LABEL() { return true; } +template bool -BaselineCompiler::emit_JSOP_POP() +BaselineCodeGen::emit_JSOP_POP() { frame.pop(); return true; } +template bool -BaselineCompiler::emit_JSOP_POPN() +BaselineCodeGen::emit_JSOP_POPN() { frame.popn(GET_UINT16(pc)); return true; } +template bool -BaselineCompiler::emit_JSOP_DUPAT() +BaselineCodeGen::emit_JSOP_DUPAT() { frame.syncStack(0); @@ -1302,8 +1324,9 @@ BaselineCompiler::emit_JSOP_DUPAT() return true; } +template bool -BaselineCompiler::emit_JSOP_DUP() +BaselineCodeGen::emit_JSOP_DUP() { // Keep top stack value in R0, sync the rest so that we can use R1. We use // separate registers because every register can be used by at most one @@ -1317,8 +1340,9 @@ BaselineCompiler::emit_JSOP_DUP() return true; } +template bool -BaselineCompiler::emit_JSOP_DUP2() +BaselineCodeGen::emit_JSOP_DUP2() { frame.syncStack(0); @@ -1330,8 +1354,9 @@ BaselineCompiler::emit_JSOP_DUP2() return true; } +template bool -BaselineCompiler::emit_JSOP_SWAP() +BaselineCodeGen::emit_JSOP_SWAP() { // Keep top stack values in R0 and R1. frame.popRegsAndSync(2); @@ -1341,8 +1366,9 @@ BaselineCompiler::emit_JSOP_SWAP() return true; } +template bool -BaselineCompiler::emit_JSOP_PICK() +BaselineCodeGen::emit_JSOP_PICK() { frame.syncStack(0); @@ -1370,8 +1396,9 @@ BaselineCompiler::emit_JSOP_PICK() return true; } +template bool -BaselineCompiler::emit_JSOP_UNPICK() +BaselineCodeGen::emit_JSOP_UNPICK() { frame.syncStack(0); @@ -1398,8 +1425,9 @@ BaselineCompiler::emit_JSOP_UNPICK() return true; } +template bool -BaselineCompiler::emit_JSOP_GOTO() +BaselineCodeGen::emit_JSOP_GOTO() { frame.syncStack(0); @@ -1408,8 +1436,9 @@ BaselineCompiler::emit_JSOP_GOTO() return true; } +template bool -BaselineCompiler::emitToBoolean() +BaselineCodeGen::emitToBoolean() { Label skipIC; masm.branchTestBoolean(Assembler::Equal, R0, &skipIC); @@ -1423,8 +1452,9 @@ BaselineCompiler::emitToBoolean() return true; } +template bool -BaselineCompiler::emitTest(bool branchIfTrue) +BaselineCodeGen::emitTest(bool branchIfTrue) { bool knownBoolean = frame.peek(-1)->isKnownBoolean(); @@ -1440,20 +1470,23 @@ BaselineCompiler::emitTest(bool branchIfTrue) return true; } +template bool -BaselineCompiler::emit_JSOP_IFEQ() +BaselineCodeGen::emit_JSOP_IFEQ() { return emitTest(false); } +template bool -BaselineCompiler::emit_JSOP_IFNE() +BaselineCodeGen::emit_JSOP_IFNE() { return emitTest(true); } +template bool -BaselineCompiler::emitAndOr(bool branchIfTrue) +BaselineCodeGen::emitAndOr(bool branchIfTrue) { bool knownBoolean = frame.peek(-1)->isKnownBoolean(); @@ -1469,20 +1502,23 @@ BaselineCompiler::emitAndOr(bool branchIfTrue) return true; } +template bool -BaselineCompiler::emit_JSOP_AND() +BaselineCodeGen::emit_JSOP_AND() { return emitAndOr(false); } +template bool -BaselineCompiler::emit_JSOP_OR() +BaselineCodeGen::emit_JSOP_OR() { return emitAndOr(true); } +template bool -BaselineCompiler::emit_JSOP_NOT() +BaselineCodeGen::emit_JSOP_NOT() { bool knownBoolean = frame.peek(-1)->isKnownBoolean(); @@ -1499,8 +1535,9 @@ BaselineCompiler::emit_JSOP_NOT() return true; } +template bool -BaselineCompiler::emit_JSOP_POS() +BaselineCodeGen::emit_JSOP_POS() { // Keep top stack value in R0. frame.popRegsAndSync(1); @@ -1519,8 +1556,9 @@ BaselineCompiler::emit_JSOP_POS() return true; } +template bool -BaselineCompiler::emit_JSOP_LOOPHEAD() +BaselineCodeGen::emit_JSOP_LOOPHEAD() { if (!emit_JSOP_JUMPTARGET()) { return false; @@ -1528,8 +1566,9 @@ BaselineCompiler::emit_JSOP_LOOPHEAD() return emitInterruptCheck(); } +template bool -BaselineCompiler::emit_JSOP_LOOPENTRY() +BaselineCodeGen::emit_JSOP_LOOPENTRY() { if (!emit_JSOP_JUMPTARGET()) { return false; @@ -1544,31 +1583,35 @@ BaselineCompiler::emit_JSOP_LOOPENTRY() return true; } +template bool -BaselineCompiler::emit_JSOP_VOID() +BaselineCodeGen::emit_JSOP_VOID() { frame.pop(); frame.push(UndefinedValue()); return true; } +template bool -BaselineCompiler::emit_JSOP_UNDEFINED() +BaselineCodeGen::emit_JSOP_UNDEFINED() { // If this ever changes, change what JSOP_GIMPLICITTHIS does too. frame.push(UndefinedValue()); return true; } +template bool -BaselineCompiler::emit_JSOP_HOLE() +BaselineCodeGen::emit_JSOP_HOLE() { frame.push(MagicValue(JS_ELEMENTS_HOLE)); return true; } +template bool -BaselineCompiler::emit_JSOP_NULL() +BaselineCodeGen::emit_JSOP_NULL() { frame.push(NullValue()); return true; @@ -1578,8 +1621,9 @@ typedef bool (*ThrowCheckIsObjectFn)(JSContext*, CheckIsObjectKind); static const VMFunction ThrowCheckIsObjectInfo = FunctionInfo(ThrowCheckIsObject, "ThrowCheckIsObject"); +template bool -BaselineCompiler::emit_JSOP_CHECKISOBJ() +BaselineCodeGen::emit_JSOP_CHECKISOBJ() { frame.syncStack(0); masm.loadValue(frame.addressOfStackValue(frame.peek(-1)), R0); @@ -1602,8 +1646,9 @@ typedef bool (*CheckIsCallableFn)(JSContext*, HandleValue, CheckIsCallableKind); static const VMFunction CheckIsCallableInfo = FunctionInfo(CheckIsCallable, "CheckIsCallable"); +template bool -BaselineCompiler::emit_JSOP_CHECKISCALLABLE() +BaselineCodeGen::emit_JSOP_CHECKISCALLABLE() { frame.syncStack(0); masm.loadValue(frame.addressOfStackValue(frame.peek(-1)), R0); @@ -1629,8 +1674,9 @@ static const VMFunction ThrowInitializedThisInfo = FunctionInfo(BaselineThrowInitializedThis, "BaselineThrowInitializedThis"); +template bool -BaselineCompiler::emit_JSOP_CHECKTHIS() +BaselineCodeGen::emit_JSOP_CHECKTHIS() { frame.syncStack(0); masm.loadValue(frame.addressOfStackValue(frame.peek(-1)), R0); @@ -1638,8 +1684,9 @@ BaselineCompiler::emit_JSOP_CHECKTHIS() return emitCheckThis(R0); } +template bool -BaselineCompiler::emit_JSOP_CHECKTHISREINIT() +BaselineCodeGen::emit_JSOP_CHECKTHISREINIT() { frame.syncStack(0); masm.loadValue(frame.addressOfStackValue(frame.peek(-1)), R0); @@ -1647,8 +1694,9 @@ BaselineCompiler::emit_JSOP_CHECKTHISREINIT() return emitCheckThis(R0, /* reinit = */true); } +template bool -BaselineCompiler::emitCheckThis(ValueOperand val, bool reinit) +BaselineCodeGen::emitCheckThis(ValueOperand val, bool reinit) { Label thisOK; if (reinit) { @@ -1680,8 +1728,9 @@ typedef bool (*ThrowBadDerivedReturnFn)(JSContext*, HandleValue); static const VMFunction ThrowBadDerivedReturnInfo = FunctionInfo(jit::ThrowBadDerivedReturn, "ThrowBadDerivedReturn"); +template bool -BaselineCompiler::emit_JSOP_CHECKRETURN() +BaselineCodeGen::emit_JSOP_CHECKRETURN() { MOZ_ASSERT(script->isDerivedClassConstructor()); @@ -1718,8 +1767,9 @@ typedef bool (*GetFunctionThisFn)(JSContext*, BaselineFrame*, MutableHandleValue static const VMFunction GetFunctionThisInfo = FunctionInfo(jit::BaselineGetFunctionThis, "BaselineGetFunctionThis"); +template bool -BaselineCompiler::emit_JSOP_FUNCTIONTHIS() +BaselineCodeGen::emit_JSOP_FUNCTIONTHIS() { MOZ_ASSERT(function()); MOZ_ASSERT(!function()->isArrow()); @@ -1755,8 +1805,9 @@ static const VMFunction GetNonSyntacticGlobalThisInfo = FunctionInfo(js::GetNonSyntacticGlobalThis, "GetNonSyntacticGlobalThis"); +template bool -BaselineCompiler::emit_JSOP_GLOBALTHIS() +BaselineCodeGen::emit_JSOP_GLOBALTHIS() { frame.syncStack(0); @@ -1780,93 +1831,106 @@ BaselineCompiler::emit_JSOP_GLOBALTHIS() return true; } +template bool -BaselineCompiler::emit_JSOP_TRUE() +BaselineCodeGen::emit_JSOP_TRUE() { frame.push(BooleanValue(true)); return true; } +template bool -BaselineCompiler::emit_JSOP_FALSE() +BaselineCodeGen::emit_JSOP_FALSE() { frame.push(BooleanValue(false)); return true; } +template bool -BaselineCompiler::emit_JSOP_ZERO() +BaselineCodeGen::emit_JSOP_ZERO() { frame.push(Int32Value(0)); return true; } +template bool -BaselineCompiler::emit_JSOP_ONE() +BaselineCodeGen::emit_JSOP_ONE() { frame.push(Int32Value(1)); return true; } +template bool -BaselineCompiler::emit_JSOP_INT8() +BaselineCodeGen::emit_JSOP_INT8() { frame.push(Int32Value(GET_INT8(pc))); return true; } +template bool -BaselineCompiler::emit_JSOP_INT32() +BaselineCodeGen::emit_JSOP_INT32() { frame.push(Int32Value(GET_INT32(pc))); return true; } +template bool -BaselineCompiler::emit_JSOP_UINT16() +BaselineCodeGen::emit_JSOP_UINT16() { frame.push(Int32Value(GET_UINT16(pc))); return true; } +template bool -BaselineCompiler::emit_JSOP_UINT24() +BaselineCodeGen::emit_JSOP_UINT24() { frame.push(Int32Value(GET_UINT24(pc))); return true; } +template bool -BaselineCompiler::emit_JSOP_RESUMEINDEX() +BaselineCodeGen::emit_JSOP_RESUMEINDEX() { return emit_JSOP_UINT24(); } +template bool -BaselineCompiler::emit_JSOP_DOUBLE() +BaselineCodeGen::emit_JSOP_DOUBLE() { frame.push(script->getConst(GET_UINT32_INDEX(pc))); return true; } #ifdef ENABLE_BIGINT +template bool -BaselineCompiler::emit_JSOP_BIGINT() +BaselineCodeGen::emit_JSOP_BIGINT() { frame.push(script->getConst(GET_UINT32_INDEX(pc))); return true; } #endif +template bool -BaselineCompiler::emit_JSOP_STRING() +BaselineCodeGen::emit_JSOP_STRING() { frame.push(StringValue(script->getAtom(pc))); return true; } +template bool -BaselineCompiler::emit_JSOP_SYMBOL() +BaselineCodeGen::emit_JSOP_SYMBOL() { unsigned which = GET_UINT8(pc); JS::Symbol* sym = cx->runtime()->wellKnownSymbols->get(which); @@ -1878,8 +1942,9 @@ typedef JSObject* (*DeepCloneObjectLiteralFn)(JSContext*, HandleObject, NewObjec static const VMFunction DeepCloneObjectLiteralInfo = FunctionInfo(DeepCloneObjectLiteral, "DeepCloneObjectLiteral"); +template bool -BaselineCompiler::emit_JSOP_OBJECT() +BaselineCodeGen::emit_JSOP_OBJECT() { if (cx->realm()->creationOptions().cloneSingletons()) { RootedObject obj(cx, script->getObject(GET_UINT32_INDEX(pc))); @@ -1907,8 +1972,9 @@ BaselineCompiler::emit_JSOP_OBJECT() return true; } +template bool -BaselineCompiler::emit_JSOP_CALLSITEOBJ() +BaselineCodeGen::emit_JSOP_CALLSITEOBJ() { RootedObject cso(cx, script->getObject(pc)); RootedObject raw(cx, script->getObject(GET_UINT32_INDEX(pc) + 1)); @@ -1928,8 +1994,9 @@ typedef JSObject* (*CloneRegExpObjectFn)(JSContext*, Handle); static const VMFunction CloneRegExpObjectInfo = FunctionInfo(CloneRegExpObject, "CloneRegExpObject"); +template bool -BaselineCompiler::emit_JSOP_REGEXP() +BaselineCodeGen::emit_JSOP_REGEXP() { RootedObject reObj(cx, script->getRegExp(pc)); @@ -1948,8 +2015,9 @@ BaselineCompiler::emit_JSOP_REGEXP() typedef JSObject* (*LambdaFn)(JSContext*, HandleFunction, HandleObject); static const VMFunction LambdaInfo = FunctionInfo(js::Lambda, "Lambda"); +template bool -BaselineCompiler::emit_JSOP_LAMBDA() +BaselineCodeGen::emit_JSOP_LAMBDA() { RootedFunction fun(cx, script->getFunction(GET_UINT32_INDEX(pc))); @@ -1973,8 +2041,9 @@ typedef JSObject* (*LambdaArrowFn)(JSContext*, HandleFunction, HandleObject, Han static const VMFunction LambdaArrowInfo = FunctionInfo(js::LambdaArrow, "LambdaArrow"); +template bool -BaselineCompiler::emit_JSOP_LAMBDA_ARROW() +BaselineCodeGen::emit_JSOP_LAMBDA_ARROW() { // Keep pushed newTarget in R0. frame.popRegsAndSync(1); @@ -2002,8 +2071,9 @@ typedef bool (*SetFunNameFn)(JSContext*, HandleFunction, HandleValue, FunctionPr static const VMFunction SetFunNameInfo = FunctionInfo(js::SetFunctionNameIfNoOwnName, "SetFunName"); +template bool -BaselineCompiler::emit_JSOP_SETFUNNAME() +BaselineCodeGen::emit_JSOP_SETFUNNAME() { frame.popRegsAndSync(2); @@ -2021,9 +2091,10 @@ BaselineCompiler::emit_JSOP_SETFUNNAME() return callVM(SetFunNameInfo); } +template void -BaselineCompiler::storeValue(const StackValue* source, const Address& dest, - const ValueOperand& scratch) +BaselineCodeGen::storeValue(const StackValue* source, const Address& dest, + const ValueOperand& scratch) { switch (source->kind()) { case StackValue::Constant: @@ -2058,80 +2129,93 @@ BaselineCompiler::storeValue(const StackValue* source, const Address& dest, } } +template bool -BaselineCompiler::emit_JSOP_BITOR() +BaselineCodeGen::emit_JSOP_BITOR() { return emitBinaryArith(); } +template bool -BaselineCompiler::emit_JSOP_BITXOR() +BaselineCodeGen::emit_JSOP_BITXOR() { return emitBinaryArith(); } +template bool -BaselineCompiler::emit_JSOP_BITAND() +BaselineCodeGen::emit_JSOP_BITAND() { return emitBinaryArith(); } +template bool -BaselineCompiler::emit_JSOP_LSH() +BaselineCodeGen::emit_JSOP_LSH() { return emitBinaryArith(); } +template bool -BaselineCompiler::emit_JSOP_RSH() +BaselineCodeGen::emit_JSOP_RSH() { return emitBinaryArith(); } +template bool -BaselineCompiler::emit_JSOP_URSH() +BaselineCodeGen::emit_JSOP_URSH() { return emitBinaryArith(); } +template bool -BaselineCompiler::emit_JSOP_ADD() +BaselineCodeGen::emit_JSOP_ADD() { return emitBinaryArith(); } +template bool -BaselineCompiler::emit_JSOP_SUB() +BaselineCodeGen::emit_JSOP_SUB() { return emitBinaryArith(); } +template bool -BaselineCompiler::emit_JSOP_MUL() +BaselineCodeGen::emit_JSOP_MUL() { return emitBinaryArith(); } +template bool -BaselineCompiler::emit_JSOP_DIV() +BaselineCodeGen::emit_JSOP_DIV() { return emitBinaryArith(); } +template bool -BaselineCompiler::emit_JSOP_MOD() +BaselineCodeGen::emit_JSOP_MOD() { return emitBinaryArith(); } +template bool -BaselineCompiler::emit_JSOP_POW() +BaselineCodeGen::emit_JSOP_POW() { return emitBinaryArith(); } +template bool -BaselineCompiler::emitBinaryArith() +BaselineCodeGen::emitBinaryArith() { // Keep top JSStack value in R0 and R2 frame.popRegsAndSync(2); @@ -2146,8 +2230,9 @@ BaselineCompiler::emitBinaryArith() return true; } +template bool -BaselineCompiler::emitUnaryArith() +BaselineCodeGen::emitUnaryArith() { // Keep top stack value in R0. frame.popRegsAndSync(1); @@ -2162,56 +2247,65 @@ BaselineCompiler::emitUnaryArith() return true; } +template bool -BaselineCompiler::emit_JSOP_BITNOT() +BaselineCodeGen::emit_JSOP_BITNOT() { return emitUnaryArith(); } +template bool -BaselineCompiler::emit_JSOP_NEG() +BaselineCodeGen::emit_JSOP_NEG() { return emitUnaryArith(); } +template bool -BaselineCompiler::emit_JSOP_LT() +BaselineCodeGen::emit_JSOP_LT() { return emitCompare(); } +template bool -BaselineCompiler::emit_JSOP_LE() +BaselineCodeGen::emit_JSOP_LE() { return emitCompare(); } +template bool -BaselineCompiler::emit_JSOP_GT() +BaselineCodeGen::emit_JSOP_GT() { return emitCompare(); } +template bool -BaselineCompiler::emit_JSOP_GE() +BaselineCodeGen::emit_JSOP_GE() { return emitCompare(); } +template bool -BaselineCompiler::emit_JSOP_EQ() +BaselineCodeGen::emit_JSOP_EQ() { return emitCompare(); } +template bool -BaselineCompiler::emit_JSOP_NE() +BaselineCodeGen::emit_JSOP_NE() { return emitCompare(); } +template bool -BaselineCompiler::emitCompare() +BaselineCodeGen::emitCompare() { // CODEGEN @@ -2228,26 +2322,30 @@ BaselineCompiler::emitCompare() return true; } +template bool -BaselineCompiler::emit_JSOP_STRICTEQ() +BaselineCodeGen::emit_JSOP_STRICTEQ() { return emitCompare(); } +template bool -BaselineCompiler::emit_JSOP_STRICTNE() +BaselineCodeGen::emit_JSOP_STRICTNE() { return emitCompare(); } +template bool -BaselineCompiler::emit_JSOP_CONDSWITCH() +BaselineCodeGen::emit_JSOP_CONDSWITCH() { return true; } +template bool -BaselineCompiler::emit_JSOP_CASE() +BaselineCodeGen::emit_JSOP_CASE() { frame.popRegsAndSync(1); @@ -2263,21 +2361,24 @@ BaselineCompiler::emit_JSOP_CASE() return true; } +template bool -BaselineCompiler::emit_JSOP_DEFAULT() +BaselineCodeGen::emit_JSOP_DEFAULT() { frame.pop(); return emit_JSOP_GOTO(); } +template bool -BaselineCompiler::emit_JSOP_LINENO() +BaselineCodeGen::emit_JSOP_LINENO() { return true; } +template bool -BaselineCompiler::emit_JSOP_NEWARRAY() +BaselineCodeGen::emit_JSOP_NEWARRAY() { frame.syncStack(0); @@ -2301,8 +2402,9 @@ typedef ArrayObject* (*NewArrayCopyOnWriteFn)(JSContext*, HandleArrayObject, gc: const VMFunction jit::NewArrayCopyOnWriteInfo = FunctionInfo(js::NewDenseCopyOnWriteArray, "NewDenseCopyOnWriteArray"); +template bool -BaselineCompiler::emit_JSOP_NEWARRAY_COPYONWRITE() +BaselineCodeGen::emit_JSOP_NEWARRAY_COPYONWRITE() { RootedScript scriptRoot(cx, script); JSObject* obj = ObjectGroup::getOrFixupCopyOnWriteObject(cx, scriptRoot, pc); @@ -2325,8 +2427,9 @@ BaselineCompiler::emit_JSOP_NEWARRAY_COPYONWRITE() return true; } +template bool -BaselineCompiler::emit_JSOP_INITELEM_ARRAY() +BaselineCodeGen::emit_JSOP_INITELEM_ARRAY() { // Keep the object and rhs on the stack. frame.syncStack(0); @@ -2350,8 +2453,9 @@ BaselineCompiler::emit_JSOP_INITELEM_ARRAY() return true; } +template bool -BaselineCompiler::emit_JSOP_NEWOBJECT() +BaselineCodeGen::emit_JSOP_NEWOBJECT() { frame.syncStack(0); @@ -2363,8 +2467,9 @@ BaselineCompiler::emit_JSOP_NEWOBJECT() return true; } +template bool -BaselineCompiler::emit_JSOP_NEWINIT() +BaselineCodeGen::emit_JSOP_NEWINIT() { frame.syncStack(0); @@ -2376,8 +2481,9 @@ BaselineCompiler::emit_JSOP_NEWINIT() return true; } +template bool -BaselineCompiler::emit_JSOP_INITELEM() +BaselineCodeGen::emit_JSOP_INITELEM() { // Store RHS in the scratch slot. storeValue(frame.peek(-1), frame.addressOfScratchValue(), R2); @@ -2403,8 +2509,9 @@ BaselineCompiler::emit_JSOP_INITELEM() return true; } +template bool -BaselineCompiler::emit_JSOP_INITHIDDENELEM() +BaselineCodeGen::emit_JSOP_INITHIDDENELEM() { return emit_JSOP_INITELEM(); } @@ -2413,8 +2520,9 @@ typedef bool (*MutateProtoFn)(JSContext* cx, HandlePlainObject obj, HandleValue static const VMFunction MutateProtoInfo = FunctionInfo(MutatePrototype, "MutatePrototype"); +template bool -BaselineCompiler::emit_JSOP_MUTATEPROTO() +BaselineCodeGen::emit_JSOP_MUTATEPROTO() { // Keep values on the stack for the decompiler. frame.syncStack(0); @@ -2435,8 +2543,9 @@ BaselineCompiler::emit_JSOP_MUTATEPROTO() return true; } +template bool -BaselineCompiler::emit_JSOP_INITPROP() +BaselineCodeGen::emit_JSOP_INITPROP() { // Load lhs in R0, rhs in R1. frame.syncStack(0); @@ -2453,20 +2562,23 @@ BaselineCompiler::emit_JSOP_INITPROP() return true; } +template bool -BaselineCompiler::emit_JSOP_INITLOCKEDPROP() +BaselineCodeGen::emit_JSOP_INITLOCKEDPROP() { return emit_JSOP_INITPROP(); } +template bool -BaselineCompiler::emit_JSOP_INITHIDDENPROP() +BaselineCodeGen::emit_JSOP_INITHIDDENPROP() { return emit_JSOP_INITPROP(); } +template bool -BaselineCompiler::emit_JSOP_GETELEM() +BaselineCodeGen::emit_JSOP_GETELEM() { // Keep top two stack values in R0 and R1. frame.popRegsAndSync(2); @@ -2481,8 +2593,9 @@ BaselineCompiler::emit_JSOP_GETELEM() return true; } +template bool -BaselineCompiler::emit_JSOP_GETELEM_SUPER() +BaselineCodeGen::emit_JSOP_GETELEM_SUPER() { // Store obj in the scratch slot. storeValue(frame.peek(-1), frame.addressOfScratchValue(), R2); @@ -2503,14 +2616,16 @@ BaselineCompiler::emit_JSOP_GETELEM_SUPER() return true; } +template bool -BaselineCompiler::emit_JSOP_CALLELEM() +BaselineCodeGen::emit_JSOP_CALLELEM() { return emit_JSOP_GETELEM(); } +template bool -BaselineCompiler::emit_JSOP_SETELEM() +BaselineCodeGen::emit_JSOP_SETELEM() { // Store RHS in the scratch slot. storeValue(frame.peek(-1), frame.addressOfScratchValue(), R2); @@ -2530,14 +2645,16 @@ BaselineCompiler::emit_JSOP_SETELEM() return true; } +template bool -BaselineCompiler::emit_JSOP_STRICTSETELEM() +BaselineCodeGen::emit_JSOP_STRICTSETELEM() { return emit_JSOP_SETELEM(); } +template bool -BaselineCompiler::emit_JSOP_SETELEM_SUPER() +BaselineCodeGen::emit_JSOP_SETELEM_SUPER() { bool strict = IsCheckStrictOp(JSOp(*pc)); @@ -2567,8 +2684,9 @@ BaselineCompiler::emit_JSOP_SETELEM_SUPER() return true; } +template bool -BaselineCompiler::emit_JSOP_STRICTSETELEM_SUPER() +BaselineCodeGen::emit_JSOP_STRICTSETELEM_SUPER() { return emit_JSOP_SETELEM_SUPER(); } @@ -2579,8 +2697,9 @@ static const VMFunction DeleteElementStrictInfo static const VMFunction DeleteElementNonStrictInfo = FunctionInfo(DeleteElementJit, "DeleteElementNonStrict"); +template bool -BaselineCompiler::emit_JSOP_DELELEM() +BaselineCodeGen::emit_JSOP_DELELEM() { // Keep values on the stack for the decompiler. frame.syncStack(0); @@ -2603,14 +2722,16 @@ BaselineCompiler::emit_JSOP_DELELEM() return true; } +template bool -BaselineCompiler::emit_JSOP_STRICTDELELEM() +BaselineCodeGen::emit_JSOP_STRICTDELELEM() { return emit_JSOP_DELELEM(); } +template bool -BaselineCompiler::emit_JSOP_IN() +BaselineCodeGen::emit_JSOP_IN() { frame.popRegsAndSync(2); @@ -2622,8 +2743,9 @@ BaselineCompiler::emit_JSOP_IN() return true; } +template bool -BaselineCompiler::emit_JSOP_HASOWN() +BaselineCodeGen::emit_JSOP_HASOWN() { frame.popRegsAndSync(2); @@ -2635,8 +2757,9 @@ BaselineCompiler::emit_JSOP_HASOWN() return true; } +template bool -BaselineCompiler::emit_JSOP_GETGNAME() +BaselineCodeGen::emit_JSOP_GETGNAME() { if (script->hasNonSyntacticScope()) { return emit_JSOP_GETNAME(); @@ -2672,8 +2795,9 @@ BaselineCompiler::emit_JSOP_GETGNAME() return true; } +template bool -BaselineCompiler::emit_JSOP_BINDGNAME() +BaselineCodeGen::emit_JSOP_BINDGNAME() { if (!script->hasNonSyntacticScope()) { // We can bind name to the global lexical scope if the binding already @@ -2708,8 +2832,9 @@ BaselineCompiler::emit_JSOP_BINDGNAME() typedef JSObject* (*BindVarFn)(JSContext*, HandleObject); static const VMFunction BindVarInfo = FunctionInfo(jit::BindVar, "BindVar"); +template bool -BaselineCompiler::emit_JSOP_BINDVAR() +BaselineCodeGen::emit_JSOP_BINDVAR() { frame.syncStack(0); masm.loadPtr(frame.addressOfEnvironmentChain(), R0.scratchReg()); @@ -2726,8 +2851,9 @@ BaselineCompiler::emit_JSOP_BINDVAR() return true; } +template bool -BaselineCompiler::emit_JSOP_SETPROP() +BaselineCodeGen::emit_JSOP_SETPROP() { // Keep lhs in R0, rhs in R1. frame.popRegsAndSync(2); @@ -2744,32 +2870,37 @@ BaselineCompiler::emit_JSOP_SETPROP() return true; } +template bool -BaselineCompiler::emit_JSOP_STRICTSETPROP() +BaselineCodeGen::emit_JSOP_STRICTSETPROP() { return emit_JSOP_SETPROP(); } +template bool -BaselineCompiler::emit_JSOP_SETNAME() +BaselineCodeGen::emit_JSOP_SETNAME() { return emit_JSOP_SETPROP(); } +template bool -BaselineCompiler::emit_JSOP_STRICTSETNAME() +BaselineCodeGen::emit_JSOP_STRICTSETNAME() { return emit_JSOP_SETPROP(); } +template bool -BaselineCompiler::emit_JSOP_SETGNAME() +BaselineCodeGen::emit_JSOP_SETGNAME() { return emit_JSOP_SETPROP(); } +template bool -BaselineCompiler::emit_JSOP_STRICTSETGNAME() +BaselineCodeGen::emit_JSOP_STRICTSETGNAME() { return emit_JSOP_SETPROP(); } @@ -2779,8 +2910,9 @@ typedef bool (*SetPropertySuperFn)(JSContext*, HandleObject, HandleValue, static const VMFunction SetPropertySuperInfo = FunctionInfo(js::SetPropertySuper, "SetPropertySuper"); +template bool -BaselineCompiler::emit_JSOP_SETPROP_SUPER() +BaselineCodeGen::emit_JSOP_SETPROP_SUPER() { bool strict = IsCheckStrictOp(JSOp(*pc)); @@ -2809,14 +2941,16 @@ BaselineCompiler::emit_JSOP_SETPROP_SUPER() return true; } +template bool -BaselineCompiler::emit_JSOP_STRICTSETPROP_SUPER() +BaselineCodeGen::emit_JSOP_STRICTSETPROP_SUPER() { return emit_JSOP_SETPROP_SUPER(); } +template bool -BaselineCompiler::emit_JSOP_GETPROP() +BaselineCodeGen::emit_JSOP_GETPROP() { // Keep object in R0. frame.popRegsAndSync(1); @@ -2831,26 +2965,30 @@ BaselineCompiler::emit_JSOP_GETPROP() return true; } +template bool -BaselineCompiler::emit_JSOP_CALLPROP() +BaselineCodeGen::emit_JSOP_CALLPROP() { return emit_JSOP_GETPROP(); } +template bool -BaselineCompiler::emit_JSOP_LENGTH() +BaselineCodeGen::emit_JSOP_LENGTH() { return emit_JSOP_GETPROP(); } +template bool -BaselineCompiler::emit_JSOP_GETBOUNDNAME() +BaselineCodeGen::emit_JSOP_GETBOUNDNAME() { return emit_JSOP_GETPROP(); } +template bool -BaselineCompiler::emit_JSOP_GETPROP_SUPER() +BaselineCodeGen::emit_JSOP_GETPROP_SUPER() { // Receiver -> R1, Object -> R0 frame.popRegsAndSync(1); @@ -2872,8 +3010,9 @@ static const VMFunction DeletePropertyStrictInfo = static const VMFunction DeletePropertyNonStrictInfo = FunctionInfo(DeletePropertyJit, "DeletePropertyNonStrict"); +template bool -BaselineCompiler::emit_JSOP_DELPROP() +BaselineCodeGen::emit_JSOP_DELPROP() { // Keep value on the stack for the decompiler. frame.syncStack(0); @@ -2895,14 +3034,16 @@ BaselineCompiler::emit_JSOP_DELPROP() return true; } +template bool -BaselineCompiler::emit_JSOP_STRICTDELPROP() +BaselineCodeGen::emit_JSOP_STRICTDELPROP() { return emit_JSOP_DELPROP(); } +template void -BaselineCompiler::getEnvironmentCoordinateObject(Register reg) +BaselineCodeGen::getEnvironmentCoordinateObject(Register reg) { EnvironmentCoordinate ec(pc); @@ -2912,8 +3053,9 @@ BaselineCompiler::getEnvironmentCoordinateObject(Register reg) } } +template Address -BaselineCompiler::getEnvironmentCoordinateAddressFromObject(Register objReg, Register reg) +BaselineCodeGen::getEnvironmentCoordinateAddressFromObject(Register objReg, Register reg) { EnvironmentCoordinate ec(pc); Shape* shape = EnvironmentCoordinateToEnvironmentShape(script, pc); @@ -2926,15 +3068,17 @@ BaselineCompiler::getEnvironmentCoordinateAddressFromObject(Register objReg, Reg return Address(objReg, NativeObject::getFixedSlotOffset(ec.slot())); } +template Address -BaselineCompiler::getEnvironmentCoordinateAddress(Register reg) +BaselineCodeGen::getEnvironmentCoordinateAddress(Register reg) { getEnvironmentCoordinateObject(reg); return getEnvironmentCoordinateAddressFromObject(reg, reg); } +template bool -BaselineCompiler::emit_JSOP_GETALIASEDVAR() +BaselineCodeGen::emit_JSOP_GETALIASEDVAR() { frame.syncStack(0); @@ -2952,8 +3096,9 @@ BaselineCompiler::emit_JSOP_GETALIASEDVAR() return true; } +template bool -BaselineCompiler::emit_JSOP_SETALIASEDVAR() +BaselineCodeGen::emit_JSOP_SETALIASEDVAR() { JSScript* outerScript = EnvironmentCoordinateFunctionScript(script, pc); if (outerScript && outerScript->treatAsRunOnce()) { @@ -3000,8 +3145,9 @@ BaselineCompiler::emit_JSOP_SETALIASEDVAR() return true; } +template bool -BaselineCompiler::emit_JSOP_GETNAME() +BaselineCodeGen::emit_JSOP_GETNAME() { frame.syncStack(0); @@ -3017,8 +3163,9 @@ BaselineCompiler::emit_JSOP_GETNAME() return true; } +template bool -BaselineCompiler::emit_JSOP_BINDNAME() +BaselineCodeGen::emit_JSOP_BINDNAME() { frame.syncStack(0); @@ -3043,8 +3190,9 @@ typedef bool (*DeleteNameFn)(JSContext*, HandlePropertyName, HandleObject, static const VMFunction DeleteNameInfo = FunctionInfo(DeleteNameOperation, "DeleteNameOperation"); +template bool -BaselineCompiler::emit_JSOP_DELNAME() +BaselineCodeGen::emit_JSOP_DELNAME() { frame.syncStack(0); masm.loadPtr(frame.addressOfEnvironmentChain(), R0.scratchReg()); @@ -3062,8 +3210,9 @@ BaselineCompiler::emit_JSOP_DELNAME() return true; } +template bool -BaselineCompiler::emit_JSOP_GETIMPORT() +BaselineCodeGen::emit_JSOP_GETIMPORT() { ModuleEnvironmentObject* env = GetModuleEnvironmentForScript(script); MOZ_ASSERT(env); @@ -3105,8 +3254,9 @@ BaselineCompiler::emit_JSOP_GETIMPORT() return true; } +template bool -BaselineCompiler::emit_JSOP_GETINTRINSIC() +BaselineCodeGen::emit_JSOP_GETINTRINSIC() { frame.syncStack(0); @@ -3121,8 +3271,9 @@ BaselineCompiler::emit_JSOP_GETINTRINSIC() typedef bool (*DefVarFn)(JSContext*, HandlePropertyName, unsigned, HandleObject); static const VMFunction DefVarInfo = FunctionInfo(DefVar, "DefVar"); +template bool -BaselineCompiler::emit_JSOP_DEFVAR() +BaselineCodeGen::emit_JSOP_DEFVAR() { frame.syncStack(0); @@ -3146,14 +3297,16 @@ BaselineCompiler::emit_JSOP_DEFVAR() typedef bool (*DefLexicalFn)(JSContext*, HandlePropertyName, unsigned, HandleObject); static const VMFunction DefLexicalInfo = FunctionInfo(DefLexical, "DefLexical"); +template bool -BaselineCompiler::emit_JSOP_DEFCONST() +BaselineCodeGen::emit_JSOP_DEFCONST() { return emit_JSOP_DEFLET(); } +template bool -BaselineCompiler::emit_JSOP_DEFLET() +BaselineCodeGen::emit_JSOP_DEFLET() { frame.syncStack(0); @@ -3178,8 +3331,9 @@ typedef bool (*DefFunOperationFn)(JSContext*, HandleScript, HandleObject, Handle static const VMFunction DefFunOperationInfo = FunctionInfo(DefFunOperation, "DefFunOperation"); +template bool -BaselineCompiler::emit_JSOP_DEFFUN() +BaselineCodeGen::emit_JSOP_DEFFUN() { frame.popRegsAndSync(1); masm.unboxObject(R0, R0.scratchReg()); @@ -3200,8 +3354,9 @@ static const VMFunction InitPropGetterSetterInfo = FunctionInfo(InitGetterSetterOperation, "InitPropGetterSetterOperation"); +template bool -BaselineCompiler::emitInitPropGetterSetter() +BaselineCodeGen::emitInitPropGetterSetter() { MOZ_ASSERT(JSOp(*pc) == JSOP_INITPROP_GETTER || JSOp(*pc) == JSOP_INITHIDDENPROP_GETTER || @@ -3229,26 +3384,30 @@ BaselineCompiler::emitInitPropGetterSetter() return true; } +template bool -BaselineCompiler::emit_JSOP_INITPROP_GETTER() +BaselineCodeGen::emit_JSOP_INITPROP_GETTER() { return emitInitPropGetterSetter(); } +template bool -BaselineCompiler::emit_JSOP_INITHIDDENPROP_GETTER() +BaselineCodeGen::emit_JSOP_INITHIDDENPROP_GETTER() { return emitInitPropGetterSetter(); } +template bool -BaselineCompiler::emit_JSOP_INITPROP_SETTER() +BaselineCodeGen::emit_JSOP_INITPROP_SETTER() { return emitInitPropGetterSetter(); } +template bool -BaselineCompiler::emit_JSOP_INITHIDDENPROP_SETTER() +BaselineCodeGen::emit_JSOP_INITHIDDENPROP_SETTER() { return emitInitPropGetterSetter(); } @@ -3259,8 +3418,9 @@ static const VMFunction InitElemGetterSetterInfo = FunctionInfo(InitGetterSetterOperation, "InitElemGetterSetterOperation"); +template bool -BaselineCompiler::emitInitElemGetterSetter() +BaselineCodeGen::emitInitElemGetterSetter() { MOZ_ASSERT(JSOp(*pc) == JSOP_INITELEM_GETTER || JSOp(*pc) == JSOP_INITHIDDENELEM_GETTER || @@ -3289,32 +3449,37 @@ BaselineCompiler::emitInitElemGetterSetter() return true; } +template bool -BaselineCompiler::emit_JSOP_INITELEM_GETTER() +BaselineCodeGen::emit_JSOP_INITELEM_GETTER() { return emitInitElemGetterSetter(); } +template bool -BaselineCompiler::emit_JSOP_INITHIDDENELEM_GETTER() +BaselineCodeGen::emit_JSOP_INITHIDDENELEM_GETTER() { return emitInitElemGetterSetter(); } +template bool -BaselineCompiler::emit_JSOP_INITELEM_SETTER() +BaselineCodeGen::emit_JSOP_INITELEM_SETTER() { return emitInitElemGetterSetter(); } +template bool -BaselineCompiler::emit_JSOP_INITHIDDENELEM_SETTER() +BaselineCodeGen::emit_JSOP_INITHIDDENELEM_SETTER() { return emitInitElemGetterSetter(); } +template bool -BaselineCompiler::emit_JSOP_INITELEM_INC() +BaselineCodeGen::emit_JSOP_INITELEM_INC() { // Keep the object and rhs on the stack. frame.syncStack(0); @@ -3343,15 +3508,17 @@ BaselineCompiler::emit_JSOP_INITELEM_INC() return true; } +template bool -BaselineCompiler::emit_JSOP_GETLOCAL() +BaselineCodeGen::emit_JSOP_GETLOCAL() { frame.pushLocal(GET_LOCALNO(pc)); return true; } +template bool -BaselineCompiler::emit_JSOP_SETLOCAL() +BaselineCodeGen::emit_JSOP_SETLOCAL() { // Ensure no other StackValue refers to the old value, for instance i + (i = 3). // This also allows us to use R0 as scratch below. @@ -3362,8 +3529,9 @@ BaselineCompiler::emit_JSOP_SETLOCAL() return true; } +template bool -BaselineCompiler::emitFormalArgAccess(uint32_t arg, bool get) +BaselineCodeGen::emitFormalArgAccess(uint32_t arg, bool get) { // Fast path: the script does not use |arguments| or formals don't // alias the arguments object. @@ -3436,15 +3604,17 @@ BaselineCompiler::emitFormalArgAccess(uint32_t arg, bool get) return true; } +template bool -BaselineCompiler::emit_JSOP_GETARG() +BaselineCodeGen::emit_JSOP_GETARG() { uint32_t arg = GET_ARGNO(pc); return emitFormalArgAccess(arg, /* get = */ true); } +template bool -BaselineCompiler::emit_JSOP_SETARG() +BaselineCodeGen::emit_JSOP_SETARG() { // Ionmonkey can't inline functions with SETARG with magic arguments. if (!script->argsObjAliasesFormals() && script->argumentsAliasesFormals()) { @@ -3457,8 +3627,9 @@ BaselineCompiler::emit_JSOP_SETARG() return emitFormalArgAccess(arg, /* get = */ false); } +template bool -BaselineCompiler::emit_JSOP_NEWTARGET() +BaselineCodeGen::emit_JSOP_NEWTARGET() { if (script->isForEval()) { frame.pushEvalNewTarget(); @@ -3523,34 +3694,39 @@ static const VMFunction ThrowRuntimeLexicalErrorInfo = FunctionInfo(jit::ThrowRuntimeLexicalError, "ThrowRuntimeLexicalError"); +template bool -BaselineCompiler::emitThrowConstAssignment() +BaselineCodeGen::emitThrowConstAssignment() { prepareVMCall(); pushArg(Imm32(JSMSG_BAD_CONST_ASSIGN)); return callVM(ThrowRuntimeLexicalErrorInfo); } +template bool -BaselineCompiler::emit_JSOP_THROWSETCONST() +BaselineCodeGen::emit_JSOP_THROWSETCONST() { return emitThrowConstAssignment(); } +template bool -BaselineCompiler::emit_JSOP_THROWSETALIASEDCONST() +BaselineCodeGen::emit_JSOP_THROWSETALIASEDCONST() { return emitThrowConstAssignment(); } +template bool -BaselineCompiler::emit_JSOP_THROWSETCALLEE() +BaselineCodeGen::emit_JSOP_THROWSETCALLEE() { return emitThrowConstAssignment(); } +template bool -BaselineCompiler::emitUninitializedLexicalCheck(const ValueOperand& val) +BaselineCodeGen::emitUninitializedLexicalCheck(const ValueOperand& val) { Label done; masm.branchTestMagicValue(Assembler::NotEqual, val, JS_UNINITIALIZED_LEXICAL, &done); @@ -3565,22 +3741,25 @@ BaselineCompiler::emitUninitializedLexicalCheck(const ValueOperand& val) return true; } +template bool -BaselineCompiler::emit_JSOP_CHECKLEXICAL() +BaselineCodeGen::emit_JSOP_CHECKLEXICAL() { frame.syncStack(0); masm.loadValue(frame.addressOfLocal(GET_LOCALNO(pc)), R0); return emitUninitializedLexicalCheck(R0); } +template bool -BaselineCompiler::emit_JSOP_INITLEXICAL() +BaselineCodeGen::emit_JSOP_INITLEXICAL() { return emit_JSOP_SETLOCAL(); } +template bool -BaselineCompiler::emit_JSOP_INITGLEXICAL() +BaselineCodeGen::emit_JSOP_INITGLEXICAL() { frame.popRegsAndSync(1); frame.push(ObjectValue(script->global().lexicalEnvironment())); @@ -3588,29 +3767,33 @@ BaselineCompiler::emit_JSOP_INITGLEXICAL() return emit_JSOP_SETPROP(); } +template bool -BaselineCompiler::emit_JSOP_CHECKALIASEDLEXICAL() +BaselineCodeGen::emit_JSOP_CHECKALIASEDLEXICAL() { frame.syncStack(0); masm.loadValue(getEnvironmentCoordinateAddress(R0.scratchReg()), R0); return emitUninitializedLexicalCheck(R0); } +template bool -BaselineCompiler::emit_JSOP_INITALIASEDLEXICAL() +BaselineCodeGen::emit_JSOP_INITALIASEDLEXICAL() { return emit_JSOP_SETALIASEDVAR(); } +template bool -BaselineCompiler::emit_JSOP_UNINITIALIZED() +BaselineCodeGen::emit_JSOP_UNINITIALIZED() { frame.push(MagicValue(JS_UNINITIALIZED_LEXICAL)); return true; } +template bool -BaselineCompiler::emitCall() +BaselineCodeGen::emitCall() { MOZ_ASSERT(IsCallPC(pc)); @@ -3631,8 +3814,9 @@ BaselineCompiler::emitCall() return true; } +template bool -BaselineCompiler::emitSpreadCall() +BaselineCodeGen::emitSpreadCall() { MOZ_ASSERT(IsCallPC(pc)); @@ -3651,86 +3835,100 @@ BaselineCompiler::emitSpreadCall() return true; } +template bool -BaselineCompiler::emit_JSOP_CALL() +BaselineCodeGen::emit_JSOP_CALL() { return emitCall(); } +template bool -BaselineCompiler::emit_JSOP_CALL_IGNORES_RV() +BaselineCodeGen::emit_JSOP_CALL_IGNORES_RV() { return emitCall(); } +template bool -BaselineCompiler::emit_JSOP_CALLITER() +BaselineCodeGen::emit_JSOP_CALLITER() { return emitCall(); } +template bool -BaselineCompiler::emit_JSOP_NEW() +BaselineCodeGen::emit_JSOP_NEW() { return emitCall(); } +template bool -BaselineCompiler::emit_JSOP_SUPERCALL() +BaselineCodeGen::emit_JSOP_SUPERCALL() { return emitCall(); } +template bool -BaselineCompiler::emit_JSOP_FUNCALL() +BaselineCodeGen::emit_JSOP_FUNCALL() { return emitCall(); } +template bool -BaselineCompiler::emit_JSOP_FUNAPPLY() +BaselineCodeGen::emit_JSOP_FUNAPPLY() { return emitCall(); } +template bool -BaselineCompiler::emit_JSOP_EVAL() +BaselineCodeGen::emit_JSOP_EVAL() { return emitCall(); } +template bool -BaselineCompiler::emit_JSOP_STRICTEVAL() +BaselineCodeGen::emit_JSOP_STRICTEVAL() { return emitCall(); } +template bool -BaselineCompiler::emit_JSOP_SPREADCALL() +BaselineCodeGen::emit_JSOP_SPREADCALL() { return emitSpreadCall(); } +template bool -BaselineCompiler::emit_JSOP_SPREADNEW() +BaselineCodeGen::emit_JSOP_SPREADNEW() { return emitSpreadCall(); } +template bool -BaselineCompiler::emit_JSOP_SPREADSUPERCALL() +BaselineCodeGen::emit_JSOP_SPREADSUPERCALL() { return emitSpreadCall(); } +template bool -BaselineCompiler::emit_JSOP_SPREADEVAL() +BaselineCodeGen::emit_JSOP_SPREADEVAL() { return emitSpreadCall(); } +template bool -BaselineCompiler::emit_JSOP_STRICTSPREADEVAL() +BaselineCodeGen::emit_JSOP_STRICTSPREADEVAL() { return emitSpreadCall(); } @@ -3739,8 +3937,9 @@ typedef bool (*OptimizeSpreadCallFn)(JSContext*, HandleValue, bool*); static const VMFunction OptimizeSpreadCallInfo = FunctionInfo(OptimizeSpreadCall, "OptimizeSpreadCall"); +template bool -BaselineCompiler::emit_JSOP_OPTIMIZE_SPREADCALL() +BaselineCodeGen::emit_JSOP_OPTIMIZE_SPREADCALL() { frame.syncStack(0); masm.loadValue(frame.addressOfStackValue(frame.peek(-1)), R0); @@ -3762,8 +3961,9 @@ typedef bool (*ImplicitThisFn)(JSContext*, HandleObject, HandlePropertyName, const VMFunction jit::ImplicitThisInfo = FunctionInfo(ImplicitThisOperation, "ImplicitThisOperation"); +template bool -BaselineCompiler::emit_JSOP_IMPLICITTHIS() +BaselineCodeGen::emit_JSOP_IMPLICITTHIS() { frame.syncStack(0); masm.loadPtr(frame.addressOfEnvironmentChain(), R0.scratchReg()); @@ -3781,8 +3981,9 @@ BaselineCompiler::emit_JSOP_IMPLICITTHIS() return true; } +template bool -BaselineCompiler::emit_JSOP_GIMPLICITTHIS() +BaselineCodeGen::emit_JSOP_GIMPLICITTHIS() { if (!script->hasNonSyntacticScope()) { frame.push(UndefinedValue()); @@ -3792,8 +3993,9 @@ BaselineCompiler::emit_JSOP_GIMPLICITTHIS() return emit_JSOP_IMPLICITTHIS(); } +template bool -BaselineCompiler::emit_JSOP_INSTANCEOF() +BaselineCodeGen::emit_JSOP_INSTANCEOF() { frame.popRegsAndSync(2); @@ -3805,8 +4007,9 @@ BaselineCompiler::emit_JSOP_INSTANCEOF() return true; } +template bool -BaselineCompiler::emit_JSOP_TYPEOF() +BaselineCodeGen::emit_JSOP_TYPEOF() { frame.popRegsAndSync(1); @@ -3818,8 +4021,9 @@ BaselineCompiler::emit_JSOP_TYPEOF() return true; } +template bool -BaselineCompiler::emit_JSOP_TYPEOFEXPR() +BaselineCodeGen::emit_JSOP_TYPEOFEXPR() { return emit_JSOP_TYPEOF(); } @@ -3828,8 +4032,9 @@ typedef bool (*ThrowMsgFn)(JSContext*, const unsigned); static const VMFunction ThrowMsgInfo = FunctionInfo(js::ThrowMsgOperation, "ThrowMsgOperation"); +template bool -BaselineCompiler::emit_JSOP_THROWMSG() +BaselineCodeGen::emit_JSOP_THROWMSG() { prepareVMCall(); pushArg(Imm32(GET_UINT16(pc))); @@ -3839,8 +4044,9 @@ BaselineCompiler::emit_JSOP_THROWMSG() typedef bool (*ThrowFn)(JSContext*, HandleValue); static const VMFunction ThrowInfo = FunctionInfo(js::Throw, "Throw"); +template bool -BaselineCompiler::emit_JSOP_THROW() +BaselineCodeGen::emit_JSOP_THROW() { // Keep value to throw in R0. frame.popRegsAndSync(1); @@ -3851,8 +4057,9 @@ BaselineCompiler::emit_JSOP_THROW() return callVM(ThrowInfo); } +template bool -BaselineCompiler::emit_JSOP_TRY() +BaselineCodeGen::emit_JSOP_TRY() { if (!emit_JSOP_JUMPTARGET()) { return false; @@ -3863,8 +4070,9 @@ BaselineCompiler::emit_JSOP_TRY() return true; } +template bool -BaselineCompiler::emit_JSOP_FINALLY() +BaselineCodeGen::emit_JSOP_FINALLY() { // JSOP_FINALLY has a def count of 2, but these values are already on the // stack (they're pushed by JSOP_GOSUB). Update the compiler's stack state. @@ -3875,8 +4083,9 @@ BaselineCompiler::emit_JSOP_FINALLY() return emitInterruptCheck(); } +template bool -BaselineCompiler::emit_JSOP_GOSUB() +BaselineCodeGen::emit_JSOP_GOSUB() { // Jump to the finally block. frame.syncStack(0); @@ -3897,8 +4106,9 @@ LoadBaselineScriptResumeEntries(MacroAssembler& masm, JSScript* script, Register masm.addPtr(scratch, dest); } +template bool -BaselineCompiler::emit_JSOP_RETSUB() +BaselineCodeGen::emit_JSOP_RETSUB() { frame.popRegsAndSync(2); @@ -3928,10 +4138,11 @@ typedef bool (*PushLexicalEnvFn)(JSContext*, BaselineFrame*, Handle(jit::PushLexicalEnv, "PushLexicalEnv"); +template bool -BaselineCompiler::emit_JSOP_PUSHLEXICALENV() +BaselineCodeGen::emit_JSOP_PUSHLEXICALENV() { - LexicalScope& scope = script->getScope(pc)->as(); + LexicalScope& scope = script->getScope(pc)->template as(); // Call a stub to push the block on the block chain. prepareVMCall(); @@ -3952,8 +4163,9 @@ static const VMFunction DebugLeaveThenPopLexicalEnvInfo = FunctionInfo(jit::DebugLeaveThenPopLexicalEnv, "DebugLeaveThenPopLexicalEnv"); +template bool -BaselineCompiler::emit_JSOP_POPLEXICALENV() +BaselineCodeGen::emit_JSOP_POPLEXICALENV() { prepareVMCall(); @@ -3978,8 +4190,9 @@ static const VMFunction DebugLeaveThenFreshenLexicalEnvInfo = FunctionInfo(jit::DebugLeaveThenFreshenLexicalEnv, "DebugLeaveThenFreshenLexicalEnv"); +template bool -BaselineCompiler::emit_JSOP_FRESHENLEXICALENV() +BaselineCodeGen::emit_JSOP_FRESHENLEXICALENV() { prepareVMCall(); @@ -4005,8 +4218,9 @@ static const VMFunction DebugLeaveThenRecreateLexicalEnvInfo = FunctionInfo(jit::DebugLeaveThenRecreateLexicalEnv, "DebugLeaveThenRecreateLexicalEnv"); +template bool -BaselineCompiler::emit_JSOP_RECREATELEXICALENV() +BaselineCodeGen::emit_JSOP_RECREATELEXICALENV() { prepareVMCall(); @@ -4026,8 +4240,9 @@ typedef bool (*DebugLeaveLexicalEnvFn)(JSContext*, BaselineFrame*, jsbytecode*); static const VMFunction DebugLeaveLexicalEnvInfo = FunctionInfo(jit::DebugLeaveLexicalEnv, "DebugLeaveLexicalEnv"); +template bool -BaselineCompiler::emit_JSOP_DEBUGLEAVELEXICALENV() +BaselineCodeGen::emit_JSOP_DEBUGLEAVELEXICALENV() { if (!compileDebugInstrumentation_) { return true; @@ -4045,8 +4260,9 @@ typedef bool (*PushVarEnvFn)(JSContext*, BaselineFrame*, HandleScope); static const VMFunction PushVarEnvInfo = FunctionInfo(jit::PushVarEnv, "PushVarEnv"); +template bool -BaselineCompiler::emit_JSOP_PUSHVARENV() +BaselineCodeGen::emit_JSOP_PUSHVARENV() { prepareVMCall(); masm.loadBaselineFramePtr(BaselineFrameReg, R0.scratchReg()); @@ -4060,8 +4276,9 @@ typedef bool (*PopVarEnvFn)(JSContext*, BaselineFrame*); static const VMFunction PopVarEnvInfo = FunctionInfo(jit::PopVarEnv, "PopVarEnv"); +template bool -BaselineCompiler::emit_JSOP_POPVARENV() +BaselineCodeGen::emit_JSOP_POPVARENV() { prepareVMCall(); masm.loadBaselineFramePtr(BaselineFrameReg, R0.scratchReg()); @@ -4074,10 +4291,11 @@ typedef bool (*EnterWithFn)(JSContext*, BaselineFrame*, HandleValue, Handle(jit::EnterWith, "EnterWith"); +template bool -BaselineCompiler::emit_JSOP_ENTERWITH() +BaselineCodeGen::emit_JSOP_ENTERWITH() { - WithScope& withScope = script->getScope(pc)->as(); + WithScope& withScope = script->getScope(pc)->template as(); // Pop "with" object to R0. frame.popRegsAndSync(1); @@ -4097,8 +4315,9 @@ typedef bool (*LeaveWithFn)(JSContext*, BaselineFrame*); static const VMFunction LeaveWithInfo = FunctionInfo(jit::LeaveWith, "LeaveWith"); +template bool -BaselineCompiler::emit_JSOP_LEAVEWITH() +BaselineCodeGen::emit_JSOP_LEAVEWITH() { // Call a stub to pop the with object from the environment chain. prepareVMCall(); @@ -4113,8 +4332,9 @@ typedef bool (*GetAndClearExceptionFn)(JSContext*, MutableHandleValue); static const VMFunction GetAndClearExceptionInfo = FunctionInfo(GetAndClearException, "GetAndClearException"); +template bool -BaselineCompiler::emit_JSOP_EXCEPTION() +BaselineCodeGen::emit_JSOP_EXCEPTION() { prepareVMCall(); @@ -4130,8 +4350,9 @@ typedef bool (*OnDebuggerStatementFn)(JSContext*, BaselineFrame*, jsbytecode* pc static const VMFunction OnDebuggerStatementInfo = FunctionInfo(jit::OnDebuggerStatement, "OnDebuggerStatement"); +template bool -BaselineCompiler::emit_JSOP_DEBUGGER() +BaselineCodeGen::emit_JSOP_DEBUGGER() { prepareVMCall(); pushArg(ImmPtr(pc)); @@ -4160,8 +4381,9 @@ static const VMFunction DebugEpilogueInfo = FunctionInfo(jit::DebugEpilogueOnBaselineReturn, "DebugEpilogueOnBaselineReturn"); +template bool -BaselineCompiler::emitReturn() +BaselineCodeGen::emitReturn() { if (compileDebugInstrumentation_) { // Move return value into the frame's rval slot. @@ -4195,8 +4417,9 @@ BaselineCompiler::emitReturn() return true; } +template bool -BaselineCompiler::emit_JSOP_RETURN() +BaselineCodeGen::emit_JSOP_RETURN() { MOZ_ASSERT(frame.stackDepth() == 1); @@ -4204,8 +4427,9 @@ BaselineCompiler::emit_JSOP_RETURN() return emitReturn(); } +template void -BaselineCompiler::emitLoadReturnValue(ValueOperand val) +BaselineCodeGen::emitLoadReturnValue(ValueOperand val) { Label done, noRval; masm.branchTest32(Assembler::Zero, frame.addressOfFlags(), @@ -4219,8 +4443,9 @@ BaselineCompiler::emitLoadReturnValue(ValueOperand val) masm.bind(&done); } +template bool -BaselineCompiler::emit_JSOP_RETRVAL() +BaselineCodeGen::emit_JSOP_RETRVAL() { MOZ_ASSERT(frame.stackDepth() == 0); @@ -4241,8 +4466,9 @@ BaselineCompiler::emit_JSOP_RETRVAL() typedef bool (*ToIdFn)(JSContext*, HandleValue, MutableHandleValue); static const VMFunction ToIdInfo = FunctionInfo(js::ToIdOperation, "ToIdOperation"); +template bool -BaselineCompiler::emit_JSOP_TOID() +BaselineCodeGen::emit_JSOP_TOID() { // Load index in R0, but keep values on the stack for the decompiler. frame.syncStack(0); @@ -4271,8 +4497,9 @@ BaselineCompiler::emit_JSOP_TOID() typedef JSObject* (*ToAsyncFn)(JSContext*, HandleFunction); static const VMFunction ToAsyncInfo = FunctionInfo(js::WrapAsyncFunction, "ToAsync"); +template bool -BaselineCompiler::emit_JSOP_TOASYNC() +BaselineCodeGen::emit_JSOP_TOASYNC() { frame.syncStack(0); masm.unboxObject(frame.addressOfStackValue(frame.peek(-1)), R0.scratchReg()); @@ -4294,8 +4521,9 @@ typedef JSObject* (*ToAsyncGenFn)(JSContext*, HandleFunction); static const VMFunction ToAsyncGenInfo = FunctionInfo(js::WrapAsyncGenerator, "ToAsyncGen"); +template bool -BaselineCompiler::emit_JSOP_TOASYNCGEN() +BaselineCodeGen::emit_JSOP_TOASYNCGEN() { frame.syncStack(0); masm.unboxObject(frame.addressOfStackValue(frame.peek(-1)), R0.scratchReg()); @@ -4317,8 +4545,9 @@ typedef JSObject* (*ToAsyncIterFn)(JSContext*, HandleObject, HandleValue); static const VMFunction ToAsyncIterInfo = FunctionInfo(js::CreateAsyncFromSyncIterator, "ToAsyncIter"); +template bool -BaselineCompiler::emit_JSOP_TOASYNCITER() +BaselineCodeGen::emit_JSOP_TOASYNCITER() { frame.syncStack(0); masm.unboxObject(frame.addressOfStackValue(frame.peek(-2)), R0.scratchReg()); @@ -4341,8 +4570,9 @@ BaselineCompiler::emit_JSOP_TOASYNCITER() typedef bool (*TrySkipAwaitFn)(JSContext*, HandleValue, MutableHandleValue); static const VMFunction TrySkipAwaitInfo = FunctionInfo(jit::TrySkipAwait, "TrySkipAwait"); +template bool -BaselineCompiler::emit_JSOP_TRYSKIPAWAIT() +BaselineCodeGen::emit_JSOP_TRYSKIPAWAIT() { frame.syncStack(0); masm.loadValue(frame.addressOfStackValue(frame.peek(-1)), R0); @@ -4375,8 +4605,9 @@ typedef bool (*ThrowObjectCoercibleFn)(JSContext*, HandleValue); static const VMFunction ThrowObjectCoercibleInfo = FunctionInfo(ThrowObjectCoercible, "ThrowObjectCoercible"); +template bool -BaselineCompiler::emit_JSOP_CHECKOBJCOERCIBLE() +BaselineCodeGen::emit_JSOP_CHECKOBJCOERCIBLE() { frame.syncStack(0); masm.loadValue(frame.addressOfStackValue(frame.peek(-1)), R0); @@ -4402,8 +4633,9 @@ BaselineCompiler::emit_JSOP_CHECKOBJCOERCIBLE() typedef JSString* (*ToStringFn)(JSContext*, HandleValue); static const VMFunction ToStringInfo = FunctionInfo(ToStringSlow, "ToStringSlow"); +template bool -BaselineCompiler::emit_JSOP_TOSTRING() +BaselineCodeGen::emit_JSOP_TOSTRING() { // Keep top stack value in R0. frame.popRegsAndSync(1); @@ -4428,8 +4660,9 @@ BaselineCompiler::emit_JSOP_TOSTRING() return true; } +template bool -BaselineCompiler::emit_JSOP_TABLESWITCH() +BaselineCodeGen::emit_JSOP_TABLESWITCH() { frame.popRegsAndSync(1); @@ -4473,8 +4706,9 @@ BaselineCompiler::emit_JSOP_TABLESWITCH() return true; } +template bool -BaselineCompiler::emit_JSOP_ITER() +BaselineCodeGen::emit_JSOP_ITER() { frame.popRegsAndSync(1); @@ -4486,8 +4720,9 @@ BaselineCompiler::emit_JSOP_ITER() return true; } +template bool -BaselineCompiler::emit_JSOP_MOREITER() +BaselineCodeGen::emit_JSOP_MOREITER() { frame.syncStack(0); masm.loadValue(frame.addressOfStackValue(frame.peek(-1)), R0); @@ -4500,8 +4735,9 @@ BaselineCompiler::emit_JSOP_MOREITER() return true; } +template bool -BaselineCompiler::emitIsMagicValue() +BaselineCodeGen::emitIsMagicValue() { frame.syncStack(0); @@ -4519,14 +4755,16 @@ BaselineCompiler::emitIsMagicValue() return true; } +template bool -BaselineCompiler::emit_JSOP_ISNOITER() +BaselineCodeGen::emit_JSOP_ISNOITER() { return emitIsMagicValue(); } +template bool -BaselineCompiler::emit_JSOP_ENDITER() +BaselineCodeGen::emit_JSOP_ENDITER() { if (!emit_JSOP_JUMPTARGET()) { return false; @@ -4540,14 +4778,16 @@ BaselineCompiler::emit_JSOP_ENDITER() return true; } +template bool -BaselineCompiler::emit_JSOP_ISGENCLOSING() +BaselineCodeGen::emit_JSOP_ISGENCLOSING() { return emitIsMagicValue(); } +template bool -BaselineCompiler::emit_JSOP_GETRVAL() +BaselineCodeGen::emit_JSOP_GETRVAL() { frame.syncStack(0); @@ -4557,8 +4797,9 @@ BaselineCompiler::emit_JSOP_GETRVAL() return true; } +template bool -BaselineCompiler::emit_JSOP_SETRVAL() +BaselineCodeGen::emit_JSOP_SETRVAL() { // Store to the frame's return value slot. storeValue(frame.peek(-1), frame.addressOfReturnValue(), R2); @@ -4567,8 +4808,9 @@ BaselineCompiler::emit_JSOP_SETRVAL() return true; } +template bool -BaselineCompiler::emit_JSOP_CALLEE() +BaselineCodeGen::emit_JSOP_CALLEE() { MOZ_ASSERT(function()); frame.syncStack(0); @@ -4578,8 +4820,9 @@ BaselineCompiler::emit_JSOP_CALLEE() return true; } +template void -BaselineCompiler::getThisEnvironmentCallee(Register reg) +BaselineCodeGen::getThisEnvironmentCallee(Register reg) { // Directly load callee from frame if we have a HomeObject if (function() && function()->allowSuperProperty()) { @@ -4617,8 +4860,9 @@ typedef JSObject* (*HomeObjectSuperBaseFn)(JSContext*, HandleObject); static const VMFunction HomeObjectSuperBaseInfo = FunctionInfo(HomeObjectSuperBase, "HomeObjectSuperBase"); +template bool -BaselineCompiler::emit_JSOP_SUPERBASE() +BaselineCodeGen::emit_JSOP_SUPERBASE() { frame.syncStack(0); @@ -4664,8 +4908,9 @@ typedef JSObject* (*SuperFunOperationFn)(JSContext*, HandleObject); static const VMFunction SuperFunOperationInfo = FunctionInfo(SuperFunOperation, "SuperFunOperation"); +template bool -BaselineCompiler::emit_JSOP_SUPERFUN() +BaselineCodeGen::emit_JSOP_SUPERFUN() { frame.syncStack(0); @@ -4716,8 +4961,9 @@ typedef bool (*NewArgumentsObjectFn)(JSContext*, BaselineFrame*, MutableHandleVa static const VMFunction NewArgumentsObjectInfo = FunctionInfo(jit::NewArgumentsObject, "NewArgumentsObject"); +template bool -BaselineCompiler::emit_JSOP_ARGUMENTS() +BaselineCodeGen::emit_JSOP_ARGUMENTS() { frame.syncStack(0); @@ -4755,8 +5001,9 @@ typedef bool (*RunOnceScriptPrologueFn)(JSContext*, HandleScript); static const VMFunction RunOnceScriptPrologueInfo = FunctionInfo(js::RunOnceScriptPrologue, "RunOnceScriptPrologue"); +template bool -BaselineCompiler::emit_JSOP_RUNONCE() +BaselineCodeGen::emit_JSOP_RUNONCE() { frame.syncStack(0); @@ -4768,8 +5015,9 @@ BaselineCompiler::emit_JSOP_RUNONCE() return callVM(RunOnceScriptPrologueInfo); } +template bool -BaselineCompiler::emit_JSOP_REST() +BaselineCodeGen::emit_JSOP_REST() { frame.syncStack(0); @@ -4786,8 +5034,9 @@ typedef JSObject* (*CreateGeneratorFn)(JSContext*, BaselineFrame*); static const VMFunction CreateGeneratorInfo = FunctionInfo(jit::CreateGenerator, "CreateGenerator"); +template bool -BaselineCompiler::emit_JSOP_GENERATOR() +BaselineCodeGen::emit_JSOP_GENERATOR() { MOZ_ASSERT(frame.stackDepth() == 0); @@ -4804,8 +5053,9 @@ BaselineCompiler::emit_JSOP_GENERATOR() return true; } +template bool -BaselineCompiler::emit_JSOP_INITIALYIELD() +BaselineCodeGen::emit_JSOP_INITIALYIELD() { frame.syncStack(0); MOZ_ASSERT(frame.stackDepth() == 1); @@ -4841,8 +5091,9 @@ typedef bool (*NormalSuspendFn)(JSContext*, HandleObject, BaselineFrame*, jsbyte static const VMFunction NormalSuspendInfo = FunctionInfo(jit::NormalSuspend, "NormalSuspend"); +template bool -BaselineCompiler::emit_JSOP_YIELD() +BaselineCodeGen::emit_JSOP_YIELD() { // Store generator in R0. frame.popRegsAndSync(1); @@ -4889,8 +5140,9 @@ BaselineCompiler::emit_JSOP_YIELD() return emitReturn(); } +template bool -BaselineCompiler::emit_JSOP_AWAIT() +BaselineCodeGen::emit_JSOP_AWAIT() { return emit_JSOP_YIELD(); } @@ -4899,8 +5151,9 @@ typedef bool (*DebugAfterYieldFn)(JSContext*, BaselineFrame*, jsbytecode*, bool* static const VMFunction DebugAfterYieldInfo = FunctionInfo(jit::DebugAfterYield, "DebugAfterYield"); +template bool -BaselineCompiler::emit_JSOP_DEBUGAFTERYIELD() +BaselineCodeGen::emit_JSOP_DEBUGAFTERYIELD() { if (!compileDebugInstrumentation_) { return true; @@ -4931,8 +5184,9 @@ typedef bool (*FinalSuspendFn)(JSContext*, HandleObject, jsbytecode*); static const VMFunction FinalSuspendInfo = FunctionInfo(jit::FinalSuspend, "FinalSuspend"); +template bool -BaselineCompiler::emit_JSOP_FINALYIELDRVAL() +BaselineCodeGen::emit_JSOP_FINALYIELDRVAL() { // Store generator in R0. frame.popRegsAndSync(1); @@ -4960,8 +5214,9 @@ typedef bool (*GeneratorThrowFn)(JSContext*, BaselineFrame*, Handle(jit::GeneratorThrowOrReturn, "GeneratorThrowOrReturn", TailCall); +template bool -BaselineCompiler::emit_JSOP_RESUME() +BaselineCodeGen::emit_JSOP_RESUME() { GeneratorObject::ResumeKind resumeKind = GeneratorObject::getResumeKind(pc); @@ -5204,8 +5459,9 @@ typedef bool (*CheckSelfHostedFn)(JSContext*, HandleValue); static const VMFunction CheckSelfHostedInfo = FunctionInfo(js::Debug_CheckSelfHosted, "Debug_CheckSelfHosted"); +template bool -BaselineCompiler::emit_JSOP_DEBUGCHECKSELFHOSTED() +BaselineCodeGen::emit_JSOP_DEBUGCHECKSELFHOSTED() { #ifdef DEBUG frame.syncStack(0); @@ -5222,15 +5478,17 @@ BaselineCompiler::emit_JSOP_DEBUGCHECKSELFHOSTED() } +template bool -BaselineCompiler::emit_JSOP_IS_CONSTRUCTING() +BaselineCodeGen::emit_JSOP_IS_CONSTRUCTING() { frame.push(MagicValue(JS_IS_CONSTRUCTING)); return true; } +template bool -BaselineCompiler::emit_JSOP_JUMPTARGET() +BaselineCodeGen::emit_JSOP_JUMPTARGET() { if (!script->hasScriptCounts()) { return true; @@ -5246,8 +5504,9 @@ static const VMFunction CheckClassHeritageOperationInfo = FunctionInfo(js::CheckClassHeritageOperation, "CheckClassHeritageOperation"); +template bool -BaselineCompiler::emit_JSOP_CHECKCLASSHERITAGE() +BaselineCodeGen::emit_JSOP_CHECKCLASSHERITAGE() { frame.syncStack(0); @@ -5259,8 +5518,9 @@ BaselineCompiler::emit_JSOP_CHECKCLASSHERITAGE() return callVM(CheckClassHeritageOperationInfo); } +template bool -BaselineCompiler::emit_JSOP_INITHOMEOBJECT() +BaselineCodeGen::emit_JSOP_INITHOMEOBJECT() { // Load HomeObject in R0. frame.popRegsAndSync(1); @@ -5284,8 +5544,9 @@ BaselineCompiler::emit_JSOP_INITHOMEOBJECT() return true; } +template bool -BaselineCompiler::emit_JSOP_BUILTINPROTO() +BaselineCodeGen::emit_JSOP_BUILTINPROTO() { // The builtin prototype is a constant for a given global. JSProtoKey key = static_cast(GET_UINT8(pc)); @@ -5303,8 +5564,9 @@ static const VMFunction ObjectWithProtoOperationInfo = FunctionInfo(js::ObjectWithProtoOperation, "ObjectWithProtoOperationInfo"); +template bool -BaselineCompiler::emit_JSOP_OBJWITHPROTO() +BaselineCodeGen::emit_JSOP_OBJWITHPROTO() { frame.syncStack(0); @@ -5327,8 +5589,9 @@ typedef JSObject* (*FunWithProtoFn)(JSContext*, HandleFunction, HandleObject, Ha static const VMFunction FunWithProtoInfo = FunctionInfo(js::FunWithProtoOperation, "FunWithProtoOperation"); +template bool -BaselineCompiler::emit_JSOP_FUNWITHPROTO() +BaselineCodeGen::emit_JSOP_FUNWITHPROTO() { frame.popRegsAndSync(1); @@ -5354,8 +5617,9 @@ static const VMFunction MakeDefaultConstructorInfo = FunctionInfo(js::MakeDefaultConstructor, "MakeDefaultConstructor"); +template bool -BaselineCompiler::emit_JSOP_CLASSCONSTRUCTOR() +BaselineCodeGen::emit_JSOP_CLASSCONSTRUCTOR() { frame.syncStack(0); @@ -5373,8 +5637,9 @@ BaselineCompiler::emit_JSOP_CLASSCONSTRUCTOR() return true; } +template bool -BaselineCompiler::emit_JSOP_DERIVEDCONSTRUCTOR() +BaselineCodeGen::emit_JSOP_DERIVEDCONSTRUCTOR() { frame.popRegsAndSync(1); @@ -5398,8 +5663,9 @@ static const VMFunction GetOrCreateModuleMetaObjectInfo = FunctionInfo(js::GetOrCreateModuleMetaObject, "GetOrCreateModuleMetaObject"); +template bool -BaselineCompiler::emit_JSOP_IMPORTMETA() +BaselineCodeGen::emit_JSOP_IMPORTMETA() { RootedModuleObject module(cx, GetModuleObjectForScript(script)); MOZ_ASSERT(module); @@ -5422,8 +5688,9 @@ static const VMFunction StartDynamicModuleImportInfo = FunctionInfo(js::StartDynamicModuleImport, "StartDynamicModuleImport"); +template bool -BaselineCompiler::emit_JSOP_DYNAMIC_IMPORT() +BaselineCodeGen::emit_JSOP_DYNAMIC_IMPORT() { RootedValue referencingPrivate(cx, FindScriptOrModulePrivateForScript(script)); @@ -5441,3 +5708,6 @@ BaselineCompiler::emit_JSOP_DYNAMIC_IMPORT() frame.push(R0); return true; } + +// Instantiate explicitly for now to make sure it compiles. +template class jit::BaselineCodeGen; diff --git a/js/src/jit/BaselineCompiler.h b/js/src/jit/BaselineCompiler.h index ab04317ab9ac..2d78a7ed58d2 100644 --- a/js/src/jit/BaselineCompiler.h +++ b/js/src/jit/BaselineCompiler.h @@ -249,8 +249,16 @@ namespace jit { _(JSOP_IMPORTMETA) \ _(JSOP_DYNAMIC_IMPORT) -class BaselineCompiler final +// Base class for BaselineCompiler and BaselineInterpreterGenerator. The Handler +// template is a class storing fields/methods that are interpreter or compiler +// specific. This can be combined with template specialization of methods in +// this class to specialize behavior. +template +class BaselineCodeGen { + protected: + Handler handler; + JSContext* cx; JSScript* script; jsbytecode* pc; @@ -263,20 +271,11 @@ class BaselineCompiler final FrameInfo frame; js::Vector retAddrEntries_; + js::Vector traceLoggerToggleOffsets_; - // Stores the native code offset for a bytecode pc. - struct PCMappingEntry - { - uint32_t pcOffset; - uint32_t nativeOffset; - PCMappingSlotInfo slotInfo; - - // If set, insert a PCMappingIndexEntry before encoding the - // current entry. - bool addIndexEntry; - }; - - js::Vector pcMappingEntries_; + FixedList