!10104 Bug fix when modify proto

Merge pull request !10104 from yinwuxiao/proto
This commit is contained in:
openharmony_ci 2024-11-15 06:32:16 +00:00 committed by Gitee
commit d3b5af8fd7
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
55 changed files with 634 additions and 175 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -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, &notCOWArray);
Bind(&notCOWArray);
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, &notCOWArray);
Bind(&notCOWArray);
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, &notCOWArray);
Bind(&notCOWArray);
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, &notCOWArray);
Bind(&notCOWArray);
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, &notCOWArray);
Bind(&notCOWArray);
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, &notCOWArray);
Bind(&notCOWArray);
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, &notCOWArray);
Bind(&notCOWArray);
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, &notCOWArray);
Bind(&notCOWArray);
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, &notCOWArray);
Bind(&notCOWArray);
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, &notCOWArray);
Bind(&notCOWArray);
GateRef arrayCls = LoadHClass(thisValue);
ElementsKindHclassCompare(glue, arrayCls, &matchCls, slowPath);
Bind(&matchCls);
Label arg0HeapObject(env);
Label callable(env);
Label thisIsStable(env);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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(&notArray);
{
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, &notEqualHClass);
Bind(&notEqualHClass);
{
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);

View File

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

View File

@ -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, &notProto,
BranchWeight::ONE_WEIGHT, BranchWeight::DEOPT_WEIGHT, "isProtoTypeHClass");
builder_.Branch(builder_.IsPrototypeHClass(receiverHC), &isProto, &notProto,
BranchWeight::ONE_WEIGHT, BranchWeight::DEOPT_WEIGHT, "isPrototypeHClass");
builder_.Bind(&isProto);
GateRef propKey =
builder_.GetObjectByIndexFromConstPool(glue_, gate, frameState,

View File

@ -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, &notProto,
BranchWeight::ONE_WEIGHT, BranchWeight::DEOPT_WEIGHT, "isProtoTypeHClass");
builder_.Branch(builder_.IsPrototypeHClass(receiverHC), &isProto, &notProto,
BranchWeight::ONE_WEIGHT, BranchWeight::DEOPT_WEIGHT, "isPrototypeHClass");
builder_.Bind(&isProto);
GateRef propKey =

View File

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

View File

@ -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";
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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_;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View 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 = []
}

View 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]);

View 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

View 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 = []
}

View 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]);

View 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

View 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 = []
}

View 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]);

View 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

View 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 = []
}

View 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));
}

View 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

View 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 = []
}

View 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]);

View 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