From e4445e417b1d341d00ce4db5f5466dab4616311a Mon Sep 17 00:00:00 2001 From: changjiaxing Date: Thu, 28 Jul 2022 21:47:37 +0800 Subject: [PATCH] Add tonumeric instruction and json_stringifier(Cherry pick) issue:https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I5JGB3 Signed-off-by: changjiaxing --- ecmascript/base/json_stringifier.cpp | 8 +++--- ecmascript/builtins.cpp | 18 ++++++++++--- ecmascript/builtins.h | 5 +++- .../builtins/tests/builtins_json_test.cpp | 13 +++++----- ecmascript/compiler/bc_call_signature.h | 1 + .../compiler/bytecode_circuit_builder.cpp | 7 ++++++ ecmascript/compiler/interpreter_stub.cpp | 21 ++++++++++++++++ ecmascript/compiler/slowpath_lowering.cpp | 11 ++++++++ ecmascript/compiler/slowpath_lowering.h | 1 + ecmascript/ecma_isa.yaml | 4 +++ ecmascript/interpreter/interpreter-inl.h | 15 ++++++++++- ecmascript/interpreter/interpreter.h | 1 + .../interpreter/interpreter_assembly.cpp | 17 ++++++++++++- ecmascript/interpreter/interpreter_assembly.h | 1 - ecmascript/interpreter/slow_runtime_stub.cpp | 12 ++++++++- ecmascript/interpreter/slow_runtime_stub.h | 1 + .../debugger_instruction_dispatch.inl | 2 +- .../debugger_instruction_handler.inl | 5 ++++ .../templates/instruction_dispatch.inl | 2 +- ecmascript/runtime_call_id.h | 2 +- ecmascript/stubs/runtime_stubs-inl.h | 5 ++++ ecmascript/stubs/runtime_stubs.cpp | 7 ++++++ ecmascript/stubs/runtime_stubs.h | 2 ++ test/aottest/BUILD.gn | 1 + test/aottest/tonumeric/BUILD.gn | 18 +++++++++++++ test/aottest/tonumeric/expect_output.txt | 16 ++++++++++++ test/aottest/tonumeric/tonumeric.ts | 25 +++++++++++++++++++ 27 files changed, 201 insertions(+), 20 deletions(-) create mode 100644 test/aottest/tonumeric/BUILD.gn create mode 100644 test/aottest/tonumeric/expect_output.txt create mode 100644 test/aottest/tonumeric/tonumeric.ts diff --git a/ecmascript/base/json_stringifier.cpp b/ecmascript/base/json_stringifier.cpp index 79682be2..b10ccb33 100644 --- a/ecmascript/base/json_stringifier.cpp +++ b/ecmascript/base/json_stringifier.cpp @@ -287,7 +287,7 @@ JSTaggedValue JsonStringifier::GetSerializeValue(const JSHandle & JSTaggedValue tagValue = value.GetTaggedValue(); JSHandle undefined = thread_->GlobalConstants()->GetHandledUndefined(); // If Type(value) is Object, then - if (value->IsECMAObject()) { + if (value->IsECMAObject() || value->IsBigInt()) { // a. Let toJSON be Get(value, "toJSON"). JSHandle toJson = thread_->GlobalConstants()->GetHandledToJsonString(); JSHandle toJsonFun( @@ -370,13 +370,13 @@ JSTaggedValue JsonStringifier::SerializeJSONProperty(const JSHandle(valHandle))); - return tagValue; + THROW_TYPE_ERROR_AND_RETURN(thread_, "cannot serialize a BigInt", JSTaggedValue::Exception()); } default: { if (!tagValue.IsCallable()) { @@ -646,6 +646,8 @@ void JsonStringifier::SerializePrimitiveRef(const JSHandle &primi } } else if (primitive.IsBoolean()) { result_ += primitive.IsTrue() ? "true" : "false"; + } else if (primitive.IsBigInt()) { + THROW_TYPE_ERROR(thread_, "cannot serialize a BigInt"); } } diff --git a/ecmascript/builtins.cpp b/ecmascript/builtins.cpp index ad99651c..52af795b 100644 --- a/ecmascript/builtins.cpp +++ b/ecmascript/builtins.cpp @@ -273,14 +273,15 @@ void Builtins::Initialize(const JSHandle &env, JSThread *thread) if (env == vm_->GetGlobalEnv()) { InitializeAllTypeError(env, objFuncDynclass); InitializeSymbol(env, primRefObjDynclass); + InitializeBigInt(env, primRefObjDynclass); } else { // error and symbol need to be shared when initialize realm InitializeAllTypeErrorWithRealm(env); InitializeSymbolWithRealm(env, primRefObjDynclass); + InitializeBigIntWithRealm(env); } InitializeNumber(env, globalObject, primRefObjDynclass); - InitializeBigInt(env, objFuncDynclass); InitializeDate(env, objFuncDynclass); InitializeObject(env, objFuncPrototype, objectFunction); InitializeBoolean(env, primRefObjDynclass); @@ -769,12 +770,23 @@ void Builtins::InitializeNumber(const JSHandle &env, const JSHandleSetNumberFunction(thread_, numFunction); } +void Builtins::InitializeBigIntWithRealm(const JSHandle &realm) const +{ + [[maybe_unused]] EcmaHandleScope scope(thread_); + JSHandle env = vm_->GetGlobalEnv(); + realm->SetBigIntFunction(thread_, env->GetBigIntFunction()); + + JSHandle nameString(factory_->NewFromASCII("BigInt")); + JSHandle globalObject(thread_, realm->GetGlobalObject()); + PropertyDescriptor descriptor(thread_, env->GetBigIntFunction(), true, false, true); + JSObject::DefineOwnProperty(thread_, globalObject, nameString, descriptor); +} -void Builtins::InitializeBigInt(const JSHandle &env, const JSHandle &objFuncDynclass) const +void Builtins::InitializeBigInt(const JSHandle &env, const JSHandle &primRefObjDynclass) const { [[maybe_unused]] EcmaHandleScope scope(thread_); // BigInt.prototype - JSHandle bigIntFuncPrototype = factory_->NewJSObjectWithInit(objFuncDynclass); + JSHandle bigIntFuncPrototype = factory_->NewJSObjectWithInit(primRefObjDynclass); JSHandle bigIntFuncPrototypeValue(bigIntFuncPrototype); // BigInt.prototype_or_dynclass diff --git a/ecmascript/builtins.h b/ecmascript/builtins.h index e2b8abb2..aa7dbcb1 100644 --- a/ecmascript/builtins.h +++ b/ecmascript/builtins.h @@ -72,7 +72,10 @@ private: void InitializeNumber(const JSHandle &env, const JSHandle &globalObject, const JSHandle &primRefObjDynclass); - void InitializeBigInt(const JSHandle &env, const JSHandle &objFuncDynclass) const; + void InitializeBigInt(const JSHandle &env, const JSHandle &primRefObjDynclass) const; + + void InitializeBigIntWithRealm(const JSHandle &realm) const; + void InitializeDate(const JSHandle &env, const JSHandle &objFuncDynclass) const; void InitializeBoolean(const JSHandle &env, const JSHandle &primRefObjDynclass) const; diff --git a/ecmascript/builtins/tests/builtins_json_test.cpp b/ecmascript/builtins/tests/builtins_json_test.cpp index f35a145d..d82cd18c 100644 --- a/ecmascript/builtins/tests/builtins_json_test.cpp +++ b/ecmascript/builtins/tests/builtins_json_test.cpp @@ -569,11 +569,12 @@ HWTEST_F_L0(BuiltinsJsonTest, Stringify6) // Test for bigint object ecmaRuntimeCallInfo->SetCallArg(0, bigIntHandle.GetTaggedValue()); prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo.get()); - JSTaggedValue result = BuiltinsJson::Stringify(ecmaRuntimeCallInfo.get()); - TestHelper::TearDownFrame(thread, prev); - CString str = ConvertToString(EcmaString::Cast(result.GetTaggedObject())); - ASSERT_TRUE(result.IsString()); - ASSERT_TRUE(EcmaString::StringsAreEqual(EcmaString::Cast(numericValue.GetTaggedValue().GetTaggedObject()), - EcmaString::Cast(result.GetTaggedObject()))); + [[maybe_unused]] JSTaggedValue result = BuiltinsJson::Stringify(ecmaRuntimeCallInfo.get()); + bool hasPendingException = false; + if (thread->HasPendingException()) { + hasPendingException = true; + thread->ClearException(); + } + ASSERT_TRUE(hasPendingException); } } // namespace panda::test diff --git a/ecmascript/compiler/bc_call_signature.h b/ecmascript/compiler/bc_call_signature.h index 4a4245e6..b8cbdd25 100644 --- a/ecmascript/compiler/bc_call_signature.h +++ b/ecmascript/compiler/bc_call_signature.h @@ -158,6 +158,7 @@ namespace panda::ecmascript::kungfu { T(HandleLdFunctionPref) \ T(HandleNewLexEnvWithNameDynPrefImm16Imm16) \ T(HandleLdBigIntPrefId32) \ + T(HandleToNumericPrefV8) \ T(HandleMovDynV8V8) \ T(HandleMovDynV16V16) \ T(HandleLdaStrId32) \ diff --git a/ecmascript/compiler/bytecode_circuit_builder.cpp b/ecmascript/compiler/bytecode_circuit_builder.cpp index 1401bae1..ac41aba7 100644 --- a/ecmascript/compiler/bytecode_circuit_builder.cpp +++ b/ecmascript/compiler/bytecode_circuit_builder.cpp @@ -1687,6 +1687,13 @@ BytecodeInfo BytecodeCircuitBuilder::GetBytecodeInfo(const uint8_t *pc) info.inputs.emplace_back(StringId(stringId)); break; } + case EcmaOpcode::TONUMERIC_PREF_V8: { + uint16_t v0 = READ_INST_8_1(); + info.accOut = true; + info.offset = BytecodeOffset::THREE; + info.inputs.emplace_back(VirtualRegister(v0)); + break; + } case EcmaOpcode::SUPERCALL_PREF_IMM16_V8: { uint16_t range = READ_INST_16_1(); uint16_t v0 = READ_INST_8_3(); diff --git a/ecmascript/compiler/interpreter_stub.cpp b/ecmascript/compiler/interpreter_stub.cpp index db20829a..b938f918 100644 --- a/ecmascript/compiler/interpreter_stub.cpp +++ b/ecmascript/compiler/interpreter_stub.cpp @@ -5088,6 +5088,27 @@ DECLARE_ASM_HANDLER(HandleLdBigIntPrefId32) DISPATCH_WITH_ACC(PREF_ID32); } +DECLARE_ASM_HANDLER(HandleToNumericPrefV8) +{ + auto env = GetEnvironment(); + DEFVARIABLE(varAcc, VariableType::JS_ANY(), acc); + GateRef v0 = ReadInst8_1(pc); + GateRef value = GetVregValue(sp, ZExtInt8ToPtr(v0)); + GateRef res = CallRuntime(glue, RTSTUB_ID(ToNumeric), { value }); + Label isException(env); + Label notException(env); + Branch(TaggedIsException(res), &isException, ¬Exception); + Bind(&isException); + { + DISPATCH_LAST_WITH_ACC(); + } + Bind(¬Exception); + { + varAcc = res; + DISPATCH_WITH_ACC(PREF_V8); + } +} + DECLARE_ASM_HANDLER(HandleNewLexEnvWithNameDynPrefImm16Imm16) { auto env = GetEnvironment(); diff --git a/ecmascript/compiler/slowpath_lowering.cpp b/ecmascript/compiler/slowpath_lowering.cpp index 5072f219..c030a896 100644 --- a/ecmascript/compiler/slowpath_lowering.cpp +++ b/ecmascript/compiler/slowpath_lowering.cpp @@ -469,6 +469,9 @@ void SlowPathLowering::Lower(GateRef gate) case LDBIGINT_PREF_ID32: LowerLdBigInt(gate, glue, jsFunc); break; + case TONUMERIC_PREF_V8: + LowerToNumeric(gate, glue); + break; case LDMODULEVAR_PREF_ID32_IMM8: LowerLdModuleVar(gate, glue); break; @@ -1411,6 +1414,14 @@ void SlowPathLowering::LowerLdBigInt(GateRef gate, GateRef glue, GateRef jsFunc) ReplaceHirToSubCfg(gate, result, successControl, failControl, true); } +void SlowPathLowering::LowerToNumeric(GateRef gate, GateRef glue) +{ + const int id = RTSTUB_ID(ToNumeric); + // 1: number of value inputs + ASSERT(acc_.GetNumValueIn(gate) == 1); + GateRef newGate = LowerCallRuntime(glue, id, {acc_.GetValueIn(gate, 0)}); + ReplaceHirToCall(gate, newGate); +} void SlowPathLowering::LowerLdModuleVar(GateRef gate, GateRef glue) { std::vector successControl; diff --git a/ecmascript/compiler/slowpath_lowering.h b/ecmascript/compiler/slowpath_lowering.h index a200bce2..c64e1d38 100644 --- a/ecmascript/compiler/slowpath_lowering.h +++ b/ecmascript/compiler/slowpath_lowering.h @@ -208,6 +208,7 @@ private: void LowerGetTemplateObject(GateRef gate, GateRef glue); void LowerSetObjectWithProto(GateRef gate, GateRef glue); void LowerLdBigInt(GateRef gate, GateRef glue, GateRef jsFunc); + void LowerToNumeric(GateRef gate, GateRef glue); void LowerLdModuleVar(GateRef gate, GateRef glue); void LowerGetModuleNamespace(GateRef gate, GateRef glue); void LowerGetIteratorNext(GateRef gate, GateRef glue); diff --git a/ecmascript/ecma_isa.yaml b/ecmascript/ecma_isa.yaml index 47f71d64..88af7df4 100644 --- a/ecmascript/ecma_isa.yaml +++ b/ecmascript/ecma_isa.yaml @@ -600,3 +600,7 @@ groups: prefix: ecma format: [pref_op_id_32] properties: [string_id] + - sig: ecma.tonumeric v:in:top + acc: inout:top + prefix: ecma + format: [pref_op_v_8] \ No newline at end of file diff --git a/ecmascript/interpreter/interpreter-inl.h b/ecmascript/interpreter/interpreter-inl.h index e7c11799..eb3a4d30 100644 --- a/ecmascript/interpreter/interpreter-inl.h +++ b/ecmascript/interpreter/interpreter-inl.h @@ -1144,7 +1144,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool LOG_INST() << "intrinsics::tonumber" << " v" << v0; JSTaggedValue value = GET_VREG_VALUE(v0); - if (value.IsNumber() || value.IsBigInt()) { + if (value.IsNumber()) { // fast path SET_ACC(value); } else { @@ -3459,6 +3459,18 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool SET_ACC(res); DISPATCH(BytecodeInstruction::Format::PREF_ID32); } + HANDLE_OPCODE(HANDLE_TONUMERIC_PREF_V8) { + uint16_t v0 = READ_INST_8_1(); + + LOG_INST() << "intrinsics::tonumeric" + << " v" << v0; + JSTaggedValue value = GET_VREG_VALUE(v0); + SAVE_PC(); + JSTaggedValue res = SlowRuntimeStub::ToNumeric(thread, value); + INTERPRETER_RETURN_IF_ABRUPT(res); + SET_ACC(res); + DISPATCH(BytecodeInstruction::Format::PREF_V8); + } HANDLE_OPCODE(HANDLE_SUPERCALL_PREF_IMM16_V8) { uint16_t range = READ_INST_16_1(); uint16_t v0 = READ_INST_8_3(); @@ -4038,6 +4050,7 @@ std::string GetEcmaOpcodeStr(EcmaOpcode opcode) {STOWNBYNAMEWITHNAMESET_PREF_ID32_V8, "STOWNBYNAMEWITHNAMESET"}, {LDFUNCTION_PREF, "LDFUNCTION"}, {LDBIGINT_PREF_ID32, "LDBIGINT"}, + {TONUMERIC_PREF_V8, "TONUMERIC"}, {MOV_DYN_V8_V8, "MOV_DYN"}, {MOV_DYN_V16_V16, "MOV_DYN"}, {LDA_STR_ID32, "LDA_STR"}, diff --git a/ecmascript/interpreter/interpreter.h b/ecmascript/interpreter/interpreter.h index d37e9b5b..c24f3ee4 100644 --- a/ecmascript/interpreter/interpreter.h +++ b/ecmascript/interpreter/interpreter.h @@ -204,6 +204,7 @@ enum EcmaOpcode { LDFUNCTION_PREF, NEWLEXENVWITHNAMEDYN_PREF_IMM16_IMM16, LDBIGINT_PREF_ID32, + TONUMERIC_PREF_V8, MOV_DYN_V8_V8, MOV_DYN_V16_V16, LDA_STR_ID32, diff --git a/ecmascript/interpreter/interpreter_assembly.cpp b/ecmascript/interpreter/interpreter_assembly.cpp index 0c141160..b378090c 100644 --- a/ecmascript/interpreter/interpreter_assembly.cpp +++ b/ecmascript/interpreter/interpreter_assembly.cpp @@ -745,7 +745,7 @@ void InterpreterAssembly::HandleToNumberPrefV8( LOG_INST() << "intrinsics::tonumber" << " v" << v0; JSTaggedValue value = GET_VREG_VALUE(v0); - if (value.IsNumber() || value.IsBigInt()) { + if (value.IsNumber()) { // fast path SET_ACC(value); } else { @@ -3336,6 +3336,21 @@ void InterpreterAssembly::HandleLdBigIntPrefId32( DISPATCH(BytecodeInstruction::Format::PREF_ID32); } +void InterpreterAssembly::HandleToNumericPrefV8( + JSThread *thread, const uint8_t *pc, JSTaggedType *sp, JSTaggedValue constpool, JSTaggedValue profileTypeInfo, + JSTaggedValue acc, int32_t hotnessCounter) +{ + uint16_t v0 = READ_INST_8_1(); + + LOG_INST() << "intrinsics::tonumeric" + << " v" << v0; + JSTaggedValue value = GET_VREG_VALUE(v0); + JSTaggedValue res = SlowRuntimeStub::ToNumeric(thread, value); + INTERPRETER_RETURN_IF_ABRUPT(res); + SET_ACC(res); + DISPATCH(BytecodeInstruction::Format::PREF_V8); +} + void InterpreterAssembly::HandleSuperCallPrefImm16V8( JSThread *thread, const uint8_t *pc, JSTaggedType *sp, JSTaggedValue constpool, JSTaggedValue profileTypeInfo, JSTaggedValue acc, int32_t hotnessCounter) diff --git a/ecmascript/interpreter/interpreter_assembly.h b/ecmascript/interpreter/interpreter_assembly.h index 12c8a516..5a8a0152 100644 --- a/ecmascript/interpreter/interpreter_assembly.h +++ b/ecmascript/interpreter/interpreter_assembly.h @@ -168,7 +168,6 @@ static std::array asmDispat InterpreterAssembly::HandleOverflow, InterpreterAssembly::HandleOverflow, InterpreterAssembly::HandleOverflow, - InterpreterAssembly::HandleOverflow, }; } // namespace panda::ecmascript #endif // ECMASCRIPT_INTERPRETER_INTERPRETER_ASSEMBLY_64BIT_H diff --git a/ecmascript/interpreter/slow_runtime_stub.cpp b/ecmascript/interpreter/slow_runtime_stub.cpp index 5caca98a..85770194 100644 --- a/ecmascript/interpreter/slow_runtime_stub.cpp +++ b/ecmascript/interpreter/slow_runtime_stub.cpp @@ -126,7 +126,17 @@ JSTaggedValue SlowRuntimeStub::ToNumber(JSThread *thread, JSTaggedValue value) JSHandle number(thread, value); // may return exception - return JSTaggedValue::ToNumeric(thread, number).GetTaggedValue(); + return JSTaggedValue::ToNumber(thread, number); +} + +JSTaggedValue SlowRuntimeStub::ToNumeric(JSThread *thread, JSTaggedValue value) +{ + INTERPRETER_TRACE(thread, Tonumeric); + [[maybe_unused]] EcmaHandleScope handleScope(thread); + + JSHandle numeric(thread, value); + // may return exception + return JSTaggedValue::ToNumeric(thread, numeric).GetTaggedValue(); } JSTaggedValue SlowRuntimeStub::NotDyn(JSThread *thread, JSTaggedValue value) diff --git a/ecmascript/interpreter/slow_runtime_stub.h b/ecmascript/interpreter/slow_runtime_stub.h index 1b7380c8..db167c1c 100644 --- a/ecmascript/interpreter/slow_runtime_stub.h +++ b/ecmascript/interpreter/slow_runtime_stub.h @@ -31,6 +31,7 @@ public: static JSTaggedValue NegDyn(JSThread *thread, JSTaggedValue value); static JSTaggedValue AsyncFunctionEnter(JSThread *thread); static JSTaggedValue ToNumber(JSThread *thread, JSTaggedValue value); + static JSTaggedValue ToNumeric(JSThread *thread, JSTaggedValue value); static JSTaggedValue NotDyn(JSThread *thread, JSTaggedValue value); static JSTaggedValue IncDyn(JSThread *thread, JSTaggedValue value); static JSTaggedValue DecDyn(JSThread *thread, JSTaggedValue value); diff --git a/ecmascript/interpreter/templates/debugger_instruction_dispatch.inl b/ecmascript/interpreter/templates/debugger_instruction_dispatch.inl index 146ad8f0..34352f02 100644 --- a/ecmascript/interpreter/templates/debugger_instruction_dispatch.inl +++ b/ecmascript/interpreter/templates/debugger_instruction_dispatch.inl @@ -149,6 +149,7 @@ &&DEBUG_HANDLE_LDFUNCTION_PREF, &&DEBUG_HANDLE_NEWLEXENVWITHNAMEDYN_PREF_IMM16_IMM16, &&DEBUG_HANDLE_LDBIGINT_PREF_ID32, + &&DEBUG_HANDLE_TONUMERIC_PREF_V8, &&DEBUG_HANDLE_MOV_DYN_V8_V8, &&DEBUG_HANDLE_MOV_DYN_V16_V16, &&DEBUG_HANDLE_LDA_STR_ID32, @@ -268,4 +269,3 @@ &&DEBUG_HANDLE_OVERFLOW, &&DEBUG_HANDLE_OVERFLOW, &&DEBUG_HANDLE_OVERFLOW, - &&DEBUG_HANDLE_OVERFLOW, diff --git a/ecmascript/interpreter/templates/debugger_instruction_handler.inl b/ecmascript/interpreter/templates/debugger_instruction_handler.inl index 08c25388..85e80ba1 100644 --- a/ecmascript/interpreter/templates/debugger_instruction_handler.inl +++ b/ecmascript/interpreter/templates/debugger_instruction_handler.inl @@ -693,6 +693,11 @@ NOTIFY_DEBUGGER_EVENT(); REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDBIGINT_PREF_ID32); } + HANDLE_OPCODE(DEBUG_HANDLE_TONUMERIC_PREF_V8) + { + NOTIFY_DEBUGGER_EVENT(); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::TONUMERIC_PREF_V8); + } HANDLE_OPCODE(DEBUG_HANDLE_MOV_DYN_V8_V8) { NOTIFY_DEBUGGER_EVENT(); diff --git a/ecmascript/interpreter/templates/instruction_dispatch.inl b/ecmascript/interpreter/templates/instruction_dispatch.inl index a7de27ff..17b73cc8 100644 --- a/ecmascript/interpreter/templates/instruction_dispatch.inl +++ b/ecmascript/interpreter/templates/instruction_dispatch.inl @@ -149,6 +149,7 @@ &&HANDLE_LDFUNCTION_PREF, &&HANDLE_NEWLEXENVWITHNAMEDYN_PREF_IMM16_IMM16, &&HANDLE_LDBIGINT_PREF_ID32, + &&HANDLE_TONUMERIC_PREF_V8, &&HANDLE_MOV_DYN_V8_V8, &&HANDLE_MOV_DYN_V16_V16, &&HANDLE_LDA_STR_ID32, @@ -268,4 +269,3 @@ &&HANDLE_OVERFLOW, &&HANDLE_OVERFLOW, &&HANDLE_OVERFLOW, - &&HANDLE_OVERFLOW, diff --git a/ecmascript/runtime_call_id.h b/ecmascript/runtime_call_id.h index bff01d68..d8b45450 100644 --- a/ecmascript/runtime_call_id.h +++ b/ecmascript/runtime_call_id.h @@ -31,7 +31,6 @@ namespace panda::ecmascript { V(Ldboolean) \ V(Ldnumber) \ V(Ldstring) \ - V(Ldbigint) \ V(Ldnull) \ V(Ldsymbol) \ V(Ldfunction) \ @@ -228,6 +227,7 @@ namespace panda::ecmascript { V(SetPropertyByName) \ V(GreaterEqDynWithIC) \ V(LdBigInt) \ + V(Tonumeric) \ V(DefineGeneratorFuncWithMethodId) \ V(GetSuperConstructor) // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) diff --git a/ecmascript/stubs/runtime_stubs-inl.h b/ecmascript/stubs/runtime_stubs-inl.h index 2cf45b15..b2a82194 100644 --- a/ecmascript/stubs/runtime_stubs-inl.h +++ b/ecmascript/stubs/runtime_stubs-inl.h @@ -993,6 +993,11 @@ JSTaggedValue RuntimeStubs::RuntimeStGlobalVar(JSThread *thread, const JSHandle< } JSTaggedValue RuntimeStubs::RuntimeToNumber(JSThread *thread, const JSHandle &value) +{ + return JSTaggedValue::ToNumber(thread, value); +} + +JSTaggedValue RuntimeStubs::RuntimeToNumeric(JSThread *thread, const JSHandle &value) { return JSTaggedValue::ToNumeric(thread, value).GetTaggedValue(); } diff --git a/ecmascript/stubs/runtime_stubs.cpp b/ecmascript/stubs/runtime_stubs.cpp index 418c095c..a2468a90 100644 --- a/ecmascript/stubs/runtime_stubs.cpp +++ b/ecmascript/stubs/runtime_stubs.cpp @@ -1527,6 +1527,13 @@ DEF_RUNTIME_STUBS(LdBigInt) return RuntimeLdBigInt(thread, numberBigInt).GetRawData(); } +DEF_RUNTIME_STUBS(ToNumeric) +{ + RUNTIME_STUBS_HEADER(ToNumeric); + JSHandle value = GetHArg(argv, argc, 0); // 0: means the zeroth parameter + return RuntimeToNumeric(thread, value).GetRawData(); +} + DEF_RUNTIME_STUBS(NewLexicalEnvWithNameDyn) { RUNTIME_STUBS_HEADER(NewLexicalEnvWithNameDyn); diff --git a/ecmascript/stubs/runtime_stubs.h b/ecmascript/stubs/runtime_stubs.h index 10fb250d..914396b1 100644 --- a/ecmascript/stubs/runtime_stubs.h +++ b/ecmascript/stubs/runtime_stubs.h @@ -212,6 +212,7 @@ using JSFunctionEntryType = uint64_t (*)(uintptr_t glue, uintptr_t prevFp, uint3 V(DefineGetterSetterByValue) \ V(SuperCall) \ V(LdBigInt) \ + V(ToNumeric) \ V(NewLexicalEnvWithNameDyn) \ V(GetAotUnmapedArgs) \ V(CopyAotRestArgs) \ @@ -390,6 +391,7 @@ private: static inline JSTaggedValue RuntimeStGlobalVar(JSThread *thread, const JSHandle &prop, const JSHandle &value); static inline JSTaggedValue RuntimeToNumber(JSThread *thread, const JSHandle &value); + static inline JSTaggedValue RuntimeToNumeric(JSThread *thread, const JSHandle &value); static inline JSTaggedValue RuntimeEqDyn(JSThread *thread, const JSHandle &left, const JSHandle &right); static inline JSTaggedValue RuntimeNotEqDyn(JSThread *thread, const JSHandle &left, diff --git a/test/aottest/BUILD.gn b/test/aottest/BUILD.gn index 69bdc94f..616b53dd 100644 --- a/test/aottest/BUILD.gn +++ b/test/aottest/BUILD.gn @@ -67,6 +67,7 @@ group("ark_aot_test") { "sub:subAotAction", "throw:throwAotAction", "tonumber:tonumberAotAction", + "tonumeric:tonumericAotAction", "trystglobalbynameprefid32:trystglobalbynameprefid32AotAction", "typeof:typeofAotAction", "xor:xorAotAction", diff --git a/test/aottest/tonumeric/BUILD.gn b/test/aottest/tonumeric/BUILD.gn new file mode 100644 index 00000000..a98ecb80 --- /dev/null +++ b/test/aottest/tonumeric/BUILD.gn @@ -0,0 +1,18 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//ark/js_runtime/test/test_helper.gni") + +host_aot_test_action("tonumeric") { + deps = [] +} diff --git a/test/aottest/tonumeric/expect_output.txt b/test/aottest/tonumeric/expect_output.txt new file mode 100644 index 00000000..468eb70c --- /dev/null +++ b/test/aottest/tonumeric/expect_output.txt @@ -0,0 +1,16 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +6 +8.7 +NaN diff --git a/test/aottest/tonumeric/tonumeric.ts b/test/aottest/tonumeric/tonumeric.ts new file mode 100644 index 00000000..27647267 --- /dev/null +++ b/test/aottest/tonumeric/tonumeric.ts @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +declare function print(str:any):string; +var val1:number = 5; +val1++; +print(val1); +var val2:number = 7.7; +val2++; +print(val2); +var val3:number = NaN; +val3++; +print(val3); \ No newline at end of file -- Gitee