description:ECMA 2022规范支持TaggedArray.At

Signed-off-by: zha.wei <zhawei@kaihong.com>
This commit is contained in:
zha.wei 2023-06-27 21:09:25 +08:00
parent f34644dd71
commit f8e4c5ea4a
4 changed files with 92 additions and 0 deletions

View File

@ -2935,6 +2935,9 @@ JSTaggedValue BuiltinsArray::At(EcmaRuntimeCallInfo *argv)
// 1. Let O be ToObject(this value).
JSHandle<JSTaggedValue> thisHandle = GetThis(argv);
if (thisHandle->IsStableJSArray(thread)) {
return JSStableArray::At(JSHandle<JSArray>::Cast(thisHandle), argv);
}
JSHandle<JSObject> thisObjHandle = JSTaggedValue::ToObject(thread, thisHandle);
// ReturnIfAbrupt(O).
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);

View File

@ -658,4 +658,29 @@ JSTaggedValue JSStableArray::FastCopyFromArrayToTypedArray(JSThread *thread, JSH
}
return JSTaggedValue::Undefined();
}
JSTaggedValue JSStableArray::At(JSHandle<JSArray> 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<JSTaggedValue> taggedValue = JSArray::FastGetPropertyByValue(thread, JSHandle<JSTaggedValue>(receiver), k);
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
return taggedValue.GetTaggedValue();
}
} // namespace panda::ecmascript

View File

@ -53,6 +53,7 @@ public:
static JSTaggedValue FastCopyFromArrayToTypedArray(JSThread *thread, JSHandle<JSTypedArray> &target,
DataViewType targetType, uint32_t targetOffset,
uint32_t srcLength, JSHandle<TaggedArray> &elements);
static JSTaggedValue At(JSHandle<JSArray> receiver, EcmaRuntimeCallInfo *argv);
};
} // namespace panda::ecmascript
#endif // ECMASCRIPT_JS_STABLE_ARRAY_H

View File

@ -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<TaggedArray> handleTagArr(objFactory->NewTaggedArray(lengthArr));
for (int i = 0; i < lengthArr; i++) {
handleTagArr->Set(thread, i, JSTaggedValue(i));
}
JSHandle<JSArray> 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