From 50ee964a21d1f799421d5f5f1fb26500684cfbf4 Mon Sep 17 00:00:00 2001 From: wupengyong Date: Mon, 18 Oct 2021 11:32:58 +0800 Subject: [PATCH] add function call and bugfix ThrowTypeAndReturn Signed-off-by: wupengyong Change-Id: I085d81d00b00a0b49daa0d28af591b83dc1c9759 --- ecmascript/compiler/fast_stub.cpp | 25 +++++++++++++++++ ecmascript/compiler/fast_stub.h | 10 +++++++ ecmascript/compiler/fast_stub_define.h | 2 ++ ecmascript/compiler/stub.cpp | 5 ++-- ecmascript/compiler/stub.h | 30 +++++++++++++++++++++ ecmascript/compiler/stub_aot_compiler.cpp | 1 + ecmascript/compiler/stub_descriptor.cpp | 33 +++++++++++++++++++++++ ecmascript/compiler/tests/stub_tests.cpp | 16 +++++++++++ ecmascript/message_string.h | 5 ++-- ecmascript/runtime_trampolines.cpp | 17 ++++++++++++ ecmascript/runtime_trampolines.h | 1 + 11 files changed, 141 insertions(+), 4 deletions(-) diff --git a/ecmascript/compiler/fast_stub.cpp b/ecmascript/compiler/fast_stub.cpp index 2dee2e8473..0b9bf373f8 100644 --- a/ecmascript/compiler/fast_stub.cpp +++ b/ecmascript/compiler/fast_stub.cpp @@ -1160,4 +1160,29 @@ void FastModStub::GenerateCircuit() } } } + +void FunctionCallInternalStub::GenerateCircuit() +{ + auto env = GetEnvironment(); + AddrShift thread = PtrArgument(0); + AddrShift func = PtrArgument(1); + AddrShift thisArg = Int64Argument(2); /* 2 : 3rd parameter is value */ + AddrShift argc = Int32Argument(3); /* 3 : 4th parameter is value */ + AddrShift argv = PtrArgument(4); /* 4 : 5th parameter is ptr */ + Label funcNotBuiltinsConstructor(env); + Label funcIsBuiltinsConstructorOrFuncNotClassConstructor(env); + Label funcIsClassConstructor(env); + Branch(NotBuiltinsConstructor(func), &funcNotBuiltinsConstructor, + &funcIsBuiltinsConstructorOrFuncNotClassConstructor); + Bind(&funcNotBuiltinsConstructor); + { + Branch(IsClassConstructor(func), &funcIsClassConstructor, &funcIsBuiltinsConstructorOrFuncNotClassConstructor); + Bind(&funcIsClassConstructor); + ThrowTypeAndReturn(thread, GET_MESSAGE_STRING_ID(FunctionCallNotConstructor), FalseConstant()); + } + Bind(&funcIsBuiltinsConstructorOrFuncNotClassConstructor); + StubDescriptor *execute = GET_STUBDESCRIPTOR(Execute); + Return(CallRuntime(execute, thread, GetWord64Constant(FAST_STUB_ID(Execute)), + {thread, func, thisArg, argc, argv})); +} } // namespace kungfu \ No newline at end of file diff --git a/ecmascript/compiler/fast_stub.h b/ecmascript/compiler/fast_stub.h index 109b7be5d6..642d5c2063 100644 --- a/ecmascript/compiler/fast_stub.h +++ b/ecmascript/compiler/fast_stub.h @@ -149,5 +149,15 @@ public: NO_COPY_SEMANTIC(FastModStub); void GenerateCircuit() override; }; + +class FunctionCallInternalStub : public Stub { +public: + // 5 : 5 means argument counts + explicit FunctionCallInternalStub(Circuit *circuit) : Stub("FunctionCallInternal", 5, circuit) {} + ~FunctionCallInternalStub() = default; + NO_MOVE_SEMANTIC(FunctionCallInternalStub); + NO_COPY_SEMANTIC(FunctionCallInternalStub); + void GenerateCircuit() override; +}; } // namespace kungfu #endif // ECMASCRIPT_COMPILER_FASTPATH_STUB_H \ No newline at end of file diff --git a/ecmascript/compiler/fast_stub_define.h b/ecmascript/compiler/fast_stub_define.h index 036fc11f4e..9147c85009 100644 --- a/ecmascript/compiler/fast_stub_define.h +++ b/ecmascript/compiler/fast_stub_define.h @@ -27,6 +27,7 @@ namespace kungfu { V(JSProxySetProperty, 6) \ V(GetHash32, 2) \ V(FindElementWithCache, 4) \ + V(Execute, 5) \ V(StringGetHashCode, 1) // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) @@ -57,6 +58,7 @@ namespace kungfu { V(FindOwnProperty2, 6) \ V(FindOwnElement2, 6) \ V(GetPropertyByIndex, 3) \ + V(FunctionCallInternal, 5) \ V(SetPropertyByIndex, 4) // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) diff --git a/ecmascript/compiler/stub.cpp b/ecmascript/compiler/stub.cpp index d5e801fa9e..4550be2bf2 100644 --- a/ecmascript/compiler/stub.cpp +++ b/ecmascript/compiler/stub.cpp @@ -646,9 +646,10 @@ AddrShift Stub::JSObjectGetProperty(AddrShift obj, AddrShift hClass, AddrShift a void Stub::ThrowTypeAndReturn(AddrShift thread, int messageId, AddrShift val) { + AddrShift taggedId = GetInteger32Constant(messageId); StubDescriptor *throwTypeError = GET_STUBDESCRIPTOR(ThrowTypeError); - AddrShift taggedId = IntBuildTagged(GetInteger32Constant(messageId)); - CallStub(throwTypeError, GetWord64Constant(FAST_STUB_ID(ThrowTypeError)), {thread, taggedId}); + CallRuntime(throwTypeError, thread, GetWord64Constant(FAST_STUB_ID(ThrowTypeError)), + {thread, taggedId}); Return(val); } diff --git a/ecmascript/compiler/stub.h b/ecmascript/compiler/stub.h index 1ae07f2419..c6042d41e5 100644 --- a/ecmascript/compiler/stub.h +++ b/ecmascript/compiler/stub.h @@ -22,6 +22,7 @@ #include "ecmascript/compiler/circuit_builder.h" #include "ecmascript/compiler/gate.h" #include "ecmascript/compiler/stub_descriptor.h" +#include "ecmascript/js_function.h" #include "ecmascript/js_object.h" #include "ecmascript/js_tagged_value.h" #include "ecmascript/layout_info.h" @@ -1065,6 +1066,35 @@ public: GetWord64Constant(0)); } + AddrShift NotBuiltinsConstructor(AddrShift object) + { + AddrShift hclass = LoadHClass(object); + AddrShift bitfieldOffset = GetPtrConstant(panda::ecmascript::JSHClass::BIT_FIELD_OFFSET); + + AddrShift bitfield = Load(INT64_TYPE, hclass, bitfieldOffset); + // decode + return Word64Equal( + Word64And( + Word64LSR(bitfield, GetWord64Constant(panda::ecmascript::JSHClass::BuiltinsCtorBit::START_BIT)), + GetWord64Constant((1LLU << panda::ecmascript::JSHClass::BuiltinsCtorBit::SIZE) - 1)), + GetWord64Constant(0)); + } + + AddrShift IsClassConstructor(AddrShift object) + { + AddrShift functionInfoFlagOffset = GetPtrConstant(panda::ecmascript::JSFunction::FUNCTION_INFO_FLAG_OFFSET); + AddrShift functionInfoTaggedValue = Load(MachineType::UINT64_TYPE, object, functionInfoFlagOffset); + AddrShift functionInfoInt32 = TaggedCastToInt32(functionInfoTaggedValue); + AddrShift functionInfoFlag = ZExtInt32ToInt64(functionInfoInt32); + // decode + return Word64NotEqual( + Word64And( + Word64LSR(functionInfoFlag, + GetWord64Constant(panda::ecmascript::JSFunction::ClassConstructorBit::START_BIT)), + GetWord64Constant((1LLU << panda::ecmascript::JSFunction::ClassConstructorBit::SIZE) - 1)), + GetWord64Constant(0)); + } + AddrShift IsExtensible(AddrShift object) { AddrShift hclass = LoadHClass(object); diff --git a/ecmascript/compiler/stub_aot_compiler.cpp b/ecmascript/compiler/stub_aot_compiler.cpp index 79d0ab6d8c..6bfb263536 100644 --- a/ecmascript/compiler/stub_aot_compiler.cpp +++ b/ecmascript/compiler/stub_aot_compiler.cpp @@ -159,6 +159,7 @@ void StubAotCompiler::BuildStubModuleAndSave(const char *triple, panda::ecmascri SET_STUB_TO_MODULE(module, SetElement) \ SET_STUB_TO_MODULE(module, GetPropertyByIndex) \ SET_STUB_TO_MODULE(module, SetPropertyByIndex) \ + SET_STUB_TO_MODULE(module, FunctionCallInternal) \ SET_STUB_TO_MODULE(module, GetPropertyByName) int main(const int argc, const char **argv) diff --git a/ecmascript/compiler/stub_descriptor.cpp b/ecmascript/compiler/stub_descriptor.cpp index 135f379f5f..ea20f07e10 100644 --- a/ecmascript/compiler/stub_descriptor.cpp +++ b/ecmascript/compiler/stub_descriptor.cpp @@ -334,6 +334,39 @@ CALL_STUB_INIT_DESCRIPTOR(FindElementWithCache) descriptor->SetStubKind(StubDescriptor::CallStubKind::RUNTIME_STUB); } +CALL_STUB_INIT_DESCRIPTOR(Execute) +{ + // 5 : 5 input parameters + static StubDescriptor execute("Execute", 0, 5, ArgumentsOrder::DEFAULT_ORDER, UINT64_TYPE); + *descriptor = execute; + std::array params = { // 5 : 5 input parameters + MachineType::UINT64_TYPE, + MachineType::UINT64_TYPE, + MachineType::UINT64_TYPE, + MachineType::UINT32_TYPE, + MachineType::UINT64_TYPE, + }; + descriptor->SetParameters(params.data()); + descriptor->SetStubKind(StubDescriptor::CallStubKind::RUNTIME_STUB); +} + +CALL_STUB_INIT_DESCRIPTOR(FunctionCallInternal) +{ + // 5 : 5 input parameters + static StubDescriptor functionCallInternal("FunctionCallInternal", 0, 5, + ArgumentsOrder::DEFAULT_ORDER, UINT64_TYPE); + *descriptor = functionCallInternal; + std::array params = { // 5 : 5 input parameters + MachineType::UINT64_TYPE, + MachineType::UINT64_TYPE, + MachineType::UINT64_TYPE, + MachineType::UINT32_TYPE, + MachineType::UINT64_TYPE, + }; + descriptor->SetParameters(params.data()); + descriptor->SetStubKind(StubDescriptor::CallStubKind::RUNTIME_STUB); +} + CALL_STUB_INIT_DESCRIPTOR(StringGetHashCode) { static StubDescriptor stringGetHashCode("StringGetHashCode", 0, 1, ArgumentsOrder::DEFAULT_ORDER, UINT32_TYPE); diff --git a/ecmascript/compiler/tests/stub_tests.cpp b/ecmascript/compiler/tests/stub_tests.cpp index 173fda779d..8bd6d0b5b6 100644 --- a/ecmascript/compiler/tests/stub_tests.cpp +++ b/ecmascript/compiler/tests/stub_tests.cpp @@ -502,6 +502,22 @@ HWTEST_F_L0(StubTest, FastFindOwnElementStub) assembler.Run(); } +HWTEST_F_L0(StubTest, FunctionCallInternal) +{ + auto module = stubModule.GetModule(); + auto findFunction = stubModule.GetStubFunction(FAST_STUB_ID(FunctionCallInternal)); + Circuit netOfGates; + FunctionCallInternalStub optimizer(&netOfGates); + optimizer.GenerateCircuit(); + netOfGates.PrintAllGates(); + auto cfg = Scheduler::Run(&netOfGates); + PrintCircuitByBasicBlock(cfg, netOfGates); + LLVMIRBuilder llvmBuilder(&cfg, &netOfGates, &stubModule, findFunction); + llvmBuilder.Build(); + LLVMAssembler assembler(module, "x86_64-unknown-linux-gnu"); + assembler.Run(); +} + HWTEST_F_L0(StubTest, GetElementStub) { auto module = stubModule.GetModule(); diff --git a/ecmascript/message_string.h b/ecmascript/message_string.h index 61a6ba1bfc..144f8bdb21 100644 --- a/ecmascript/message_string.h +++ b/ecmascript/message_string.h @@ -20,8 +20,9 @@ namespace panda::ecmascript { // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define MESSAGE_STRING_LIST(V) \ - V(SetReadOnlyProperty, "Cannot set readonly property") \ +#define MESSAGE_STRING_LIST(V) \ + V(SetReadOnlyProperty, "Cannot set readonly property") \ + V(FunctionCallNotConstructor, "class constructor cannot call") \ V(SetPropertyWhenNotExtensible, "Cannot add property in prevent extensions ") class MessageString { diff --git a/ecmascript/runtime_trampolines.cpp b/ecmascript/runtime_trampolines.cpp index e9592ee8ac..36457e055a 100644 --- a/ecmascript/runtime_trampolines.cpp +++ b/ecmascript/runtime_trampolines.cpp @@ -22,6 +22,7 @@ #include "ecmascript/layout_info.h" #include "ecmascript/message_string.h" #include "ecmascript/object_factory.h" +#include "ecmascript/interpreter/interpreter-inl.h" namespace panda::ecmascript { bool RuntimeTrampolines::AddElementInternal(uint64_t argThread, uint64_t argReceiver, uint32_t argIndex, @@ -122,4 +123,20 @@ uint32_t RuntimeTrampolines::StringGetHashCode(uint64_t ecmaString) auto string = reinterpret_cast(ecmaString); return string->GetHashcode(); } + +uint64_t RuntimeTrampolines::Execute(uint64_t argThread, uint64_t argFunc, + uint64_t thisArg, uint32_t argc, uint64_t argArgv) +{ + auto thread = reinterpret_cast(argThread); + auto func = reinterpret_cast(argFunc); + auto argv = reinterpret_cast(argArgv); + CallParams params; + params.callTarget = func; + params.newTarget = JSTaggedValue::VALUE_UNDEFINED; + params.thisArg = thisArg; + params.argc = argc; + params.argv = argv; + + return EcmaInterpreter::Execute(thread, params).GetRawData(); +} } // namespace panda::ecmascript diff --git a/ecmascript/runtime_trampolines.h b/ecmascript/runtime_trampolines.h index 7d7c286760..62a20bb957 100644 --- a/ecmascript/runtime_trampolines.h +++ b/ecmascript/runtime_trampolines.h @@ -48,6 +48,7 @@ public: static uint32_t GetHash32(uint64_t key, uint64_t len); static int32_t FindElementWithCache(uint64_t argThread, uint64_t hClass, uint64_t key, int32_t num); static uint32_t StringGetHashCode(uint64_t ecmaString); + static uint64_t Execute(uint64_t argThread, uint64_t argFunc, uint64_t thisArg, uint32_t argc, uint64_t argArgv); }; class CallRuntimeTrampolinesScope { -- Gitee