From 3b57196f6e6e092e7e083f234ae94f539e1b5b3c Mon Sep 17 00:00:00 2001 From: getingke Date: Thu, 7 Oct 2021 10:48:03 +0800 Subject: [PATCH 1/2] fixed for setpropertybyvalue Signed-off-by: getingke Change-Id: I90717258dad21158e547718b80c64089eee18d1c --- ecmascript/compiler/circuit_builder.cpp | 4 +- ecmascript/compiler/fast_stub.cpp | 82 ++++++++ ecmascript/compiler/fast_stub.h | 20 ++ ecmascript/compiler/fast_stub_define.h | 7 +- ecmascript/compiler/stub.cpp | 241 +++++++++++++++++++++++ ecmascript/compiler/stub.h | 20 +- ecmascript/compiler/stub_descriptor.cpp | 44 +++++ ecmascript/compiler/tests/stub_tests.cpp | 45 ++++- ecmascript/ecma_string.h | 13 +- ecmascript/runtime_trampolines.cpp | 7 + ecmascript/runtime_trampolines.h | 1 + 11 files changed, 470 insertions(+), 14 deletions(-) diff --git a/ecmascript/compiler/circuit_builder.cpp b/ecmascript/compiler/circuit_builder.cpp index 0fcc17683a..541311d2f5 100644 --- a/ecmascript/compiler/circuit_builder.cpp +++ b/ecmascript/compiler/circuit_builder.cpp @@ -365,7 +365,7 @@ AddrShift CircuitBuilder::NewCallGate(StubDescriptor *descriptor, AddrShift targ AddrShift CircuitBuilder::NewCallRuntimeGate(StubDescriptor *descriptor, AddrShift thread, AddrShift target, std::initializer_list args) { - ASSERT(descriptor->GetStubKind() == StubDescriptor::RUNTIME_STUB); + ASSERT(descriptor->GetStubKind() == StubDescriptor::CallStubKind::RUNTIME_STUB); std::vector inputs; auto dependEntry = Circuit::GetCircuitRoot(OpCode(OpCode::DEPEND_ENTRY)); inputs.push_back(dependEntry); @@ -382,7 +382,7 @@ AddrShift CircuitBuilder::NewCallRuntimeGate(StubDescriptor *descriptor, AddrShi AddrShift CircuitBuilder::NewCallRuntimeGate(StubDescriptor *descriptor, AddrShift thread, AddrShift target, AddrShift depend, std::initializer_list args) { - ASSERT(descriptor->GetStubKind() == StubDescriptor::RUNTIME_STUB); + ASSERT(descriptor->GetStubKind() == StubDescriptor::CallStubKind::RUNTIME_STUB); std::vector inputs; inputs.push_back(depend); inputs.push_back(target); diff --git a/ecmascript/compiler/fast_stub.cpp b/ecmascript/compiler/fast_stub.cpp index ac005e5b53..131a7f5e67 100644 --- a/ecmascript/compiler/fast_stub.cpp +++ b/ecmascript/compiler/fast_stub.cpp @@ -1158,4 +1158,86 @@ void FastModStub::GenerateCircuit() } } } + +void FastGetPropertyByValueStub::GenerateCircuit() +{ + auto env = GetEnvironment(); + AddrShift thread = PtrArgument(0); + AddrShift receiver = PtrArgument(1); + DEFVARIABLE(key, TAGGED_TYPE, PtrArgument(2)); /* 2 : 3rd parameter is key */ + + Label isNumberOrStringSymbol(env); + Label notNumber(env); + Label isStringOrSymbol(env); + Label notStringOrSymbol(env); + Label exit(env); + + Branch(TaggedIsNumber(*key), &isNumberOrStringSymbol, ¬Number); + Bind(¬Number); + { + Branch(TaggedIsStringOrSymbol(*key), &isNumberOrStringSymbol, ¬StringOrSymbol); + Bind(¬StringOrSymbol); + { + Return(GetHoleConstant()); + } + } + Bind(&isNumberOrStringSymbol); + { + AddrShift index = TryToElementsIndex(*key); + Label validIndex(env); + Label notValidIndex(env); + Branch(Int32GreaterThanOrEqual(index, GetInteger32Constant(0)), &validIndex, ¬ValidIndex); + Bind(&validIndex); + { + auto getPropertyByIndex = GET_STUBDESCRIPTOR(GetPropertyByIndex); + Return(CallStub(getPropertyByIndex, GetWord64Constant(FAST_STUB_ID(GetPropertyByIndex)), + {thread, receiver, *key})); + } + Bind(¬ValidIndex); + { + Label notNumber(env); + Label getByName(env); + Branch(TaggedIsNumber(*key), &exit, ¬Number); + Bind(¬Number); + { + Label isString(env); + Label notString(env); + Label isInternalString(env); + Label notIntenalString(env); + Branch(TaggedIsString(*key), &isString, ¬String); + Bind(&isString); + { + Branch(IsInternalString(*key), &isInternalString, ¬IntenalString); + Bind(&isInternalString); + Jump(&getByName); + Bind(¬IntenalString); + { + StubDescriptor *newInternalString = GET_STUBDESCRIPTOR(NewInternalString); + key = CallRuntime(newInternalString, thread, + GetWord64Constant(FAST_STUB_ID(NewInternalString)), + {thread, *key}); + Jump(&getByName); + } + } + Bind(¬String); + { + Jump(&getByName); + } + } + Bind(&getByName); + { + auto getPropertyByName = GET_STUBDESCRIPTOR(GetPropertyByName); + Return(CallStub(getPropertyByName, GetWord64Constant(FAST_STUB_ID(GetPropertyByName)), + {thread, receiver, *key})); + } + } + } + Bind(&exit); + Return(GetHoleConstant()); +} + +void FastSetPropertyByValueStub::GenerateCircuit() +{ + +} } // namespace kungfu \ No newline at end of file diff --git a/ecmascript/compiler/fast_stub.h b/ecmascript/compiler/fast_stub.h index 6814fa37c7..004a627968 100644 --- a/ecmascript/compiler/fast_stub.h +++ b/ecmascript/compiler/fast_stub.h @@ -149,5 +149,25 @@ public: NO_COPY_SEMANTIC(FastModStub); void GenerateCircuit() override; }; + +class FastGetPropertyByValueStub : public Stub { +public: + // 3 : 3 means argument counts + explicit FastGetPropertyByValueStub(Circuit *circuit) : Stub("FastGetPropertyByValue", 3, circuit) {} + ~FastGetPropertyByValueStub() = default; + NO_MOVE_SEMANTIC(FastGetPropertyByValueStub); + NO_COPY_SEMANTIC(FastGetPropertyByValueStub); + void GenerateCircuit() override; +}; + +class FastSetPropertyByValueStub : public Stub { +public: + // 4 : 4 means argument counts + explicit FastSetPropertyByValueStub(Circuit *circuit) : Stub("FastSetPropertyByValue", 4, circuit) {} + ~FastSetPropertyByValueStub() = default; + NO_MOVE_SEMANTIC(FastSetPropertyByValueStub); + NO_COPY_SEMANTIC(FastSetPropertyByValueStub); + 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 ccf3bf3c31..7c5151394a 100644 --- a/ecmascript/compiler/fast_stub_define.h +++ b/ecmascript/compiler/fast_stub_define.h @@ -27,7 +27,8 @@ namespace kungfu { V(JSProxySetProperty, 6) \ V(GetHash32, 2) \ V(FindElementWithCache, 4) \ - V(StringGetHashCode, 1) + V(StringGetHashCode, 1) \ + V(NewInternalString, 2) // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define FAST_RUNTIME_STUB_LIST(V) \ @@ -57,7 +58,9 @@ namespace kungfu { V(FindOwnProperty2, 6) \ V(FindOwnElement2, 6) \ V(GetPropertyByIndex, 3) \ - V(SetPropertyByIndex, 4) + V(SetPropertyByIndex, 4) \ + V(GetPropertyByValue, 3) \ + V(SetPropertyByValue, 4) #define CALL_STUB_LIST(V) \ FAST_RUNTIME_STUB_LIST(V) \ diff --git a/ecmascript/compiler/stub.cpp b/ecmascript/compiler/stub.cpp index 4f9a0eeb82..e5cb6ef22b 100644 --- a/ecmascript/compiler/stub.cpp +++ b/ecmascript/compiler/stub.cpp @@ -778,4 +778,245 @@ void Stub::UpdateAndStoreRepresention(AddrShift hclass, AddrShift value) AddrShift newRep = UpdateRepresention(GetElementRepresentation(hclass), value); SetElementRepresentation(hclass, newRep); } + +AddrShift Stub::TaggedIsString(AddrShift obj) +{ + auto env = GetEnvironment(); + Label entry(env); + [[maybe_unused]] SubCircuitScope subCircuit(env, &entry); + Label exit(env); + DEFVARIABLE(result, BOOL_TYPE, FalseConstant()); + Label isHeapObject(env); + Branch(TaggedIsHeapObject(obj), &isHeapObject, &exit); + Bind(&isHeapObject); + { + result = Word32Equal(GetObjectType(LoadHClass(obj)), + GetInteger32Constant(static_cast(panda::ecmascript::JSType::STRING))); + Jump(&exit); + } + Bind(&exit); + return *result; +} + +AddrShift Stub::TaggedIsStringOrSymbol(AddrShift obj) +{ + auto env = GetEnvironment(); + Label entry(env); + [[maybe_unused]] SubCircuitScope subCircuit(env, &entry); + Label exit(env); + DEFVARIABLE(result, BOOL_TYPE, FalseConstant()); + Label isHeapObject(env); + Branch(TaggedIsHeapObject(obj), &isHeapObject, &exit); + Bind(&isHeapObject); + { + AddrShift objType = GetObjectType(LoadHClass(obj)); + result = Word32Equal(objType, + GetInteger32Constant(static_cast(panda::ecmascript::JSType::STRING))); + Label isString(env); + Label notString(env); + Branch(*result, &exit, ¬String); + Bind(¬String); + { + result = Word32Equal(objType, + GetInteger32Constant(static_cast(panda::ecmascript::JSType::SYMBOL))); + Jump(&exit); + } + } + Bind(&exit); + return *result; +} + +AddrShift Stub::IsUtf16String(AddrShift string) +{ + // compressedStringsEnabled fixed to true constant + AddrShift len = Load(MachineType::UINT32_TYPE, string, + GetPtrConstant(panda::ecmascript::EcmaString::GetLengthOffset())); + return Word32Equal( + Word32And(len, GetInteger32Constant(panda::ecmascript::EcmaString::STRING_COMPRESSED_BIT)), + GetInteger32Constant(panda::ecmascript::EcmaString::STRING_UNCOMPRESSED)); +} + +AddrShift Stub::IsUtf8String(AddrShift string) +{ + // compressedStringsEnabled fixed to true constant + AddrShift len = Load(MachineType::UINT32_TYPE, string, + GetPtrConstant(panda::ecmascript::EcmaString::GetLengthOffset())); + return Word32Equal( + Word32And(len, GetInteger32Constant(panda::ecmascript::EcmaString::STRING_COMPRESSED_BIT)), + GetInteger32Constant(panda::ecmascript::EcmaString::STRING_COMPRESSED)); +} + +AddrShift Stub::IsInternalString(AddrShift string) +{ + // compressedStringsEnabled fixed to true constant + AddrShift len = Load(MachineType::UINT32_TYPE, string, + GetPtrConstant(panda::ecmascript::EcmaString::GetLengthOffset())); + return Word32NotEqual( + Word32And(len, GetInteger32Constant(panda::ecmascript::EcmaString::STRING_INTERN_BIT)), + GetInteger32Constant(0)); +} + +AddrShift Stub::IsDigit(AddrShift ch) +{ + return TruncInt32ToInt1( + Word32And(SExtInt1ToInt32(Int32GreaterThanOrEqual(ch, GetInteger32Constant('9'))), + SExtInt1ToInt32(Int32LessThanOrEqual(ch, GetInteger32Constant('0'))))); +} + +AddrShift Stub::StringToElementIndex(AddrShift string) +{ + auto env = GetEnvironment(); + Label entry(env); + [[maybe_unused]] SubCircuitScope subCircuit(env, &entry); + Label exit(env); + DEFVARIABLE(result, INT32_TYPE, GetInteger32Constant(-1)); + Label greatThanZero(env); + Label inRange(env); + AddrShift len = Load(MachineType::UINT32_TYPE, string, + GetPtrConstant(panda::ecmascript::EcmaString::GetLengthOffset())); + len = Word32LSR(len, GetInteger32Constant(2)); + Branch(Word32Equal(len, GetInteger32Constant(0)), &exit, &greatThanZero); + Bind(&greatThanZero); + Branch(Int32GreaterThan(len, GetInteger32Constant(panda::ecmascript::MAX_INDEX_LEN)), &exit, &inRange); + Bind(&inRange); + { + AddrShift dataUtf16 = Load(POINTER_TYPE, string, GetPtrConstant(panda::ecmascript::EcmaString::GetDataOffset())); + DEFVARIABLE(c, UINT32_TYPE, GetInteger32Constant(0)); + Label isUtf16(env); + Label isUtf8(env); + Label getChar1(env); + AddrShift isUtf16String = IsUtf16String(string); + Branch(isUtf16String, &isUtf16, &isUtf8); + Bind(&isUtf16); + { + c = Load(INT16_TYPE, dataUtf16); + Jump(&getChar1); + } + Bind(&isUtf8); + { + c = Load(INT8_TYPE, dataUtf16); + Jump(&getChar1); + } + Bind(&getChar1); + { + Label isDigitZero(env); + Label notDigitZero(env); + Branch(Word32Equal(*c, GetInteger32Constant('0')), &isDigitZero, ¬DigitZero); + Bind(&isDigitZero); + { + Label lengthIsOne(env); + Branch(Word32Equal(len, GetInteger32Constant(1)), &lengthIsOne, &exit); + Bind(&lengthIsOne); + { + result = GetInteger32Constant(0); + Jump(&exit); + } + } + Bind(¬DigitZero); + { + Label isDigit(env); + DEFVARIABLE(i, UINT32_TYPE, GetInteger32Constant(1)); + DEFVARIABLE(n, UINT32_TYPE, Int32Sub(*c, GetInteger32Constant('0'))); + Branch(IsDigit(*c), &isDigit, &exit); + Label loopHead(env); + Label loopEnd(env); + Label afterLoop(env); + Bind(&isDigit); + Branch(Int32LessThan(*i, len), &loopHead, &exit); + LoopBegin(&loopHead); + { + Label isUtf16(env); + Label notUtf16(env); + Label getChar2(env); + Branch(isUtf16String, &isUtf16, ¬Utf16); + Bind(&isUtf16); + { + c = Load(INT16_TYPE, dataUtf16, PtrMul(*i, GetPtrConstant(2))); + Jump(&getChar2); + } + Bind(¬Utf16); + { + c = Load(INT8_TYPE, dataUtf16, *i); + Jump(&getChar2); + } + Bind(&getChar2); + { + Label isDigit(env); + Branch(IsDigit(*c), &isDigit, &exit); + Bind(&isDigit); + { + n = Int32Add(Int32Mul(*n, GetInteger32Constant(10)), + Int32Sub(*c, GetInteger32Constant('0'))); + i = Int32Add(*i, GetInteger32Constant(1)); + Branch(Int32LessThan(*i, len), &loopEnd, &afterLoop); + } + } + } + Bind(&loopEnd); + LoopEnd(&loopHead); + Bind(&afterLoop); + { + Label lessThanMaxIndex(env); + Branch(Int32LessThan(*n, GetInteger32Constant(panda::ecmascript::JSObject::MAX_ELEMENT_INDEX)), + &lessThanMaxIndex, &exit); + Bind(&lessThanMaxIndex); + { + result = *n; + Jump(&exit); + } + } + } + } + } + Bind(&exit); + return *result; +} + +AddrShift Stub::TryToElementsIndex(AddrShift key) +{ + auto env = GetEnvironment(); + Label entry(env); + [[maybe_unused]] SubCircuitScope subCircuit(env, &entry); + Label exit(env); + Label isKeyInt(env); + Label notKeyInt(env); + + DEFVARIABLE(resultKey, INT32_TYPE, GetInteger32Constant(0)); + Branch(TaggedIsInt(key), &isKeyInt, ¬KeyInt); + Bind(&isKeyInt); + { + resultKey = TaggedCastToInt32(key); + Jump(&exit); + } + Bind(¬KeyInt); + { + Label isString(env); + Label notString(env); + Branch(TaggedIsString(key), &isString, ¬String); + Bind(&isString); + { + resultKey = StringToElementIndex(key); + Jump(&exit); + } + Bind(¬String); + { + Label isDouble(env); + Branch(TaggedIsDouble(key), &isDouble, &exit); + Bind(&isDouble); + { + AddrShift number = TaggedCastToDouble(key); + AddrShift integer = ChangeInt64ToInt32(CastDoubleToInt64(number)); + Label isEqual(env); + Branch(DoubleEqual(number, CastInt64ToFloat64(SExtInt32ToInt64(integer))), &isEqual, &exit); + Bind(&isEqual); + { + resultKey = integer; + Jump(&exit); + } + } + } + } + Bind(&exit); + return *resultKey; +} } // namespace kungfu \ No newline at end of file diff --git a/ecmascript/compiler/stub.h b/ecmascript/compiler/stub.h index 1260e34bb6..d82f79c2a4 100644 --- a/ecmascript/compiler/stub.h +++ b/ecmascript/compiler/stub.h @@ -829,6 +829,10 @@ public: WordLogicAnd(SExtInt1ToInt32(TaggedIsObject(x)), WordLogicNot(SExtInt1ToInt32(TaggedIsSpecial(x))))); } + AddrShift TaggedIsString(AddrShift obj); + + AddrShift TaggedIsStringOrSymbol(AddrShift obj); + AddrShift DoubleIsNAN(AddrShift x) { AddrShift diff = DoubleEqual(x, x); @@ -841,8 +845,8 @@ public: AddrShift negativeInfinity = GetDoubleConstant(-base::POSITIVE_INFINITY); AddrShift diff1 = DoubleEqual(x, infinity); AddrShift diff2 = DoubleEqual(x, negativeInfinity); - return Word32Or(Word32Equal(SExtInt1ToInt32(diff1), GetInteger32Constant(1)), - Word32Equal(SExtInt1ToInt32(diff2), GetInteger32Constant(1))); + return TruncInt32ToInt1(Word32Or(Word32Equal(SExtInt1ToInt32(diff1), GetInteger32Constant(1)), + Word32Equal(SExtInt1ToInt32(diff2), GetInteger32Constant(1)))); } AddrShift IntBuildTagged(AddrShift x) @@ -1270,6 +1274,18 @@ public: AddrShift JSObjectGetProperty(AddrShift obj, AddrShift hClass, AddrShift propAttr); + AddrShift IsUtf16String(AddrShift string); + + AddrShift IsUtf8String(AddrShift string); + + AddrShift IsInternalString(AddrShift string); + + AddrShift IsDigit(AddrShift ch); + + AddrShift StringToElementIndex(AddrShift string); + + AddrShift TryToElementsIndex(AddrShift key); + AddrShift TaggedCastToInt64(AddrShift x) { return Word64And(x, GetWord64Constant(~panda::ecmascript::JSTaggedValue::TAG_MASK)); diff --git a/ecmascript/compiler/stub_descriptor.cpp b/ecmascript/compiler/stub_descriptor.cpp index 31cc658a5a..93716b87eb 100644 --- a/ecmascript/compiler/stub_descriptor.cpp +++ b/ecmascript/compiler/stub_descriptor.cpp @@ -208,6 +208,36 @@ CALL_STUB_INIT_DESCRIPTOR(SetPropertyByIndex) descriptor->SetParameters(params.data()); } +CALL_STUB_INIT_DESCRIPTOR(GetPropertyByValue) +{ + // 3 : 3 input parameters + static StubDescriptor getPropertyByValue("GetPropertyByValue", 0, 3, ArgumentsOrder::DEFAULT_ORDER, UINT64_TYPE); + *descriptor = getPropertyByValue; + // 3 : 3 input parameters + std::array params = { + MachineType::UINT64_TYPE, + MachineType::UINT64_TYPE, + MachineType::UINT64_TYPE, + }; + descriptor->SetParameters(params.data()); +} + +CALL_STUB_INIT_DESCRIPTOR(SetPropertyByValue) +{ + // 4 : 4 input parameters + static StubDescriptor setPropertyByValue("SetPropertyByValue", 0, 4, ArgumentsOrder::DEFAULT_ORDER, UINT64_TYPE); + *descriptor = setPropertyByValue; + // 4 : 4 input parameters + std::array params = { + MachineType::UINT64_TYPE, + MachineType::UINT64_TYPE, + MachineType::UINT64_TYPE, + MachineType::UINT64_TYPE, + }; + descriptor->SetParameters(params.data()); +} + + CALL_STUB_INIT_DESCRIPTOR(AddElementInternal) { // 5 : 5 input parameters @@ -334,6 +364,20 @@ CALL_STUB_INIT_DESCRIPTOR(StringGetHashCode) descriptor->SetStubKind(StubDescriptor::CallStubKind::RUNTIME_STUB); } +CALL_STUB_INIT_DESCRIPTOR(NewInternalString) +{ + // 2 : 2 input parameters + static StubDescriptor stringGetHashCode("NewInternalString", 0, 2, ArgumentsOrder::DEFAULT_ORDER, UINT64_TYPE); + *descriptor = stringGetHashCode; + // 2 : 2 input parameters + std::array params = { + MachineType::UINT64_TYPE, + MachineType::UINT64_TYPE, + }; + descriptor->SetParameters(params.data()); + descriptor->SetStubKind(StubDescriptor::CallStubKind::RUNTIME_STUB); +} + void FastStubDescriptors::InitializeStubDescriptors() { // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) diff --git a/ecmascript/compiler/tests/stub_tests.cpp b/ecmascript/compiler/tests/stub_tests.cpp index c684a94da8..59acabb7b7 100644 --- a/ecmascript/compiler/tests/stub_tests.cpp +++ b/ecmascript/compiler/tests/stub_tests.cpp @@ -1264,8 +1264,8 @@ HWTEST_F_L0(StubTest, FastModTest) for (size_t bbIdx = 0; bbIdx < cfg.size(); bbIdx++) { std::cout << (netOfGates.GetOpCode(cfg[bbIdx].front()).IsCFGMerge() ? "MERGE_" : "BB_") << bbIdx << ":" << std::endl; - for (size_t instIdex = cfg[bbIdx].size(); instIdex < 0; instIdex--) { - netOfGates.Print(cfg[bbIdx][instIdex - 1]); + for (size_t instIdx = cfg[bbIdx].size(); instIdx < 0; instIdx--) { + netOfGates.Print(cfg[bbIdx][instIdx - 1]); } } LLVMIRBuilder llvmBuilder(&cfg, &netOfGates, module, function); @@ -1318,4 +1318,45 @@ HWTEST_F_L0(StubTest, FastModTest) std::cout << "result1 for FastMod(7, 'helloworld') = " << result5.GetRawData() << std::endl; EXPECT_EQ(result5, expectRes5); } + +HWTEST_F_L0(StubTest, FastGetPropertyByValueStub) +{ + auto module = stubModule.GetModule(); + LLVMValueRef function = LLVMGetNamedFunction(module, "GetPropertyByValue"); + Circuit netOfGates; + FastGetPropertyByValueStub optimizer(&netOfGates); + optimizer.GenerateCircuit(); + netOfGates.PrintAllGates(); + bool result = Verifier::Run(&netOfGates); + ASSERT_TRUE(result); + auto cfg = Scheduler::Run(&netOfGates); + for (size_t bbIdx = 0; bbIdx < cfg.size(); bbIdx++) { + std::cout << (netOfGates.GetOpCode(cfg[bbIdx].front()).IsCFGMerge() ? "MERGE_" : "BB_") << bbIdx << ":" + << std::endl; + for (size_t instIdx = cfg[bbIdx].size(); instIdx > 0; instIdx--) { + netOfGates.Print(cfg[bbIdx][instIdx - 1]); + } + } + LLVMIRBuilder llvmBuilder(&cfg, &netOfGates, &stubModule, function); + llvmBuilder.Build(); + LLVMAssembler assembler(module); + assembler.Run(); + auto engine = assembler.GetEngine(); + auto *getPropertyByValuePtr = reinterpret_cast( + reinterpret_cast(LLVMGetPointerToGlobal(engine, function))); + auto *factory = JSThread::Cast(thread)->GetEcmaVM()->GetFactory(); + JSHandle obj = factory->NewEmptyJSObject(); + int x = 213; + int y = 10; + JSHandle strA(factory->NewFromCanBeCompressString("a")); + JSHandle strBig(factory->NewFromCanBeCompressString("biggest")); + FastRuntimeStub::SetPropertyByName(thread, obj.GetTaggedValue(), strA.GetTaggedValue(), JSTaggedValue(x)); + FastRuntimeStub::SetPropertyByName(thread, obj.GetTaggedValue(), strBig.GetTaggedValue(), JSTaggedValue(y)); + assembler.Disassemble(); + JSTaggedValue resVal = getPropertyByValuePtr(thread, obj.GetTaggedValue().GetRawData(), + strA.GetTaggedValue().GetRawData()); + EXPECT_EQ(resVal.GetNumber(), x); + resVal = getPropertyByValuePtr(thread, obj.GetTaggedValue().GetRawData(), strBig.GetTaggedValue().GetRawData()); + EXPECT_EQ(resVal.GetNumber(), y); +} } // namespace panda::test diff --git a/ecmascript/ecma_string.h b/ecmascript/ecma_string.h index 499295787b..eab7f02229 100644 --- a/ecmascript/ecma_string.h +++ b/ecmascript/ecma_string.h @@ -45,6 +45,13 @@ public: static EcmaString *FastSubString(const JSHandle &src, uint32_t start, uint32_t utf16Len, const EcmaVM *vm); + static constexpr uint32_t STRING_COMPRESSED_BIT = 0x1; + static constexpr uint32_t STRING_INTERN_BIT = 0x2; + enum CompressedStatus { + STRING_COMPRESSED, + STRING_UNCOMPRESSED, + }; + template uint16_t At(int32_t index) const; @@ -285,12 +292,6 @@ private: static void CopyUtf16AsUtf8(const uint16_t *utf16From, uint8_t *utf8To, uint32_t utf16Len); static bool compressedStringsEnabled; - static constexpr uint32_t STRING_COMPRESSED_BIT = 0x1; - static constexpr uint32_t STRING_INTERN_BIT = 0x2; - enum CompressedStatus { - STRING_COMPRESSED, - STRING_UNCOMPRESSED, - }; static bool IsASCIICharacter(uint16_t data) { diff --git a/ecmascript/runtime_trampolines.cpp b/ecmascript/runtime_trampolines.cpp index 839459d5e0..a0e7a775d7 100644 --- a/ecmascript/runtime_trampolines.cpp +++ b/ecmascript/runtime_trampolines.cpp @@ -103,4 +103,11 @@ uint32_t RuntimeTrampolines::StringGetHashCode(uint64_t ecmaString) auto string = reinterpret_cast(ecmaString); return string->GetHashcode(); } + +uint64_t RuntimeTrampolines::NewInternalString(uint64_t argThread, uint64_t argKey) +{ + auto thread = reinterpret_cast(argThread); + JSHandle keyHandle(thread, JSTaggedValue(reinterpret_cast(argKey))); + return JSTaggedValue(thread->GetEcmaVM()->GetFactory()->InternString(keyHandle)).GetRawData(); +} } // namespace panda::ecmascript diff --git a/ecmascript/runtime_trampolines.h b/ecmascript/runtime_trampolines.h index 678ea521ee..6fe25f01a6 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 NewInternalString(uint64_t argThread, uint64_t argKey); }; } // namespace panda::ecmascript #endif \ No newline at end of file -- Gitee From f879a5192709531c03840d9a7a719ed5ce2c9d79 Mon Sep 17 00:00:00 2001 From: getingke Date: Sat, 9 Oct 2021 17:53:12 +0800 Subject: [PATCH 2/2] fixed for get/setpropertybyvalue Signed-off-by: getingke Change-Id: I9aaed17a6a1ad7a087202c29b1bc49aa4c70561b --- ecmascript/compiler/compile_llvm_lib.sh | 4 +- ecmascript/compiler/fast_stub.cpp | 75 +++++++++++++++++++++++- ecmascript/compiler/gate.cpp | 17 ++++++ ecmascript/compiler/gate.h | 5 ++ ecmascript/compiler/llvm_ir_builder.cpp | 17 +++++- ecmascript/compiler/stub.cpp | 45 +++++++++----- ecmascript/compiler/stub.h | 20 ++++--- ecmascript/compiler/tests/stub_tests.cpp | 41 ++++++++++++- 8 files changed, 196 insertions(+), 28 deletions(-) diff --git a/ecmascript/compiler/compile_llvm_lib.sh b/ecmascript/compiler/compile_llvm_lib.sh index 58c117ed66..bc0d573522 100755 --- a/ecmascript/compiler/compile_llvm_lib.sh +++ b/ecmascript/compiler/compile_llvm_lib.sh @@ -32,13 +32,13 @@ fi cd ${BASE_HOME}/third_party/llvm-project if [ ! -d "build" ];then mkdir build && cd build - cmake -GNinja -DCMAKE_BUILD_TYPE=Release ../llvm + cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_TERMINFO=OFF ../llvm ninja else cd build if [ ! -d "lib" ]; then rm -rf * - cmake -GNinja -DCMAKE_BUILD_TYPE=Release ../llvm + cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_TERMINFO=OFF ../llvm ninja fi fi diff --git a/ecmascript/compiler/fast_stub.cpp b/ecmascript/compiler/fast_stub.cpp index 131a7f5e67..fa3eb7139f 100644 --- a/ecmascript/compiler/fast_stub.cpp +++ b/ecmascript/compiler/fast_stub.cpp @@ -1191,7 +1191,7 @@ void FastGetPropertyByValueStub::GenerateCircuit() { auto getPropertyByIndex = GET_STUBDESCRIPTOR(GetPropertyByIndex); Return(CallStub(getPropertyByIndex, GetWord64Constant(FAST_STUB_ID(GetPropertyByIndex)), - {thread, receiver, *key})); + {thread, receiver, index})); } Bind(¬ValidIndex); { @@ -1238,6 +1238,79 @@ void FastGetPropertyByValueStub::GenerateCircuit() void FastSetPropertyByValueStub::GenerateCircuit() { + auto env = GetEnvironment(); + AddrShift thread = PtrArgument(0); + AddrShift receiver = PtrArgument(1); + DEFVARIABLE(key, TAGGED_TYPE, PtrArgument(2)); /* 2 : 3rd parameter is key */ + AddrShift value = Int64Argument(3); /* 3 : 4th parameter is value */ + Label isNumberOrStringSymbol(env); + Label notNumber(env); + Label isStringOrSymbol(env); + Label notStringOrSymbol(env); + Label exit(env); + + Branch(TaggedIsNumber(*key), &isNumberOrStringSymbol, ¬Number); + Bind(¬Number); + { + Branch(TaggedIsStringOrSymbol(*key), &isNumberOrStringSymbol, ¬StringOrSymbol); + Bind(¬StringOrSymbol); + { + Return(GetHoleConstant()); + } + } + Bind(&isNumberOrStringSymbol); + { + AddrShift index = TryToElementsIndex(*key); + Label validIndex(env); + Label notValidIndex(env); + Branch(Int32GreaterThanOrEqual(index, GetInteger32Constant(0)), &validIndex, ¬ValidIndex); + Bind(&validIndex); + { + auto setPropertyByIndex = GET_STUBDESCRIPTOR(SetPropertyByIndex); + Return(CallStub(setPropertyByIndex, GetWord64Constant(FAST_STUB_ID(SetPropertyByIndex)), + {thread, receiver, index, value})); + } + Bind(¬ValidIndex); + { + Label notNumber(env); + Label getByName(env); + Branch(TaggedIsNumber(*key), &exit, ¬Number); + Bind(¬Number); + { + Label isString(env); + Label notString(env); + Label isInternalString(env); + Label notIntenalString(env); + Branch(TaggedIsString(*key), &isString, ¬String); + Bind(&isString); + { + Branch(IsInternalString(*key), &isInternalString, ¬IntenalString); + Bind(&isInternalString); + Jump(&getByName); + Bind(¬IntenalString); + { + StubDescriptor *newInternalString = GET_STUBDESCRIPTOR(NewInternalString); + key = CallRuntime(newInternalString, thread, + GetWord64Constant(FAST_STUB_ID(NewInternalString)), + {thread, *key}); + Jump(&getByName); + } + } + Bind(¬String); + { + Jump(&getByName); + } + } + Bind(&getByName); + { + auto setPropertyByName = GET_STUBDESCRIPTOR(SetPropertyByName); + Return(CallStub(setPropertyByName, GetWord64Constant(FAST_STUB_ID(SetPropertyByName)), + {thread, receiver, *key, value})); + } + } + } + Bind(&exit); + Return(GetHoleConstant()); } } // namespace kungfu \ No newline at end of file diff --git a/ecmascript/compiler/gate.cpp b/ecmascript/compiler/gate.cpp index f2e09834fd..bcecfaddb5 100644 --- a/ecmascript/compiler/gate.cpp +++ b/ecmascript/compiler/gate.cpp @@ -185,12 +185,20 @@ Properties OpCode::GetProperties() const return {INT64, NO_STATE, NO_DEPEND, VALUE(INT32), NO_ROOT}; case ZEXT_INT1_TO_INT32: return {INT32, NO_STATE, NO_DEPEND, VALUE(INT1), NO_ROOT}; + case ZEXT_INT8_TO_INT32: + return {INT32, NO_STATE, NO_DEPEND, VALUE(INT8), NO_ROOT}; + case ZEXT_INT16_TO_INT32: + return {INT32, NO_STATE, NO_DEPEND, VALUE(INT16), NO_ROOT}; case ZEXT_INT1_TO_INT64: return {INT64, NO_STATE, NO_DEPEND, VALUE(INT1), NO_ROOT}; case SEXT_INT32_TO_INT64: return {INT64, NO_STATE, NO_DEPEND, VALUE(INT32), NO_ROOT}; case SEXT_INT1_TO_INT32: return {INT32, NO_STATE, NO_DEPEND, VALUE(INT1), NO_ROOT}; + case SEXT_INT8_TO_INT32: + return {INT32, NO_STATE, NO_DEPEND, VALUE(INT8), NO_ROOT}; + case SEXT_INT16_TO_INT32: + return {INT32, NO_STATE, NO_DEPEND, VALUE(INT8), NO_ROOT}; case SEXT_INT1_TO_INT64: return {INT64, NO_STATE, NO_DEPEND, VALUE(INT1), NO_ROOT}; case TRUNC_INT64_TO_INT32: @@ -400,9 +408,13 @@ std::string OpCode::Str() const {FLOAT64_CONSTANT, "FLOAT64_CONSTANT"}, {ZEXT_INT32_TO_INT64, "ZEXT_INT32_TO_INT64"}, {ZEXT_INT1_TO_INT32, "ZEXT_INT1_TO_INT32"}, + {ZEXT_INT8_TO_INT32, "ZEXT_INT8_TO_INT32"}, + {ZEXT_INT16_TO_INT32, "ZEXT_INT16_TO_INT32"}, {ZEXT_INT1_TO_INT64, "ZEXT_INT1_TO_INT64"}, {SEXT_INT32_TO_INT64, "SEXT_INT32_TO_INT64"}, {SEXT_INT1_TO_INT32, "SEXT_INT1_TO_INT32"}, + {SEXT_INT8_TO_INT32, "SEXT_INT8_TO_INT32"}, + {SEXT_INT16_TO_INT32, "SEXT_INT16_TO_INT32"}, {SEXT_INT1_TO_INT64, "SEXT_INT1_TO_INT64"}, {TRUNC_INT64_TO_INT32, "TRUNC_INT64_TO_INT32"}, {TRUNC_INT64_TO_INT1, "TRUNC_INT64_TO_INT1"}, @@ -1305,4 +1317,9 @@ bool OpCode::IsLoopHead() const { return (this->op == OpCode::LOOP_BEGIN); } + +bool OpCode::IsNop() const +{ + return (this->op == OpCode::NOP); +} } // namespace kungfu \ No newline at end of file diff --git a/ecmascript/compiler/gate.h b/ecmascript/compiler/gate.h index a112479593..fbc99b7094 100644 --- a/ecmascript/compiler/gate.h +++ b/ecmascript/compiler/gate.h @@ -147,9 +147,13 @@ public: FLOAT64_CONSTANT, ZEXT_INT32_TO_INT64, ZEXT_INT1_TO_INT32, + ZEXT_INT8_TO_INT32, + ZEXT_INT16_TO_INT32, ZEXT_INT1_TO_INT64, SEXT_INT32_TO_INT64, SEXT_INT1_TO_INT32, + SEXT_INT8_TO_INT32, + SEXT_INT16_TO_INT32, SEXT_INT1_TO_INT64, TRUNC_INT64_TO_INT32, TRUNC_INT64_TO_INT1, @@ -253,6 +257,7 @@ public: [[nodiscard]] bool IsCFGMerge() const; [[nodiscard]] bool IsControlCase() const; [[nodiscard]] bool IsLoopHead() const; + [[nodiscard]] bool IsNop() const; ~OpCode() = default; private: diff --git a/ecmascript/compiler/llvm_ir_builder.cpp b/ecmascript/compiler/llvm_ir_builder.cpp index 388aed1e90..262972b25d 100644 --- a/ecmascript/compiler/llvm_ir_builder.cpp +++ b/ecmascript/compiler/llvm_ir_builder.cpp @@ -235,7 +235,9 @@ void LLVMIRBuilder::Build() VisitFloat64Constant(gate, doubleValue); break; } - case OpCode::ZEXT_INT1_TO_INT32: { + case OpCode::ZEXT_INT1_TO_INT32: // no break, fall through + case OpCode::ZEXT_INT8_TO_INT32: + case OpCode::ZEXT_INT16_TO_INT32: { VisitZExtInt(gate, ins[0], MachineRep::K_WORD32); break; } @@ -364,6 +366,16 @@ void LLVMIRBuilder::Build() VisitIntOrUintCmp(gate, ins[0], ins[1], LLVMIntNE); break; } + case OpCode::INT8_LOAD: { + AddrShift base = ins[1]; + VisitLoad(gate, MachineRep::K_WORD8, base); + break; + } + case OpCode::INT16_LOAD: { + AddrShift base = ins[1]; + VisitLoad(gate, MachineRep::K_WORD16, base); + break; + } case OpCode::INT32_LOAD: { AddrShift base = ins[1]; VisitLoad(gate, MachineRep::K_WORD32, base); @@ -572,6 +584,9 @@ LLVMTypeRef LLVMIRBuilder::GetMachineRepType(MachineRep rep) const case MachineRep::K_WORD8: dstType = LLVMInt8TypeInContext(context_); break; + case MachineRep::K_WORD16: + dstType = LLVMInt16TypeInContext(context_); + break; case MachineRep::K_WORD32: dstType = LLVMInt32TypeInContext(context_); break; diff --git a/ecmascript/compiler/stub.cpp b/ecmascript/compiler/stub.cpp index e5cb6ef22b..765cced15d 100644 --- a/ecmascript/compiler/stub.cpp +++ b/ecmascript/compiler/stub.cpp @@ -34,10 +34,11 @@ AddrShift Stub::Variable::AddPhiOperand(AddrShift val) Label label = env_->GetLabelFromSelector(val); size_t idx = 0; for (auto pred : label.GetPredecessors()) { + auto preVal = pred.ReadVariable(this); + ASSERT(!env_->GetCircuit()->GetOpCode(preVal).IsNop()); idx++; - val = AddOperandToSelector(val, idx, pred.ReadVariable(this)); + val = AddOperandToSelector(val, idx, preVal); } - return TryRemoveTrivialPhi(val); } @@ -66,6 +67,7 @@ AddrShift Stub::Variable::TryRemoveTrivialPhi(AddrShift phiVal) // the phi is unreachable or in the start block same = env_->GetCircuit()->LoadGatePtr(env_->GetCircuitBuilder().UndefineConstant()); } + auto same_addr_shift = env_->GetCircuit()->SaveGatePtr(same); // remove the trivial phi // get all users of phi except self @@ -92,10 +94,15 @@ AddrShift Stub::Variable::TryRemoveTrivialPhi(AddrShift phiVal) for (auto out : outs) { if (IsSelector(out->GetGate())) { auto out_addr_shift = env_->GetCircuit()->SaveGatePtr(out->GetGate()); - TryRemoveTrivialPhi(out_addr_shift); + auto result = TryRemoveTrivialPhi(out_addr_shift); + if (same_addr_shift == out_addr_shift) + { + same_addr_shift = result; + } + } } - return env_->GetCircuit()->SaveGatePtr(same); + return same_addr_shift; } void Stub::Variable::RerouteOuts(const std::vector &outs, Gate *newGate) @@ -123,7 +130,10 @@ void LabelImpl::WriteVariable(Variable *var, AddrShift value) AddrShift LabelImpl::ReadVariable(Variable *var) { if (valueMap_.find(var) != valueMap_.end()) { - return valueMap_.at(var); + auto result = valueMap_.at(var); + if (!env_->GetCircuit()->GetOpCode(result).IsNop()) { + return result; + } } return ReadVariableRecursive(var); } @@ -859,8 +869,8 @@ AddrShift Stub::IsInternalString(AddrShift string) AddrShift Stub::IsDigit(AddrShift ch) { return TruncInt32ToInt1( - Word32And(SExtInt1ToInt32(Int32GreaterThanOrEqual(ch, GetInteger32Constant('9'))), - SExtInt1ToInt32(Int32LessThanOrEqual(ch, GetInteger32Constant('0'))))); + Word32And(SExtInt1ToInt32(Int32LessThanOrEqual(ch, GetInteger32Constant('9'))), + SExtInt1ToInt32(Int32GreaterThanOrEqual(ch, GetInteger32Constant('0'))))); } AddrShift Stub::StringToElementIndex(AddrShift string) @@ -880,7 +890,7 @@ AddrShift Stub::StringToElementIndex(AddrShift string) Branch(Int32GreaterThan(len, GetInteger32Constant(panda::ecmascript::MAX_INDEX_LEN)), &exit, &inRange); Bind(&inRange); { - AddrShift dataUtf16 = Load(POINTER_TYPE, string, GetPtrConstant(panda::ecmascript::EcmaString::GetDataOffset())); + AddrShift dataUtf16 = PtrAdd(string, GetPtrConstant(panda::ecmascript::EcmaString::GetDataOffset())); DEFVARIABLE(c, UINT32_TYPE, GetInteger32Constant(0)); Label isUtf16(env); Label isUtf8(env); @@ -889,12 +899,12 @@ AddrShift Stub::StringToElementIndex(AddrShift string) Branch(isUtf16String, &isUtf16, &isUtf8); Bind(&isUtf16); { - c = Load(INT16_TYPE, dataUtf16); + c = ZExtInt16ToInt32(Load(INT16_TYPE, dataUtf16)); Jump(&getChar1); } Bind(&isUtf8); { - c = Load(INT8_TYPE, dataUtf16); + c = ZExtInt8ToInt32(Load(INT8_TYPE, dataUtf16)); Jump(&getChar1); } Bind(&getChar1); @@ -931,25 +941,28 @@ AddrShift Stub::StringToElementIndex(AddrShift string) Branch(isUtf16String, &isUtf16, ¬Utf16); Bind(&isUtf16); { - c = Load(INT16_TYPE, dataUtf16, PtrMul(*i, GetPtrConstant(2))); + c = ZExtInt16ToInt32(Load(INT16_TYPE, dataUtf16, PtrMul(*i, GetPtrConstant(2)))); Jump(&getChar2); } Bind(¬Utf16); { - c = Load(INT8_TYPE, dataUtf16, *i); + c = ZExtInt8ToInt32(Load(INT8_TYPE, dataUtf16, *i)); Jump(&getChar2); } Bind(&getChar2); { - Label isDigit(env); - Branch(IsDigit(*c), &isDigit, &exit); - Bind(&isDigit); + Label isDigit2(env); + Label notDigit2(env); + Branch(IsDigit(*c), &isDigit2, ¬Digit2); + Bind(&isDigit2); { n = Int32Add(Int32Mul(*n, GetInteger32Constant(10)), Int32Sub(*c, GetInteger32Constant('0'))); i = Int32Add(*i, GetInteger32Constant(1)); Branch(Int32LessThan(*i, len), &loopEnd, &afterLoop); } + Bind(¬Digit2); + Jump(&exit); } } Bind(&loopEnd); @@ -957,7 +970,7 @@ AddrShift Stub::StringToElementIndex(AddrShift string) Bind(&afterLoop); { Label lessThanMaxIndex(env); - Branch(Int32LessThan(*n, GetInteger32Constant(panda::ecmascript::JSObject::MAX_ELEMENT_INDEX)), + Branch(Word32LessThan(*n, GetInteger32Constant(panda::ecmascript::JSObject::MAX_ELEMENT_INDEX)), &lessThanMaxIndex, &exit); Bind(&lessThanMaxIndex); { diff --git a/ecmascript/compiler/stub.h b/ecmascript/compiler/stub.h index d82f79c2a4..525f5566f3 100644 --- a/ecmascript/compiler/stub.h +++ b/ecmascript/compiler/stub.h @@ -751,11 +751,6 @@ public: return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT32_AND), x, y); } - AddrShift WordLogicNot(AddrShift x) - { - return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT32_REV), x); - } - AddrShift Word32LSL(AddrShift x, AddrShift y) { return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT32_LSL), x, y); @@ -819,14 +814,15 @@ public: Word64Equal(Word64And(x, GetWord64Constant(~panda::ecmascript::JSTaggedValue::TAG_SPECIAL_MASK)), GetWord64Constant(0))), WordLogicOr(SExtInt1ToInt32(Word64NotEqual( - Word64And(x, GetWord64Constant(panda::ecmascript::JSTaggedValue::TAG_SPECIAL_MASK)), + Word64And(x, GetWord64Constant(panda::ecmascript::JSTaggedValue::TAG_SPECIAL_VALUE)), GetWord64Constant(0))), SExtInt1ToInt32(TaggedIsHole(x))))); } AddrShift TaggedIsHeapObject(AddrShift x) { return TruncInt32ToInt1( - WordLogicAnd(SExtInt1ToInt32(TaggedIsObject(x)), WordLogicNot(SExtInt1ToInt32(TaggedIsSpecial(x))))); + WordLogicAnd(SExtInt1ToInt32(TaggedIsObject(x)), + SExtInt1ToInt32(Word32Equal(SExtInt1ToInt32(TaggedIsSpecial(x)), GetInteger32Constant(0))))); } AddrShift TaggedIsString(AddrShift obj); @@ -1342,6 +1338,16 @@ public: return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::ZEXT_INT1_TO_INT32), x); } + AddrShift ZExtInt8ToInt32(AddrShift x) + { + return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::ZEXT_INT8_TO_INT32), x); + } + + AddrShift ZExtInt16ToInt32(AddrShift x) + { + return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::ZEXT_INT16_TO_INT32), x); + } + AddrShift TruncInt64ToInt32(AddrShift x) { return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::TRUNC_INT64_TO_INT32), x); diff --git a/ecmascript/compiler/tests/stub_tests.cpp b/ecmascript/compiler/tests/stub_tests.cpp index 59acabb7b7..bd5e71d718 100644 --- a/ecmascript/compiler/tests/stub_tests.cpp +++ b/ecmascript/compiler/tests/stub_tests.cpp @@ -1322,12 +1322,31 @@ HWTEST_F_L0(StubTest, FastModTest) HWTEST_F_L0(StubTest, FastGetPropertyByValueStub) { auto module = stubModule.GetModule(); + LLVMValueRef getPropertyByIndexfunction = LLVMGetNamedFunction(module, "GetPropertyByIndex"); + Circuit netOfGates2; + FastGetPropertyByIndexStub getPropertyByIndexStub(&netOfGates2); + getPropertyByIndexStub.GenerateCircuit(); + netOfGates2.PrintAllGates(); + auto cfg2 = Scheduler::Run(&netOfGates2); + LLVMIRBuilder llvmBuilder2(&cfg2, &netOfGates2, &stubModule, getPropertyByIndexfunction); + llvmBuilder2.Build(); + + LLVMValueRef getPropertyByNamefunction = LLVMGetNamedFunction(module, "GetPropertyByName"); + Circuit netOfGates1; + FastGetPropertyByNameStub getPropertyByNameStub(&netOfGates1); + getPropertyByNameStub.GenerateCircuit(); + bool result = Verifier::Run(&netOfGates1); + ASSERT_TRUE(result); + auto cfg1 = Scheduler::Run(&netOfGates1); + LLVMIRBuilder llvmBuilder1(&cfg1, &netOfGates1, &stubModule, getPropertyByNamefunction); + llvmBuilder1.Build(); + LLVMValueRef function = LLVMGetNamedFunction(module, "GetPropertyByValue"); Circuit netOfGates; FastGetPropertyByValueStub optimizer(&netOfGates); optimizer.GenerateCircuit(); netOfGates.PrintAllGates(); - bool result = Verifier::Run(&netOfGates); + result = Verifier::Run(&netOfGates); ASSERT_TRUE(result); auto cfg = Scheduler::Run(&netOfGates); for (size_t bbIdx = 0; bbIdx < cfg.size(); bbIdx++) { @@ -1344,19 +1363,39 @@ HWTEST_F_L0(StubTest, FastGetPropertyByValueStub) auto engine = assembler.GetEngine(); auto *getPropertyByValuePtr = reinterpret_cast( reinterpret_cast(LLVMGetPointerToGlobal(engine, function))); + auto *getPropertyByNamePtr = reinterpret_cast( + reinterpret_cast(LLVMGetPointerToGlobal(engine, getPropertyByNamefunction))); + auto *getpropertyByIndexPtr = reinterpret_cast( + reinterpret_cast(LLVMGetPointerToGlobal(engine, getPropertyByIndexfunction))); auto *factory = JSThread::Cast(thread)->GetEcmaVM()->GetFactory(); JSHandle obj = factory->NewEmptyJSObject(); int x = 213; int y = 10; + + FastRuntimeStub::SetOwnElement(thread, obj.GetTaggedValue(), 1, JSTaggedValue(x)); + FastRuntimeStub::SetOwnElement(thread, obj.GetTaggedValue(), 10250, JSTaggedValue(y)); + JSHandle strA(factory->NewFromCanBeCompressString("a")); JSHandle strBig(factory->NewFromCanBeCompressString("biggest")); + JSHandle strDigit(factory->NewFromCanBeCompressString("10250")); + FastRuntimeStub::SetPropertyByName(thread, obj.GetTaggedValue(), strA.GetTaggedValue(), JSTaggedValue(x)); FastRuntimeStub::SetPropertyByName(thread, obj.GetTaggedValue(), strBig.GetTaggedValue(), JSTaggedValue(y)); assembler.Disassemble(); + + JSTaggedValue resVal1 = getPropertyByNamePtr(thread, obj.GetTaggedValue().GetRawData(), + strA.GetTaggedValue().GetRawData()); + EXPECT_EQ(resVal1.GetNumber(), x); JSTaggedValue resVal = getPropertyByValuePtr(thread, obj.GetTaggedValue().GetRawData(), strA.GetTaggedValue().GetRawData()); EXPECT_EQ(resVal.GetNumber(), x); resVal = getPropertyByValuePtr(thread, obj.GetTaggedValue().GetRawData(), strBig.GetTaggedValue().GetRawData()); EXPECT_EQ(resVal.GetNumber(), y); + resVal = getpropertyByIndexPtr(thread, obj.GetTaggedValue(), 1); + EXPECT_EQ(resVal.GetNumber(), x); + resVal = getPropertyByValuePtr(thread, obj.GetTaggedValue().GetRawData(), JSTaggedValue(10250).GetRawData()); + EXPECT_EQ(resVal.GetNumber(), y); + resVal = getPropertyByValuePtr(thread, obj.GetTaggedValue().GetRawData(), strDigit.GetTaggedValue().GetRawData()); + EXPECT_EQ(resVal.GetNumber(), y); } } // namespace panda::test -- Gitee