From f8e4c5ea4abf30bb92da8a5cf4cd8e5b0ad9b110 Mon Sep 17 00:00:00 2001 From: "zha.wei" Date: Tue, 27 Jun 2023 21:09:25 +0800 Subject: [PATCH] =?UTF-8?q?description:ECMA=202022=E8=A7=84=E8=8C=83?= =?UTF-8?q?=E6=94=AF=E6=8C=81TaggedArray.At?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zha.wei --- ecmascript/builtins/builtins_array.cpp | 3 ++ ecmascript/js_stable_array.cpp | 25 +++++++++ ecmascript/js_stable_array.h | 1 + ecmascript/tests/js_stable_array_test.cpp | 63 +++++++++++++++++++++++ 4 files changed, 92 insertions(+) diff --git a/ecmascript/builtins/builtins_array.cpp b/ecmascript/builtins/builtins_array.cpp index e82fa47d7c..83c20baf1e 100644 --- a/ecmascript/builtins/builtins_array.cpp +++ b/ecmascript/builtins/builtins_array.cpp @@ -2935,6 +2935,9 @@ JSTaggedValue BuiltinsArray::At(EcmaRuntimeCallInfo *argv) // 1. Let O be ToObject(this value). JSHandle thisHandle = GetThis(argv); + if (thisHandle->IsStableJSArray(thread)) { + return JSStableArray::At(JSHandle::Cast(thisHandle), argv); + } JSHandle thisObjHandle = JSTaggedValue::ToObject(thread, thisHandle); // ReturnIfAbrupt(O). RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); diff --git a/ecmascript/js_stable_array.cpp b/ecmascript/js_stable_array.cpp index 94f85eb807..8ec6c3e940 100644 --- a/ecmascript/js_stable_array.cpp +++ b/ecmascript/js_stable_array.cpp @@ -658,4 +658,29 @@ JSTaggedValue JSStableArray::FastCopyFromArrayToTypedArray(JSThread *thread, JSH } return JSTaggedValue::Undefined(); } + +JSTaggedValue JSStableArray::At(JSHandle receiver, EcmaRuntimeCallInfo *argv) +{ + JSThread *thread = argv->GetThread(); + uint32_t thisLen = receiver->GetArrayLength(); + if (thisLen == 0) { + return JSTaggedValue::Undefined(); + } + JSTaggedNumber index = JSTaggedValue::ToInteger(thread, base::BuiltinsBase::GetCallArg(argv, 0)); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + int64_t relativeIndex = index.GetNumber(); + int64_t k = 0; + if (relativeIndex >= 0) { + k = relativeIndex; + } else { + k = thisLen + relativeIndex; + } + if (k < 0 || k >= thisLen) { + return JSTaggedValue::Undefined(); + } + + JSHandle taggedValue = JSArray::FastGetPropertyByValue(thread, JSHandle(receiver), k); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + return taggedValue.GetTaggedValue(); +} } // namespace panda::ecmascript diff --git a/ecmascript/js_stable_array.h b/ecmascript/js_stable_array.h index 48da8cb0ff..96e59ffc95 100644 --- a/ecmascript/js_stable_array.h +++ b/ecmascript/js_stable_array.h @@ -53,6 +53,7 @@ public: static JSTaggedValue FastCopyFromArrayToTypedArray(JSThread *thread, JSHandle &target, DataViewType targetType, uint32_t targetOffset, uint32_t srcLength, JSHandle &elements); + static JSTaggedValue At(JSHandle receiver, EcmaRuntimeCallInfo *argv); }; } // namespace panda::ecmascript #endif // ECMASCRIPT_JS_STABLE_ARRAY_H diff --git a/ecmascript/tests/js_stable_array_test.cpp b/ecmascript/tests/js_stable_array_test.cpp index f9edeccf32..93dade9590 100644 --- a/ecmascript/tests/js_stable_array_test.cpp +++ b/ecmascript/tests/js_stable_array_test.cpp @@ -342,4 +342,67 @@ HWTEST_F_L0(JSStableArrayTest, Join_StringElements_DefinedSep) EXPECT_STREQ(EcmaStringAccessor(handleEcmaStrRet).ToCString().c_str(), "a <> a <> a <> a <> a <> a <> a <> a <> a <> a"); } + +/** + * @tc.name: At + * @tc.desc: Create a source Array whose elements are Numbers and an EcmaRuntimeCallInfo, define the first arg of the + EcmaRuntimeCallInfo an number as the index, check whether the element returned through calling + At function with the source Array and the EcmaRuntimeCallInfo is within expectations. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F_L0(JSStableArrayTest, At_NUMBER_INDEX) +{ + ObjectFactory *objFactory = thread->GetEcmaVM()->GetFactory(); + + int32_t lengthArr = 10; + JSHandle handleTagArr(objFactory->NewTaggedArray(lengthArr)); + for (int i = 0; i < lengthArr; i++) { + handleTagArr->Set(thread, i, JSTaggedValue(i)); + } + JSHandle handleArr(JSArray::CreateArrayFromList(thread, handleTagArr)); + auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); + ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); + ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); + ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(0)); + [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo); + + JSTaggedValue thisTagValue = JSStableArray::At(handleArr, ecmaRuntimeCallInfo); + TestHelper::TearDownFrame(thread, prev); + + EXPECT_EQ(thisTagValue.GetNumber(), 0); + + ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); + ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); + ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); + ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(9)); + prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo); + + thisTagValue = JSStableArray::At(handleArr, ecmaRuntimeCallInfo); + TestHelper::TearDownFrame(thread, prev); + + EXPECT_EQ(thisTagValue.GetNumber(), 9); + + ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); + ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); + ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); + ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(-1)); + prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo); + + thisTagValue = JSStableArray::At(handleArr, ecmaRuntimeCallInfo); + TestHelper::TearDownFrame(thread, prev); + + EXPECT_EQ(thisTagValue.GetNumber(), 9); + + ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); + ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); + ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); + ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(10)); + prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo); + + thisTagValue = JSStableArray::At(handleArr, ecmaRuntimeCallInfo); + TestHelper::TearDownFrame(thread, prev); + + EXPECT_EQ(thisTagValue, JSTaggedValue::Undefined()); +} } // namespace panda::test \ No newline at end of file