mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-12-03 16:31:12 +00:00
commit
91e3932d51
@ -1292,21 +1292,31 @@ JSTaggedValue BuiltinsArray::Join(EcmaRuntimeCallInfo *argv)
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
JSHandle<JSTaggedValue> thisHandle = GetThis(argv);
|
||||
auto factory = thread->GetEcmaVM()->GetFactory();
|
||||
auto context = thread->GetCurrentEcmaContext();
|
||||
bool noCircular = context->JoinStackPushFastPath(thisHandle);
|
||||
if (!noCircular) {
|
||||
return factory->GetEmptyString().GetTaggedValue();
|
||||
}
|
||||
if (thisHandle->IsStableJSArray(thread)) {
|
||||
return JSStableArray::Join(JSHandle<JSArray>::Cast(thisHandle), argv);
|
||||
}
|
||||
|
||||
// 1. Let O be ToObject(this value).
|
||||
JSHandle<JSObject> thisObjHandle = JSTaggedValue::ToObject(thread, thisHandle);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
// 2. ReturnIfAbrupt(O).
|
||||
RETURN_EXCEPTION_AND_POP_JOINSTACK(thread, thisHandle);
|
||||
JSHandle<JSTaggedValue> thisObjVal(thisObjHandle);
|
||||
|
||||
// 2. Let len be ? LengthOfArrayLike(O).
|
||||
// 3. Let len be ToLength(Get(O, "length")).
|
||||
int64_t len = ArrayHelper::GetLength(thread, thisObjVal);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
if (len > UINT32_MAX) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "Invalid array length", JSTaggedValue::Exception());
|
||||
}
|
||||
// 4. ReturnIfAbrupt(len).
|
||||
RETURN_EXCEPTION_AND_POP_JOINSTACK(thread, thisHandle);
|
||||
|
||||
// 3. If separator is undefined, let sep be ",".
|
||||
// 4. Else, let sep be ? ToString(separator).
|
||||
// 5. If separator is undefined, let separator be the single-element String ",".
|
||||
// 6. Let sep be ToString(separator).
|
||||
JSHandle<JSTaggedValue> sepHandle;
|
||||
if ((GetCallArg(argv, 0)->IsUndefined())) {
|
||||
sepHandle = thread->GlobalConstants()->GetHandledCommaString();
|
||||
@ -1315,7 +1325,6 @@ JSTaggedValue BuiltinsArray::Join(EcmaRuntimeCallInfo *argv)
|
||||
}
|
||||
|
||||
JSHandle<EcmaString> sepStringHandle = JSTaggedValue::ToString(thread, sepHandle);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
uint32_t allocateLength = 0;
|
||||
uint32_t sepLength = EcmaStringAccessor(sepStringHandle).GetLength();
|
||||
|
||||
@ -1323,18 +1332,11 @@ JSTaggedValue BuiltinsArray::Join(EcmaRuntimeCallInfo *argv)
|
||||
allocateLength = sepLength * (len - 1) + len;
|
||||
}
|
||||
if (allocateLength > EcmaString::MAX_STRING_LENGTH) {
|
||||
context->JoinStackPopFastPath(thisHandle);
|
||||
THROW_RANGE_ERROR_AND_RETURN(thread, "Invalid string length", JSTaggedValue::Exception());
|
||||
}
|
||||
|
||||
if (thisHandle->IsStableJSArray(thread)) {
|
||||
return JSStableArray::Join(thread, JSHandle<JSArray>::Cast(thisHandle), sepStringHandle, len);
|
||||
}
|
||||
auto context = thread->GetCurrentEcmaContext();
|
||||
bool noCircular = context->JoinStackPushFastPath(thisHandle);
|
||||
if (!noCircular) {
|
||||
return factory->GetEmptyString().GetTaggedValue();
|
||||
}
|
||||
|
||||
// 7. ReturnIfAbrupt(sep).
|
||||
RETURN_EXCEPTION_AND_POP_JOINSTACK(thread, thisHandle);
|
||||
std::u16string sepStr = EcmaStringAccessor(sepStringHandle).ToU16String();
|
||||
|
||||
// 8. If len is zero, return the empty String.
|
||||
|
@ -477,18 +477,24 @@ JSTaggedValue JSStableArray::JoinUseTreeString(const JSThread* thread, const JSH
|
||||
return vec.front().GetTaggedValue();
|
||||
}
|
||||
|
||||
JSTaggedValue JSStableArray::Join(JSThread *thread, JSHandle<JSArray> receiver,
|
||||
JSHandle<EcmaString> sepStringHandle, int64_t length)
|
||||
JSTaggedValue JSStableArray::Join(JSHandle<JSArray> receiver, EcmaRuntimeCallInfo *argv)
|
||||
{
|
||||
JSThread *thread = argv->GetThread();
|
||||
uint32_t length = receiver->GetArrayLength();
|
||||
JSHandle<JSTaggedValue> sepHandle = base::BuiltinsBase::GetCallArg(argv, 0);
|
||||
int sep = ',';
|
||||
uint32_t sepLength = 1;
|
||||
JSHandle<EcmaString> sepStringHandle;
|
||||
auto context = thread->GetCurrentEcmaContext();
|
||||
JSHandle<JSTaggedValue> receiverValue = JSHandle<JSTaggedValue>::Cast(receiver);
|
||||
SetSepValue(sepStringHandle, sep, sepLength);
|
||||
auto factory = thread->GetEcmaVM()->GetFactory();
|
||||
bool noCircular = context->JoinStackPushFastPath(receiverValue);
|
||||
if (!noCircular) {
|
||||
return factory->GetEmptyString().GetTaggedValue();
|
||||
if (!sepHandle->IsUndefined()) {
|
||||
if (sepHandle->IsString()) {
|
||||
sepStringHandle = JSHandle<EcmaString>::Cast(sepHandle);
|
||||
} else {
|
||||
sepStringHandle = JSTaggedValue::ToString(thread, sepHandle);
|
||||
RETURN_EXCEPTION_AND_POP_JOINSTACK(thread, receiverValue);
|
||||
}
|
||||
SetSepValue(sepStringHandle, sep, sepLength);
|
||||
}
|
||||
if (length == 0) {
|
||||
const GlobalEnvConstants *globalConst = thread->GlobalConstants();
|
||||
@ -517,7 +523,7 @@ JSTaggedValue JSStableArray::Join(JSThread *thread, JSHandle<JSArray> receiver,
|
||||
element = ElementAccessor::Get(obj, k);
|
||||
if (element.IsHole() && JSTaggedValue::HasProperty(thread, receiverValue, k)) {
|
||||
element = JSArray::FastGetPropertyByValue(thread, receiverValue, k).GetTaggedValue();
|
||||
RETURN_EXCEPTION_AND_POP_JOINSTACK(thread, receiverValue);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
}
|
||||
}
|
||||
if (!element.IsUndefinedOrNull() && !element.IsHole()) {
|
||||
|
@ -39,8 +39,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(JSThread *thread, JSHandle<JSArray> receiver,
|
||||
JSHandle<EcmaString> sepStringHandle, int64_t length);
|
||||
static JSTaggedValue Join(JSHandle<JSArray> receiver, EcmaRuntimeCallInfo *argv);
|
||||
static JSTaggedValue HandleFindIndexOfStable(JSThread *thread, JSHandle<JSObject> thisObjHandle,
|
||||
JSHandle<JSTaggedValue> callbackFnHandle,
|
||||
JSHandle<JSTaggedValue> thisArgHandle, uint32_t &k);
|
||||
|
@ -47,10 +47,7 @@ public:
|
||||
ecmaRuntimeCallInfo->SetCallArg(0,
|
||||
JSHandle<JSTaggedValue>::Cast(objFactory->NewFromStdString(sep)).GetTaggedValue());
|
||||
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
|
||||
JSHandle<JSTaggedValue> sepHandle = JSHandle<JSTaggedValue>::Cast(objFactory->NewFromStdString(sep));
|
||||
JSHandle<EcmaString> sepStringHandle = JSTaggedValue::ToString(thread, sepHandle);
|
||||
JSHandle<JSTaggedValue> handleTagValEcmaStrRet(thread,
|
||||
JSStableArray::Join(thread, handleArr, sepStringHandle, lengthArr));
|
||||
JSHandle<JSTaggedValue> handleTagValEcmaStrRet(thread, JSStableArray::Join(handleArr, ecmaRuntimeCallInfo));
|
||||
TestHelper::TearDownFrame(thread, prev);
|
||||
return handleTagValEcmaStrRet;
|
||||
}
|
||||
@ -249,10 +246,8 @@ HWTEST_F_L0(JSStableArrayTest, Join_NumberElements_UndefinedSep)
|
||||
std::vector<JSTaggedValue> args{};
|
||||
auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, args, 4);
|
||||
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
|
||||
JSHandle<JSTaggedValue> sepHandle = thread->GlobalConstants()->GetHandledCommaString();
|
||||
JSHandle<EcmaString> sepStringHandle = JSTaggedValue::ToString(thread, sepHandle);
|
||||
JSHandle<JSTaggedValue> handleTagValEcmaStrRet(thread,
|
||||
JSStableArray::Join(thread, handleArr, sepStringHandle, lengthArr));
|
||||
JSStableArray::Join(handleArr, ecmaRuntimeCallInfo));
|
||||
TestHelper::TearDownFrame(thread, prev);
|
||||
|
||||
JSHandle<EcmaString> handleEcmaStrRet(handleTagValEcmaStrRet);
|
||||
@ -282,10 +277,8 @@ HWTEST_F_L0(JSStableArrayTest, Join_StringElements_UndefinedSep)
|
||||
std::vector<JSTaggedValue> args{};
|
||||
auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, args, 4);
|
||||
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
|
||||
JSHandle<JSTaggedValue> sepHandle = thread->GlobalConstants()->GetHandledCommaString();
|
||||
JSHandle<EcmaString> sepStringHandle = JSTaggedValue::ToString(thread, sepHandle);
|
||||
JSHandle<JSTaggedValue> handleTagValEcmaStrRet(thread,
|
||||
JSStableArray::Join(thread, handleArr, sepStringHandle, lengthArr));
|
||||
JSStableArray::Join(handleArr, ecmaRuntimeCallInfo));
|
||||
TestHelper::TearDownFrame(thread, prev);
|
||||
|
||||
JSHandle<EcmaString> handleEcmaStrRet(handleTagValEcmaStrRet);
|
||||
@ -314,10 +307,8 @@ HWTEST_F_L0(JSStableArrayTest, Join_NumberElements_DefinedSep)
|
||||
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> sepHandle = JSHandle<JSTaggedValue>::Cast(objFactory->NewFromStdString("^"));
|
||||
JSHandle<EcmaString> sepStringHandle = JSTaggedValue::ToString(thread, sepHandle);
|
||||
JSHandle<JSTaggedValue> handleTagValEcmaStrRet(thread,
|
||||
JSStableArray::Join(thread, handleArr, sepStringHandle, lengthArr));
|
||||
JSStableArray::Join(handleArr, ecmaRuntimeCallInfo));
|
||||
TestHelper::TearDownFrame(thread, prev);
|
||||
|
||||
JSHandle<EcmaString> handleEcmaStrRet(handleTagValEcmaStrRet);
|
||||
@ -350,10 +341,8 @@ HWTEST_F_L0(JSStableArrayTest, Join_StringElements_DefinedSep)
|
||||
ecmaRuntimeCallInfo->SetCallArg(0,
|
||||
JSHandle<JSTaggedValue>::Cast(objFactory->NewFromStdString(" <> ")).GetTaggedValue());
|
||||
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
|
||||
JSHandle<JSTaggedValue> sepHandle = JSHandle<JSTaggedValue>::Cast(objFactory->NewFromStdString(" <> "));
|
||||
JSHandle<EcmaString> sepStringHandle = JSTaggedValue::ToString(thread, sepHandle);
|
||||
JSHandle<JSTaggedValue> handleTagValEcmaStrRet(thread,
|
||||
JSStableArray::Join(thread, handleArr, sepStringHandle, lengthArr));
|
||||
JSStableArray::Join(handleArr, ecmaRuntimeCallInfo));
|
||||
TestHelper::TearDownFrame(thread, prev);
|
||||
|
||||
JSHandle<EcmaString> handleEcmaStrRet(handleTagValEcmaStrRet);
|
||||
|
@ -111,68 +111,4 @@ const element = {
|
||||
}
|
||||
};
|
||||
const arr_join = [element, ,'c'];
|
||||
print("abc" == arr_join.join(''));
|
||||
|
||||
{
|
||||
const a = [1,2,3];
|
||||
let callCount = 0;
|
||||
const sep = {
|
||||
toString() {
|
||||
callCount++;
|
||||
return a.join('-');
|
||||
}
|
||||
};
|
||||
print(a.join(sep));
|
||||
print(callCount);
|
||||
// Verify cycle detection works properly after nested call
|
||||
print(a.join());
|
||||
}
|
||||
|
||||
{
|
||||
const a = [1,2,3];
|
||||
let callCount = 0;
|
||||
print(a.join({
|
||||
toString() {
|
||||
callCount++;
|
||||
Object.defineProperty(a, '0', {
|
||||
get(){ return 666; }
|
||||
});
|
||||
return ',';
|
||||
}
|
||||
}));
|
||||
print(callCount);
|
||||
print(a.join());
|
||||
}
|
||||
|
||||
{
|
||||
const a = [1,2];
|
||||
a.length = 3;
|
||||
let callCount = 0;
|
||||
print(a.join({
|
||||
toString() {
|
||||
callCount++;
|
||||
a.__proto__ = { '2': 4 };
|
||||
return ',';
|
||||
}
|
||||
}));
|
||||
print(callCount);
|
||||
a.__proto__ = Array.prototype;
|
||||
print(a.join());
|
||||
}
|
||||
|
||||
{
|
||||
const a = [1,2,3];
|
||||
let callCount = 0;
|
||||
print(a.join({
|
||||
toString() {
|
||||
callCount++;
|
||||
a.pop();
|
||||
Object.defineProperty(Array.prototype, '2', {
|
||||
get(){ return 777; }
|
||||
});
|
||||
return ',';
|
||||
}
|
||||
}));
|
||||
print(callCount);
|
||||
print(a.join());
|
||||
}
|
||||
print("abc" == arr_join.join(''));
|
@ -30,15 +30,3 @@ NaN
|
||||
NaN
|
||||
NaN0
|
||||
true
|
||||
11-2-321-2-33
|
||||
1
|
||||
1,2,3
|
||||
666,2,3
|
||||
1
|
||||
666,2,3
|
||||
1,2,4
|
||||
1
|
||||
1,2,
|
||||
1,2,777
|
||||
1
|
||||
1,2
|
||||
|
@ -1781,6 +1781,7 @@
|
||||
"mjsunit/enumeration-order.js",
|
||||
"mjsunit/deopt-minus-zero.js",
|
||||
"mjsunit/object-get-own-property-names.js",
|
||||
"mjsunit/array-join-separator-tostring-side-effects.js",
|
||||
"mjsunit/unicodelctest-no-optimization.js",
|
||||
"mjsunit/clone-ic-regression-crbug-1466315.js",
|
||||
"mjsunit/mjsunit-assertion-error.js",
|
||||
|
Loading…
Reference in New Issue
Block a user