mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2025-04-12 20:59:19 +00:00
Optimized sendable array Api
Optimized sendable array Api Issue: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/IBFW53?from=project-issue Signed-off-by: 18157154025 <liuhongchen5@huawei.com> Change-Id: Ie5f2d6358cdc38a31fca41351bf83c08875447bb
This commit is contained in:
parent
ac36ea29bf
commit
18a2224ccf
@ -1311,7 +1311,7 @@ JSTaggedValue BuiltinsArray::Join(EcmaRuntimeCallInfo *argv)
|
||||
return factory->GetEmptyString().GetTaggedValue();
|
||||
}
|
||||
if (thisHandle->IsStableJSArray(thread)) {
|
||||
return JSStableArray::Join(JSHandle<JSArray>::Cast(thisHandle), argv);
|
||||
return JSStableArray::Join(thisHandle, argv);
|
||||
}
|
||||
|
||||
// 1. Let O be ToObject(this value).
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "ecmascript/js_map_iterator.h"
|
||||
#include "ecmascript/js_stable_array.h"
|
||||
#include "ecmascript/object_fast_operator-inl.h"
|
||||
#include "ecmascript/base/sort_helper.h"
|
||||
|
||||
namespace panda::ecmascript::builtins {
|
||||
namespace {
|
||||
@ -96,6 +97,121 @@ JSTaggedValue BuiltinsSharedArray::ArrayConstructor(EcmaRuntimeCallInfo *argv)
|
||||
return newArrayHandle.GetTaggedValue();
|
||||
}
|
||||
|
||||
JSTaggedValue BuiltinsSharedArray::FromArrayNoMaping(JSThread *thread, const JSHandle<JSTaggedValue>& items,
|
||||
JSHandle<JSObject>& newArrayHandle)
|
||||
{
|
||||
JSHandle<JSObject> arrayLikeObj = JSTaggedValue::ToObject(thread, items);
|
||||
JSHandle<JSTaggedValue> arrayLike(arrayLikeObj) ;
|
||||
int64_t len = ArrayHelper::GetArrayLength(thread, arrayLike);
|
||||
int k = 0;
|
||||
JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
|
||||
JSMutableHandle<JSTaggedValue> mapValue(thread, JSTaggedValue::Undefined());
|
||||
|
||||
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
|
||||
JSHandle<TaggedArray> eleArray = factory->NewTaggedArray(len, JSTaggedValue::Undefined(),
|
||||
MemSpaceType::SHARED_OLD_SPACE);
|
||||
while (k < len) {
|
||||
mapValue.Update(JSArray::FastGetPropertyByValue(thread, arrayLike, k));
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
|
||||
if (!mapValue->IsSharedType()) {
|
||||
auto error = ContainerError::ParamError(thread, "Parameter error.Only accept sendable value.");
|
||||
THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
|
||||
}
|
||||
|
||||
eleArray->Set(thread, k, mapValue);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
k++;
|
||||
thread->CheckSafepointIfSuspended();
|
||||
}
|
||||
newArrayHandle->SetElements(thread, eleArray);
|
||||
JSSharedArray::Cast(*newArrayHandle)->SetArrayLength(thread, k);
|
||||
return newArrayHandle.GetTaggedValue();
|
||||
}
|
||||
|
||||
template<bool itemIsSharedArray>
|
||||
JSTaggedValue BuiltinsSharedArray::FromArray(JSThread *thread, const JSHandle<JSTaggedValue>& items,
|
||||
const JSHandle<JSTaggedValue>& thisArgHandle,
|
||||
const JSHandle<JSTaggedValue> mapfn,
|
||||
JSHandle<JSObject>& newArrayHandle)
|
||||
{
|
||||
JSHandle<JSObject> arrayLikeObj = JSTaggedValue::ToObject(thread, items);
|
||||
JSHandle<JSTaggedValue> arrayLike(arrayLikeObj) ;
|
||||
int64_t len = ArrayHelper::GetArrayLength(thread, arrayLike);
|
||||
int k = 0;
|
||||
JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
|
||||
JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
|
||||
CVector<JSHandle<JSTaggedValue>> valueVec(0);
|
||||
valueVec.reserve(len);
|
||||
JSMutableHandle<JSTaggedValue> mapValue(thread, JSTaggedValue::Undefined());
|
||||
while (k < len) {
|
||||
if constexpr (itemIsSharedArray) {
|
||||
mapValue.Update(ElementAccessor::Get(thread, arrayLikeObj, k));
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
} else {
|
||||
mapValue.Update(JSArray::FastGetPropertyByValue(thread, arrayLike, k));
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
}
|
||||
|
||||
key.Update(JSTaggedValue(k));
|
||||
const uint32_t argsLength = 2; // 2: «kValue, k»
|
||||
EcmaRuntimeCallInfo *info =
|
||||
EcmaInterpreter::NewRuntimeCallInfo(thread, mapfn, thisArgHandle, undefined, argsLength);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
info->SetCallArg(mapValue.GetTaggedValue(), key.GetTaggedValue());
|
||||
JSTaggedValue callResult = JSFunction::Call(info);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
JSHandle<JSTaggedValue> result = JSHandle<JSTaggedValue>(thread, callResult);
|
||||
len = ArrayHelper::GetArrayLength(thread, arrayLike);
|
||||
|
||||
if (!result->IsSharedType()) {
|
||||
auto error = ContainerError::ParamError(thread, "Parameter error.Only accept sendable value.");
|
||||
THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
|
||||
}
|
||||
|
||||
valueVec.push_back(result);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
k++;
|
||||
thread->CheckSafepointIfSuspended();
|
||||
}
|
||||
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
|
||||
JSHandle<TaggedArray> eleArray = factory->NewTaggedArray(k, JSTaggedValue::Undefined(),
|
||||
MemSpaceType::SHARED_OLD_SPACE);
|
||||
for (int idx = 0; idx < k; ++idx) {
|
||||
eleArray->Set(thread, idx, valueVec[idx]);
|
||||
}
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
newArrayHandle->SetElements(thread, eleArray);
|
||||
JSSharedArray::Cast(*newArrayHandle)->SetArrayLength(thread, k);
|
||||
return newArrayHandle.GetTaggedValue();
|
||||
}
|
||||
|
||||
template JSTaggedValue BuiltinsSharedArray::FromArray<true>(JSThread *thread, const JSHandle<JSTaggedValue>& items,
|
||||
const JSHandle<JSTaggedValue>& thisArgHandle,
|
||||
const JSHandle<JSTaggedValue> mapfn,
|
||||
JSHandle<JSObject>& newArrayHandle);
|
||||
|
||||
template JSTaggedValue BuiltinsSharedArray::FromArray<false>(JSThread *thread, const JSHandle<JSTaggedValue>& items,
|
||||
const JSHandle<JSTaggedValue>& thisArgHandle,
|
||||
const JSHandle<JSTaggedValue> mapfn,
|
||||
JSHandle<JSObject>& newArrayHandle);
|
||||
|
||||
JSTaggedValue BuiltinsSharedArray::FromSharedArray(JSThread *thread, const JSHandle<JSTaggedValue>& items,
|
||||
JSHandle<JSObject>& newArrayHandle)
|
||||
{
|
||||
int64_t len = ArrayHelper::GetLength(thread, items);
|
||||
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
|
||||
JSHandle<TaggedArray> eleArray = factory->NewTaggedArray(len, JSTaggedValue::Undefined(),
|
||||
MemSpaceType::SHARED_OLD_SPACE);
|
||||
JSHandle<JSObject> thisObjHandle = JSTaggedValue::ToObject(thread, items);
|
||||
TaggedArray *element = TaggedArray::Cast(thisObjHandle->GetElements().GetTaggedObject());
|
||||
eleArray->Copy(thread, 0, 0, element, len);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
newArrayHandle->SetElements(thread, eleArray);
|
||||
JSSharedArray::Cast(*newArrayHandle)->SetArrayLength(thread, len);
|
||||
return newArrayHandle.GetTaggedValue();
|
||||
}
|
||||
|
||||
// 22.1.2.1 Array.from ( items [ , mapfn [ , thisArg ] ] )
|
||||
// NOLINTNEXTLINE(readability-function-size)
|
||||
JSTaggedValue BuiltinsSharedArray::From(EcmaRuntimeCallInfo *argv)
|
||||
@ -109,9 +225,9 @@ JSTaggedValue BuiltinsSharedArray::From(EcmaRuntimeCallInfo *argv)
|
||||
// 2. If mapfn is undefined, let mapping be false.
|
||||
bool mapping = false;
|
||||
// 3. else
|
||||
// a. If IsCallable(mapfn) is false, throw a TypeError exception.
|
||||
// b. If thisArg was supplied, let T be thisArg; else let T be undefined.
|
||||
// c. Let mapping be true
|
||||
// a. If IsCallable(mapfn) is false, throw a TypeError exception.
|
||||
// b. If thisArg was supplied, let T be thisArg; else let T be undefined.
|
||||
// c. Let mapping be true
|
||||
JSHandle<JSTaggedValue> thisArgHandle = GetCallArg(argv, INDEX_TWO);
|
||||
JSHandle<JSTaggedValue> mapfn = GetCallArg(argv, 1);
|
||||
if (!mapfn->IsUndefined()) {
|
||||
@ -142,6 +258,7 @@ JSTaggedValue BuiltinsSharedArray::From(EcmaRuntimeCallInfo *argv)
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
// 6. If usingIterator is not undefined, then
|
||||
JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
|
||||
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
|
||||
if (!usingIterator->IsUndefined()) {
|
||||
// Fast path for MapIterator
|
||||
JSHandle<JSTaggedValue> iterator(thread, JSTaggedValue::Hole());
|
||||
@ -182,6 +299,23 @@ JSTaggedValue BuiltinsSharedArray::From(EcmaRuntimeCallInfo *argv)
|
||||
// g. Repeat
|
||||
JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
|
||||
JSMutableHandle<JSTaggedValue> mapValue(thread, JSTaggedValue::Undefined());
|
||||
// fastpath for jsarray
|
||||
if ((items->IsJSArray() && iterator->IsJSArrayIterator())) {
|
||||
if (mapping) {
|
||||
return BuiltinsSharedArray::FromArray<false>(thread, items, thisArgHandle, mapfn, newArrayHandle);
|
||||
} else {
|
||||
return BuiltinsSharedArray::FromArrayNoMaping(thread, items, newArrayHandle);
|
||||
}
|
||||
}
|
||||
|
||||
if (items->IsJSSharedArray()) {
|
||||
if (mapping) {
|
||||
return BuiltinsSharedArray::FromArray<true>(thread, items, thisArgHandle, mapfn, newArrayHandle);
|
||||
} else {
|
||||
return BuiltinsSharedArray::FromSharedArray(thread, items, newArrayHandle);
|
||||
}
|
||||
}
|
||||
|
||||
while (true) {
|
||||
key.Update(JSTaggedValue(k));
|
||||
// i. Let Pk be ToString(k).
|
||||
@ -277,6 +411,8 @@ JSTaggedValue BuiltinsSharedArray::From(EcmaRuntimeCallInfo *argv)
|
||||
JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
|
||||
JSMutableHandle<JSTaggedValue> mapValue(thread, JSTaggedValue::Undefined());
|
||||
int64_t k = 0;
|
||||
JSHandle<TaggedArray> eleArray = factory->NewTaggedArray(len, JSTaggedValue::Undefined(),
|
||||
MemSpaceType::SHARED_OLD_SPACE);
|
||||
while (k < len) {
|
||||
JSHandle<JSTaggedValue> kValue = JSSharedArray::FastGetPropertyByValue(thread, arrayLike, k);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
@ -297,13 +433,13 @@ JSTaggedValue BuiltinsSharedArray::From(EcmaRuntimeCallInfo *argv)
|
||||
auto error = ContainerError::ParamError(thread, "Parameter error.Only accept sendable value.");
|
||||
THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
|
||||
}
|
||||
JSObject::CreateDataPropertyOrThrow(thread, newArrayHandle, k, mapValue, SCheckMode::SKIP);
|
||||
eleArray->Set(thread, k, mapValue);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
k++;
|
||||
}
|
||||
newArrayHandle->SetElements(thread, eleArray);
|
||||
// 17. Let setStatus be Set(A, "length", len, true).
|
||||
JSHandle<JSTaggedValue> lenHandle(thread, JSTaggedValue(len));
|
||||
JSSharedArray::LengthSetter(thread, newArrayHandle, lenHandle, true);
|
||||
JSSharedArray::Cast(*newArrayHandle)->SetArrayLength(thread, len);
|
||||
newArrayHandle->GetJSHClass()->SetExtensible(false);
|
||||
// 18. ReturnIfAbrupt(setStatus).
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
@ -703,9 +839,9 @@ JSTaggedValue BuiltinsSharedArray::Fill(EcmaRuntimeCallInfo *argv)
|
||||
// d. Increase k by 1.
|
||||
int64_t k = start;
|
||||
JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
|
||||
TaggedArray *elements = TaggedArray::Cast(thisObjHandle->GetElements().GetTaggedObject());
|
||||
while (k < end) {
|
||||
BuiltinsSharedArray::SetElementValue(thread, thisObjHandle, k, value);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
elements->Set(thread, k, value);
|
||||
k++;
|
||||
}
|
||||
|
||||
@ -714,7 +850,7 @@ JSTaggedValue BuiltinsSharedArray::Fill(EcmaRuntimeCallInfo *argv)
|
||||
}
|
||||
|
||||
JSTaggedValue BuiltinsSharedArray::FilterArray(JSThread *thread, JSHandle<JSTaggedValue> &thisArgHandle,
|
||||
JSHandle<JSTaggedValue> &thisObjVal, JSHandle<JSObject> newArrayHandle,
|
||||
JSHandle<JSTaggedValue> &thisObjVal, JSHandle<JSObject>& newArrayHandle,
|
||||
JSHandle<JSTaggedValue> &callbackFnHandle)
|
||||
{
|
||||
JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
|
||||
@ -730,24 +866,33 @@ JSTaggedValue BuiltinsSharedArray::FilterArray(JSThread *thread, JSHandle<JSTagg
|
||||
uint32_t toIndex = 0;
|
||||
JSHandle<JSObject> thisObjHandle = JSTaggedValue::ToObject(thread, thisObjVal);
|
||||
JSMutableHandle<JSTaggedValue> kValue(thread, JSTaggedValue::Undefined());
|
||||
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
|
||||
JSHandle<TaggedArray> eleArray = factory->NewTaggedArray(len, JSTaggedValue::Undefined(),
|
||||
MemSpaceType::SHARED_OLD_SPACE);
|
||||
while (k < len) {
|
||||
kValue.Update(BuiltinsSharedArray::GetElementByKey(thread, thisObjHandle, k));
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
key.Update(JSTaggedValue(k));
|
||||
EcmaRuntimeCallInfo *info =
|
||||
EcmaInterpreter::NewRuntimeCallInfo(thread, callbackFnHandle, thisArgHandle, undefined, argsLength);
|
||||
EcmaInterpreter::NewRuntimeCallInfo(thread, callbackFnHandle, thisArgHandle, undefined, argsLength);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
info->SetCallArg(kValue.GetTaggedValue(), key.GetTaggedValue(), thisObjVal.GetTaggedValue());
|
||||
callResult = JSFunction::Call(info);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
if (callResult.ToBoolean()) {
|
||||
toIndexHandle.Update(JSTaggedValue(toIndex));
|
||||
JSObject::CreateDataPropertyOrThrow(thread, newArrayHandle, toIndexHandle, kValue, SCheckMode::SKIP);
|
||||
eleArray->Set(thread, toIndex, kValue);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
toIndex++;
|
||||
}
|
||||
k++;
|
||||
}
|
||||
|
||||
newArrayHandle->SetElements(thread, eleArray);
|
||||
if (TaggedArray::ShouldTrim(len, toIndex)) {
|
||||
eleArray->Trim(thread, toIndex);
|
||||
}
|
||||
JSSharedArray::Cast(*newArrayHandle)->SetArrayLength(thread, toIndex);
|
||||
|
||||
return newArrayHandle.GetTaggedValue();
|
||||
}
|
||||
|
||||
@ -1065,6 +1210,35 @@ JSTaggedValue BuiltinsSharedArray::IndexOfSlowPath(
|
||||
return JSTaggedValue(-1);
|
||||
}
|
||||
|
||||
JSTaggedValue BuiltinsSharedArray::IndexOfStable(EcmaRuntimeCallInfo *argv, JSThread *thread,
|
||||
const JSHandle<JSTaggedValue> &thisHandle)
|
||||
{
|
||||
int64_t length = ArrayHelper::GetArrayLength(thread, thisHandle);
|
||||
if (length == 0) {
|
||||
return JSTaggedValue(-1);
|
||||
}
|
||||
int64_t fromIndex = 0;
|
||||
uint32_t argc = argv->GetArgsNumber();
|
||||
// 2: [target, fromIndex]. Note that fromIndex is missing in most usage cases.
|
||||
if (UNLIKELY(argc >= 2)) {
|
||||
JSHandle<JSTaggedValue> fromIndexHandle = argv->GetCallArg(1);
|
||||
fromIndex = ArrayHelper::GetStartIndex(thread, fromIndexHandle, length);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
// Slow path when fromIndex is obtained from an ECMAObject
|
||||
// due to potential side effects in its 'toString' and 'valueOf' methods which modify the array object.
|
||||
if (UNLIKELY(fromIndexHandle->IsECMAObject())) {
|
||||
return IndexOfSlowPath(argv, thread, thisHandle, length, fromIndex);
|
||||
}
|
||||
}
|
||||
if (fromIndex >= length) {
|
||||
return JSTaggedValue(-1);
|
||||
}
|
||||
|
||||
JSHandle<JSTaggedValue> target = GetCallArg(argv, 0);
|
||||
return JSStableArray::IndexOf(
|
||||
thread, thisHandle, target, static_cast<uint32_t>(fromIndex), static_cast<uint32_t>(length));
|
||||
}
|
||||
|
||||
// 22.1.3.11 Array.prototype.indexOf ( searchElement [ , fromIndex ] )
|
||||
JSTaggedValue BuiltinsSharedArray::IndexOf(EcmaRuntimeCallInfo *argv)
|
||||
{
|
||||
@ -1078,7 +1252,7 @@ JSTaggedValue BuiltinsSharedArray::IndexOf(EcmaRuntimeCallInfo *argv)
|
||||
|
||||
[[maybe_unused]] ConcurrentApiScope<JSSharedArray> scope(thread, thisHandle);
|
||||
|
||||
return IndexOfSlowPath(argv, thread, thisHandle);
|
||||
return IndexOfStable(argv, thread, thisHandle);
|
||||
}
|
||||
|
||||
// 22.1.3.12 Array.prototype.join (separator)
|
||||
@ -1092,8 +1266,8 @@ JSTaggedValue BuiltinsSharedArray::Join(EcmaRuntimeCallInfo *argv)
|
||||
|
||||
[[maybe_unused]] ConcurrentApiScope<JSSharedArray> scope(thread, thisHandle);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
auto opResult = BuiltinsArray::Join(argv);
|
||||
return opResult;
|
||||
|
||||
return JSStableArray::Join(thisHandle, argv);
|
||||
}
|
||||
|
||||
// 22.1.3.13 Array.prototype.keys ( )
|
||||
@ -1257,7 +1431,8 @@ JSTaggedValue BuiltinsSharedArray::PopInner(EcmaRuntimeCallInfo *argv, JSHandle<
|
||||
// h. ReturnIfAbrupt(setStatus).
|
||||
// i. Return element.
|
||||
int64_t newLen = len - 1;
|
||||
JSHandle<JSTaggedValue> element(thread, BuiltinsSharedArray::GetElementByKey(thread, thisObjHandle, newLen));
|
||||
JSHandle<JSTaggedValue> element(thread, ElementAccessor::Get(thread, thisObjHandle, newLen));
|
||||
// BuiltinsSharedArray::GetElementByKey(thread, thisObjHandle, newLen));
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
uint32_t capacity = ElementAccessor::GetElementsLength(thisObjHandle);
|
||||
if (TaggedArray::ShouldTrim(capacity, newLen)) {
|
||||
@ -1265,8 +1440,7 @@ JSTaggedValue BuiltinsSharedArray::PopInner(EcmaRuntimeCallInfo *argv, JSHandle<
|
||||
elements->Trim(thread, newLen);
|
||||
}
|
||||
|
||||
JSHandle<JSTaggedValue> indexHandle(thread, JSTaggedValue(newLen));
|
||||
JSSharedArray::LengthSetter(thread, thisObjHandle, indexHandle, true);
|
||||
JSSharedArray::Cast(*thisObjHandle)->SetArrayLength(thread, newLen);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
|
||||
return element.GetTaggedValue();
|
||||
@ -1303,8 +1477,9 @@ JSTaggedValue BuiltinsSharedArray::Push(EcmaRuntimeCallInfo *argv)
|
||||
}
|
||||
|
||||
uint32_t newLength = argc + len;
|
||||
TaggedArray *element = TaggedArray::Cast(thisObjHandle->GetElements().GetTaggedObject());
|
||||
if (newLength > ElementAccessor::GetElementsLength(thisObjHandle)) {
|
||||
JSObject::GrowElementsCapacity(thread, thisObjHandle, newLength, true);
|
||||
element = *JSObject::GrowElementsCapacity(thread, thisObjHandle, newLength, true);
|
||||
}
|
||||
|
||||
// 8. Repeat, while items is not empty
|
||||
@ -1319,15 +1494,13 @@ JSTaggedValue BuiltinsSharedArray::Push(EcmaRuntimeCallInfo *argv)
|
||||
auto error = ContainerError::ParamError(thread, "Parameter error.Only accept sendable value.");
|
||||
THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
|
||||
}
|
||||
BuiltinsSharedArray::SetElementValue(thread, thisObjHandle, len, kValue);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
element->Set(thread, len, kValue);
|
||||
k++;
|
||||
len++;
|
||||
}
|
||||
|
||||
// 9. Let setStatus be Set(O, "length", len, true).
|
||||
JSHandle<JSTaggedValue> key(thread, JSTaggedValue(len));
|
||||
JSSharedArray::LengthSetter(thread, thisObjHandle, key, true);
|
||||
JSSharedArray::Cast(*thisObjHandle)->SetArrayLength(thread, len);
|
||||
// 10. ReturnIfAbrupt(setStatus).
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
|
||||
@ -1471,18 +1644,19 @@ JSTaggedValue BuiltinsSharedArray::Shift(EcmaRuntimeCallInfo *argv)
|
||||
// i. Let deleteStatus be DeletePropertyOrThrow(O, to).
|
||||
// ii. ReturnIfAbrupt(deleteStatus).
|
||||
// g. Increase k by 1.
|
||||
JSMutableHandle<JSTaggedValue> fromValue(thread, JSTaggedValue::Undefined());
|
||||
int64_t k = 1;
|
||||
while (k < len) {
|
||||
fromValue.Update(BuiltinsSharedArray::GetElementByKey(thread, thisObjHandle, k));
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
BuiltinsSharedArray::SetElementValue(thread, thisObjHandle, k - 1, fromValue);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
k++;
|
||||
TaggedArray *element = TaggedArray::Cast(thisObjHandle->GetElements().GetTaggedObject());
|
||||
int64_t newLen = len - 1;
|
||||
element->Copy<true, true>(thread, 0, 1, element, newLen);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
|
||||
uint32_t capacity = ElementAccessor::GetElementsLength(thisObjHandle);
|
||||
if (TaggedArray::ShouldTrim(capacity, newLen)) {
|
||||
TaggedArray *elements = TaggedArray::Cast(thisObjHandle->GetElements().GetTaggedObject());
|
||||
elements->Trim(thread, newLen);
|
||||
}
|
||||
|
||||
// 12. Let setStatus be Set(O, "length", len–1, true).
|
||||
JSHandle<JSTaggedValue> newLenHandle(thread, JSTaggedValue(len - 1));
|
||||
JSHandle<JSTaggedValue> newLenHandle(thread, JSTaggedValue(newLen));
|
||||
JSSharedArray::LengthSetter(thread, thisObjHandle, newLenHandle, true);
|
||||
// 13. ReturnIfAbrupt(setStatus).
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
@ -1595,13 +1769,8 @@ JSTaggedValue BuiltinsSharedArray::Sort(EcmaRuntimeCallInfo *argv)
|
||||
[[maybe_unused]] ConcurrentApiScope<JSSharedArray, ModType::WRITE> scope(thread, thisHandle);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
|
||||
// Array sort
|
||||
if (thisHandle->IsStableJSArray(thread) && callbackFnHandle->IsUndefined()) {
|
||||
JSStableArray::Sort(thread, thisHandle, callbackFnHandle);
|
||||
} else {
|
||||
JSSharedArray::Sort(thread, JSHandle<JSTaggedValue>::Cast(thisObjHandle), callbackFnHandle);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
}
|
||||
JSHandle<TaggedArray> elements(thread, thisObjHandle->GetElements());
|
||||
base::TimSort::Sort(thread, elements, callbackFnHandle);
|
||||
return thisObjHandle.GetTaggedValue();
|
||||
}
|
||||
|
||||
@ -1894,63 +2063,33 @@ JSTaggedValue BuiltinsSharedArray::Unshift(EcmaRuntimeCallInfo *argv)
|
||||
// 4. ReturnIfAbrupt(len).
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
|
||||
// 6. If argCount > 0, then
|
||||
// a. If len+ argCount > 253-1, throw a TypeError exception.
|
||||
// b. Let k be len.
|
||||
// c. Repeat, while k > 0,
|
||||
// i. Let from be ToString(k–1).
|
||||
// ii. Let to be ToString(k+argCount –1).
|
||||
// iii. Let fromPresent be HasProperty(O, from).
|
||||
// iv. ReturnIfAbrupt(fromPresent).
|
||||
// v. If fromPresent is true, then
|
||||
// 1. Let fromValue be Get(O, from).
|
||||
// 2. ReturnIfAbrupt(fromValue).
|
||||
// 3. Let setStatus be Set(O, to, fromValue, true).
|
||||
// 4. ReturnIfAbrupt(setStatus).
|
||||
// vi. Else fromPresent is false,
|
||||
// 1. Let deleteStatus be DeletePropertyOrThrow(O, to).
|
||||
// 2. ReturnIfAbrupt(deleteStatus).
|
||||
// vii. Decrease k by 1.
|
||||
int64_t newLen = len + argc;
|
||||
if (argc > 0) {
|
||||
if (len + argc > base::MAX_SAFE_INTEGER) {
|
||||
if (newLen > base::MAX_SAFE_INTEGER) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "out of range.", JSTaggedValue::Exception());
|
||||
}
|
||||
|
||||
JSMutableHandle<JSTaggedValue> toKey(thread, JSTaggedValue::Undefined());
|
||||
JSMutableHandle<JSTaggedValue> fromValue(thread, JSTaggedValue::Undefined());
|
||||
int64_t k = len;
|
||||
while (k > 0) {
|
||||
toKey.Update(JSTaggedValue(k + argc - 1));
|
||||
fromValue.Update(BuiltinsSharedArray::GetElementByKey(thread, thisObjHandle, k - 1));
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
JSSharedArray::FastSetPropertyByValue(thread, thisHandle, toKey, fromValue);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
k--;
|
||||
TaggedArray *element = TaggedArray::Cast(thisObjHandle->GetElements().GetTaggedObject());
|
||||
if (newLen > ElementAccessor::GetElementsLength(thisObjHandle)) {
|
||||
element = *JSObject::GrowElementsCapacity(thread, thisObjHandle, newLen, true);
|
||||
}
|
||||
// d. Let j be 0.
|
||||
// e. Let items be a List whose elements are, in left to right order, the arguments that were passed to this
|
||||
// function invocation.
|
||||
// f. Repeat, while items is not empty
|
||||
// i. Remove the first element from items and let E be the value of that element.
|
||||
// ii. Let setStatus be Set(O, ToString(j), E, true).
|
||||
// iii. ReturnIfAbrupt(setStatus).
|
||||
// iv. Increase j by 1.
|
||||
element->Copy<true, true>(thread, argc, 0, element, len);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
|
||||
int64_t j = 0;
|
||||
JSMutableHandle<JSTaggedValue> toValue(thread, JSTaggedValue::Undefined());
|
||||
while (j < argc) {
|
||||
toKey.Update(JSTaggedValue(j));
|
||||
JSHandle<JSTaggedValue> toValue = GetCallArg(argv, j);
|
||||
toValue.Update(GetCallArg(argv, j));
|
||||
if (!toValue->IsSharedType()) {
|
||||
auto error = ContainerError::ParamError(thread, "Parameter error.Only accept sendable value.");
|
||||
THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
|
||||
}
|
||||
JSSharedArray::FastSetPropertyByValue(thread, thisHandle, toKey, toValue);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
element->Set(thread, j, toValue);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
// 7. Let setStatus be Set(O, "length", len+argCount, true).
|
||||
int64_t newLen = len + argc;
|
||||
JSHandle<JSTaggedValue> newLenHandle(thread, JSTaggedValue(newLen));
|
||||
JSSharedArray::LengthSetter(thread, thisObjHandle, newLenHandle, true);
|
||||
// 8. ReturnIfAbrupt(setStatus).
|
||||
@ -2611,11 +2750,11 @@ JSTaggedValue BuiltinsSharedArray::CopyWithin(EcmaRuntimeCallInfo *argv)
|
||||
// h. Let to be to + direction.
|
||||
// i. Let count be count − 1.
|
||||
JSMutableHandle<JSTaggedValue> kValue(thread, JSTaggedValue::Undefined());
|
||||
TaggedArray *elements = TaggedArray::Cast(thisObjHandle->GetElements().GetTaggedObject());
|
||||
while (count > 0) {
|
||||
kValue.Update(BuiltinsSharedArray::GetElementByKey(thread, thisObjHandle, copyFrom));
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
BuiltinsSharedArray::SetElementValue(thread, thisObjHandle, copyTo, kValue);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
elements->Set(thread, copyTo, kValue);
|
||||
copyFrom = copyFrom + direction;
|
||||
copyTo = copyTo + direction;
|
||||
count--;
|
||||
@ -2704,8 +2843,10 @@ JSTaggedValue BuiltinsSharedArray::Reverse(EcmaRuntimeCallInfo *argv)
|
||||
if (enableElementsKind) {
|
||||
if (kind == ElementsKind::INT || kind == ElementsKind::HOLE_INT) {
|
||||
FastReverse(thread, elements, 0, len, ElementsKind::INT);
|
||||
return thisObjHandle.GetTaggedValue();
|
||||
} else if (kind == ElementsKind::NUMBER || kind == ElementsKind::HOLE_NUMBER) {
|
||||
FastReverse(thread, elements, 0, len, ElementsKind::NUMBER);
|
||||
return thisObjHandle.GetTaggedValue();
|
||||
}
|
||||
}
|
||||
FastReverse(thread, elements, 0, len, ElementsKind::TAGGED);
|
||||
|
@ -186,7 +186,7 @@ public:
|
||||
JSHandle<JSTaggedValue> &callbackFnHandle);
|
||||
|
||||
static JSTaggedValue FilterArray(JSThread *thread, JSHandle<JSTaggedValue> &thisArgHandle,
|
||||
JSHandle<JSTaggedValue> &thisObjVal, JSHandle<JSObject> newArrayHandle,
|
||||
JSHandle<JSTaggedValue> &thisObjVal, JSHandle<JSObject>& newArrayHandle,
|
||||
JSHandle<JSTaggedValue> &callbackFnHandle);
|
||||
|
||||
static Span<const std::pair<std::string_view, bool>> GetPrototypeProperties()
|
||||
@ -211,11 +211,22 @@ public:
|
||||
|
||||
private:
|
||||
static inline JSTaggedValue GetElementByKey(JSThread *thread, JSHandle<JSObject>& thisObjHandle, uint32_t index);
|
||||
static JSTaggedValue PopInner(EcmaRuntimeCallInfo *argv, JSHandle<JSTaggedValue> &thisHandle,
|
||||
JSHandle<JSObject> &thisObjHandle);
|
||||
static int64_t FillNewTaggedArray(JSThread *thread, EcmaRuntimeCallInfo *argv, int argc,
|
||||
int64_t newArrayIdx, JSHandle<TaggedArray> &eleArray);
|
||||
static int64_t CalNewArrayLen(JSThread *thread, EcmaRuntimeCallInfo *argv, int argc);
|
||||
static inline JSTaggedValue PopInner(EcmaRuntimeCallInfo *argv, JSHandle<JSTaggedValue> &thisHandle,
|
||||
JSHandle<JSObject> &thisObjHandle);
|
||||
static inline int64_t FillNewTaggedArray(JSThread *thread, EcmaRuntimeCallInfo *argv, int argc,
|
||||
int64_t newArrayIdx, JSHandle<TaggedArray> &eleArray);
|
||||
static inline int64_t CalNewArrayLen(JSThread *thread, EcmaRuntimeCallInfo *argv, int argc);
|
||||
static inline JSTaggedValue IndexOfStable(EcmaRuntimeCallInfo *argv, JSThread *thread,
|
||||
const JSHandle<JSTaggedValue> &thisHandle);
|
||||
static inline JSTaggedValue FromSharedArray(JSThread *thread, const JSHandle<JSTaggedValue>& items,
|
||||
JSHandle<JSObject>& newArrayHandle);
|
||||
static inline JSTaggedValue FromArrayNoMaping(JSThread *thread, const JSHandle<JSTaggedValue>& items,
|
||||
JSHandle<JSObject>& newArrayHandle);
|
||||
template<bool itemIsSharedArray>
|
||||
static inline JSTaggedValue FromArray(JSThread *thread, const JSHandle<JSTaggedValue>& items,
|
||||
const JSHandle<JSTaggedValue>& thisArgHandle,
|
||||
const JSHandle<JSTaggedValue> mapfn,
|
||||
JSHandle<JSObject>& newArrayHandle);
|
||||
|
||||
#define BUILTIN_SENDABLE_ARRAY_FUNCTION_ENTRY(name, method, length, id) \
|
||||
base::BuiltinFunctionEntry::Create(name, BuiltinsSharedArray::method, length, kungfu::BuiltinsStubCSigns::id),
|
||||
|
@ -475,7 +475,7 @@ void JSStableArray::ProcessElements(JSThread *thread, JSHandle<JSTaggedValue> re
|
||||
JSHandle<JSObject> obj(thread, receiverValue.GetTaggedValue());
|
||||
JSTaggedValue element = JSTaggedValue::Undefined();
|
||||
for (uint32_t k = 0; k < len; k++) {
|
||||
if (receiverValue->IsStableJSArray(thread)) {
|
||||
if (receiverValue->IsStableJSArray(thread) || receiverValue->IsJSSharedArray()) {
|
||||
element = k < ElementAccessor::GetElementsLength(obj) ?
|
||||
ElementAccessor::Get(thread, obj, k) : JSTaggedValue::Hole();
|
||||
} else {
|
||||
@ -553,18 +553,17 @@ JSTaggedValue JSStableArray::DoStableArrayJoin(JSThread *thread, JSHandle<JSTagg
|
||||
return JSTaggedValue(newString);
|
||||
}
|
||||
|
||||
JSTaggedValue JSStableArray::Join(JSHandle<JSArray> receiver, EcmaRuntimeCallInfo *argv)
|
||||
JSTaggedValue JSStableArray::Join(JSHandle<JSTaggedValue> receiverValue, EcmaRuntimeCallInfo *argv)
|
||||
{
|
||||
JSThread *thread = argv->GetThread();
|
||||
const GlobalEnvConstants *globalConst = thread->GlobalConstants();
|
||||
auto context = thread->GetCurrentEcmaContext();
|
||||
|
||||
// 1. Let O be ToObject(this.value)
|
||||
JSHandle<JSTaggedValue> receiverValue = JSHandle<JSTaggedValue>::Cast(receiver);
|
||||
JSHandle<JSObject> obj(thread, receiverValue.GetTaggedValue());
|
||||
|
||||
// 2. Let len be ToLength(Get(O, "length"))
|
||||
uint32_t len = receiver->GetArrayLength();
|
||||
uint32_t len = base::ArrayHelper::GetArrayLength(thread, receiverValue);
|
||||
|
||||
int sep = ',';
|
||||
uint32_t sepLength = 1;
|
||||
@ -673,17 +672,16 @@ JSTaggedValue JSStableArray::JoinUseTreeString(const JSThread *thread,
|
||||
return vec.front().GetTaggedValue();
|
||||
}
|
||||
|
||||
JSTaggedValue JSStableArray::Join(JSHandle<JSArray> receiver, EcmaRuntimeCallInfo *argv)
|
||||
JSTaggedValue JSStableArray::Join(JSHandle<JSTaggedValue> receiverValue, EcmaRuntimeCallInfo *argv)
|
||||
{
|
||||
JSThread *thread = argv->GetThread();
|
||||
uint32_t length = receiver->GetArrayLength();
|
||||
uint32_t len = base::ArrayHelper::GetArrayLength(thread, receiverValue);
|
||||
JSHandle<JSTaggedValue> sepHandle = base::BuiltinsBase::GetCallArg(argv, 0);
|
||||
int sep = ',';
|
||||
uint32_t sepLength = 1;
|
||||
const GlobalEnvConstants *globalConst = thread->GlobalConstants();
|
||||
JSHandle<EcmaString> sepStringHandle = JSHandle<EcmaString>::Cast(globalConst->GetHandledCommaString());
|
||||
auto context = thread->GetCurrentEcmaContext();
|
||||
JSHandle<JSTaggedValue> receiverValue = JSHandle<JSTaggedValue>::Cast(receiver);
|
||||
if (!sepHandle->IsUndefined()) {
|
||||
if (sepHandle->IsString()) {
|
||||
sepStringHandle = JSHandle<EcmaString>::Cast(sepHandle);
|
||||
@ -1754,7 +1752,7 @@ JSTaggedValue JSStableArray::Sort(JSThread *thread, const JSHandle<JSTaggedValue
|
||||
const JSHandle<JSTaggedValue> &callbackFnHandle)
|
||||
{
|
||||
// 3. Let len be ?LengthOfArrayLike(obj).
|
||||
uint32_t len = JSHandle<JSArray>::Cast(thisObjVal)->GetArrayLength();
|
||||
uint32_t len = base::ArrayHelper::GetArrayLength(thread, thisObjVal);
|
||||
// ReturnIfAbrupt(len).
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
// If len is 0 or 1, no need to sort
|
||||
|
@ -42,7 +42,7 @@ public:
|
||||
JSHandle<JSObject> newArrayHandle, uint32_t len);
|
||||
static JSTaggedValue Shift(JSHandle<JSArray> receiver, EcmaRuntimeCallInfo *argv);
|
||||
static JSTaggedValue Shift(JSHandle<JSSharedArray> receiver, EcmaRuntimeCallInfo *argv);
|
||||
static JSTaggedValue Join(JSHandle<JSArray> receiver, EcmaRuntimeCallInfo *argv);
|
||||
static JSTaggedValue Join(JSHandle<JSTaggedValue> receiver, EcmaRuntimeCallInfo *argv);
|
||||
static JSTaggedValue HandleFindIndexOfStable(JSThread *thread, JSHandle<JSObject> thisObjHandle,
|
||||
JSHandle<JSTaggedValue> callbackFnHandle,
|
||||
JSHandle<JSTaggedValue> thisArgHandle, uint32_t &k);
|
||||
|
@ -102,12 +102,16 @@ inline void Barriers::SynchronizedSetObject(const JSThread *thread, void *obj, s
|
||||
}
|
||||
}
|
||||
|
||||
static inline void CopyMaybeOverlap(JSTaggedValue* dst, JSTaggedValue* src, size_t count)
|
||||
static inline void CopyMaybeOverlap(JSTaggedValue* dst, const JSTaggedValue* src, size_t count)
|
||||
{
|
||||
std::copy_n(src, count, dst);
|
||||
if (dst > src && dst < src + count) {
|
||||
std::copy_backward(src, src + count, dst + count);
|
||||
} else {
|
||||
std::copy_n(src, count, dst);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void CopyNoOverlap(JSTaggedValue* __restrict__ dst, JSTaggedValue* __restrict__ src, size_t count)
|
||||
static inline void CopyNoOverlap(JSTaggedValue* __restrict__ dst, const JSTaggedValue* __restrict__ src, size_t count)
|
||||
{
|
||||
std::copy_n(src, count, dst);
|
||||
}
|
||||
@ -117,7 +121,7 @@ ARK_NOINLINE bool BatchBitSet(const JSThread* thread, Region* objectRegion, JSTa
|
||||
|
||||
template <bool needWriteBarrier, bool maybeOverlap>
|
||||
void Barriers::CopyObject(const JSThread *thread, const TaggedObject *dstObj, JSTaggedValue *dstAddr,
|
||||
JSTaggedValue *srcAddr, size_t count)
|
||||
const JSTaggedValue *srcAddr, size_t count)
|
||||
{
|
||||
// NOTE: The logic in CopyObject should be synced with WriteBarrier.
|
||||
// if any new feature/bugfix be added in CopyObject, it should also be added to WriteBarrier.
|
||||
@ -168,7 +172,7 @@ void Barriers::CopyObject(const JSThread *thread, const TaggedObject *dstObj, JS
|
||||
}
|
||||
|
||||
template <bool maybeOverlap>
|
||||
inline void Barriers::CopyObjectPrimitive(JSTaggedValue* dst, JSTaggedValue* src, size_t count)
|
||||
inline void Barriers::CopyObjectPrimitive(JSTaggedValue* dst, const JSTaggedValue* src, size_t count)
|
||||
{
|
||||
// Copy Primitive value don't need thread.
|
||||
ASSERT((ToUintPtr(dst) % static_cast<uint8_t>(MemAlignment::MEM_ALIGN_OBJECT)) == 0);
|
||||
|
@ -54,14 +54,14 @@ public:
|
||||
// Note: dstObj is the object address for dstAddr, it must point to the head of an object.
|
||||
template<bool needWriteBarrier, bool maybeOverlap>
|
||||
static void CopyObject(const JSThread *thread, const TaggedObject *dstObj, JSTaggedValue *dstAddr,
|
||||
JSTaggedValue *srcAddr, size_t count);
|
||||
const JSTaggedValue *srcAddr, size_t count);
|
||||
|
||||
// dstAddr/srcAddr is the address will be copied to/from.
|
||||
// It can be a derived pointer point to the middle of an object.
|
||||
//
|
||||
// Note: dstObj is the object address for dstAddr, it must point to the head of an object.
|
||||
template<bool maybeOverlap>
|
||||
static void CopyObjectPrimitive(JSTaggedValue* dst, JSTaggedValue* src, size_t count);
|
||||
static void CopyObjectPrimitive(JSTaggedValue* dst, const JSTaggedValue* src, size_t count);
|
||||
static void SynchronizedSetClass(const JSThread *thread, void *obj, JSTaggedType value);
|
||||
static void SynchronizedSetObject(const JSThread *thread, void *obj, size_t offset, JSTaggedType value,
|
||||
bool isPrimitive = false);
|
||||
|
@ -64,7 +64,7 @@ MAYBE_INLINE JSTaggedValue TaggedArray::Get(uint32_t idx) const
|
||||
|
||||
#undef MAYBE_INLINE
|
||||
|
||||
template <bool needBarrier>
|
||||
template <bool needBarrier, bool maybeOverlap>
|
||||
inline void TaggedArray::Copy(const JSThread* thread, uint32_t dstStart, uint32_t srcStart,
|
||||
const TaggedArray* srcArray, uint32_t count)
|
||||
{
|
||||
@ -74,7 +74,7 @@ inline void TaggedArray::Copy(const JSThread* thread, uint32_t dstStart, uint32_
|
||||
size_t taggedTypeSize = JSTaggedValue::TaggedTypeSize();
|
||||
JSTaggedValue* to = reinterpret_cast<JSTaggedValue*>(ToUintPtr(GetData()) + taggedTypeSize * dstStart);
|
||||
JSTaggedValue* from = reinterpret_cast<JSTaggedValue*>(ToUintPtr(srcArray->GetData()) + taggedTypeSize * srcStart);
|
||||
Barriers::CopyObject<needBarrier, false>(thread, this, to, from, count);
|
||||
Barriers::CopyObject<needBarrier, maybeOverlap>(thread, this, to, from, count);
|
||||
}
|
||||
} // namespace panda::ecmascript
|
||||
#endif // ECMASCRIPT_TAGGED_ARRAY_INL_H
|
||||
|
@ -45,7 +45,7 @@ public:
|
||||
|
||||
void SetBit(const JSThread* thread, uint32_t idx, uint32_t bitOffset, const JSTaggedValue &value);
|
||||
|
||||
template <bool needBarrier = true>
|
||||
template <bool needBarrier = true, bool maybeOverlap = false>
|
||||
inline void Copy(const JSThread* thread, uint32_t dstStart, uint32_t srcStart,
|
||||
const TaggedArray *srcArray, uint32_t count);
|
||||
|
||||
|
@ -40,12 +40,13 @@ public:
|
||||
JSHandle<JSTaggedValue> CallJoin(JSHandle<TaggedArray> handleTagArr, JSTaggedValue sepValue) const
|
||||
{
|
||||
JSHandle<JSArray> handleArr(JSArray::CreateArrayFromList(thread, handleTagArr));
|
||||
JSHandle<JSTaggedValue> tagArrValue = JSHandle<JSTaggedValue>::Cast(handleArr);
|
||||
auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
|
||||
ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
|
||||
ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
|
||||
ecmaRuntimeCallInfo->SetCallArg(0, sepValue);
|
||||
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
|
||||
JSHandle<JSTaggedValue> handleTagValEcmaStrRet(thread, JSStableArray::Join(handleArr, ecmaRuntimeCallInfo));
|
||||
JSHandle<JSTaggedValue> handleTagValEcmaStrRet(thread, JSStableArray::Join(tagArrValue, ecmaRuntimeCallInfo));
|
||||
TestHelper::TearDownFrame(thread, prev);
|
||||
return handleTagValEcmaStrRet;
|
||||
}
|
||||
@ -257,10 +258,11 @@ HWTEST_F_L0(JSStableArrayTest, Join_NumberElements_UndefinedSep)
|
||||
}
|
||||
JSHandle<JSArray> handleArr(JSArray::CreateArrayFromList(thread, handleTagArr));
|
||||
std::vector<JSTaggedValue> args{};
|
||||
JSHandle<JSTaggedValue> tagArrValue = JSHandle<JSTaggedValue>::Cast(handleArr);
|
||||
auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, args, 4);
|
||||
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
|
||||
JSHandle<JSTaggedValue> handleTagValEcmaStrRet(thread,
|
||||
JSStableArray::Join(handleArr, ecmaRuntimeCallInfo));
|
||||
JSStableArray::Join(tagArrValue, ecmaRuntimeCallInfo));
|
||||
TestHelper::TearDownFrame(thread, prev);
|
||||
|
||||
JSHandle<EcmaString> handleEcmaStrRet(handleTagValEcmaStrRet);
|
||||
@ -288,10 +290,11 @@ HWTEST_F_L0(JSStableArrayTest, Join_StringElements_UndefinedSep)
|
||||
}
|
||||
JSHandle<JSArray> handleArr(JSArray::CreateArrayFromList(thread, handleTagArr));
|
||||
std::vector<JSTaggedValue> args{};
|
||||
JSHandle<JSTaggedValue> tagArrValue = JSHandle<JSTaggedValue>::Cast(handleArr);
|
||||
auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, args, 4);
|
||||
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
|
||||
JSHandle<JSTaggedValue> handleTagValEcmaStrRet(thread,
|
||||
JSStableArray::Join(handleArr, ecmaRuntimeCallInfo));
|
||||
JSStableArray::Join(tagArrValue, ecmaRuntimeCallInfo));
|
||||
TestHelper::TearDownFrame(thread, prev);
|
||||
|
||||
JSHandle<EcmaString> handleEcmaStrRet(handleTagValEcmaStrRet);
|
||||
@ -317,11 +320,12 @@ HWTEST_F_L0(JSStableArrayTest, Join_NumberElements_DefinedSep)
|
||||
handleTagArr->Set(thread, i, JSTaggedValue(i));
|
||||
}
|
||||
JSHandle<JSArray> handleArr(JSArray::CreateArrayFromList(thread, handleTagArr));
|
||||
JSHandle<JSTaggedValue> tagArrValue = JSHandle<JSTaggedValue>::Cast(handleArr);
|
||||
std::vector<JSTaggedValue> args{JSHandle<JSTaggedValue>::Cast(objFactory->NewFromStdString("^")).GetTaggedValue()};
|
||||
auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, args, 6);
|
||||
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
|
||||
JSHandle<JSTaggedValue> handleTagValEcmaStrRet(thread,
|
||||
JSStableArray::Join(handleArr, ecmaRuntimeCallInfo));
|
||||
JSStableArray::Join(tagArrValue, ecmaRuntimeCallInfo));
|
||||
TestHelper::TearDownFrame(thread, prev);
|
||||
|
||||
JSHandle<EcmaString> handleEcmaStrRet(handleTagValEcmaStrRet);
|
||||
@ -348,6 +352,7 @@ HWTEST_F_L0(JSStableArrayTest, Join_StringElements_DefinedSep)
|
||||
handleTagArr->Set(thread, i, handleTagValElementEcmaStr.GetTaggedValue());
|
||||
}
|
||||
JSHandle<JSArray> handleArr(JSArray::CreateArrayFromList(thread, handleTagArr));
|
||||
JSHandle<JSTaggedValue> tagArrValue = JSHandle<JSTaggedValue>::Cast(handleArr);
|
||||
auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
|
||||
ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
|
||||
ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
|
||||
@ -355,7 +360,7 @@ HWTEST_F_L0(JSStableArrayTest, Join_StringElements_DefinedSep)
|
||||
JSHandle<JSTaggedValue>::Cast(objFactory->NewFromStdString(" <> ")).GetTaggedValue());
|
||||
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
|
||||
JSHandle<JSTaggedValue> handleTagValEcmaStrRet(thread,
|
||||
JSStableArray::Join(handleArr, ecmaRuntimeCallInfo));
|
||||
JSStableArray::Join(tagArrValue, ecmaRuntimeCallInfo));
|
||||
TestHelper::TearDownFrame(thread, prev);
|
||||
|
||||
JSHandle<EcmaString> handleEcmaStrRet(handleTagValEcmaStrRet);
|
||||
|
@ -57,7 +57,18 @@ Start Test fill
|
||||
10,11,11,8
|
||||
10,11,11,8
|
||||
Start Test pop
|
||||
poped: 44
|
||||
70
|
||||
5,12,8,130,44,10,20,30,100,50,80,90,150,200,5,12,8,130,44,10,20,30,100,50,80,90,150,200,5,12,8,130,44,10,20,30,100,50,80,90,150,200,5,12,8,130,44,10,20,30,100,50,80,90,150,200,5,12,8,130,44,10,20,30,100,50,80,90,150
|
||||
5,12,8,130,44,10,20,30,100,50,80,90,150,200,5,12,8,130,44,10,20,30,100,50,80,90,150,200,5,12,8,130,44,10,20,30,100,50,80,90,150,200,5,12,8,130,44,10,20,30,100,50,80,90,150,200,5,12,8,130,44,10,20,30,100,50,80,90
|
||||
5,12,8,130,44,10,20,30,100,50,80,90,150,200,5,12,8,130,44,10,20,30,100,50,80,90,150,200,5,12,8,130,44,10,20,30,100,50,80,90,150,200,5,12,8,130,44,10,20,30,100,50,80,90,150,200,5,12,8,130,44,10,20,30,100,50,80
|
||||
5,12,8,130,44,10,20,30,100,50,80,90,150,200,5,12,8,130,44,10,20,30,100,50,80,90,150,200,5,12,8,130,44,10,20,30,100,50,80,90,150,200,5,12,8,130,44,10,20,30,100,50,80,90,150,200,5,12,8,130,44,10,20,30,100,50
|
||||
5,12,8,130,44,10,20,30,100,50,80,90,150,200,5,12,8,130,44,10,20,30,100,50,80,90,150,200,5,12,8,130,44,10,20,30,100,50,80,90,150,200,5,12,8,130,44,10,20,30,100,50,80,90,150,200,5,12,8,130,44,10,20,30,100
|
||||
5,12,8,130,44,10,20,30,100,50,80,90,150,200,5,12,8,130,44,10,20,30,100,50,80,90,150,200,5,12,8,130,44,10,20,30,100,50,80,90,150,200,5,12,8,130,44,10,20,30,100,50,80,90,150,200,5,12,8,130,44,10,20,30
|
||||
5,12,8,130,44,10,20,30,100,50,80,90,150,200,5,12,8,130,44,10,20,30,100,50,80,90,150,200,5,12,8,130,44,10,20,30,100,50,80,90,150,200,5,12,8,130,44,10,20,30,100,50,80,90,150,200,5,12,8,130,44,10,20
|
||||
5,12,8,130,44,10,20,30,100,50,80,90,150,200,5,12,8,130,44,10,20,30,100,50,80,90,150,200,5,12,8,130,44,10,20,30,100,50,80,90,150,200,5,12,8,130,44,10,20,30,100,50,80,90,150,200,5,12,8,130,44,10
|
||||
5,12,8,130,44,10,20,30,100,50,80,90,150,200,5,12,8,130,44,10,20,30,100,50,80,90,150,200,5,12,8,130,44,10,20,30,100,50,80,90,150,200,5,12,8,130,44,10,20,30,100,50,80,90,150,200,5,12,8,130,44
|
||||
5,12,8,130,44,10,20,30,100,50,80,90,150,200,5,12,8,130,44,10,20,30,100,50,80,90,150,200,5,12,8,130,44,10,20,30,100,50,80,90,150,200,5,12,8,130,44,10,20,30,100,50,80,90,150,200,5,12,8,130
|
||||
60
|
||||
Start Test randomUpdate
|
||||
30
|
||||
add element by index access failed. err: TypeError: Cannot add property in prevent extensions, code: undefined
|
||||
@ -74,6 +85,15 @@ E,,M,P,T,Y
|
||||
Create from sendable undefined element list success. arr: ,,1
|
||||
h,e,l,l,o
|
||||
1,2,3
|
||||
SA,SB,SC
|
||||
SSA,SSB,SSC
|
||||
Create from sendable array. err: BusinessError: Parameter error.Only accept sendable value., code: 401
|
||||
1
|
||||
1
|
||||
1
|
||||
4,3
|
||||
4,3,2,6,4,3,4
|
||||
abcdcde,bcdecde,cdefcde,cfghcde,abcdcdecde,bcdecdecde,cdefcdecde,cfghcdecde
|
||||
Start Test fromTemplate
|
||||
artTSTest1: 1,2,3
|
||||
arkTSTest2: 1,2,3
|
||||
@ -108,9 +128,32 @@ Start Test shift
|
||||
2
|
||||
2
|
||||
undefined
|
||||
2,4,6,100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70
|
||||
49
|
||||
4,6,100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70
|
||||
6,100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70
|
||||
100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70
|
||||
50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70
|
||||
60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70
|
||||
70,2,4,6,100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70
|
||||
2,4,6,100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70
|
||||
4,6,100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70
|
||||
6,100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70
|
||||
100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70,2,4,6,100,50,60,70
|
||||
39
|
||||
Start Test unshift
|
||||
1,2,3
|
||||
3
|
||||
5
|
||||
4,5,1,2,3
|
||||
5
|
||||
4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3
|
||||
35
|
||||
4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3
|
||||
70
|
||||
36
|
||||
4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3
|
||||
36
|
||||
Start Test slice
|
||||
ant,bison,camel,duck,elephant
|
||||
camel,duck,elephant
|
||||
@ -142,6 +185,8 @@ exuberant,destruction,present
|
||||
5
|
||||
8
|
||||
44
|
||||
spray,elite,exuberant,destruction,present,spray,elite,exuberant,destruction,present,spray,elite,exuberant,destruction,present,spray,elite,exuberant,destruction,present,spray,elite,exuberant,destruction,present,spray,elite,exuberant,destruction,present,spray,elite,exuberant,destruction,present,spray,elite,exuberant,destruction,present
|
||||
destruction,destruction,destruction,destruction,destruction,destruction,destruction,destruction
|
||||
Start Test reduce
|
||||
10
|
||||
20
|
||||
|
@ -204,8 +204,15 @@ function fill() {
|
||||
// remove
|
||||
function pop() {
|
||||
print("Start Test pop")
|
||||
const sharedArray = new SendableArray<number>(5, 12, 8, 130, 44);
|
||||
print("poped: " + sharedArray.pop());
|
||||
const sharedArray = new SendableArray<number>(5, 12, 8, 130, 44, 10, 20, 30, 100, 50, 80, 90, 150, 200);
|
||||
let sharedArray2 = sharedArray.concat(sharedArray).concat(sharedArray).concat(sharedArray).concat(sharedArray);
|
||||
print(sharedArray2.length);
|
||||
let len = sharedArray2.length;
|
||||
for (let idx = 0; idx < 10; ++idx) {
|
||||
sharedArray2.pop();
|
||||
print(sharedArray2)
|
||||
}
|
||||
print(sharedArray2.length);
|
||||
}
|
||||
|
||||
// update
|
||||
@ -280,6 +287,56 @@ function from(): void {
|
||||
} catch (err) {
|
||||
print("Create from sendable list failed without constructor functions. err: " + err + ", code: " + err.code);
|
||||
}
|
||||
|
||||
let sArr = SendableArray.from<string>(['A', 'B', 'C'], (str: string) => 'S' + str);
|
||||
print(sArr);
|
||||
let sArr1 = SendableArray.from<string>(sArr, (str: string) => 'S' + str);
|
||||
print(sArr1);
|
||||
|
||||
try {
|
||||
let sArr2 = SendableArray.from<string>(sArr, (str: string) =>{
|
||||
return new SuperUnSharedClass(1);
|
||||
});
|
||||
print(sArr2);
|
||||
} catch (err) {
|
||||
print("Create from sendable array. err: " + err + ", code: " + err.code);
|
||||
}
|
||||
|
||||
try {
|
||||
let sArr2 = SendableArray.from<SuperClass>(sArr, (str: string) =>{
|
||||
return new SuperClass(1);
|
||||
});
|
||||
sArr2.forEach((element: SubClass) => print(element.num)); // 5, 8, 44
|
||||
} catch (err) {
|
||||
print("Create from sendable array. err: " + err + ", code: " + err.code);
|
||||
}
|
||||
|
||||
let normalArr = new Array<number>(3,2,1,5);
|
||||
let sArr3 = SendableArray.from<number>(normalArr, (num: number) =>{
|
||||
normalArr.pop();
|
||||
return num += 1;
|
||||
});
|
||||
print(sArr3)
|
||||
|
||||
let normalArr1 = new Array<number>(3,2,1,5);
|
||||
let sArr4 = SendableArray.from<number>(normalArr1, (num: number) =>{
|
||||
if (num < 3) {
|
||||
normalArr1.push(num + 1);
|
||||
}
|
||||
|
||||
return num += 1;
|
||||
});
|
||||
print(sArr4)
|
||||
|
||||
let normalArr2 = new Array<string>("abcd","bcde","cdef","cfgh");
|
||||
let sArr5 = SendableArray.from<number>(normalArr2, (str: string) =>{
|
||||
if (str.length <= 4) {
|
||||
normalArr2.push(str + "cde");
|
||||
}
|
||||
|
||||
return str + "cde";
|
||||
});
|
||||
print(sArr5)
|
||||
}
|
||||
|
||||
function fromTemplate(): void {
|
||||
@ -358,13 +415,38 @@ function shift() {
|
||||
|
||||
const emptyArray = new SendableArray<number>();
|
||||
print(emptyArray.shift());
|
||||
|
||||
const array2 = new SendableArray<number>(2, 4, 6, 100, 50, 60, 70);
|
||||
let array3 = array2.concat(array2).concat(array2).concat(array2).concat(array2).concat(array2).concat(array2);
|
||||
print(array3);
|
||||
print(array3.length);
|
||||
let len = array3.length;
|
||||
for (let idx = 0; idx < 10; ++idx) {
|
||||
array3.shift();
|
||||
print(array3);
|
||||
}
|
||||
print(array3.length)
|
||||
}
|
||||
|
||||
function unshift() {
|
||||
print("Start Test unshift")
|
||||
const array = SendableArray.from<number>([1, 2, 3]);
|
||||
print(array.unshift(4, 5));
|
||||
print(array);
|
||||
print(array.length);
|
||||
print(array.unshift(4, 5));
|
||||
print(array);
|
||||
print(array.length);
|
||||
|
||||
let arr2 = array.concat(array).concat(array).concat(array).concat(array).concat(array).concat(array);
|
||||
print(arr2);
|
||||
print(arr2.length);
|
||||
let arr3 = arr2.concat(arr2);
|
||||
print(arr3);
|
||||
print(arr3.length);
|
||||
print(arr2.unshift(arr3));
|
||||
print(arr2);
|
||||
print(arr2.length);
|
||||
|
||||
}
|
||||
|
||||
function slice() {
|
||||
@ -456,6 +538,11 @@ function filter() {
|
||||
);
|
||||
const result = array2.filter<SubClass>((value: SuperClass, index: number, obj: Array<SuperClass>) => value instanceof SubClass);
|
||||
result.forEach((element: SubClass) => print(element.num)); // 5, 8, 44
|
||||
|
||||
const words1 = new SendableArray<string>('spray', 'elite', 'exuberant', 'destruction', 'present');
|
||||
let words2 = words1.concat(words).concat(words).concat(words).concat(words).concat(words).concat(words).concat(words);
|
||||
print(words2)
|
||||
print(words2.filter((word: string) => word.length > 10))
|
||||
}
|
||||
|
||||
function reduce() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user