mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-11-26 19:50:55 +00:00
!10104 Bug fix when modify proto
Merge pull request !10104 from yinwuxiao/proto
This commit is contained in:
commit
d3b5af8fd7
@ -2151,7 +2151,9 @@ void Builtins::InitializeArray(const JSHandle<GlobalEnv> &env, const JSHandle<JS
|
||||
// Arraybase.prototype
|
||||
JSHandle<JSHClass> arrBaseFuncInstanceHClass = factory_->CreateJSArrayInstanceClass(
|
||||
objFuncPrototypeVal, BuiltinsArray::GetNumPrototypeInlinedProperties());
|
||||
|
||||
// Since we don't want the operations on the array prototype to go through the IR code.
|
||||
// Specially we set the bit of the array prototype to true.
|
||||
arrBaseFuncInstanceHClass->SetIsJSArrayPrototypeModified(true);
|
||||
// Array.prototype
|
||||
JSHandle<JSObject> arrFuncPrototype = factory_->NewJSObjectWithInit(arrBaseFuncInstanceHClass);
|
||||
JSHandle<JSArray>::Cast(arrFuncPrototype)->SetLength(FunctionLength::ZERO);
|
||||
|
@ -151,6 +151,20 @@ JSTaggedValue BuiltinsArkTools::IsSlicedString(EcmaRuntimeCallInfo *info)
|
||||
return GetTaggedBoolean(str->IsSlicedString());
|
||||
}
|
||||
|
||||
JSTaggedValue BuiltinsArkTools::IsStableJsArray(EcmaRuntimeCallInfo *info)
|
||||
{
|
||||
[[maybe_unused]] DisallowGarbageCollection noGc;
|
||||
ASSERT(info);
|
||||
JSThread *thread = info->GetThread();
|
||||
RETURN_IF_DISALLOW_ARKTOOLS(thread);
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
|
||||
ASSERT(info->GetArgsNumber() == 1);
|
||||
JSHandle<JSTaggedValue> object = GetCallArg(info, 0);
|
||||
return (object->IsStableJSArray(thread)) ?
|
||||
GetTaggedBoolean(true) : GetTaggedBoolean(false);
|
||||
}
|
||||
|
||||
JSTaggedValue BuiltinsArkTools::IsNotHoleProperty(EcmaRuntimeCallInfo *info)
|
||||
{
|
||||
[[maybe_unused]] DisallowGarbageCollection noGc;
|
||||
|
@ -85,6 +85,7 @@
|
||||
V("isSmi", IsSmi, 1, INVALID) \
|
||||
V("createPrivateSymbol", CreatePrivateSymbol, 1, INVALID) \
|
||||
V("isArray", IsArray, 1, INVALID) \
|
||||
V("isStableJsArray", IsStableJsArray, 1, INVALID) \
|
||||
V("createDataProperty", CreateDataProperty, 3, INVALID) \
|
||||
V("functionGetInferredName", FunctionGetInferredName, 1, INVALID) \
|
||||
V("stringLessThan", StringLessThan, 2, INVALID) \
|
||||
@ -184,6 +185,8 @@ public:
|
||||
|
||||
static JSTaggedValue IsSlicedString(EcmaRuntimeCallInfo *info);
|
||||
|
||||
static JSTaggedValue IsStableJsArray(EcmaRuntimeCallInfo *info);
|
||||
|
||||
static JSTaggedValue IsNotHoleProperty(EcmaRuntimeCallInfo *info);
|
||||
|
||||
static JSTaggedValue ForcePartialGC(EcmaRuntimeCallInfo *info);
|
||||
|
@ -52,10 +52,20 @@ JSTaggedValue BuiltinsArray::ArrayConstructor(EcmaRuntimeCallInfo *argv)
|
||||
// In NewJSObjectByConstructor(), will get prototype.
|
||||
// 5. ReturnIfAbrupt(proto).
|
||||
|
||||
auto CheckAndSetPrototypeModified = [] (JSThread* thread, const JSHandle<JSObject>& newArrayHandle) {
|
||||
if (!JSArray::IsProtoNotChangeJSArray(thread, newArrayHandle)) {
|
||||
newArrayHandle->GetJSHClass()->SetIsJSArrayPrototypeModified(true);
|
||||
}
|
||||
};
|
||||
|
||||
// 22.1.1.1 Array ( )
|
||||
if (argc == 0) {
|
||||
// 6. Return ArrayCreate(0, proto).
|
||||
return JSArray::ArrayCreate(thread, JSTaggedNumber(0), newTarget).GetTaggedValue();
|
||||
auto arrayHandle = JSArray::ArrayCreate(thread, JSTaggedNumber(0), newTarget);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
auto newArrayHandle = JSHandle<JSObject>::Cast(arrayHandle);
|
||||
CheckAndSetPrototypeModified(thread, newArrayHandle);
|
||||
return newArrayHandle.GetTaggedValue();
|
||||
}
|
||||
|
||||
// 22.1.1.2 Array(len)
|
||||
@ -88,6 +98,7 @@ JSTaggedValue BuiltinsArray::ArrayConstructor(EcmaRuntimeCallInfo *argv)
|
||||
JSArray::SetCapacity(thread, newArrayHandle, 0, newLen, true);
|
||||
|
||||
// 11. Return array.
|
||||
CheckAndSetPrototypeModified(thread, newArrayHandle);
|
||||
return newArrayHandle.GetTaggedValue();
|
||||
}
|
||||
|
||||
@ -149,6 +160,7 @@ JSTaggedValue BuiltinsArray::ArrayConstructor(EcmaRuntimeCallInfo *argv)
|
||||
// 11. Assert: the value of array’s length property is numberOfArgs.
|
||||
// 12. Return array.
|
||||
JSArray::Cast(*newArrayHandle)->SetArrayLength(thread, argc);
|
||||
CheckAndSetPrototypeModified(thread, newArrayHandle);
|
||||
return newArrayHandle.GetTaggedValue();
|
||||
}
|
||||
|
||||
@ -869,12 +881,16 @@ JSTaggedValue BuiltinsArray::Fill(EcmaRuntimeCallInfo *argv)
|
||||
} else {
|
||||
end = argEnd < len ? argEnd : len;
|
||||
}
|
||||
|
||||
if (start < end) {
|
||||
thread->NotifyArrayPrototypeChangedGuardians(thisObjHandle);
|
||||
}
|
||||
|
||||
// 11. Repeat, while k < final
|
||||
// a. Let Pk be ToString(k).
|
||||
// b. Let setStatus be Set(O, Pk, value, true).
|
||||
// c. ReturnIfAbrupt(setStatus).
|
||||
// d. Increase k by 1.
|
||||
|
||||
if (thisObjVal->IsStableJSArray(thread) && !startArg->IsJSObject() && !endArg->IsJSObject()) {
|
||||
return JSStableArray::Fill(thread, thisObjHandle, value, start, end, len);
|
||||
}
|
||||
@ -1651,26 +1667,28 @@ JSTaggedValue BuiltinsArray::Push(EcmaRuntimeCallInfo *argv)
|
||||
JSHandle<JSTaggedValue> thisHandle = GetThis(argv);
|
||||
// 1. Let O be ToObject(this value).
|
||||
JSHandle<JSObject> thisObjHandle = JSTaggedValue::ToObject(thread, thisHandle);
|
||||
// 2. Let argCount be the number of elements in items.
|
||||
uint32_t argc = argv->GetArgsNumber();
|
||||
if (argc > 0) {
|
||||
thread->NotifyArrayPrototypeChangedGuardians(thisObjHandle);
|
||||
}
|
||||
if (thisHandle->IsStableJSArray(thread) && JSObject::IsArrayLengthWritable(thread, thisObjHandle)) {
|
||||
return JSStableArray::Push(JSHandle<JSArray>::Cast(thisHandle), argv);
|
||||
}
|
||||
// 6. Let argCount be the number of elements in items.
|
||||
uint32_t argc = argv->GetArgsNumber();
|
||||
|
||||
// 2. ReturnIfAbrupt(O).
|
||||
// 3. ReturnIfAbrupt(O).
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
JSHandle<JSTaggedValue> thisObjVal(thisObjHandle);
|
||||
|
||||
// 3. Let len be ToLength(Get(O, "length")).
|
||||
// 4. Let len be ToLength(Get(O, "length")).
|
||||
int64_t len = ArrayHelper::GetArrayLength(thread, thisObjVal);
|
||||
// 4. ReturnIfAbrupt(len).
|
||||
// 5. ReturnIfAbrupt(len).
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
// 7. If len + argCount > 253-1, throw a TypeError exception.
|
||||
// 6. If len + argCount > 253-1, throw a TypeError exception.
|
||||
if ((len + static_cast<int64_t>(argc)) > base::MAX_SAFE_INTEGER) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "out of range.", JSTaggedValue::Exception());
|
||||
}
|
||||
|
||||
// 8. Repeat, while items is not empty
|
||||
// 7. Repeat, while items is not empty
|
||||
// a. Remove the first element from items and let E be the value of the element.
|
||||
// b. Let setStatus be Set(O, ToString(len), E, true).
|
||||
// c. ReturnIfAbrupt(setStatus).
|
||||
@ -1686,14 +1704,14 @@ JSTaggedValue BuiltinsArray::Push(EcmaRuntimeCallInfo *argv)
|
||||
len++;
|
||||
}
|
||||
|
||||
// 9. Let setStatus be Set(O, "length", len, true).
|
||||
// 8. Let setStatus be Set(O, "length", len, true).
|
||||
JSHandle<JSTaggedValue> lengthKey = thread->GlobalConstants()->GetHandledLengthString();
|
||||
key.Update(JSTaggedValue(len));
|
||||
JSTaggedValue::SetProperty(thread, thisObjVal, lengthKey, key, true);
|
||||
// 10. ReturnIfAbrupt(setStatus).
|
||||
// 9. ReturnIfAbrupt(setStatus).
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
|
||||
// 11. Return len.
|
||||
// 10. Return len.
|
||||
return GetTaggedDouble(len);
|
||||
}
|
||||
|
||||
@ -2436,6 +2454,7 @@ JSTaggedValue BuiltinsArray::Splice(EcmaRuntimeCallInfo *argv)
|
||||
// c. ReturnIfAbrupt(dc).
|
||||
// d. Let actualDeleteCount be min(max(dc,0), len – actualStart).
|
||||
if (argc > 1) {
|
||||
thread->NotifyArrayPrototypeChangedGuardians(thisObjHandle);
|
||||
insertCount = argc - 2; // 2:2 means there are two arguments before the insert items.
|
||||
JSHandle<JSTaggedValue> msg1 = GetCallArg(argv, 1);
|
||||
JSTaggedNumber argDeleteCount = JSTaggedValue::ToInteger(thread, msg1);
|
||||
@ -2734,19 +2753,16 @@ JSTaggedValue BuiltinsArray::Unshift(EcmaRuntimeCallInfo *argv)
|
||||
|
||||
// 5. Let argCount be the number of actual arguments.
|
||||
int64_t argc = argv->GetArgsNumber();
|
||||
|
||||
// 1. Let O be ToObject(this value).
|
||||
JSHandle<JSTaggedValue> thisHandle = GetThis(argv);
|
||||
JSHandle<JSObject> thisObjHandle = JSTaggedValue::ToObject(thread, thisHandle);
|
||||
// 2. ReturnIfAbrupt(O).
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
JSHandle<JSTaggedValue> thisObjVal(thisObjHandle);
|
||||
|
||||
// 3. Let len be ToLength(Get(O, "length")).
|
||||
int64_t len = ArrayHelper::GetArrayLength(thread, thisObjVal);
|
||||
// 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.
|
||||
@ -2768,6 +2784,7 @@ JSTaggedValue BuiltinsArray::Unshift(EcmaRuntimeCallInfo *argv)
|
||||
if (len + argc > base::MAX_SAFE_INTEGER) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "out of range.", JSTaggedValue::Exception());
|
||||
}
|
||||
thread->NotifyArrayPrototypeChangedGuardians(thisObjHandle);
|
||||
JSMutableHandle<JSTaggedValue> fromKey(thread, JSTaggedValue::Undefined());
|
||||
JSMutableHandle<JSTaggedValue> toKey(thread, JSTaggedValue::Undefined());
|
||||
int64_t k = len;
|
||||
|
@ -179,7 +179,6 @@ void BuiltinsArrayStubBuilder::Unshift(GateRef glue, GateRef thisValue, GateRef
|
||||
Label afterCopy(env);
|
||||
Label grow(env);
|
||||
Label setValue(env);
|
||||
Label matchCls(env);
|
||||
Label numEqual2(env);
|
||||
Label numEqual3(env);
|
||||
Label threeArgs(env);
|
||||
@ -190,9 +189,6 @@ void BuiltinsArrayStubBuilder::Unshift(GateRef glue, GateRef thisValue, GateRef
|
||||
Bind(&isJsArray);
|
||||
BRANCH(IsStableJSArray(glue, thisValue), &isStableJsArray, slowPath);
|
||||
Bind(&isStableJsArray);
|
||||
GateRef arrayCls = LoadHClass(thisValue);
|
||||
ElementsKindHclassCompare(glue, arrayCls, &matchCls, slowPath);
|
||||
Bind(&matchCls);
|
||||
BRANCH(Int64GreaterThan(numArgs, IntPtr(0)), &numNotEqualZero, slowPath);
|
||||
Bind(&numNotEqualZero);
|
||||
GateRef thisLen = ZExtInt32ToInt64(GetArrayLength(thisValue));
|
||||
@ -832,7 +828,6 @@ void BuiltinsArrayStubBuilder::ForEach([[maybe_unused]] GateRef glue, GateRef th
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
Label thisExists(env);
|
||||
Label matchCls(env);
|
||||
Label isHeapObject(env);
|
||||
Label isGeneric(env);
|
||||
Label isJsArray(env);
|
||||
@ -852,9 +847,6 @@ void BuiltinsArrayStubBuilder::ForEach([[maybe_unused]] GateRef glue, GateRef th
|
||||
Bind(&isStability);
|
||||
BRANCH(IsJsCOWArray(thisValue), slowPath, ¬COWArray);
|
||||
Bind(¬COWArray);
|
||||
GateRef arrayCls = LoadHClass(thisValue);
|
||||
ElementsKindHclassCompare(glue, arrayCls, &matchCls, slowPath);
|
||||
Bind(&matchCls);
|
||||
Label arg0HeapObject(env);
|
||||
Label callable(env);
|
||||
Label thisIsStable(env);
|
||||
@ -3066,7 +3058,6 @@ void BuiltinsArrayStubBuilder::Splice(GateRef glue, GateRef thisValue, GateRef n
|
||||
Label isJsArray(env);
|
||||
Label isStability(env);
|
||||
Label defaultConstr(env);
|
||||
Label matchCls(env);
|
||||
Label isGeneric(env);
|
||||
BRANCH(TaggedIsHeapObject(thisValue), &isHeapObject, slowPath);
|
||||
Bind(&isHeapObject);
|
||||
@ -3080,8 +3071,6 @@ void BuiltinsArrayStubBuilder::Splice(GateRef glue, GateRef thisValue, GateRef n
|
||||
BRANCH(IsJsCOWArray(thisValue), slowPath, ¬COWArray);
|
||||
Bind(¬COWArray);
|
||||
GateRef arrayCls = LoadHClass(thisValue);
|
||||
ElementsKindHclassCompare(glue, arrayCls, &matchCls, slowPath);
|
||||
Bind(&matchCls);
|
||||
GateRef arrayLen = GetArrayLength(thisValue);
|
||||
Label lessThreeArg(env);
|
||||
|
||||
@ -3349,7 +3338,6 @@ void BuiltinsArrayStubBuilder::ToSpliced(GateRef glue, GateRef thisValue, GateRe
|
||||
Label isJsArray(env);
|
||||
Label isStability(env);
|
||||
Label defaultConstr(env);
|
||||
Label matchCls(env);
|
||||
Label isGeneric(env);
|
||||
BRANCH(TaggedIsHeapObject(thisValue), &isHeapObject, slowPath);
|
||||
Bind(&isHeapObject);
|
||||
@ -3362,9 +3350,6 @@ void BuiltinsArrayStubBuilder::ToSpliced(GateRef glue, GateRef thisValue, GateRe
|
||||
Label notCOWArray(env);
|
||||
BRANCH(IsJsCOWArray(thisValue), slowPath, ¬COWArray);
|
||||
Bind(¬COWArray);
|
||||
GateRef arrayCls = LoadHClass(thisValue);
|
||||
ElementsKindHclassCompare(glue, arrayCls, &matchCls, slowPath);
|
||||
Bind(&matchCls);
|
||||
GateRef thisLen = GetArrayLength(thisValue);
|
||||
Label lessThreeArg(env);
|
||||
DEFVARIABLE(actualStart, VariableType::INT32(), Int32(0));
|
||||
@ -3581,7 +3566,6 @@ void BuiltinsArrayStubBuilder::CopyWithin(GateRef glue, GateRef thisValue, GateR
|
||||
Label isStability(env);
|
||||
Label isGeneric(env);
|
||||
Label notCOWArray(env);
|
||||
Label matchCls(env);
|
||||
BRANCH(TaggedIsUndefinedOrNull(thisValue), slowPath, &thisExists);
|
||||
Bind(&thisExists);
|
||||
BRANCH(TaggedIsHeapObject(thisValue), &isHeapObject, slowPath);
|
||||
@ -3594,9 +3578,6 @@ void BuiltinsArrayStubBuilder::CopyWithin(GateRef glue, GateRef thisValue, GateR
|
||||
Bind(&isStability);
|
||||
BRANCH(IsJsCOWArray(thisValue), slowPath, ¬COWArray);
|
||||
Bind(¬COWArray);
|
||||
GateRef arrayCls = LoadHClass(thisValue);
|
||||
ElementsKindHclassCompare(glue, arrayCls, &matchCls, slowPath);
|
||||
Bind(&matchCls);
|
||||
DEFVARIABLE(startPos, VariableType::INT64(), Int64(0));
|
||||
DEFVARIABLE(endPos, VariableType::INT64(), Int64(0));
|
||||
Label targetTagExists(env);
|
||||
@ -3797,7 +3778,6 @@ void BuiltinsArrayStubBuilder::Some(GateRef glue, GateRef thisValue, GateRef num
|
||||
Label isStability(env);
|
||||
Label notCOWArray(env);
|
||||
Label equalCls(env);
|
||||
Label matchCls(env);
|
||||
Label isGeneric(env);
|
||||
BRANCH(TaggedIsUndefinedOrNull(thisValue), slowPath, &thisExists);
|
||||
Bind(&thisExists);
|
||||
@ -3811,9 +3791,6 @@ void BuiltinsArrayStubBuilder::Some(GateRef glue, GateRef thisValue, GateRef num
|
||||
Bind(&isStability);
|
||||
BRANCH(IsJsCOWArray(thisValue), slowPath, ¬COWArray);
|
||||
Bind(¬COWArray);
|
||||
GateRef arrayCls = LoadHClass(thisValue);
|
||||
ElementsKindHclassCompare(glue, arrayCls, &matchCls, slowPath);
|
||||
Bind(&matchCls);
|
||||
Label arg0HeapObject(env);
|
||||
Label callable(env);
|
||||
Label thisIsStable(env);
|
||||
@ -4000,7 +3977,6 @@ void BuiltinsArrayStubBuilder::Every(GateRef glue, GateRef thisValue, GateRef nu
|
||||
Label equalCls(env);
|
||||
Label arg0HeapObject(env);
|
||||
Label callable(env);
|
||||
Label matchCls(env);
|
||||
Label isGeneric(env);
|
||||
BRANCH(TaggedIsUndefinedOrNull(thisValue), slowPath, &thisExists);
|
||||
Bind(&thisExists);
|
||||
@ -4014,9 +3990,6 @@ void BuiltinsArrayStubBuilder::Every(GateRef glue, GateRef thisValue, GateRef nu
|
||||
Bind(&isStability);
|
||||
BRANCH(IsJsCOWArray(thisValue), slowPath, ¬COWArray);
|
||||
Bind(¬COWArray);
|
||||
GateRef arrayCls = LoadHClass(thisValue);
|
||||
ElementsKindHclassCompare(glue, arrayCls, &matchCls, slowPath);
|
||||
Bind(&matchCls);
|
||||
GateRef callbackFnHandle = GetCallArg0(numArgs);
|
||||
BRANCH(TaggedIsHeapObject(callbackFnHandle), &arg0HeapObject, slowPath);
|
||||
Bind(&arg0HeapObject);
|
||||
@ -4187,7 +4160,6 @@ void BuiltinsArrayStubBuilder::ReduceRight(GateRef glue, GateRef thisValue, Gate
|
||||
Label isStability(env);
|
||||
Label notCOWArray(env);
|
||||
Label equalCls(env);
|
||||
Label matchCls(env);
|
||||
Label isGeneric(env);
|
||||
BRANCH(TaggedIsUndefinedOrNull(thisValue), slowPath, &thisExists);
|
||||
Bind(&thisExists);
|
||||
@ -4201,9 +4173,6 @@ void BuiltinsArrayStubBuilder::ReduceRight(GateRef glue, GateRef thisValue, Gate
|
||||
Bind(&isStability);
|
||||
BRANCH(IsJsCOWArray(thisValue), slowPath, ¬COWArray);
|
||||
Bind(¬COWArray);
|
||||
GateRef arrayCls = LoadHClass(thisValue);
|
||||
ElementsKindHclassCompare(glue, arrayCls, &matchCls, slowPath);
|
||||
Bind(&matchCls);
|
||||
DEFVARIABLE(thisLen, VariableType::INT32(), Int32(0));
|
||||
DEFVARIABLE(accumulator, VariableType::JS_ANY(), Undefined());
|
||||
DEFVARIABLE(k, VariableType::INT32(), Int32(0));
|
||||
@ -4391,7 +4360,6 @@ void BuiltinsArrayStubBuilder::FindLastIndex(GateRef glue, GateRef thisValue, Ga
|
||||
Label notCOWArray(env);
|
||||
Label equalCls(env);
|
||||
Label isGeneric(env);
|
||||
Label matchCls(env);
|
||||
BRANCH(TaggedIsUndefinedOrNull(thisValue), slowPath, &thisExists);
|
||||
Bind(&thisExists);
|
||||
BRANCH(TaggedIsHeapObject(thisValue), &isHeapObject, slowPath);
|
||||
@ -4404,9 +4372,6 @@ void BuiltinsArrayStubBuilder::FindLastIndex(GateRef glue, GateRef thisValue, Ga
|
||||
Bind(&isStability);
|
||||
BRANCH(IsJsCOWArray(thisValue), slowPath, ¬COWArray);
|
||||
Bind(¬COWArray);
|
||||
GateRef arrayCls = LoadHClass(thisValue);
|
||||
ElementsKindHclassCompare(glue, arrayCls, &matchCls, slowPath);
|
||||
Bind(&matchCls);
|
||||
Label arg0HeapObject(env);
|
||||
Label callable(env);
|
||||
Label thisIsStable(env);
|
||||
@ -4582,7 +4547,6 @@ void BuiltinsArrayStubBuilder::FindLast(GateRef glue, GateRef thisValue, GateRef
|
||||
Label isStability(env);
|
||||
Label notCOWArray(env);
|
||||
Label equalCls(env);
|
||||
Label matchCls(env);
|
||||
Label isGeneric(env);
|
||||
BRANCH(TaggedIsUndefinedOrNull(thisValue), slowPath, &thisExists);
|
||||
Bind(&thisExists);
|
||||
@ -4596,9 +4560,6 @@ void BuiltinsArrayStubBuilder::FindLast(GateRef glue, GateRef thisValue, GateRef
|
||||
Bind(&isStability);
|
||||
BRANCH(IsJsCOWArray(thisValue), slowPath, ¬COWArray);
|
||||
Bind(¬COWArray);
|
||||
GateRef arrayCls = LoadHClass(thisValue);
|
||||
ElementsKindHclassCompare(glue, arrayCls, &matchCls, slowPath);
|
||||
Bind(&matchCls);
|
||||
Label arg0HeapObject(env);
|
||||
Label callable(env);
|
||||
Label thisIsStable(env);
|
||||
@ -4971,7 +4932,6 @@ void BuiltinsArrayStubBuilder::FlatMap(GateRef glue, GateRef thisValue, GateRef
|
||||
Label isStability(env);
|
||||
Label notCOWArray(env);
|
||||
Label equalCls(env);
|
||||
Label matchCls(env);
|
||||
Label isGeneric(env);
|
||||
BRANCH(TaggedIsUndefinedOrNull(thisValue), slowPath, &thisExists);
|
||||
Bind(&thisExists);
|
||||
@ -4985,9 +4945,6 @@ void BuiltinsArrayStubBuilder::FlatMap(GateRef glue, GateRef thisValue, GateRef
|
||||
Bind(&isStability);
|
||||
BRANCH(IsJsCOWArray(thisValue), slowPath, ¬COWArray);
|
||||
Bind(¬COWArray);
|
||||
GateRef arrayCls = LoadHClass(thisValue);
|
||||
ElementsKindHclassCompare(glue, arrayCls, &matchCls, slowPath);
|
||||
Bind(&matchCls);
|
||||
Label arg0HeapObject(env);
|
||||
Label callable(env);
|
||||
Label thisIsStable(env);
|
||||
|
@ -472,6 +472,7 @@ public:
|
||||
inline GateRef IsStableArguments(GateRef hClass);
|
||||
inline GateRef IsStableArray(GateRef hClass);
|
||||
inline GateRef IsDictionaryElement(GateRef hClass);
|
||||
inline GateRef IsJSArrayPrototypeModified(GateRef hClass);
|
||||
inline GateRef IsClassConstructor(GateRef object);
|
||||
inline GateRef IsClassConstructorWithBitField(GateRef bitfield);
|
||||
inline GateRef IsConstructor(GateRef object);
|
||||
@ -481,7 +482,7 @@ public:
|
||||
inline GateRef IsJSObject(GateRef obj);
|
||||
inline GateRef IsCallable(GateRef obj);
|
||||
inline GateRef IsCallableFromBitField(GateRef bitfield);
|
||||
inline GateRef IsProtoTypeHClass(GateRef hclass);
|
||||
inline GateRef IsPrototypeHClass(GateRef hclass);
|
||||
inline GateRef IsJsProxy(GateRef obj);
|
||||
GateRef IsJSHClass(GateRef obj);
|
||||
inline void StoreHClass(GateRef glue, GateRef object, GateRef hClass);
|
||||
|
@ -92,8 +92,8 @@ namespace panda::ecmascript::kungfu {
|
||||
V(BuiltinInstanceHClassMismatch2, BUILTININSTANCEHCLASSMISMATCH2) \
|
||||
V(BuiltinPrototypeHClassMismatch1, BUILTINPROTOHCLASSMISMATCH1) \
|
||||
V(BuiltinPrototypeHClassMismatch2, BUILTINPROTOHCLASSMISMATCH2) \
|
||||
V(ProtoTypeChanged1, PROTOTYPECHANGED1) \
|
||||
V(ProtoTypeChanged2, PROTOTYPECHANGED2) \
|
||||
V(PrototypeChanged1, PROTOTYPECHANGED1) \
|
||||
V(PrototypeChanged2, PROTOTYPECHANGED2) \
|
||||
V(BuiltinIsHole1, BUILTINISHOLE1) \
|
||||
V(NewBuiltinCtorFail1, NEWBUILTINCTORFAIL1) \
|
||||
V(NewBuiltinCtorObject, NEWBUILTINCTOROBJECT) \
|
||||
|
@ -589,7 +589,7 @@ GateRef CircuitBuilder::IsStabelArray(GateRef glue, GateRef obj)
|
||||
Bind(&targetIsStableArray);
|
||||
{
|
||||
GateRef guardiansOffset =
|
||||
IntPtr(JSThread::GlueData::GetStableArrayElementsGuardiansOffset(false));
|
||||
IntPtr(JSThread::GlueData::GetArrayElementsGuardiansOffset(false));
|
||||
result = Load(VariableType::BOOL(), glue, guardiansOffset);
|
||||
Jump(&exit);
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ GateRef CircuitBuilder::IsCallable(GateRef obj)
|
||||
return IsCallableFromBitField(bitfield);
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::IsProtoTypeHClass(GateRef hClass)
|
||||
GateRef CircuitBuilder::IsPrototypeHClass(GateRef hClass)
|
||||
{
|
||||
GateRef bitfield = LoadConstOffset(VariableType::INT32(), hClass, JSHClass::BIT_FIELD_OFFSET);
|
||||
return TruncInt32ToInt1(Int32And(Int32LSR(bitfield,
|
||||
@ -300,6 +300,16 @@ GateRef CircuitBuilder::IsStableElements(GateRef hClass)
|
||||
Int32(0));
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::IsJSArrayPrototypeModified(GateRef hClass)
|
||||
{
|
||||
GateRef bitfieldOffset = Int32(JSHClass::BIT_FIELD_OFFSET);
|
||||
GateRef bitfield = Load(VariableType::INT32(), hClass, bitfieldOffset);
|
||||
return NotEqual(Int32And(Int32LSR(bitfield,
|
||||
Int32(JSHClass::IsJSArrayPrototypeModifiedBit::START_BIT)),
|
||||
Int32((1LU << JSHClass::IsJSArrayPrototypeModifiedBit::SIZE) - 1)),
|
||||
Int32(0));
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::HasConstructor(GateRef object)
|
||||
{
|
||||
GateRef hClass = LoadHClass(object);
|
||||
|
@ -283,7 +283,7 @@ void MCRLowering::LowerArrayGuardianCheck(GateRef gate)
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
|
||||
GateRef frameState = acc_.GetFrameState(gate);
|
||||
GateRef guardiansOffset = builder_.IntPtr(JSThread::GlueData::GetStableArrayElementsGuardiansOffset(false));
|
||||
GateRef guardiansOffset = builder_.IntPtr(JSThread::GlueData::GetArrayElementsGuardiansOffset(false));
|
||||
GateRef check = builder_.Load(VariableType::BOOL(), glue_, guardiansOffset);
|
||||
builder_.DeoptCheck(check, frameState, DeoptType::NOTSARRAY1);
|
||||
|
||||
|
@ -49,7 +49,7 @@ bool ClassParser::RecordTypeInfo(const PGODefineOpType &defType, const PGOTypeLo
|
||||
}
|
||||
PGOSampleType ctorSampleType(ctorPt);
|
||||
|
||||
auto protoPt = defType.GetProtoTypePt();
|
||||
auto protoPt = defType.GetPrototypePt();
|
||||
if (protoPt.IsNone()) {
|
||||
return false;
|
||||
}
|
||||
@ -136,7 +136,7 @@ bool FunctionParser::RecordTypeInfo(const PGODefineOpType &defType, const PGOTyp
|
||||
}
|
||||
PGOSampleType ctorSampleType(ctorPt);
|
||||
|
||||
auto protoPt = defType.GetProtoTypePt();
|
||||
auto protoPt = defType.GetPrototypePt();
|
||||
if (protoPt.IsNone()) {
|
||||
return false;
|
||||
}
|
||||
|
@ -1313,6 +1313,11 @@ inline GateRef StubBuilder::IsDictionaryElement(GateRef hClass)
|
||||
return env_->GetBuilder()->IsDictionaryElement(hClass);
|
||||
}
|
||||
|
||||
inline GateRef StubBuilder::IsJSArrayPrototypeModified(GateRef hClass)
|
||||
{
|
||||
return env_->GetBuilder()->IsJSArrayPrototypeModified(hClass);
|
||||
}
|
||||
|
||||
inline GateRef StubBuilder::IsClassConstructorFromBitField(GateRef bitfield)
|
||||
{
|
||||
// decode
|
||||
@ -2161,7 +2166,7 @@ inline void StubBuilder::SetParentToHClass(VariableType type, GateRef glue, Gate
|
||||
Store(type, glue, hClass, offset, parent);
|
||||
}
|
||||
|
||||
inline void StubBuilder::SetIsProtoTypeToHClass(GateRef glue, GateRef hClass, GateRef value)
|
||||
inline void StubBuilder::SetIsPrototypeToHClass(GateRef glue, GateRef hClass, GateRef value)
|
||||
{
|
||||
GateRef oldValue = ZExtInt1ToInt32(value);
|
||||
GateRef bitfield = GetBitFieldFromHClass(hClass);
|
||||
@ -2185,7 +2190,7 @@ inline void StubBuilder::SetIsAOT(GateRef glue, GateRef hClass, GateRef value)
|
||||
SetBitFieldToHClass(glue, hClass, newVal);
|
||||
}
|
||||
|
||||
inline GateRef StubBuilder::IsProtoTypeHClass(GateRef hClass)
|
||||
inline GateRef StubBuilder::IsPrototypeHClass(GateRef hClass)
|
||||
{
|
||||
GateRef bitfield = GetBitFieldFromHClass(hClass);
|
||||
return TruncInt32ToInt1(Int32And(Int32LSR(bitfield,
|
||||
|
@ -1349,7 +1349,7 @@ void StubBuilder::JSHClassAddProperty(GateRef glue, GateRef receiver, GateRef ke
|
||||
Label needUpdateAOTHClass(env);
|
||||
Label normalNotify(env);
|
||||
Label endUpdate(env);
|
||||
GateRef updateCondition = LogicAndBuilder(env).And(isAOTHClass).And(IsProtoTypeHClass(newClass)).Done();
|
||||
GateRef updateCondition = LogicAndBuilder(env).And(isAOTHClass).And(IsPrototypeHClass(newClass)).Done();
|
||||
Branch(updateCondition, &needUpdateAOTHClass, &normalNotify);
|
||||
Bind(&needUpdateAOTHClass);
|
||||
{
|
||||
@ -3849,7 +3849,7 @@ GateRef StubBuilder::AddElementInternal(GateRef glue, GateRef receiver, GateRef
|
||||
}
|
||||
Bind(¬Array);
|
||||
{
|
||||
NotifyStableArrayElementsGuardians(glue, receiver);
|
||||
NotifyArrayPrototypeChangedGuardians(glue, receiver);
|
||||
GateRef hclass = LoadHClass(receiver);
|
||||
GateRef elements = GetElementsArray(receiver);
|
||||
Label isDicMode(env);
|
||||
@ -3991,35 +3991,35 @@ GateRef StubBuilder::ShouldTransToDict(GateRef capacity, GateRef index)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void StubBuilder::NotifyStableArrayElementsGuardians(GateRef glue, GateRef receiver)
|
||||
void StubBuilder::NotifyArrayPrototypeChangedGuardians(GateRef glue, GateRef receiver)
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
Label subEntry(env);
|
||||
env->SubCfgEntry(&subEntry);
|
||||
Label exit(env);
|
||||
GateRef guardiansOffset =
|
||||
IntPtr(JSThread::GlueData::GetStableArrayElementsGuardiansOffset(env->Is32Bit()));
|
||||
IntPtr(JSThread::GlueData::GetArrayElementsGuardiansOffset(env->Is32Bit()));
|
||||
GateRef guardians = Load(VariableType::BOOL(), glue, guardiansOffset);
|
||||
Label isGuardians(env);
|
||||
BRANCH(Equal(guardians, True()), &isGuardians, &exit);
|
||||
Bind(&isGuardians);
|
||||
{
|
||||
GateRef hclass = LoadHClass(receiver);
|
||||
Label isProtoType(env);
|
||||
BRANCH(BitOr(IsProtoTypeHClass(hclass), IsJsArray(receiver)), &isProtoType, &exit);
|
||||
Bind(&isProtoType);
|
||||
Label isPrototype(env);
|
||||
BRANCH(BitOr(IsPrototypeHClass(hclass), IsJsArray(receiver)), &isPrototype, &exit);
|
||||
Bind(&isPrototype);
|
||||
{
|
||||
Label isEnvProtoType(env);
|
||||
Label isEnvPrototype(env);
|
||||
GateRef glueGlobalEnvOffset = IntPtr(JSThread::GlueData::GetGlueGlobalEnvOffset(env->Is32Bit()));
|
||||
GateRef glueGlobalEnv = Load(VariableType::NATIVE_POINTER(), glue, glueGlobalEnvOffset);
|
||||
GateRef isEnvProtoTypeCheck = LogicOrBuilder(env)
|
||||
GateRef isEnvPrototypeCheck = LogicOrBuilder(env)
|
||||
.Or(Equal(GetGlobalEnvValue(VariableType::JS_ANY(), glueGlobalEnv,
|
||||
GlobalEnv::OBJECT_FUNCTION_PROTOTYPE_INDEX), receiver))
|
||||
.Or(Equal(GetGlobalEnvValue(VariableType::JS_ANY(), glueGlobalEnv,
|
||||
GlobalEnv::ARRAY_PROTOTYPE_INDEX), receiver))
|
||||
.Done();
|
||||
BRANCH(isEnvProtoTypeCheck, &isEnvProtoType, &exit);
|
||||
Bind(&isEnvProtoType);
|
||||
BRANCH(isEnvPrototypeCheck, &isEnvPrototype, &exit);
|
||||
Bind(&isEnvPrototype);
|
||||
Store(VariableType::BOOL(), glue, glue, guardiansOffset, False());
|
||||
Jump(&exit);
|
||||
}
|
||||
@ -5347,15 +5347,15 @@ void StubBuilder::NotifyHClassChanged(GateRef glue, GateRef oldHClass, GateRef n
|
||||
Label entry(env);
|
||||
env->SubCfgEntry(&entry);
|
||||
Label exit(env);
|
||||
Label isProtoType(env);
|
||||
BRANCH(IsProtoTypeHClass(oldHClass), &isProtoType, &exit);
|
||||
Bind(&isProtoType);
|
||||
Label isPrototype(env);
|
||||
BRANCH(IsPrototypeHClass(oldHClass), &isPrototype, &exit);
|
||||
Bind(&isPrototype);
|
||||
{
|
||||
Label notEqualHClass(env);
|
||||
BRANCH(Equal(oldHClass, newHClass), &exit, ¬EqualHClass);
|
||||
Bind(¬EqualHClass);
|
||||
{
|
||||
SetIsProtoTypeToHClass(glue, newHClass, True());
|
||||
SetIsPrototypeToHClass(glue, newHClass, True());
|
||||
CallRuntime(glue, RTSTUB_ID(NoticeThroughChainAndRefreshUser), { oldHClass, newHClass });
|
||||
Jump(&exit);
|
||||
}
|
||||
@ -9208,7 +9208,7 @@ GateRef StubBuilder::HasStableElements(GateRef glue, GateRef obj)
|
||||
Bind(&targetIsStableElements);
|
||||
{
|
||||
GateRef guardiansOffset =
|
||||
IntPtr(JSThread::GlueData::GetStableArrayElementsGuardiansOffset(env->Is32Bit()));
|
||||
IntPtr(JSThread::GlueData::GetArrayElementsGuardiansOffset(env->Is32Bit()));
|
||||
result = Load(VariableType::BOOL(), glue, guardiansOffset);
|
||||
Jump(&exit);
|
||||
}
|
||||
@ -9237,7 +9237,7 @@ GateRef StubBuilder::IsStableJSArguments(GateRef glue, GateRef obj)
|
||||
Bind(&targetIsStableArguments);
|
||||
{
|
||||
GateRef guardiansOffset =
|
||||
IntPtr(JSThread::GlueData::GetStableArrayElementsGuardiansOffset(env->Is32Bit()));
|
||||
IntPtr(JSThread::GlueData::GetArrayElementsGuardiansOffset(env->Is32Bit()));
|
||||
result = Load(VariableType::BOOL(), glue, guardiansOffset);
|
||||
Jump(&exit);
|
||||
}
|
||||
@ -9257,19 +9257,23 @@ GateRef StubBuilder::IsStableJSArray(GateRef glue, GateRef obj)
|
||||
Label exit(env);
|
||||
Label targetIsHeapObject(env);
|
||||
Label targetIsStableArray(env);
|
||||
|
||||
BRANCH(TaggedIsHeapObject(obj), &targetIsHeapObject, &exit);
|
||||
Bind(&targetIsHeapObject);
|
||||
{
|
||||
GateRef jsHclass = LoadHClass(obj);
|
||||
BRANCH(IsStableArray(jsHclass), &targetIsStableArray, &exit);
|
||||
GateRef jsHClass = LoadHClass(obj);
|
||||
BRANCH(IsStableArray(jsHClass), &targetIsStableArray, &exit);
|
||||
Bind(&targetIsStableArray);
|
||||
{
|
||||
GateRef guardiansOffset =
|
||||
IntPtr(JSThread::GlueData::GetStableArrayElementsGuardiansOffset(env->Is32Bit()));
|
||||
GateRef guardians = Load(VariableType::BOOL(), glue, guardiansOffset);
|
||||
result.WriteVariable(guardians);
|
||||
Jump(&exit);
|
||||
Label isPrototypeNotModified(env);
|
||||
BRANCH(IsJSArrayPrototypeModified(jsHClass), &exit, &isPrototypeNotModified);
|
||||
Bind(&isPrototypeNotModified);
|
||||
{
|
||||
GateRef guardiansOffset =
|
||||
IntPtr(JSThread::GlueData::GetArrayElementsGuardiansOffset(env->Is32Bit()));
|
||||
GateRef guardians = Load(VariableType::BOOL(), glue, guardiansOffset);
|
||||
result.WriteVariable(guardians);
|
||||
Jump(&exit);
|
||||
}
|
||||
}
|
||||
}
|
||||
Bind(&exit);
|
||||
|
@ -399,6 +399,7 @@ public:
|
||||
GateRef IsDictionaryMode(GateRef object);
|
||||
GateRef IsDictionaryModeByHClass(GateRef hClass);
|
||||
GateRef IsDictionaryElement(GateRef hClass);
|
||||
GateRef IsJSArrayPrototypeModified(GateRef hClass);
|
||||
GateRef IsStableElements(GateRef hClass);
|
||||
GateRef HasConstructorByHClass(GateRef hClass);
|
||||
GateRef HasConstructor(GateRef object);
|
||||
@ -549,9 +550,9 @@ public:
|
||||
void SetEnumCacheToHClass(VariableType type, GateRef glue, GateRef hClass, GateRef key);
|
||||
void SetTransitionsToHClass(VariableType type, GateRef glue, GateRef hClass, GateRef transition);
|
||||
void SetParentToHClass(VariableType type, GateRef glue, GateRef hClass, GateRef parent);
|
||||
void SetIsProtoTypeToHClass(GateRef glue, GateRef hClass, GateRef value);
|
||||
void SetIsPrototypeToHClass(GateRef glue, GateRef hClass, GateRef value);
|
||||
inline void SetIsAOT(GateRef glue, GateRef hClass, GateRef value);
|
||||
GateRef IsProtoTypeHClass(GateRef hClass);
|
||||
GateRef IsPrototypeHClass(GateRef hClass);
|
||||
void SetPropertyInlinedProps(GateRef glue, GateRef obj, GateRef hClass,
|
||||
GateRef value, GateRef attrOffset, VariableType type = VariableType::JS_ANY(),
|
||||
MemoryAttribute mAttr = MemoryAttribute::Default());
|
||||
@ -845,7 +846,7 @@ public:
|
||||
GateRef GetGlobalOwnProperty(GateRef glue, GateRef receiver, GateRef key, ProfileOperation callback);
|
||||
GateRef AddElementInternal(GateRef glue, GateRef receiver, GateRef index, GateRef value, GateRef attr);
|
||||
GateRef ShouldTransToDict(GateRef capcity, GateRef index);
|
||||
void NotifyStableArrayElementsGuardians(GateRef glue, GateRef receiver);
|
||||
void NotifyArrayPrototypeChangedGuardians(GateRef glue, GateRef receiver);
|
||||
GateRef GrowElementsCapacity(GateRef glue, GateRef receiver, GateRef capacity);
|
||||
|
||||
inline GateRef GetObjectFromConstPool(GateRef constpool, GateRef index);
|
||||
|
@ -889,11 +889,11 @@ void TypedBytecodeLowering::TypedStObjByNameTransition(GateRef gate, GateRef rec
|
||||
builder_.StoreConstOffset(VariableType::JS_ANY(), newHolderHC, JSHClass::PROTOTYPE_OFFSET, prototype);
|
||||
}
|
||||
if (!tacc.IsPrototypeHclass(i)) {
|
||||
builder_.DeoptCheck(builder_.BoolNot(builder_.IsProtoTypeHClass(receiverHC)), frameState,
|
||||
builder_.DeoptCheck(builder_.BoolNot(builder_.IsPrototypeHClass(receiverHC)), frameState,
|
||||
DeoptType::PROTOTYPECHANGED2);
|
||||
} else {
|
||||
builder_.Branch(builder_.IsProtoTypeHClass(receiverHC), &isProto, ¬Proto,
|
||||
BranchWeight::ONE_WEIGHT, BranchWeight::DEOPT_WEIGHT, "isProtoTypeHClass");
|
||||
builder_.Branch(builder_.IsPrototypeHClass(receiverHC), &isProto, ¬Proto,
|
||||
BranchWeight::ONE_WEIGHT, BranchWeight::DEOPT_WEIGHT, "isPrototypeHClass");
|
||||
builder_.Bind(&isProto);
|
||||
GateRef propKey =
|
||||
builder_.GetObjectByIndexFromConstPool(glue_, gate, frameState,
|
||||
|
@ -2827,11 +2827,11 @@ void TypedHCRLowering::LowerMonoStoreProperty(GateRef gate, GateRef glue)
|
||||
builder_.StoreConstOffset(VariableType::JS_ANY(), newHolderHC, JSHClass::PROTOTYPE_OFFSET, prototype);
|
||||
}
|
||||
if (!isPrototype) {
|
||||
builder_.DeoptCheck(builder_.BoolNot(builder_.IsProtoTypeHClass(receiverHC)), frameState,
|
||||
builder_.DeoptCheck(builder_.BoolNot(builder_.IsPrototypeHClass(receiverHC)), frameState,
|
||||
DeoptType::PROTOTYPECHANGED2);
|
||||
} else {
|
||||
builder_.Branch(builder_.IsProtoTypeHClass(receiverHC), &isProto, ¬Proto,
|
||||
BranchWeight::ONE_WEIGHT, BranchWeight::DEOPT_WEIGHT, "isProtoTypeHClass");
|
||||
builder_.Branch(builder_.IsPrototypeHClass(receiverHC), &isProto, ¬Proto,
|
||||
BranchWeight::ONE_WEIGHT, BranchWeight::DEOPT_WEIGHT, "isPrototypeHClass");
|
||||
builder_.Bind(&isProto);
|
||||
|
||||
GateRef propKey =
|
||||
|
@ -565,7 +565,7 @@ CString *HeapSnapshot::GenerateNodeName(TaggedObject *entry)
|
||||
case JSType::GLOBAL_ENV:
|
||||
return GetString("GlobalEnv");
|
||||
case JSType::PROTOTYPE_HANDLER:
|
||||
return GetString("ProtoTypeHandler");
|
||||
return GetString("PrototypeHandler");
|
||||
case JSType::TRANSITION_HANDLER:
|
||||
return GetString("TransitionHandler");
|
||||
case JSType::TRANS_WITH_PROTO_HANDLER:
|
||||
|
@ -663,7 +663,6 @@ static void DumpHClass(const JSHClass *jshclass, std::ostream &os, bool withDeta
|
||||
os << "| NumberOfProps :" << std::dec << jshclass->NumberOfProps();
|
||||
os << "| InlinedProperties :" << std::dec << jshclass->GetInlinedProperties();
|
||||
os << "| IsAOT :" << std::boolalpha << jshclass->IsAOT();
|
||||
os << "| Level :" << std::dec << static_cast<int>(jshclass->GetLevel());
|
||||
os << "\n";
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,6 @@ public:
|
||||
const JSHandle<T> &value, ElementsKind kind);
|
||||
static bool IsDictionaryMode(JSHandle<JSObject> receiver);
|
||||
static bool IsDictionaryMode(JSObject *receiver);
|
||||
|
||||
static uint32_t GetElementsLength(JSHandle<JSObject> receiver);
|
||||
static uint32_t GetElementsLength(JSObject *receiver);
|
||||
|
||||
|
@ -774,4 +774,20 @@ void JSArray::CheckAndCopyArray(const JSThread *thread, JSHandle<JSArray> obj)
|
||||
obj->SetProperties(thread, newProps.GetTaggedValue());
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
bool JSArray::IsProtoNotChangeJSArray(JSThread *thread, const JSHandle<JSObject> &obj)
|
||||
{
|
||||
if (obj->IsJSArray()) {
|
||||
if (obj->GetJSHClass()->GetElementsKind() != ElementsKind::GENERIC) {
|
||||
return true;
|
||||
}
|
||||
JSTaggedValue arrayProtoValue = obj->GetJSHClass()->GetProto();
|
||||
JSTaggedValue genericArrayHClass = thread->GlobalConstants()->GetElementHoleTaggedClass();
|
||||
JSTaggedValue genericArrayProtoValue = \
|
||||
JSHClass::Cast(genericArrayHClass.GetTaggedObject())->GetProto();
|
||||
return genericArrayProtoValue == arrayProtoValue;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} // namespace panda::ecmascript
|
||||
|
@ -45,6 +45,7 @@ public:
|
||||
const PropertyDescriptor &desc);
|
||||
|
||||
static bool IsLengthString(JSThread *thread, const JSHandle<JSTaggedValue> &key);
|
||||
static bool IsProtoNotChangeJSArray(JSThread *thread, const JSHandle<JSObject> &obj);
|
||||
// ecma6 7.3 Operations on Objects
|
||||
static JSHandle<JSArray> CreateArrayFromList(JSThread *thread, const JSHandle<TaggedArray> &elements);
|
||||
static JSHandle<JSArray> CreateArrayFromList(JSThread *thread, const JSHandle<JSTaggedValue> &newtarget,
|
||||
|
@ -147,7 +147,6 @@ void JSHClass::InitializeWithDefaultValue(const JSThread *thread, uint32_t size,
|
||||
SetProtoChangeMarker(thread, JSTaggedValue::Null());
|
||||
SetProtoChangeDetails(thread, JSTaggedValue::Null());
|
||||
SetEnumCache(thread, JSTaggedValue::Null());
|
||||
SetLevel(0);
|
||||
}
|
||||
|
||||
bool JSHClass::IsJSTypeShared(JSType type)
|
||||
@ -492,7 +491,10 @@ void JSHClass::SetPrototypeTransition(JSThread *thread, const JSHandle<JSObject>
|
||||
auto newClass = SetPrototypeWithNotification(thread, hclass, proto, isChangeProto);
|
||||
RestoreElementsKindToGeneric(*newClass);
|
||||
object->SynchronizedSetClass(thread, *newClass);
|
||||
thread->NotifyStableArrayElementsGuardians(object, StableArrayChangeKind::PROTO);
|
||||
if (object->IsJSArray()) {
|
||||
thread->NotifyArrayPrototypeChangedGuardians(object);
|
||||
newClass->SetIsJSArrayPrototypeModified(true);
|
||||
}
|
||||
ObjectOperator::UpdateDetectorOnSetPrototype(thread, object.GetTaggedValue());
|
||||
}
|
||||
|
||||
|
@ -395,10 +395,10 @@ public:
|
||||
using IsClassConstructorOrPrototypeBit = HasConstructorBits::NextFlag; // 22
|
||||
using IsNativeBindingObjectBit = IsClassConstructorOrPrototypeBit::NextFlag; // 23
|
||||
using IsAOTBit = IsNativeBindingObjectBit::NextFlag; // 24
|
||||
using LevelBit = IsAOTBit::NextField<uint32_t, LEVEL_BTTFIELD_NUM>; // 25-29
|
||||
using IsJSFunctionBit = LevelBit::NextFlag; // 30
|
||||
using IsOnHeap = IsJSFunctionBit::NextFlag; // 31
|
||||
using IsJSSharedBit = IsOnHeap::NextFlag; // 32
|
||||
using IsJSArrayPrototypeModifiedBit = IsAOTBit::NextFlag; // 25
|
||||
using IsJSFunctionBit = IsJSArrayPrototypeModifiedBit::NextFlag; // 26
|
||||
using IsOnHeap = IsJSFunctionBit::NextFlag; // 27
|
||||
using IsJSSharedBit = IsOnHeap::NextFlag; // 28
|
||||
using BitFieldLastBit = IsJSSharedBit;
|
||||
static_assert(BitFieldLastBit::START_BIT + BitFieldLastBit::SIZE <= sizeof(uint32_t) * BITS_PER_BYTE, "Invalid");
|
||||
|
||||
@ -587,6 +587,11 @@ public:
|
||||
IsDictionaryBit::Set<uint32_t>(flag, GetBitFieldAddr());
|
||||
}
|
||||
|
||||
inline void SetIsJSArrayPrototypeModified(bool flag) const
|
||||
{
|
||||
IsJSArrayPrototypeModifiedBit::Set<uint32_t>(flag, GetBitFieldAddr());
|
||||
}
|
||||
|
||||
inline void SetAOT(bool flag) const
|
||||
{
|
||||
IsAOTBit::Set<uint32_t>(flag, GetBitFieldAddr());
|
||||
@ -1511,6 +1516,12 @@ public:
|
||||
return IsDictionaryBit::Decode(bits);
|
||||
}
|
||||
|
||||
inline bool IsJSArrayPrototypeModifiedFromBitField() const
|
||||
{
|
||||
uint32_t bits = GetBitField();
|
||||
return IsJSArrayPrototypeModifiedBit::Decode(bits);
|
||||
}
|
||||
|
||||
// created from AOT
|
||||
inline bool IsAOT() const
|
||||
{
|
||||
@ -1794,19 +1805,6 @@ public:
|
||||
return ElementsKindBits::Decode(bits);
|
||||
}
|
||||
|
||||
inline void SetLevel(uint8_t level)
|
||||
{
|
||||
uint32_t bits = GetBitField();
|
||||
uint32_t newVal = LevelBit::Update(bits, level);
|
||||
SetBitField(newVal);
|
||||
}
|
||||
|
||||
inline uint8_t GetLevel() const
|
||||
{
|
||||
uint32_t bits = GetBitField();
|
||||
return LevelBit::Decode(bits);
|
||||
}
|
||||
|
||||
inline void SetIsDictionaryElement(bool value)
|
||||
{
|
||||
uint32_t newVal = DictionaryElementBits::Update(GetBitField(), value);
|
||||
|
@ -404,7 +404,7 @@ bool JSObject::AddElementInternal(JSThread *thread, const JSHandle<JSObject> &re
|
||||
}
|
||||
}
|
||||
}
|
||||
thread->NotifyStableArrayElementsGuardians(receiver, StableArrayChangeKind::NOT_PROTO);
|
||||
thread->NotifyArrayPrototypeChangedGuardians(receiver);
|
||||
|
||||
// check whether to convert to dictionary
|
||||
if (receiver->GetJSHClass()->IsDictionaryElement() && receiver->IsJSArray()) {
|
||||
|
@ -353,13 +353,14 @@ bool JSTaggedValue::IsJSCOWArray() const
|
||||
bool JSTaggedValue::IsStableJSArray(JSThread *thread) const
|
||||
{
|
||||
return IsHeapObject() && GetTaggedObject()->GetClass()->IsStableJSArray() &&
|
||||
!thread->IsStableArrayElementsGuardiansInvalid();
|
||||
!thread->IsArrayPrototypeChangedGuardiansInvalid() &&
|
||||
!GetTaggedObject()->GetClass()->IsJSArrayPrototypeModifiedFromBitField();
|
||||
}
|
||||
|
||||
bool JSTaggedValue::IsStableJSArguments(JSThread *thread) const
|
||||
{
|
||||
return IsHeapObject() && GetTaggedObject()->GetClass()->IsStableJSArguments() &&
|
||||
!thread->IsStableArrayElementsGuardiansInvalid();
|
||||
!thread->IsArrayPrototypeChangedGuardiansInvalid();
|
||||
}
|
||||
|
||||
bool JSTaggedValue::IsTaggedArray() const
|
||||
@ -385,7 +386,7 @@ bool JSTaggedValue::IsGeneratorContext() const
|
||||
bool JSTaggedValue::HasStableElements(JSThread *thread) const
|
||||
{
|
||||
return IsHeapObject() && GetTaggedObject()->GetClass()->IsStableElements() &&
|
||||
!thread->IsStableArrayElementsGuardiansInvalid();
|
||||
!thread->IsArrayPrototypeChangedGuardiansInvalid();
|
||||
}
|
||||
|
||||
bool JSTaggedValue::WithinInt32() const
|
||||
|
@ -564,9 +564,9 @@ void JSThread::ShrinkHandleStorage(int prevIndex)
|
||||
GetCurrentEcmaContext()->ShrinkHandleStorage(prevIndex);
|
||||
}
|
||||
|
||||
void JSThread::NotifyStableArrayElementsGuardians(JSHandle<JSObject> receiver, StableArrayChangeKind changeKind)
|
||||
void JSThread::NotifyArrayPrototypeChangedGuardians(JSHandle<JSObject> receiver)
|
||||
{
|
||||
if (!glueData_.stableArrayElementsGuardians_) {
|
||||
if (!glueData_.arrayPrototypeChangedGuardians_) {
|
||||
return;
|
||||
}
|
||||
if (!receiver->GetJSHClass()->IsPrototype() && !receiver->IsJSArray()) {
|
||||
@ -575,17 +575,14 @@ void JSThread::NotifyStableArrayElementsGuardians(JSHandle<JSObject> receiver, S
|
||||
auto env = GetEcmaVM()->GetGlobalEnv();
|
||||
if (receiver.GetTaggedValue() == env->GetObjectFunctionPrototype().GetTaggedValue() ||
|
||||
receiver.GetTaggedValue() == env->GetArrayPrototype().GetTaggedValue()) {
|
||||
glueData_.stableArrayElementsGuardians_ = false;
|
||||
glueData_.arrayPrototypeChangedGuardians_ = false;
|
||||
return;
|
||||
}
|
||||
if (changeKind == StableArrayChangeKind::PROTO && receiver->IsJSArray()) {
|
||||
glueData_.stableArrayElementsGuardians_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
void JSThread::ResetGuardians()
|
||||
{
|
||||
glueData_.stableArrayElementsGuardians_ = true;
|
||||
glueData_.arrayPrototypeChangedGuardians_ = true;
|
||||
}
|
||||
|
||||
void JSThread::SetInitialBuiltinHClass(
|
||||
|
@ -84,8 +84,6 @@ enum class BCStubStatus: uint8_t {
|
||||
JIT_PROFILE_BC_STUB,
|
||||
};
|
||||
|
||||
enum class StableArrayChangeKind { PROTO, NOT_PROTO };
|
||||
|
||||
enum ThreadType : uint8_t {
|
||||
JS_THREAD,
|
||||
JIT_THREAD,
|
||||
@ -339,11 +337,11 @@ public:
|
||||
return ctorHclassEntries_;
|
||||
}
|
||||
|
||||
void NotifyStableArrayElementsGuardians(JSHandle<JSObject> receiver, StableArrayChangeKind changeKind);
|
||||
void NotifyArrayPrototypeChangedGuardians(JSHandle<JSObject> receiver);
|
||||
|
||||
bool IsStableArrayElementsGuardiansInvalid() const
|
||||
bool IsArrayPrototypeChangedGuardiansInvalid() const
|
||||
{
|
||||
return !glueData_.stableArrayElementsGuardians_;
|
||||
return !glueData_.arrayPrototypeChangedGuardians_;
|
||||
}
|
||||
|
||||
void ResetGuardians();
|
||||
@ -966,7 +964,7 @@ public:
|
||||
BcStubEntriesIndex = 0,
|
||||
ExceptionIndex,
|
||||
GlobalObjIndex,
|
||||
StableArrayElementsGuardiansIndex,
|
||||
ArrayElementsGuardiansIndex,
|
||||
CurrentFrameIndex,
|
||||
LeaveFrameIndex,
|
||||
LastFpIndex,
|
||||
@ -1019,9 +1017,9 @@ public:
|
||||
return GetOffset<static_cast<size_t>(Index::GlobalObjIndex)>(isArch32);
|
||||
}
|
||||
|
||||
static size_t GetStableArrayElementsGuardiansOffset(bool isArch32)
|
||||
static size_t GetArrayElementsGuardiansOffset(bool isArch32)
|
||||
{
|
||||
return GetOffset<static_cast<size_t>(Index::StableArrayElementsGuardiansIndex)>(isArch32);
|
||||
return GetOffset<static_cast<size_t>(Index::ArrayElementsGuardiansIndex)>(isArch32);
|
||||
}
|
||||
|
||||
static size_t GetGlobalConstOffset(bool isArch32)
|
||||
@ -1243,7 +1241,7 @@ public:
|
||||
alignas(EAS) BCStubEntries bcStubEntries_ {};
|
||||
alignas(EAS) JSTaggedValue exception_ {JSTaggedValue::Hole()};
|
||||
alignas(EAS) JSTaggedValue globalObject_ {JSTaggedValue::Hole()};
|
||||
alignas(EAS) bool stableArrayElementsGuardians_ {true};
|
||||
alignas(EAS) bool arrayPrototypeChangedGuardians_ {true};
|
||||
alignas(EAS) JSTaggedType *currentFrame_ {nullptr};
|
||||
alignas(EAS) JSTaggedType *leaveFrame_ {nullptr};
|
||||
alignas(EAS) JSTaggedType *lastFp_ {nullptr};
|
||||
|
@ -3674,9 +3674,9 @@ bool FunctionRef::Inherit(const EcmaVM *vm, Local<FunctionRef> parent)
|
||||
return false;
|
||||
}
|
||||
// Set this.Prototype.__proto__ to parent.Prototype
|
||||
JSHandle<JSTaggedValue> parentProtoType(thread, JSFunction::PrototypeGetter(thread, parentHandle));
|
||||
JSHandle<JSTaggedValue> thisProtoType(thread, JSFunction::PrototypeGetter(thread, thisHandle));
|
||||
return JSObject::SetPrototype(thread, JSHandle<JSObject>::Cast(thisProtoType), parentProtoType);
|
||||
JSHandle<JSTaggedValue> parentPrototype(thread, JSFunction::PrototypeGetter(thread, parentHandle));
|
||||
JSHandle<JSTaggedValue> thisPrototype(thread, JSFunction::PrototypeGetter(thread, thisHandle));
|
||||
return JSObject::SetPrototype(thread, JSHandle<JSObject>::Cast(thisPrototype), parentPrototype);
|
||||
}
|
||||
|
||||
void FunctionRef::SetName(const EcmaVM *vm, Local<StringRef> name)
|
||||
|
@ -7985,7 +7985,7 @@ HWTEST_F_L0(JSNApiSplTest, FunctionRef_GetFunctionPrototype)
|
||||
Local<FunctionRef> setLocal = JSNApiHelper::ToLocal<FunctionRef>(set);
|
||||
gettimeofday(&g_beginTime, nullptr);
|
||||
for (int i = 0; i < NUM_COUNT; i++) {
|
||||
[[maybe_unused]] Local<JSValueRef> funcProtoType = setLocal->GetFunctionPrototype(vm_);
|
||||
[[maybe_unused]] Local<JSValueRef> funcPrototype = setLocal->GetFunctionPrototype(vm_);
|
||||
}
|
||||
gettimeofday(&g_endTime, nullptr);
|
||||
TEST_TIME(FunctionRef::GetFunctionPrototype);
|
||||
|
@ -579,13 +579,13 @@ HWTEST_F_L0(JSNApiTests, DeleteProperty)
|
||||
|
||||
/**
|
||||
* @tc.number: ffi_interface_api_011
|
||||
* @tc.name: GetProtoType
|
||||
* @tc.name: GetPrototype
|
||||
* @tc.desc:Verify that the GetPrototype method correctly returns the prototype of the function or object,
|
||||
* and verify that the returned prototype is of an object type.
|
||||
* @tc.type: FUNC
|
||||
* @tc.require: parameter
|
||||
*/
|
||||
HWTEST_F_L0(JSNApiTests, GetProtoType)
|
||||
HWTEST_F_L0(JSNApiTests, GetPrototype)
|
||||
{
|
||||
LocalScope scope(vm_);
|
||||
Local<FunctionRef> function = FunctionRef::New(vm_, nullptr);
|
||||
|
@ -1268,8 +1268,8 @@ void PGOProfiler::TryDumpProtoTransitionType(JSHClass *hclass)
|
||||
return;
|
||||
}
|
||||
JSTaggedValue phc1Root = JSHClass::FindProtoRootHClass(ihc1);
|
||||
auto transitionProtoType = GetProfileType(JSHClass::Cast(phc1Root.GetTaggedObject()), true);
|
||||
if (!transitionProtoType.IsRootType()) {
|
||||
auto transitionPrototype = GetProfileType(JSHClass::Cast(phc1Root.GetTaggedObject()), true);
|
||||
if (!transitionPrototype.IsRootType()) {
|
||||
LOG_ECMA(DEBUG) << "Set as the prototype of a function again after transition happened for this prototype!";
|
||||
return;
|
||||
}
|
||||
@ -1301,7 +1301,7 @@ void PGOProfiler::TryDumpProtoTransitionType(JSHClass *hclass)
|
||||
PGOProtoTransitionType protoTransitionType(ihc0RootType);
|
||||
protoTransitionType.SetBaseType(baseRootType, baseType);
|
||||
protoTransitionType.SetTransitionType(transitionType);
|
||||
protoTransitionType.SetTransitionProtoPt(transitionProtoType);
|
||||
protoTransitionType.SetTransitionProtoPt(transitionPrototype);
|
||||
|
||||
recordInfos_->GetProtoTransitionPool()->Add(protoTransitionType);
|
||||
}
|
||||
@ -1376,7 +1376,7 @@ void PGOProfiler::DumpDefineClass(ApEntityId abcId, const CString &recordName, E
|
||||
if (!prototypeType.IsRootType()) {
|
||||
LOG_ECMA(DEBUG) << "The profileType of prototype root hclass was not found.";
|
||||
} else {
|
||||
objDefType.SetProtoTypePt(prototypeType);
|
||||
objDefType.SetPrototypePt(prototypeType);
|
||||
recordInfos_->AddRootLayout(JSTaggedType(prototypeRootHClass), prototypeType);
|
||||
}
|
||||
}
|
||||
|
@ -623,10 +623,10 @@ bool PGORecordDetailInfos::AddDefine(
|
||||
PGOHClassTreeDesc descInfo(type.GetProfileType());
|
||||
auto iter = hclassTreeDescInfos_.find(descInfo);
|
||||
if (iter == hclassTreeDescInfos_.end()) {
|
||||
descInfo.SetProtoPt(type.GetProtoTypePt());
|
||||
descInfo.SetProtoPt(type.GetPrototypePt());
|
||||
hclassTreeDescInfos_.emplace(descInfo);
|
||||
} else {
|
||||
const_cast<PGOHClassTreeDesc &>(*iter).SetProtoPt(type.GetProtoTypePt());
|
||||
const_cast<PGOHClassTreeDesc &>(*iter).SetProtoPt(type.GetPrototypePt());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -859,7 +859,7 @@ public:
|
||||
{
|
||||
type_ = PGOProfileType(context, from.GetProfileType());
|
||||
ctorPt_ = PGOProfileType(context, from.GetCtorPt());
|
||||
protoPt_ = PGOProfileType(context, from.GetProtoTypePt());
|
||||
protoPt_ = PGOProfileType(context, from.GetPrototypePt());
|
||||
kind_ = from.GetElementsKind();
|
||||
elementsLength_ = from.GetElementsLength();
|
||||
spaceFlag_ = from.GetSpaceFlag();
|
||||
@ -923,12 +923,12 @@ public:
|
||||
return ctorPt_;
|
||||
}
|
||||
|
||||
void SetProtoTypePt(PGOProfileType type)
|
||||
void SetPrototypePt(PGOProfileType type)
|
||||
{
|
||||
protoPt_ = type;
|
||||
}
|
||||
|
||||
PGOProfileType GetProtoTypePt() const
|
||||
PGOProfileType GetPrototypePt() const
|
||||
{
|
||||
return protoPt_;
|
||||
}
|
||||
|
@ -343,7 +343,7 @@ HWTEST_F_L0(JSObjectTest, HasProperty)
|
||||
EXPECT_FALSE(flag);
|
||||
}
|
||||
|
||||
HWTEST_F_L0(JSObjectTest, HasPropertyWithProtoType)
|
||||
HWTEST_F_L0(JSObjectTest, HasPropertyWithPrototype)
|
||||
{
|
||||
JSHandle<JSObject> nullHandle(thread, JSTaggedValue::Null());
|
||||
JSHandle<JSObject> grandfather = JSObject::ObjectCreate(thread, nullHandle);
|
||||
|
@ -155,8 +155,9 @@ function filterCase4() {
|
||||
}
|
||||
Object.setPrototypeOf(arr2, notArray)
|
||||
|
||||
//aot: [trace] Check Type: NotStableArray1
|
||||
//aot: [trace] aot inline builtin: Array.prototype.filter, caller function name:#*#filterCase4@builtinArrayFilter
|
||||
print(arr1.filter(x => x == 1)); //: 1
|
||||
//aot: [trace] aot inline function name: #*@3*#filter@builtinArrayFilter caller function name: #*#filterCase4@builtinArrayFilter
|
||||
//aot: [trace] aot inline function name: #*@3*#^1@builtinArrayFilter caller function name: #*@3*#filter@builtinArrayFilter
|
||||
print(arr2.filter(x => x == 1)); //: false
|
||||
}
|
||||
@ -170,7 +171,7 @@ function filterCase5() {
|
||||
return x(1)
|
||||
}
|
||||
|
||||
//aot: [trace] Check Type: NotStableArray1
|
||||
//aot: [trace] aot inline function name: #*@4*#@builtinArrayFilter caller function name: #*#filterCase5@builtinArrayFilter
|
||||
//aot: [trace] aot inline function name: #*@4*#^1@builtinArrayFilter caller function name: #*@4*#@builtinArrayFilter
|
||||
print(arr1.filter(x => x == 1)); //: true
|
||||
}
|
||||
|
@ -214,9 +214,9 @@ function findIndexCase3() {
|
||||
findIndex: true_findIndex
|
||||
}
|
||||
|
||||
print(marr.findIndex(x => x == 1)); //aot: [trace] Check Type: NotStableArray1
|
||||
print(marr.findIndex(x => x == 1)); //aot: [trace] aot inline builtin: Array.prototype.findIndex, caller function name:#*#findIndexCase3@builtinArrayFindFindIndex
|
||||
//: 0
|
||||
|
||||
//aot: [trace] Check Type: BuiltinInstanceHClassMismatch
|
||||
Object.setPrototypeOf(marr, mimicArray)
|
||||
|
||||
print(marr.findIndex(x => x == 1)); //: 0
|
||||
@ -235,9 +235,9 @@ function findCase4() {
|
||||
}
|
||||
}
|
||||
Object.setPrototypeOf(arr2, notArray)
|
||||
|
||||
//aot: [trace] Check Type: NotStableArray1
|
||||
//aot: [trace] aot inline builtin: Array.prototype.find, caller function name:#*#findCase4@builtinArrayFindFindIndex
|
||||
print(arr1.find(x => x == 1)); //: 1
|
||||
//aot: [trace] aot inline function name: #*@6*#find@builtinArrayFindFindIndex caller function name: #*#findCase4@builtinArrayFindFindIndex
|
||||
//aot: [trace] aot inline function name: #*@6*#^1@builtinArrayFindFindIndex caller function name: #*@6*#find@builtinArrayFindFindIndex
|
||||
print(arr2.find(x => x == 1)); //: false
|
||||
}
|
||||
@ -252,8 +252,9 @@ function findIndexCase4() {
|
||||
}
|
||||
Object.setPrototypeOf(arr2, notArray)
|
||||
|
||||
//aot: [trace] Check Type: NotStableArray1
|
||||
//aot: [trace] aot inline builtin: Array.prototype.findIndex, caller function name:#*#findIndexCase4@builtinArrayFindFindIndex
|
||||
print(arr1.findIndex(x => x == 1)); //: 0
|
||||
//aot: [trace] aot inline function name: #*@7*#findIndex@builtinArrayFindFindIndex caller function name: #*#findIndexCase4@builtinArrayFindFindIndex
|
||||
//aot: [trace] aot inline function name: #*@7*#^1@builtinArrayFindFindIndex caller function name: #*@7*#findIndex@builtinArrayFindFindIndex
|
||||
print(arr2.findIndex(x => x == 1)); //: false
|
||||
}
|
||||
@ -268,7 +269,7 @@ function findCase5() {
|
||||
return x(1)
|
||||
}
|
||||
|
||||
//aot: [trace] Check Type: NotStableArray1
|
||||
//aot: [trace] aot inline function name: #*@8*#@builtinArrayFindFindIndex caller function name: #*#findCase5@builtinArrayFindFindIndex
|
||||
//aot: [trace] aot inline function name: #*@8*#^1@builtinArrayFindFindIndex caller function name: #*@8*#@builtinArrayFindFindIndex
|
||||
print(arr1.find(x => x == 1)); //: true
|
||||
}
|
||||
@ -279,7 +280,7 @@ function findIndexCase5() {
|
||||
return x(1)
|
||||
}
|
||||
|
||||
//aot: [trace] Check Type: NotStableArray1
|
||||
//aot: [trace] aot inline function name: #*@9*#@builtinArrayFindFindIndex caller function name: #*#findIndexCase5@builtinArrayFindFindIndex
|
||||
//aot: [trace] aot inline function name: #*@9*#^1@builtinArrayFindFindIndex caller function name: #*@9*#@builtinArrayFindFindIndex
|
||||
print(arr1.findIndex(x => x == 1)); //: true
|
||||
}
|
||||
|
@ -162,8 +162,9 @@ function forEachCase4() {
|
||||
}
|
||||
Object.setPrototypeOf(arr2, notArray)
|
||||
|
||||
//aot: [trace] Check Type: NotStableArray1
|
||||
//aot: [trace] aot inline builtin: Array.prototype.foreach, caller function name:#*#forEachCase4@builtinArrayForEach
|
||||
print(arr1.forEach(x => x == 1)); //: undefined
|
||||
//aot: [trace] aot inline function name: #*@4*#forEach@builtinArrayForEach caller function name: #*#forEachCase4@builtinArrayForEach
|
||||
//aot: [trace] aot inline function name: #*@4*#^1@builtinArrayForEach caller function name: #*@4*#forEach@builtinArrayForEach
|
||||
print(arr2.forEach(x => x == 1)); //: false
|
||||
}
|
||||
|
@ -169,8 +169,9 @@ function popCase4() {
|
||||
}
|
||||
Object.setPrototypeOf(arr2, notArray)
|
||||
|
||||
//aot: [trace] Check Type: NotStableArray1
|
||||
//aot: [trace] aot inline builtin: Array.prototype.pop, caller function name:#*#popCase4@builtinArrayPop
|
||||
print(arr1.pop(1)); //: 2
|
||||
//aot: [trace] aot inline function name: #*@3*#pop@builtinArrayPop caller function name: #*#popCase4@builtinArrayPop
|
||||
print(arr2.pop(1)); //: -100
|
||||
}
|
||||
popCase4()
|
||||
@ -183,7 +184,6 @@ function popCase5() {
|
||||
return x
|
||||
}
|
||||
|
||||
//aot: [trace] Check Type: NotStableArray1
|
||||
print(arr1.pop(1)); //: 1
|
||||
}
|
||||
popCase5()
|
||||
|
@ -11,7 +11,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
[trace] Check Type: ProtoTypeChanged2
|
||||
[trace] Check Type: PrototypeChanged2
|
||||
[trace] Check Type: InconsistentHClass8
|
||||
[trace] Check Type: InconsistentHClass13
|
||||
[trace] Check Type: InconsistentHClass8
|
||||
|
@ -262,6 +262,10 @@ group("ark_asm_test") {
|
||||
"allocatearraybuffer",
|
||||
"allocatesizeoverflow",
|
||||
"array",
|
||||
"arraypushproto",
|
||||
"arrayspliceproto",
|
||||
"arrayunshiftproto",
|
||||
"arrayfillproto",
|
||||
"arrayfindlast",
|
||||
"arrayfill",
|
||||
"arrayflat",
|
||||
@ -271,6 +275,7 @@ group("ark_asm_test") {
|
||||
"arrayforeach",
|
||||
"arrayjoin",
|
||||
"arraymap",
|
||||
"arraystablecheck",
|
||||
|
||||
# (issue 18938)
|
||||
#"arraypop",
|
||||
|
18
test/moduletest/arrayfillproto/BUILD.gn
Normal file
18
test/moduletest/arrayfillproto/BUILD.gn
Normal file
@ -0,0 +1,18 @@
|
||||
# Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//arkcompiler/ets_runtime/test/test_helper.gni")
|
||||
|
||||
host_moduletest_action("arrayfillproto") {
|
||||
deps = []
|
||||
}
|
26
test/moduletest/arrayfillproto/arrayfillproto.js
Normal file
26
test/moduletest/arrayfillproto/arrayfillproto.js
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @tc.name:array fill proto
|
||||
* @tc.desc:test array fill proto
|
||||
*/
|
||||
let arr1 = new Array(500);
|
||||
arr1.__proto__.length = 10;
|
||||
arr1.__proto__.fill(233, 0, 7);
|
||||
let arr2 = new Array(500);
|
||||
let arr3 = arr1.concat(arr2);
|
||||
print(arr3[0], arr3[1], arr3[2], arr3[500], arr3[501], arr3[502]);
|
14
test/moduletest/arrayfillproto/expect_output.txt
Normal file
14
test/moduletest/arrayfillproto/expect_output.txt
Normal file
@ -0,0 +1,14 @@
|
||||
# Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
233 233 233 233 233 233
|
18
test/moduletest/arraypushproto/BUILD.gn
Normal file
18
test/moduletest/arraypushproto/BUILD.gn
Normal file
@ -0,0 +1,18 @@
|
||||
# Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//arkcompiler/ets_runtime/test/test_helper.gni")
|
||||
|
||||
host_moduletest_action("arraypushproto") {
|
||||
deps = []
|
||||
}
|
25
test/moduletest/arraypushproto/arraypushproto.js
Normal file
25
test/moduletest/arraypushproto/arraypushproto.js
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @tc.name:array push proto
|
||||
* @tc.desc:test array push proto
|
||||
*/
|
||||
let arr1 = new Array(500);
|
||||
arr1.__proto__.push(1);
|
||||
let arr2 = new Array(500);
|
||||
let arr3 = arr1.concat(arr2);
|
||||
print(arr3[0], arr3[500]);
|
14
test/moduletest/arraypushproto/expect_output.txt
Normal file
14
test/moduletest/arraypushproto/expect_output.txt
Normal file
@ -0,0 +1,14 @@
|
||||
# Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
1 1
|
18
test/moduletest/arrayspliceproto/BUILD.gn
Normal file
18
test/moduletest/arrayspliceproto/BUILD.gn
Normal file
@ -0,0 +1,18 @@
|
||||
# Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//arkcompiler/ets_runtime/test/test_helper.gni")
|
||||
|
||||
host_moduletest_action("arrayspliceproto") {
|
||||
deps = []
|
||||
}
|
25
test/moduletest/arrayspliceproto/arrayspliceproto.js
Normal file
25
test/moduletest/arrayspliceproto/arrayspliceproto.js
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @tc.name:array splice proto
|
||||
* @tc.desc:test array splice proto
|
||||
*/
|
||||
let arr1 = new Array(500);
|
||||
arr1.__proto__.splice(1, 0, 1, 2, 3);
|
||||
let arr2 = new Array(500);
|
||||
let arr3 = arr1.concat(arr2);
|
||||
print(arr3[0], arr3[1], arr3[2], arr3[500], arr3[501], arr3[502]);
|
14
test/moduletest/arrayspliceproto/expect_output.txt
Normal file
14
test/moduletest/arrayspliceproto/expect_output.txt
Normal file
@ -0,0 +1,14 @@
|
||||
# Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
1 2 3 1 2 3
|
18
test/moduletest/arraystablecheck/BUILD.gn
Normal file
18
test/moduletest/arraystablecheck/BUILD.gn
Normal file
@ -0,0 +1,18 @@
|
||||
# Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//arkcompiler/ets_runtime/test/test_helper.gni")
|
||||
|
||||
host_moduletest_action("arraystablecheck") {
|
||||
deps = []
|
||||
}
|
138
test/moduletest/arraystablecheck/arraystablecheck.js
Normal file
138
test/moduletest/arraystablecheck/arraystablecheck.js
Normal file
@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @tc.name:arraystablecheck1
|
||||
* @tc.desc:test array stable or not
|
||||
*/
|
||||
|
||||
{
|
||||
let arr1 = new Array(1023);
|
||||
let arr2 = new Array(1023);
|
||||
print(ArkTools.isStableJsArray(arr1));
|
||||
print(ArkTools.isStableJsArray(arr2));
|
||||
print(ArkTools.isStableJsArray(arr2.__proto__));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @tc.name:arraystablecheck2
|
||||
* @tc.desc:test array stable or not
|
||||
*/
|
||||
|
||||
{
|
||||
let arr1 = new Array(1023);
|
||||
let arr2 = new Array(1023);
|
||||
arr1.__proto__ = arr2;
|
||||
print(ArkTools.isStableJsArray(arr1));
|
||||
print(ArkTools.isStableJsArray(arr2));
|
||||
}
|
||||
|
||||
/*
|
||||
* @tc.name:arraystablecheck3
|
||||
* @tc.desc:test array stable or not
|
||||
*/
|
||||
{
|
||||
let arr1 = new Array(1026);
|
||||
let arr2 = new Array(1026);
|
||||
print(ArkTools.isStableJsArray(arr1));
|
||||
print(ArkTools.isStableJsArray(arr2));
|
||||
}
|
||||
|
||||
/*
|
||||
* @tc.name:arraystablecheck4
|
||||
* @tc.desc:test array stable or not
|
||||
*/
|
||||
{
|
||||
class MyArray extends Array {
|
||||
|
||||
};
|
||||
let arr1 = new MyArray(1023);
|
||||
let arr2 = new MyArray(1023);
|
||||
let arr3 = arr1.concat(arr2);
|
||||
let arr4 = new Array(1023);
|
||||
print(ArkTools.isStableJsArray(arr1));
|
||||
print(ArkTools.isStableJsArray(arr2));
|
||||
print(ArkTools.isStableJsArray(arr3));
|
||||
print(ArkTools.isStableJsArray(arr4));
|
||||
}
|
||||
|
||||
/*
|
||||
* @tc.name:arraystablecheck5
|
||||
* @tc.desc:test array stable or not
|
||||
*/
|
||||
{
|
||||
class MyArray extends Array {
|
||||
|
||||
};
|
||||
let arr1 = new MyArray();
|
||||
let arr2 = new MyArray();
|
||||
let arr3 = arr1.concat();
|
||||
let arr4 = new Array();
|
||||
print(ArkTools.isStableJsArray(arr1));
|
||||
print(ArkTools.isStableJsArray(arr2));
|
||||
print(ArkTools.isStableJsArray(arr3));
|
||||
print(ArkTools.isStableJsArray(arr4));
|
||||
}
|
||||
|
||||
/*
|
||||
* @tc.name:arraystablecheck6
|
||||
* @tc.desc:test array stable or not
|
||||
*/
|
||||
{
|
||||
class MyArray extends Array {
|
||||
|
||||
};
|
||||
let arr1 = new MyArray(1, 2, 3, 4, 5);
|
||||
let arr2 = new MyArray(1, 2, 3, 4, 5);
|
||||
let arr3 = arr1.concat();
|
||||
let arr4 = new Array(1, 2, 3, 4, 5);
|
||||
print(ArkTools.isStableJsArray(arr1));
|
||||
print(ArkTools.isStableJsArray(arr2));
|
||||
print(ArkTools.isStableJsArray(arr3));
|
||||
print(ArkTools.isStableJsArray(arr4));
|
||||
}
|
||||
|
||||
/*
|
||||
* @tc.name:arraystablecheck7
|
||||
* @tc.desc:test array stable or not
|
||||
*/
|
||||
{
|
||||
let arr1 = new Array(1023);
|
||||
print(ArkTools.isStableJsArray(arr1));
|
||||
arr1.__proto__.fill(233, 0, 0);
|
||||
print(ArkTools.isStableJsArray(arr1));
|
||||
arr1.__proto__.fill();
|
||||
print(ArkTools.isStableJsArray(arr1));
|
||||
arr1.__proto__.push();
|
||||
print(ArkTools.isStableJsArray(arr1));
|
||||
arr1.__proto__.unshift();
|
||||
print(ArkTools.isStableJsArray(arr1));
|
||||
arr1.__proto__.splice();
|
||||
print(ArkTools.isStableJsArray(arr1));
|
||||
}
|
||||
|
||||
/*
|
||||
* @tc.name:arraystablecheck8
|
||||
* @tc.desc:test array stable or not
|
||||
*/
|
||||
{
|
||||
let arr1 = new Array(1023);
|
||||
let arr2 = new Array(1023);
|
||||
arr1.__proto__.push(1);
|
||||
print(ArkTools.isStableJsArray(arr1.__proto__));
|
||||
print(ArkTools.isStableJsArray(arr1));
|
||||
print(ArkTools.isStableJsArray(arr2));
|
||||
}
|
41
test/moduletest/arraystablecheck/expect_output.txt
Normal file
41
test/moduletest/arraystablecheck/expect_output.txt
Normal file
@ -0,0 +1,41 @@
|
||||
# Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
true
|
||||
true
|
||||
false
|
||||
false
|
||||
true
|
||||
false
|
||||
false
|
||||
false
|
||||
false
|
||||
false
|
||||
true
|
||||
false
|
||||
false
|
||||
false
|
||||
true
|
||||
false
|
||||
false
|
||||
false
|
||||
true
|
||||
true
|
||||
true
|
||||
true
|
||||
true
|
||||
true
|
||||
true
|
||||
false
|
||||
false
|
||||
false
|
18
test/moduletest/arrayunshiftproto/BUILD.gn
Normal file
18
test/moduletest/arrayunshiftproto/BUILD.gn
Normal file
@ -0,0 +1,18 @@
|
||||
# Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//arkcompiler/ets_runtime/test/test_helper.gni")
|
||||
|
||||
host_moduletest_action("arrayunshiftproto") {
|
||||
deps = []
|
||||
}
|
25
test/moduletest/arrayunshiftproto/arrayunshiftproto.js
Normal file
25
test/moduletest/arrayunshiftproto/arrayunshiftproto.js
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @tc.name:array unshift proto
|
||||
* @tc.desc:test array unshift proto
|
||||
*/
|
||||
let arr1 = new Array(500);
|
||||
arr1.__proto__.unshift(1);
|
||||
let arr2 = new Array(500);
|
||||
let arr3 = arr1.concat(arr2);
|
||||
print(arr3[0], arr3[500]);
|
14
test/moduletest/arrayunshiftproto/expect_output.txt
Normal file
14
test/moduletest/arrayunshiftproto/expect_output.txt
Normal file
@ -0,0 +1,14 @@
|
||||
# Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
1 1
|
Loading…
Reference in New Issue
Block a user