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:
18157154025 2025-01-08 10:47:28 +08:00
parent ac36ea29bf
commit 18a2224ccf
12 changed files with 408 additions and 117 deletions

View File

@ -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).

View File

@ -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", len1, 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(k1).
// 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);

View File

@ -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),

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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() {