!4330 支持ECMA2022规范新增Ark内部TaggedArray.At方法

Merge pull request !4330 from 查维/master
This commit is contained in:
openharmony_ci 2023-07-08 15:23:45 +00:00 committed by Gitee
commit 8bdcc56691
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
6 changed files with 108 additions and 1 deletions

View File

@ -2936,6 +2936,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,30 @@ 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();
}
TaggedArray *elements = TaggedArray::Cast(receiver->GetElements().GetTaggedObject());
auto result = JSTaggedValue::Hole();
result = elements->Get(k);
return result.IsHole() ? JSTaggedValue::Undefined() : result;
}
} // 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

View File

@ -134,4 +134,12 @@ try {
print(v21);
} catch (error) {
}
}
var arr21 = [1,2,3,4,,6];
print(arr21.at(0));
print(arr21.at(5));
print(arr21.at(-1));
print(arr21.at(6));
print(arr21.at('1.9'));
print(arr21.at(true));

View File

@ -69,3 +69,9 @@ undefined
-1
The NewTarget is undefined
undefined
1
6
6
undefined
2
2