diff --git a/ecmastdlib/ecmastdlib.pa b/ecmastdlib/ecmastdlib.pa index 5358c0f2e67bc35991722f4f4648736c8f36ff53..34cba78feee7a827a408c786f339579f858873a8 100644 --- a/ecmastdlib/ecmastdlib.pa +++ b/ecmastdlib/ecmastdlib.pa @@ -84,6 +84,7 @@ .function any Ecmascript.Intrinsics.ldlexenvDyn() .function void Ecmascript.Intrinsics.popLexenvDyn() .function any Ecmascript.Intrinsics.getUnmappedArgs() +.function any Ecmascript.Intrinsics.getUnmappedArgsInterp() .function any Ecmascript.Intrinsics.toboolean(any a0) .function any Ecmascript.Intrinsics.negate(any a0) .function any Ecmascript.Intrinsics.isUndefined(any a0) @@ -95,7 +96,9 @@ .function any Ecmascript.Intrinsics.createIterResultObj(any a0, u8 a1) .function any Ecmascript.Intrinsics.setGeneratorState(any a0, u8 a1) .function any Ecmascript.Intrinsics.suspendGenerator(any a0, any a1) +.function any Ecmascript.Intrinsics.suspendGeneratorInterp(any a0, any a1, any a2) .function any Ecmascript.Intrinsics.suspendAsyncGenerator(any a0, any a1) +.function any Ecmascript.Intrinsics.suspendAsyncGeneratorInterp(any a0, any a1, any a2) .function any Ecmascript.Intrinsics.resumeGenerator(any a0) .function any Ecmascript.Intrinsics.getResumeMode(any a0) .function any Ecmascript.Intrinsics.createGeneratorObj(any a0) @@ -112,6 +115,7 @@ .function void Ecmascript.Intrinsics.throwConstAssignment(u32 a0) .function any Ecmascript.Intrinsics.throwUndefinedIfHole(u32 a0, any a1) .function any Ecmascript.Intrinsics.copyrestargs(u16 a0) +.function any Ecmascript.Intrinsics.copyrestargsInterp(u16 a0) .function any Ecmascript.Intrinsics.ldHole() .function any Ecmascript.Intrinsics.getMethod(u32 a0, any a1) .function any Ecmascript.Intrinsics.getTemplateObject(any a0) @@ -132,6 +136,7 @@ .function any Ecmascript.Intrinsics.Call2Dyn(any a0, any a1, any a2) .function any Ecmascript.Intrinsics.Call3Dyn(any a0, any a1, any a2, any a3) .function any Ecmascript.Intrinsics.CalliRangeDyn(u16 a0, any a1) +.function any Ecmascript.Intrinsics.CalliRangeDynInterp(u16 a0, any a1) .function any Ecmascript.Intrinsics.CalliThisRangeDyn(u16 a0, any a1) .function any Ecmascript.Intrinsics.createemptyobject() .function any Ecmascript.Intrinsics.createobjectwithbuffer(u16 a0) @@ -156,7 +161,7 @@ .function void Ecmascript.Intrinsics.CopyModule(any a0) .function any Ecmascript.Intrinsics.LdModvarByName(u32 a0, any a1) .function any Ecmascript.Intrinsics.DefineClassWithBuffer(u32 a0, u16 a1, any a2, any a3) -.function any Ecmascript.Intrinsics.SuperCall(u16 a0, any a1, any a2) +.function any Ecmascript.Intrinsics.SuperCall(u16 a0, any a1, any a2, any a3) .function any Ecmascript.Intrinsics.SuperCallSpread(any a0, any a1, any a2) .function any Ecmascript.Intrinsics.defineMethod(u32 a0, any a1, any a2) .function any Ecmascript.Intrinsics.LdSuperByName(u32 a0, any a1) diff --git a/irtoc_scripts/interpreter_handlers.irt b/irtoc_scripts/interpreter_handlers.irt index f2fa1a3227c6395f5a79eabee81d3a0dee1ebe61..5dae0e8c55b7d2fe223a48faf4ab27553d7164ea 100644 --- a/irtoc_scripts/interpreter_handlers.irt +++ b/irtoc_scripts/interpreter_handlers.irt @@ -30,7 +30,6 @@ macro(:ecma_intrinsic_check_setacc) do |sym, size, *args| frame := Phi(frame_eh, frame).ptr pc := Phi(pc_eh, pc_inc).ptr acc := Phi(acc_eh, acc.u64).u64 - acc_tag := Phi(acc_tag_eh, acc_tag.u64).u64 end macro(:ecma_intrinsic_invoke) do |sym, *args| diff --git a/irtoc_scripts/interpreter_main_loop.irt b/irtoc_scripts/interpreter_main_loop.irt index cf912ddacca9d10c9b53b49ab715534ee7ecedf4..ad9867072c0a0172f25212db31c3bb6562ec1dbf 100644 --- a/irtoc_scripts/interpreter_main_loop.irt +++ b/irtoc_scripts/interpreter_main_loop.irt @@ -47,6 +47,8 @@ when "ECMA_SHR2DYN_PREF_V8" acc := handle_ecma_shr2dyn(vreg_value(op[0]), acc) # ecma_intrinsic_setacc("Shr2Dyn", vreg_value(op[0]).u64, acc.u64) + when "ECMA_ASHR2DYN_PREF_V8" + ecma_intrinsic_setacc("Ashr2Dyn", vreg_value(op[0]).any, acc.any) when "ECMA_STRICTEQDYN_PREF_V8" acc := handle_ecma_stricteqdyn(vreg_value(op[0]), acc) when "ECMA_STRICTNOTEQDYN_PREF_V8" @@ -112,16 +114,70 @@ ecma_intrinsic_setacc("Ldnan") when "ECMA_ISUNDEFINED_PREF_NONE" acc := handle_ecma_isundefined(acc.any) + when "ECMA_ISTRUE_PREF_NONE" + ecma_intrinsic_setacc("IsTrue", acc.any) + when "ECMA_ISFALSE_PREF_NONE" + ecma_intrinsic_setacc("IsFalse", acc.any) + when "ECMA_ISINDYN_PREF_V8" + ecma_intrinsic_setacc("IsinDyn", vreg_value(op[0]).any, acc.any) + when "ECMA_ISCOERCIBLE_PREF_NONE" + ecma_intrinsic_setacc("IsCoercible", acc.any) when "ECMA_CREATEOBJECTWITHBUFFER_PREF_IMM16" ecma_intrinsic_setacc("CreateObjectWithBuffer", as_imm(op[0])) + when "ECMA_CREATEOBJECTHAVINGMETHOD_PREF_IMM16" + ecma_intrinsic_setacc("CreateObjectHavingMethod", as_imm(op[0]), acc.any) + when "ECMA_CREATEOBJECTWITHEXCLUDEDKEYS_PREF_IMM16_V8_V8" + ecma_intrinsic_setacc("CreateObjectWithExcludedKeys", as_imm(op[0]), vreg_value(op[1]).any, vreg_ptr(op[2])) + when "ECMA_CREATEEMPTYOBJECT_PREF_NONE" + ecma_intrinsic_setacc("CreateEmptyObject") when "ECMA_GETPROPITERATOR_PREF_NONE" ecma_intrinsic_setacc("GetPropIterator", acc.u64) when "ECMA_GETNEXTPROPNAME_PREF_V8" acc := handle_ecma_getnextpropname(vreg_value(op[0]).u64) + when "ECMA_COPYDATAPROPERTIES_PREF_V8_V8" + ecma_intrinsic_setacc("CopyDataProperties", vreg_value(op[0]).any, vreg_value(op[1]).any) + when "ECMA_SETOBJECTWITHPROTO_PREF_V8_V8" + ecma_intrinsic_invoke("SetObjectWithProto", vreg_value(op[0]).any, vreg_value(op[1]).any) + when "ECMA_GETTEMPLATEOBJECT_PREF_V8" + ecma_intrinsic_setacc("GetTemplateObject", vreg_value(op[0]).any) # ecma runtime when "ECMA_DEFINEFUNCDYN_PREF_ID16_V8" ecma_intrinsic_setacc("DefinefuncDyn", as_id(op[0]), vreg_value(op[1]).u64) + when "ECMA_DEFINEGENERATORFUNC_PREF_ID16_V8" + ecma_intrinsic_setacc("DefineGeneratorFunc", as_id(op[0]), vreg_value(op[1]).any) + when "ECMA_DEFINENCFUNCDYN_PREF_ID16_V8" + ecma_intrinsic_setacc("DefineNCFuncDyn", as_id(op[0]), vreg_value(op[1]).any, acc.any) + when "ECMA_DEFINEASYNCFUNC_PREF_ID16_V8" + ecma_intrinsic_setacc("DefineAsyncFunc", as_id(op[0]), vreg_value(op[1]).any) + when "ECMA_ASYNCFUNCTIONENTER_PREF_NONE" + ecma_intrinsic_setacc("AsyncFunctionEnter") + when "ECMA_ASYNCFUNCTIONRESOLVE_PREF_V8" + ecma_intrinsic_setacc("AsyncFunctionResolve", vreg_value(op[0]).any, acc.any) + when "ECMA_ASYNCFUNCTIONAWAIT_PREF_V8" + ecma_intrinsic_setacc("AsyncFunctionAwait", vreg_value(op[0]).any, acc.any) + when "ECMA_ASYNCFUNCTIONREJECT_PREF_V8" + ecma_intrinsic_setacc("AsyncFunctionReject", vreg_value(op[0]).any, acc.any) + when "ECMA_DEFINECLASSWITHBUFFER_PREF_ID16_IMM16_V8_V8" + ecma_intrinsic_setacc("DefineClassWithBuffer", as_id(op[0]), as_imm(op[1]), vreg_value(op[2]).any, vreg_value(op[3]).any) + when "ECMA_DEFINEMETHOD_PREF_ID16_V8" + ecma_intrinsic_setacc("DefineMethod", as_id(op[0]), vreg_value(op[1]).any, acc.any) + when "ECMA_DEFINEGETTERSETTERBYVALUE_PREF_V8_V8_V8_V8" + ecma_intrinsic_setacc("DefineGetterSetterByValue", vreg_value(op[0]).any, vreg_value(op[1]).any, vreg_value(op[2]).any, vreg_value(op[3]).any, acc.any) + when "ECMA_TYPEOFDYN_PREF_NONE" + ecma_intrinsic_setacc("TypeofDyn", acc.any) + when "ECMA_INSTANCEOFDYN_PREF_V8" + ecma_intrinsic_setacc("InstanceofDyn", vreg_value(op[0]).any, acc.any) + when "ECMA_DELOBJPROP_PREF_V8_V8" + ecma_intrinsic_setacc("Delobjprop", vreg_value(op[0]).any, vreg_value(op[1]).any) + when "ECMA_GETMETHOD_PREF_ID32_V8" + ecma_intrinsic_setacc("GetMethod", as_id(op[0]), vreg_value(op[1]).any) + when "ECMA_GETRESUMEMODE_PREF_V8" + ecma_intrinsic_setacc("GetResumeMode", vreg_value(op[0]).any) + when "ECMA_GETUNMAPPEDARGS_PREF_NONE" + ecma_intrinsic_setacc("GetUnmappedArgsInterp") + when "ECMA_COPYRESTARGS_PREF_IMM16" + ecma_intrinsic_setacc("CopyrestargsInterp", as_imm(op[0])) # ecma frames when "ECMA_CALL0DYN_PREF_V8" @@ -132,31 +188,64 @@ ecma_intrinsic_check_setacc("Call2Dyn", i.format.size, vreg_value(op[0]).u64, vreg_value(op[1]).u64, vreg_value(op[2]).u64) when "ECMA_CALL3DYN_PREF_V8_V8_V8_V8" ecma_intrinsic_check_setacc("Call3Dyn", i.format.size, vreg_value(op[0]).u64, vreg_value(op[1]).u64, vreg_value(op[2]).u64, vreg_value(op[3]).u64) + when "ECMA_CALLSPREADDYN_PREF_V8_V8_V8" + ecma_intrinsic_setacc("CallspreadDyn", vreg_value(op[0]).any, vreg_value(op[1]).any, vreg_value(op[2]).any) + when "ECMA_NEWOBJSPREADDYN_PREF_V8_V8" + ecma_intrinsic_setacc("NewobjspreadDyn", vreg_value(op[0]).any, vreg_value(op[1]).any, acc.any) + when "ECMA_SUPERCALLSPREAD_PREF_V8" + method_ptr := LoadI(%frame).Imm(Constants::FRAME_METHOD_OFFSET).ptr + num_vregs := u32toword(read_uleb(method_file_data(method_ptr))) + new_target_idx := AddI(num_vregs).Imm(1).word + new_target := get_value(frame_vreg_ptr(%frame, new_target_idx)) + ecma_intrinsic_setacc("SuperCallSpread", vreg_value(op[0]).any, new_target, acc.any) when "ECMA_LDLEXENVDYN_PREF_NONE" acc := handle_ecma_ldlexenvdyn() + when "ECMA_POPLEXENVDYN_PREF_NONE" + ecma_intrinsic_invoke("popLexenvDyn") when "ECMA_NEWLEXENVDYN_PREF_IMM16" ecma_intrinsic_setacc("NewlexenvDyn", as_imm(op[0])) + when "ECMA_COPYLEXENVDYN_PREF_NONE" + ecma_intrinsic_setacc("CopylexenvDyn") when "ECMA_STLEXVARDYN_PREF_IMM4_IMM4" - ecma_intrinsic_setacc("StLexVarDyn", i8tou16(as_imm(op[0])), i8tou16(as_imm(op[1])), acc.u64) + ecma_intrinsic_invoke("StLexVarDyn", i8tou16(as_imm(op[0])), i8tou16(as_imm(op[1])), acc.u64) when "ECMA_STLEXVARDYN_PREF_IMM8_IMM8" - ecma_intrinsic_setacc("StLexVarDyn", i8tou16(as_imm(op[0])), i8tou16(as_imm(op[1])), acc.u64) - when "ECMA_LEXVARDYN_PREF_IMM16_IMM16" - ecma_intrinsic_setacc("StLexVarDyn", as_imm(op[0]), as_imm(op[1]), acc.u64) + ecma_intrinsic_invoke("StLexVarDyn", i8tou16(as_imm(op[0])), i8tou16(as_imm(op[1])), acc.u64) + when "ECMA_STLEXVARDYN_PREF_IMM16_IMM16" + ecma_intrinsic_invoke("StLexVarDyn", as_imm(op[0]), as_imm(op[1]), acc.u64) when "ECMA_LDLEXVARDYN_PREF_IMM4_IMM4" ecma_intrinsic_setacc("LdLexVarDyn", i8tou16(as_imm(op[0])), i8tou16(as_imm(op[1]))) when "ECMA_LDLEXVARDYN_PREF_IMM8_IMM8" ecma_intrinsic_setacc("LdLexVarDyn", i8tou16(as_imm(op[0])), i8tou16(as_imm(op[1]))) when "ECMA_LDLEXVARDYN_PREF_IMM16_IMM16" ecma_intrinsic_setacc("LdLexVarDyn", as_imm(op[0]), as_imm(op[1])) - when "ECMA_CREATEEMPTYOBJECT_PREF_NONE" - ecma_intrinsic_setacc("CreateEmptyObject") + when "ECMA_LDHOMEOBJECT_PREF_NONE" + ecma_intrinsic_setacc("LdHomeObject") when "ECMA_RETURNUNDEFINED_PREF_NONE" - acc := 10 + handle_ecma_ldconst(Constants::VALUE_UNDEFINED) + StoreI(%frame, acc).Imm(Constants::GET_ACC_OFFSET).send(acc.type) Intrinsic(:INTERPRETER_RETURN).ptr when "ECMA_RETURN_DYN_PREF_NONE" Intrinsic(:INTERPRETER_RETURN).ptr when "ECMA_CREATEARRAYWITHBUFFER_PREF_IMM16" ecma_intrinsic_setacc("CreateArrayWithBuffer", as_imm(op[0])) + when "ECMA_CREATEEMPTYARRAY_PREF_NONE" + ecma_intrinsic_setacc("CreateEmptyArray") + when "ECMA_STARRAYSPREAD_PREF_V8_V8" + ecma_intrinsic_setacc("StArraySpread", vreg_value(op[0]).any, vreg_value(op[1]).any, acc.any) + + # ecma range calls + when "ECMA_CALLITHISRANGEDYN_PREF_IMM16_V8" + ecma_intrinsic_check_setacc("CalliThisRangeDyn", i.format.size, as_imm(op[0]), vreg_ptr(op[1])) + when "ECMA_CALLIRANGEDYN_PREF_IMM16_V8" + ecma_intrinsic_check_setacc("CalliRangeDynInterp", i.format.size, i8tou16(as_imm(op[0])), vreg_ptr(op[1])) + when "ECMA_NEWOBJDYNRANGE_PREF_IMM16_V8" + ecma_intrinsic_setacc("NewobjDynrange", i8tou16(as_imm(op[0])), vreg_ptr(op[1])) + when "ECMA_SUPERCALL_PREF_IMM16_V8" + method_ptr := LoadI(%frame).Imm(Constants::FRAME_METHOD_OFFSET).ptr + num_vregs := u32toword(read_uleb(method_file_data(method_ptr))) + new_target_idx := AddI(num_vregs).Imm(1).word + new_target := get_value(frame_vreg_ptr(%frame, new_target_idx)) + ecma_intrinsic_setacc("SuperCall", as_imm(op[0]), vreg_ptr(op[1]), new_target, acc.any) # ecma load/stores by index when "ECMA_STOBJBYINDEX_PREF_IMM8_V8" @@ -185,20 +274,68 @@ handle_ecma_stobjbyvalue(vreg_value(op[0]).any, vreg_value(op[1]).any, acc.any, ins_offset) when "ECMA_LDOBJBYVALUE_PREF_V8_V8" acc := handle_ecma_ldobjbyvalue(vreg_value(op[0]).any, vreg_value(op[1]).any, ins_offset) + when "ECMA_LDSUPERBYVALUE_PREF_V8_V8" + ecma_intrinsic_setacc("LdSuperByValue", vreg_value(op[0]).any, vreg_value(op[1]).any) + when "ECMA_STOWNBYVALUE_PREF_V8_V8" + ecma_intrinsic_invoke("StOwnByValue", vreg_value(op[0]).any, vreg_value(op[1]).any, acc.any) # ecma load/stores by name when "ECMA_STOBJBYNAME_PREF_ID32_V8" handle_ecma_stobjbyname(vreg_value(op[1]).any, as_id(op[0]), acc.any, ins_offset) when "ECMA_LDOBJBYNAME_PREF_ID32_V8" acc := handle_ecma_ldobjbyname(vreg_value(op[1]).any, as_id(op[0]), ins_offset) + when "ECMA_LDSUPERBYNAME_PREF_ID32_V8" + ecma_intrinsic_setacc("LdSuperByName", as_id(op[0]), vreg_value(op[1]).any) + when "ECMA_STSUPERBYNAME_PREF_ID32_V8" + ecma_intrinsic_invoke("StSuperByName", as_id(op[0]), vreg_value(op[1]).any, acc.any) + when "ECMA_STOWNBYNAME_PREF_ID32_V8" + ecma_intrinsic_invoke("StOwnByName", as_id(op[0]), vreg_value(op[1]).any, acc.any) # load/stores from global object + when "ECMA_LDGLOBAL_PREF_NONE" + ecma_intrinsic_setacc("Ldglobal") when "ECMA_TRYLDGLOBALBYNAME_PREF_ID32" acc := handle_ecma_tryldglobalbyname(as_id(op[0]), ins_offset) + when "ECMA_TRYSTGLOBALBYNAME_PREF_ID32" + ecma_intrinsic_invoke("TryStGlobalByName", as_id(op[0]), acc.any, ins_offset) when "ECMA_LDGLOBALVAR_PREF_ID32" acc := handle_ecma_ldglobalvar(as_id(op[0]), ins_offset) when "ECMA_STGLOBALVAR_PREF_ID32" handle_ecma_stglobalvar(as_id(op[0]), acc.any, ins_offset) + when "ECMA_STGLOBALLET_PREF_ID32" + ecma_intrinsic_invoke("StGlobalLet", as_id(op[0]), acc.any) + + # ecma generators + when "ECMA_CREATEGENERATOROBJ_PREF_V8" + ecma_intrinsic_setacc("CreateGeneratorObj", vreg_value(op[0]).any) + when "ECMA_SUSPENDGENERATOR_PREF_V8" + ecma_intrinsic_setacc("SuspendGeneratorInterp", vreg_value(op[0]).any, acc.any, ins_offset.u64) + handle_return() + when "ECMA_SETGENERATORSTATE_PREF_V8_IMM8" + ecma_intrinsic_invoke("SetGeneratorState", vreg_value(op[0]).any, i8tou16(as_imm(op[1]))) + when "ECMA_RESUMEGENERATOR_PREF_V8" + ecma_intrinsic_setacc("ResumeGenerator", vreg_value(op[0]).any) + when "ECMA_CREATEITERRESULTOBJ_PREF_IMM8" + ecma_intrinsic_setacc("CreateIterResultObj", acc.any, as_imm(op[0])) + + when "ECMA_CREATEASYNCGENERATOROBJ_PREF_V8" + ecma_intrinsic_setacc("CreateAsyncGeneratorObj", vreg_value(op[0]).any) + when "ECMA_DEFINEASYNCGENERATORFUNC_PREF_ID16_V8" + ecma_intrinsic_setacc("DefineAsyncGeneratorFunc", as_id(op[0]), vreg_value(op[1]).any) + when "ECMA_GETASYNCITERATOR_PREF_NONE" + ecma_intrinsic_setacc("GetAsyncIterator", acc.u64) + when "ECMA_ASYNCGENERATORRESOLVE_PREF_V8" + ecma_intrinsic_setacc("AsyncGeneratorResolve", vreg_value(op[0]).any, acc.any) + when "ECMA_SUSPENDASYNCGENERATOR_PREF_V8" + ecma_intrinsic_setacc("SuspendAsyncGeneratorInterp", vreg_value(op[0]).any, acc.any, ins_offset.u64) + handle_return() + when "ECMA_ASYNCGENERATORREJECT_PREF_V8" + ecma_intrinsic_setacc("AsyncGeneratorReject", vreg_value(op[0]).any, acc.any) + + when "ECMA_GETITERATOR_PREF_NONE" + ecma_intrinsic_setacc("GetIterator", acc.any) + when "ECMA_CLOSEITERATOR_PREF_V8" + ecma_intrinsic_setacc("CloseIterator", vreg_value(op[0]).any, acc.any) # ecma exceptions when "ECMA_THROWDYN_PREF_NONE" @@ -206,6 +343,26 @@ pc := find_catch_block() frame := frame_eh acc := acc_eh - acc_tag := acc_tag_eh + when "ECMA_THROWCONSTASSIGNMENT_PREF_ID32" + ecma_intrinsic_invoke("ThrowConstAssignment", as_id(op[0])) + pc := find_catch_block() + frame := frame_eh + acc := acc_eh + when "ECMA_THROWPATTERNNONCOERCIBLE_PREF_NONE" + ecma_intrinsic_invoke("ThrowPatternNonCoercible") + pc := find_catch_block() + frame := frame_eh + acc := acc_eh + when "ECMA_THROWTHROWNOTEXISTS_PREF_NONE" + ecma_intrinsic_invoke("ThrowThrowNotExists") + pc := find_catch_block() + frame := frame_eh + acc := acc_eh when "ECMA_THROWUNDEFINEDIFHOLE_PREF_ID32" ecma_intrinsic_setacc("ThrowUndefinedIfHole", as_id(op[0]), acc.any) + when "ECMA_THROWIFNOTOBJECT_PREF_NONE" + ecma_intrinsic_invoke("ThrowIfNotObject", acc.any) + when "ECMA_THROWIFSUPERNOTCORRECTCALL_PREF_IMM16" + ecma_intrinsic_invoke("ThrowIfSuperNotCorrectCall", i8tou16(as_imm(op[0])), acc.any) + when "ECMA_RETHROWDYN_PREF_NONE" + ecma_intrinsic_invoke("RethrowDyn", acc.any) diff --git a/isa/isa.yaml b/isa/isa.yaml index cd21082099ed38efa48efc661f730435357e152e..659de881558a0313e031ab9ad9057045217094a1 100644 --- a/isa/isa.yaml +++ b/isa/isa.yaml @@ -726,17 +726,17 @@ groups: format: [pref_op_imm1_16_imm2_16] intrinsic_name: INTRINSIC_LD_LEX_VAR_DYN - sig: ecma.stlexvardyn imm1, imm2 - acc: inout:top + acc: in:top prefix: ecma format: [pref_op_imm1_4_imm2_4] intrinsic_name: INTRINSIC_ST_LEX_VAR_DYN - sig: ecma.stlexvardyn imm1, imm2 - acc: inout:top + acc: in:top prefix: ecma format: [pref_op_imm1_8_imm2_8] intrinsic_name: INTRINSIC_ST_LEX_VAR_DYN - sig: ecma.stlexvardyn imm1, imm2 - acc: inout:top + acc: in:top prefix: ecma format: [pref_op_imm1_16_imm2_16] intrinsic_name: INTRINSIC_ST_LEX_VAR_DYN diff --git a/runtime/ecma_runtime.yaml b/runtime/ecma_runtime.yaml index d4d094d22583a02ae40622855627549817d3e584..b7138a6072974994a86668b97e79b4640eac475c 100644 --- a/runtime/ecma_runtime.yaml +++ b/runtime/ecma_runtime.yaml @@ -781,6 +781,17 @@ intrinsics: args: [] impl: panda::ecmascript::intrinsics::GetUnmappedArgs +- name: GetUnmappedArgsInterp + space: ecmascript + class_name: Ecmascript.Intrinsics + method_name: getUnmappedArgsInterp + static: true + exception: true + signature: + ret: any + args: [] + impl: panda::ecmascript::intrinsics::GetUnmappedArgsInterp + - name: Toboolean space: ecmascript class_name: Ecmascript.Intrinsics @@ -891,7 +902,7 @@ intrinsics: args: [acc, u8] impl: panda::ecmascript::intrinsics::CreateIterResultObj -- name: SuspendGenerator +- name: suspendGenerator space: ecmascript class_name: Ecmascript.Intrinsics method_name: suspendGenerator @@ -902,6 +913,17 @@ intrinsics: args: [any, acc] impl: panda::ecmascript::intrinsics::SuspendGenerator +- name: suspendGeneratorInterp + space: ecmascript + class_name: Ecmascript.Intrinsics + method_name: suspendGeneratorInterp + static: true + exception: true + signature: + ret: any + args: [any, acc, any] + impl: panda::ecmascript::intrinsics::SuspendGeneratorInterp + - name: SuspendAsyncGenerator space: ecmascript class_name: Ecmascript.Intrinsics @@ -913,6 +935,17 @@ intrinsics: args: [any, acc] impl: panda::ecmascript::intrinsics::SuspendAsyncGenerator +- name: SuspendAsyncGeneratorInterp + space: ecmascript + class_name: Ecmascript.Intrinsics + method_name: suspendAsyncGeneratorInterp + static: true + exception: true + signature: + ret: any + args: [any, acc, any] + impl: panda::ecmascript::intrinsics::SuspendAsyncGeneratorInterp + - name: ResumeGenerator space: ecmascript class_name: Ecmascript.Intrinsics @@ -1104,6 +1137,17 @@ intrinsics: args: [u16] impl: panda::ecmascript::intrinsics::Copyrestargs +- name: CopyrestargsInterp + space: ecmascript + class_name: Ecmascript.Intrinsics + method_name: copyrestargsInterp + static: true + exception: true + signature: + ret: any + args: [u16] + impl: panda::ecmascript::intrinsics::CopyrestargsInterp + - name: Ldhole space: ecmascript class_name: Ecmascript.Intrinsics @@ -1324,6 +1368,17 @@ intrinsics: args: [u16, any] impl: panda::ecmascript::intrinsics::CalliRangeDyn +- name: CalliRangeDynInterp + space: ecmascript + class_name: Ecmascript.Intrinsics + method_name: CalliRangeDynInterp + static: true + exception: true + signature: + ret: any + args: [u16, any] + impl: panda::ecmascript::intrinsics::CalliRangeDynInterp + - name: CalliThisRangeDyn space: ecmascript class_name: Ecmascript.Intrinsics @@ -1590,7 +1645,7 @@ intrinsics: exception: true signature: ret: any - args: [u16, any, acc] + args: [u16, any, any, acc] impl: panda::ecmascript::intrinsics::SuperCall - name: SuperCallSpread diff --git a/runtime/intrinsics-inl.h b/runtime/intrinsics-inl.h index aba490471fc86debb1b4067000648914d971dc72..d339bd8f734f89bf725157cefdd66037f1a19168 100644 --- a/runtime/intrinsics-inl.h +++ b/runtime/intrinsics-inl.h @@ -19,6 +19,7 @@ #include #include "intrinsics.h" +#include "macros.h" #include "runtime/include/method-inl.h" #include "plugins/ecmascript/runtime/js_tagged_value-inl.h" #include "plugins/ecmascript/runtime/interpreter/slow_runtime_stub.h" @@ -557,12 +558,10 @@ INLINE_ECMA_INTRINSICS uint64_t DefinefuncDyn(JSThread *thread, uint32_t methodI return result.GetTaggedValue().GetRawData(); } -// a0 is args' length which include ctor and new_target, and a1 is the start index of args // NOLINTNEXTLINE(misc-definitions-in-headers) -INLINE_ECMA_INTRINSICS uint64_t NewobjDynrange([[maybe_unused]] JSThread *thread, [[maybe_unused]] uint16_t numArgs, - [[maybe_unused]] uint64_t a1) +INLINE_ECMA_INTRINSICS uint64_t NewobjDynrange(JSThread *thread, uint16_t args_num, uint64_t args) { - UNREACHABLE(); + return SlowRuntimeStub::NewObjDynRange(thread, args_num, reinterpret_cast(args)).GetRawData(); } // NOLINTNEXTLINE(misc-definitions-in-headers) @@ -597,6 +596,17 @@ INLINE_ECMA_INTRINSICS uint64_t GetUnmappedArgs([[maybe_unused]] JSThread *threa UNREACHABLE(); } +// NOLINTNEXTLINE(misc-definitions-in-headers) +INLINE_ECMA_INTRINSICS uint64_t GetUnmappedArgsInterp(JSThread *thread) +{ + ASSERT(!thread->IsCurrentFrameCompiled()); + uint32_t actual_num_args = thread->GetCurrentFrame()->GetNumActualArgs() - NUM_MANDATORY_JSFUNC_ARGS; + uint32_t start_idx = thread->GetCurrentFrame()->GetMethod()->GetNumVregs() + NUM_MANDATORY_JSFUNC_ARGS; + auto args = reinterpret_cast(&thread->GetCurrentFrame()->GetVReg(start_idx)); + return SlowRuntimeStub::GetUnmappedArgs(thread, actual_num_args, reinterpret_cast(args)) + .GetRawData(); +} + // NOLINTNEXTLINE(misc-definitions-in-headers) INLINE_ECMA_INTRINSICS uint64_t Negate(uint64_t value) { @@ -641,12 +651,30 @@ INLINE_ECMA_INTRINSICS uint64_t SuspendGenerator([[maybe_unused]] JSThread *thre } // NOLINTNEXTLINE(misc-definitions-in-headers) -INLINE_ECMA_INTRINSICS uint64_t SuspendAsyncGenerator([[maybe_unused]] JSThread *thread, [[maybe_unused]] uint64_t a0, - [[maybe_unused]] uint64_t a1) +INLINE_ECMA_INTRINSICS uint64_t SuspendGeneratorInterp(JSThread *thread, uint64_t gen_obj, uint64_t value, uint64_t pc) +{ + ASSERT(!thread->IsCurrentFrameCompiled()); + thread->GetCurrentFrame()->SetBytecodeOffset(pc); + return SlowRuntimeStub::SuspendGenerator(thread, JSTaggedValue(gen_obj), JSTaggedValue(value)).GetRawData(); +} + +// NOLINTNEXTLINE(misc-definitions-in-headers) +INLINE_ECMA_INTRINSICS uint64_t SuspendAsyncGenerator([[maybe_unused]] JSThread *thread, + [[maybe_unused]] uint64_t gen_obj, + [[maybe_unused]] uint64_t value) { UNREACHABLE(); } +// NOLINTNEXTLINE(misc-definitions-in-headers) +INLINE_ECMA_INTRINSICS uint64_t SuspendAsyncGeneratorInterp(JSThread *thread, uint64_t gen_obj, uint64_t value, + uint64_t pc) +{ + ASSERT(!thread->IsCurrentFrameCompiled()); + thread->GetCurrentFrame()->SetBytecodeOffset(pc); + return SlowRuntimeStub::SuspendAsyncGenerator(thread, JSTaggedValue(gen_obj), JSTaggedValue(value)).GetRawData(); +} + // NOLINTNEXTLINE(misc-definitions-in-headers) INLINE_ECMA_INTRINSICS void ThrowUndefined([[maybe_unused]] JSThread *thread, [[maybe_unused]] uint64_t objValue) { @@ -659,6 +687,22 @@ INLINE_ECMA_INTRINSICS uint64_t Copyrestargs([[maybe_unused]] JSThread *thread, UNREACHABLE(); } +// NOLINTNEXTLINE(misc-definitions-in-headers) +INLINE_ECMA_INTRINSICS uint64_t CopyrestargsInterp(JSThread *thread, uint16_t index) +{ + ASSERT(!thread->IsCurrentFrameCompiled()); + auto *frame = thread->GetCurrentFrame(); + uint32_t num_vregs = frame->GetMethod()->GetNumVregs(); + int32_t actual_num_args = frame->GetNumActualArgs() - NUM_MANDATORY_JSFUNC_ARGS; + int32_t tmp = actual_num_args - index; + uint32_t rest_num_args = (tmp > 0) ? tmp : 0; + uint32_t start_idx = num_vregs + NUM_MANDATORY_JSFUNC_ARGS + index; + + auto args = reinterpret_cast(&thread->GetCurrentFrame()->GetVReg(start_idx)); + + return SlowRuntimeStub::CopyRestArgs(thread, rest_num_args, args).GetRawData(); +} + // NOLINTNEXTLINE(misc-definitions-in-headers) INLINE_ECMA_INTRINSICS uint64_t Ldhole() { @@ -724,12 +768,40 @@ INLINE_ECMA_INTRINSICS uint64_t CalliRangeDyn([[maybe_unused]] JSThread *thread, UNREACHABLE(); } -// Just declared here, not used // NOLINTNEXTLINE(misc-definitions-in-headers) -INLINE_ECMA_INTRINSICS uint64_t CalliThisRangeDyn([[maybe_unused]] JSThread *thread, [[maybe_unused]] uint16_t num, - [[maybe_unused]] uint64_t objValue) +INLINE_ECMA_INTRINSICS uint64_t CalliRangeDynInterp(JSThread *thread, uint16_t args_num, uint64_t args_ptr) { - UNREACHABLE(); + auto args = reinterpret_cast(args_ptr); + thread_local std::vector args_vec; + const size_t actual_num_args = args_num + NUM_MANDATORY_JSFUNC_ARGS; + args_vec.reserve(actual_num_args); + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) + auto fn_object = args[0]; + args_vec = {fn_object, JSTaggedValue::Undefined(), JSTaggedValue::Undefined()}; + for (int i(0); i < args_num; ++i) { + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) + args_vec[i + NUM_MANDATORY_JSFUNC_ARGS] = args[i + 1]; + } + + return HandlerCall(thread, fn_object, args_vec.data(), actual_num_args).GetRawData(); +} + +// NOLINTNEXTLINE(misc-definitions-in-headers) +INLINE_ECMA_INTRINSICS uint64_t CalliThisRangeDyn(JSThread *thread, uint16_t args_num, uint64_t args_ptr) +{ + auto args = reinterpret_cast(args_ptr); + thread_local std::vector args_vec; + const size_t actual_num_args = args_num + NUM_MANDATORY_JSFUNC_ARGS - 1; + args_vec.reserve(actual_num_args); + auto fn_object = args[0]; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) + args_vec = {fn_object, JSTaggedValue::Undefined(), args[1]}; + for (int i(0); i < args_num - 1; ++i) { + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) + args_vec[i + NUM_MANDATORY_JSFUNC_ARGS] = args[i + 2]; + } + + return HandlerCall(thread, fn_object, args_vec.data(), actual_num_args).GetRawData(); } // NOLINTNEXTLINE(misc-definitions-in-headers) @@ -1645,12 +1717,12 @@ INLINE_ECMA_INTRINSICS void ThrowThrowNotExists(JSThread *thread) } // NOLINTNEXTLINE(misc-definitions-in-headers) -INLINE_ECMA_INTRINSICS uint64_t CreateObjectWithExcludedKeys([[maybe_unused]] JSThread *thread, - [[maybe_unused]] uint16_t numKeys, - [[maybe_unused]] uint64_t objValue, - [[maybe_unused]] uint64_t a0) +INLINE_ECMA_INTRINSICS uint64_t CreateObjectWithExcludedKeys(JSThread *thread, uint16_t numKeys, uint64_t obj_value, + uint64_t excluded_keys) { - UNREACHABLE(); + return SlowRuntimeStub::CreateObjectWithExcludedKeys(thread, numKeys, JSTaggedValue(obj_value), + reinterpret_cast(excluded_keys)) + .GetRawData(); } // NOLINTNEXTLINE(misc-definitions-in-headers) @@ -1728,12 +1800,13 @@ INLINE_ECMA_INTRINSICS uint64_t DefineClassWithBuffer(JSThread *thread, uint32_t return res.GetRawData(); } -// Just declared here, not used // NOLINTNEXTLINE(misc-definitions-in-headers) -INLINE_ECMA_INTRINSICS uint64_t SuperCall([[maybe_unused]] JSThread *thread, [[maybe_unused]] uint16_t range, - [[maybe_unused]] uint64_t firstVRegValue, [[maybe_unused]] uint64_t objValue) +INLINE_ECMA_INTRINSICS uint64_t SuperCall(JSThread *thread, uint16_t range, uint64_t args, uint64_t new_target, + uint64_t obj_value) { - UNREACHABLE(); + return SlowRuntimeStub::SuperCall(thread, JSTaggedValue(obj_value), JSTaggedValue(new_target), range, + reinterpret_cast(args)) + .GetRawData(); } // NOLINTNEXTLINE(misc-definitions-in-headers)