mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-06 23:54:03 +00:00
[Bug]: CreateDataProperty快速路径导致static未走define语义
对于static的情况,走define语义。 Issue: #I8XNRO Signed-off-by: lichenshuai <lichenshuai@huawei.com> Change-Id: I271926b42288035e14c63763f207d52a3358dad6
This commit is contained in:
parent
8ebd2047bb
commit
6b71e0b044
@ -576,7 +576,7 @@ GateRef AccessObjectStubBuilder::StOwnByValueWithNameSet(GateRef glue, GateRef r
|
||||
Branch(IsClassPrototype(receiver), &slowPath, ¬ClassPrototype);
|
||||
Bind(¬ClassPrototype);
|
||||
{
|
||||
result = SetPropertyByValue(glue, receiver, key, value, false);
|
||||
result = SetPropertyByValue(glue, receiver, key, value, true, ProfileOperation(), true);
|
||||
Branch(TaggedIsHole(*result), &slowPath, ¬Hole);
|
||||
Bind(¬Hole);
|
||||
{
|
||||
@ -621,7 +621,7 @@ GateRef AccessObjectStubBuilder::StOwnByNameWithNameSet(GateRef glue, GateRef re
|
||||
Branch(IsClassPrototype(receiver), ¬JSObject, ¬ClassPrototype);
|
||||
Bind(¬ClassPrototype);
|
||||
{
|
||||
result = SetPropertyByName(glue, receiver, key, value, true, True());
|
||||
result = SetPropertyByName(glue, receiver, key, value, true, True(), ProfileOperation(), false, true);
|
||||
Branch(TaggedIsHole(*result), ¬JSObject, ¬Hole);
|
||||
Bind(¬Hole);
|
||||
{
|
||||
|
@ -285,6 +285,7 @@ void SnapshotConstantPoolData::Record(const BytecodeInstruction &bcIns, int32_t
|
||||
case BytecodeInstruction::Opcode::LDOBJBYNAME_IMM16_ID16:
|
||||
case BytecodeInstruction::Opcode::STOBJBYNAME_IMM8_ID16_V8:
|
||||
case BytecodeInstruction::Opcode::STOBJBYNAME_IMM16_ID16_V8:
|
||||
case BytecodeInstruction::Opcode::DEFINEFIELDBYNAME_IMM8_ID16_V8:
|
||||
case BytecodeInstruction::Opcode::LDSUPERBYNAME_IMM8_ID16:
|
||||
case BytecodeInstruction::Opcode::LDSUPERBYNAME_IMM16_ID16:
|
||||
case BytecodeInstruction::Opcode::STSUPERBYNAME_IMM8_ID16_V8:
|
||||
|
@ -477,6 +477,7 @@ BytecodeMetaData BytecodeMetaData::InitBytecodeMetaData(const uint8_t *pc)
|
||||
case EcmaOpcode::STOBJBYNAME_IMM16_ID16_V8:
|
||||
case EcmaOpcode::STTHISBYNAME_IMM8_ID16:
|
||||
case EcmaOpcode::STTHISBYNAME_IMM16_ID16:
|
||||
case EcmaOpcode::DEFINEFIELDBYNAME_IMM8_ID16_V8:
|
||||
kind = BytecodeKind::ACCESSOR_BC;
|
||||
break;
|
||||
default:
|
||||
|
@ -437,6 +437,7 @@ public:
|
||||
case EcmaOpcode::LDTHISBYNAME_IMM16_ID16:
|
||||
case EcmaOpcode::STOBJBYNAME_IMM8_ID16_V8:
|
||||
case EcmaOpcode::STOBJBYNAME_IMM16_ID16_V8:
|
||||
case EcmaOpcode::DEFINEFIELDBYNAME_IMM8_ID16_V8:
|
||||
case EcmaOpcode::STTHISBYNAME_IMM8_ID16:
|
||||
case EcmaOpcode::STTHISBYNAME_IMM16_ID16:
|
||||
case EcmaOpcode::CALLRUNTIME_CALLINIT_PREF_IMM8_V8:
|
||||
|
@ -1936,7 +1936,7 @@ DECLARE_ASM_HANDLER(HandleStownbyvaluewithnamesetImm16V8V8)
|
||||
Branch(IsClassPrototype(receiver), &slowPath, ¬ClassPrototype);
|
||||
Bind(¬ClassPrototype);
|
||||
{
|
||||
GateRef res = SetPropertyByValue(glue, receiver, propKey, acc, true, callback);
|
||||
GateRef res = SetPropertyByValue(glue, receiver, propKey, acc, true, callback, true);
|
||||
Branch(TaggedIsHole(res), &slowPath, ¬Hole);
|
||||
Bind(¬Hole);
|
||||
{
|
||||
@ -1979,7 +1979,7 @@ DECLARE_ASM_HANDLER(HandleStownbyvaluewithnamesetImm8V8V8)
|
||||
Branch(IsClassPrototype(receiver), &slowPath, ¬ClassPrototype);
|
||||
Bind(¬ClassPrototype);
|
||||
{
|
||||
GateRef res = SetPropertyByValue(glue, receiver, propKey, acc, true, callback);
|
||||
GateRef res = SetPropertyByValue(glue, receiver, propKey, acc, true, callback, true);
|
||||
Branch(TaggedIsHole(res), &slowPath, ¬Hole);
|
||||
Bind(¬Hole);
|
||||
{
|
||||
@ -2098,7 +2098,7 @@ DECLARE_ASM_HANDLER(HandleStownbynamewithnamesetImm8Id16V8)
|
||||
Branch(IsClassPrototype(receiver), ¬JSObject, ¬ClassPrototype);
|
||||
Bind(¬ClassPrototype);
|
||||
{
|
||||
GateRef res = SetPropertyByName(glue, receiver, propKey, acc, true, True(), callback);
|
||||
GateRef res = SetPropertyByName(glue, receiver, propKey, acc, true, True(), callback, false, true);
|
||||
Branch(TaggedIsHole(res), ¬JSObject, ¬Hole);
|
||||
Bind(¬Hole);
|
||||
{
|
||||
@ -2140,7 +2140,7 @@ DECLARE_ASM_HANDLER(HandleStownbynamewithnamesetImm16Id16V8)
|
||||
Branch(IsClassPrototype(receiver), ¬JSObject, ¬ClassPrototype);
|
||||
Bind(¬ClassPrototype);
|
||||
{
|
||||
GateRef res = SetPropertyByName(glue, receiver, propKey, acc, true, True(), callback);
|
||||
GateRef res = SetPropertyByName(glue, receiver, propKey, acc, true, True(), callback, false, true);
|
||||
Branch(TaggedIsHole(res), ¬JSObject, ¬Hole);
|
||||
Bind(¬Hole);
|
||||
{
|
||||
|
@ -3336,7 +3336,7 @@ GateRef StubBuilder::FindTransitions(GateRef glue, GateRef receiver, GateRef hcl
|
||||
}
|
||||
|
||||
GateRef StubBuilder::SetPropertyByIndex(GateRef glue, GateRef receiver, GateRef index, GateRef value, bool useOwn,
|
||||
ProfileOperation callback)
|
||||
ProfileOperation callback, bool defineSemantics)
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
Label entry(env);
|
||||
@ -3352,7 +3352,7 @@ GateRef StubBuilder::SetPropertyByIndex(GateRef glue, GateRef receiver, GateRef
|
||||
Label isJsCOWArray(env);
|
||||
Label isNotJsCOWArray(env);
|
||||
Label setElementsArray(env);
|
||||
if (!useOwn) {
|
||||
if (!useOwn && !defineSemantics) {
|
||||
Jump(&loopHead);
|
||||
LoopBegin(&loopHead);
|
||||
}
|
||||
@ -3461,7 +3461,9 @@ GateRef StubBuilder::SetPropertyByIndex(GateRef glue, GateRef receiver, GateRef
|
||||
Label notAccessor(env);
|
||||
Branch(IsAccessor(attr), &isAccessor, ¬Accessor);
|
||||
Bind(&isAccessor);
|
||||
{
|
||||
if (defineSemantics) {
|
||||
Jump(&exit);
|
||||
} else {
|
||||
GateRef accessor = GetValueFromDictionary<NumberDictionary>(elements, entryA);
|
||||
Label shouldCall(env);
|
||||
Branch(ShouldCallSetter(receiver, *holder, accessor, attr), &shouldCall, ¬Accessor);
|
||||
@ -3544,7 +3546,7 @@ GateRef StubBuilder::SetPropertyByIndex(GateRef glue, GateRef receiver, GateRef
|
||||
}
|
||||
|
||||
GateRef StubBuilder::SetPropertyByName(GateRef glue, GateRef receiver, GateRef key, GateRef value,
|
||||
bool useOwn, GateRef isInternal, ProfileOperation callback, bool canUseIsInternal)
|
||||
bool useOwn, GateRef isInternal, ProfileOperation callback, bool canUseIsInternal, bool defineSemantics)
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
Label entryPass(env);
|
||||
@ -3636,7 +3638,7 @@ GateRef StubBuilder::SetPropertyByName(GateRef glue, GateRef receiver, GateRef k
|
||||
GateRef entry = FindElementWithCache(glue, layOutInfo, hclass, key, propsNum);
|
||||
Label hasEntry(env);
|
||||
// if branch condition : entry != -1
|
||||
if (useOwn) {
|
||||
if (useOwn || defineSemantics) {
|
||||
Branch(Int32NotEqual(entry, Int32(-1)), &hasEntry, &ifEnd);
|
||||
} else {
|
||||
Branch(Int32NotEqual(entry, Int32(-1)), &hasEntry, &loopExit);
|
||||
@ -3650,7 +3652,9 @@ GateRef StubBuilder::SetPropertyByName(GateRef glue, GateRef receiver, GateRef k
|
||||
Label notAccessor(env);
|
||||
Branch(IsAccessor(attr), &isAccessor, ¬Accessor);
|
||||
Bind(&isAccessor);
|
||||
{
|
||||
if (defineSemantics) {
|
||||
Jump(&exit);
|
||||
} else {
|
||||
// auto accessor = JSObject::Cast(holder)->GetProperty(hclass, attr)
|
||||
GateRef accessor = JSObjectGetProperty(*holder, hclass, attr);
|
||||
Label shouldCall(env);
|
||||
@ -3668,7 +3672,9 @@ GateRef StubBuilder::SetPropertyByName(GateRef glue, GateRef receiver, GateRef k
|
||||
Label notWritable(env);
|
||||
Branch(IsWritable(attr), &writable, ¬Writable);
|
||||
Bind(¬Writable);
|
||||
{
|
||||
if (defineSemantics) {
|
||||
Jump(&exit);
|
||||
} else {
|
||||
GateRef taggedId = Int32(GET_MESSAGE_STRING_ID(SetReadOnlyProperty));
|
||||
CallRuntime(glue, RTSTUB_ID(ThrowTypeError), { IntToTaggedInt(taggedId) });
|
||||
result = Exception();
|
||||
@ -3698,7 +3704,7 @@ GateRef StubBuilder::SetPropertyByName(GateRef glue, GateRef receiver, GateRef k
|
||||
Jump(&noNeedStore);
|
||||
}
|
||||
Bind(&noNeedStore);
|
||||
if (useOwn) {
|
||||
if (useOwn || defineSemantics) {
|
||||
Jump(&ifEnd);
|
||||
} else {
|
||||
Jump(&loopExit);
|
||||
@ -3707,7 +3713,7 @@ GateRef StubBuilder::SetPropertyByName(GateRef glue, GateRef receiver, GateRef k
|
||||
}
|
||||
Bind(¬TS);
|
||||
Label holdEqualsRecv(env);
|
||||
if (useOwn) {
|
||||
if (useOwn || defineSemantics) {
|
||||
Branch(Equal(*holder, receiver), &holdEqualsRecv, &ifEnd);
|
||||
} else {
|
||||
Branch(Equal(*holder, receiver), &holdEqualsRecv, &afterLoop);
|
||||
@ -3736,7 +3742,7 @@ GateRef StubBuilder::SetPropertyByName(GateRef glue, GateRef receiver, GateRef k
|
||||
GateRef entry1 = FindEntryFromNameDictionary(glue, array, key);
|
||||
Label notNegtiveOne(env);
|
||||
// if branch condition : entry != -1
|
||||
if (useOwn) {
|
||||
if (useOwn || defineSemantics) {
|
||||
Branch(Int32NotEqual(entry1, Int32(-1)), ¬NegtiveOne, &ifEnd);
|
||||
} else {
|
||||
Branch(Int32NotEqual(entry1, Int32(-1)), ¬NegtiveOne, &loopExit);
|
||||
@ -3750,7 +3756,9 @@ GateRef StubBuilder::SetPropertyByName(GateRef glue, GateRef receiver, GateRef k
|
||||
// if branch condition : UNLIKELY(attr.IsAccessor())
|
||||
Branch(IsAccessor(attr1), &isAccessor1, ¬Accessor1);
|
||||
Bind(&isAccessor1);
|
||||
{
|
||||
if (defineSemantics) {
|
||||
Jump(&exit);
|
||||
} else {
|
||||
// auto accessor = dict->GetValue(entry)
|
||||
GateRef accessor1 = GetValueFromDictionary<NameDictionary>(array, entry1);
|
||||
Label shouldCall1(env);
|
||||
@ -3767,7 +3775,9 @@ GateRef StubBuilder::SetPropertyByName(GateRef glue, GateRef receiver, GateRef k
|
||||
Label notWritable1(env);
|
||||
Branch(IsWritable(attr1), &writable1, ¬Writable1);
|
||||
Bind(¬Writable1);
|
||||
{
|
||||
if (defineSemantics) {
|
||||
Jump(&exit);
|
||||
} else {
|
||||
GateRef taggedId = Int32(GET_MESSAGE_STRING_ID(SetReadOnlyProperty));
|
||||
CallRuntime(glue, RTSTUB_ID(ThrowTypeError), { IntToTaggedInt(taggedId) });
|
||||
result = Exception();
|
||||
@ -3797,7 +3807,7 @@ GateRef StubBuilder::SetPropertyByName(GateRef glue, GateRef receiver, GateRef k
|
||||
}
|
||||
}
|
||||
}
|
||||
if (useOwn) {
|
||||
if (useOwn || defineSemantics) {
|
||||
Bind(&ifEnd);
|
||||
} else {
|
||||
Bind(&loopExit);
|
||||
@ -3851,7 +3861,7 @@ GateRef StubBuilder::SetPropertyByName(GateRef glue, GateRef receiver, GateRef k
|
||||
}
|
||||
|
||||
GateRef StubBuilder::SetPropertyByValue(GateRef glue, GateRef receiver, GateRef key, GateRef value, bool useOwn,
|
||||
ProfileOperation callback)
|
||||
ProfileOperation callback, bool defineSemantics)
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
Label subEntry1(env);
|
||||
@ -3891,7 +3901,7 @@ GateRef StubBuilder::SetPropertyByValue(GateRef glue, GateRef receiver, GateRef
|
||||
Branch(Int32GreaterThanOrEqual(index, Int32(0)), &validIndex, ¬ValidIndex);
|
||||
Bind(&validIndex);
|
||||
{
|
||||
result = SetPropertyByIndex(glue, receiver, index, value, useOwn);
|
||||
result = SetPropertyByIndex(glue, receiver, index, value, useOwn, callback, defineSemantics);
|
||||
Jump(&exit);
|
||||
}
|
||||
Bind(¬ValidIndex);
|
||||
@ -3938,7 +3948,8 @@ GateRef StubBuilder::SetPropertyByValue(GateRef glue, GateRef receiver, GateRef
|
||||
CheckDetectorName(glue, *varKey, &setByName, &exit);
|
||||
Bind(&setByName);
|
||||
{
|
||||
result = SetPropertyByName(glue, receiver, *varKey, value, useOwn, *isInternal, callback, true);
|
||||
result = SetPropertyByName(glue, receiver, *varKey, value, useOwn, *isInternal, callback,
|
||||
true, defineSemantics);
|
||||
Jump(&exit);
|
||||
}
|
||||
}
|
||||
|
@ -632,12 +632,12 @@ public:
|
||||
ProfileOperation callback = ProfileOperation());
|
||||
void FastSetPropertyByIndex(GateRef glue, GateRef obj, GateRef index, GateRef value);
|
||||
GateRef SetPropertyByIndex(GateRef glue, GateRef receiver, GateRef index,
|
||||
GateRef value, bool useOwn, ProfileOperation callback = ProfileOperation());
|
||||
GateRef value, bool useOwn, ProfileOperation callback = ProfileOperation(), bool defineSemantics = false);
|
||||
GateRef SetPropertyByName(GateRef glue, GateRef receiver, GateRef key,
|
||||
GateRef value, bool useOwn, GateRef isInternal, ProfileOperation callback = ProfileOperation(),
|
||||
bool canUseIsInternal = false); // Crawl prototype chain
|
||||
bool canUseIsInternal = false, bool defineSemantics = false); // Crawl prototype chain
|
||||
GateRef SetPropertyByValue(GateRef glue, GateRef receiver, GateRef key, GateRef value, bool useOwn,
|
||||
ProfileOperation callback = ProfileOperation());
|
||||
ProfileOperation callback = ProfileOperation(), bool defineSemantics = false);
|
||||
GateRef GetParentEnv(GateRef object);
|
||||
GateRef GetPropertiesFromLexicalEnv(GateRef object, GateRef index);
|
||||
void SetPropertiesToLexicalEnv(GateRef glue, GateRef object, GateRef index, GateRef value);
|
||||
|
@ -82,6 +82,7 @@ void TSInlineLowering::CandidateInlineCall(GateRef gate, ChunkQueue<InlineTypeIn
|
||||
break;
|
||||
case EcmaOpcode::STOBJBYNAME_IMM8_ID16_V8:
|
||||
case EcmaOpcode::STOBJBYNAME_IMM16_ID16_V8:
|
||||
case EcmaOpcode::DEFINEFIELDBYNAME_IMM8_ID16_V8:
|
||||
case EcmaOpcode::STTHISBYNAME_IMM8_ID16:
|
||||
case EcmaOpcode::STTHISBYNAME_IMM16_ID16:
|
||||
CandidateAccessor(gate, workList, CallKind::CALL_SETTER);
|
||||
|
@ -45,7 +45,8 @@ void InitializationAnalysis::Analyse(GateRef gate)
|
||||
EcmaOpcode ecmaOpcode = acc_.GetByteCodeOpcode(gate);
|
||||
switch (ecmaOpcode) {
|
||||
case EcmaOpcode::STOBJBYNAME_IMM8_ID16_V8:
|
||||
case EcmaOpcode::STOBJBYNAME_IMM16_ID16_V8: {
|
||||
case EcmaOpcode::STOBJBYNAME_IMM16_ID16_V8:
|
||||
case EcmaOpcode::DEFINEFIELDBYNAME_IMM8_ID16_V8: {
|
||||
CollectInitializationType(gate, ThisUsage::INDEFINITE_THIS);
|
||||
CollectInitializationInfo(gate, ThisUsage::INDEFINITE_THIS);
|
||||
break;
|
||||
@ -203,6 +204,7 @@ bool InitializationAnalysis::CheckSimpleJSGate(GateRef gate, const uint16_t inde
|
||||
}
|
||||
case EcmaOpcode::STOBJBYNAME_IMM8_ID16_V8:
|
||||
case EcmaOpcode::STOBJBYNAME_IMM16_ID16_V8:
|
||||
case EcmaOpcode::DEFINEFIELDBYNAME_IMM8_ID16_V8:
|
||||
case EcmaOpcode::STTHISBYNAME_IMM8_ID16:
|
||||
case EcmaOpcode::STTHISBYNAME_IMM16_ID16:
|
||||
case EcmaOpcode::THROW_IFSUPERNOTCORRECTCALL_PREF_IMM8:
|
||||
@ -288,6 +290,7 @@ bool InitializationAnalysis::HasEscapedThis(GateRef gate) const
|
||||
switch (ecmaOpcode) {
|
||||
case EcmaOpcode::STOBJBYNAME_IMM8_ID16_V8:
|
||||
case EcmaOpcode::STOBJBYNAME_IMM16_ID16_V8:
|
||||
case EcmaOpcode::DEFINEFIELDBYNAME_IMM8_ID16_V8:
|
||||
case EcmaOpcode::STTHISBYNAME_IMM8_ID16:
|
||||
case EcmaOpcode::STTHISBYNAME_IMM16_ID16:
|
||||
case EcmaOpcode::THROW_IFSUPERNOTCORRECTCALL_PREF_IMM8:
|
||||
|
@ -365,6 +365,7 @@ bool MethodTypeInfer::Infer(GateRef gate)
|
||||
return InferLdExternalModuleVar(gate);
|
||||
case EcmaOpcode::STOBJBYNAME_IMM8_ID16_V8:
|
||||
case EcmaOpcode::STOBJBYNAME_IMM16_ID16_V8:
|
||||
case EcmaOpcode::DEFINEFIELDBYNAME_IMM8_ID16_V8:
|
||||
return InferStObjByName(gate);
|
||||
default:
|
||||
break;
|
||||
|
@ -47,6 +47,7 @@ void PGOTypeInfer::RunTypeInfer(GateRef gate)
|
||||
break;
|
||||
case EcmaOpcode::STOBJBYNAME_IMM8_ID16_V8:
|
||||
case EcmaOpcode::STOBJBYNAME_IMM16_ID16_V8:
|
||||
case EcmaOpcode::DEFINEFIELDBYNAME_IMM8_ID16_V8:
|
||||
InferStObjByName(gate, false);
|
||||
break;
|
||||
case EcmaOpcode::STTHISBYNAME_IMM8_ID16:
|
||||
|
@ -568,14 +568,14 @@ void TypedBytecodeLowering::LowerTypedStObjByName(GateRef gate)
|
||||
|
||||
// The framestate of Call and Accessor related instructions directives is placed on IR. Using the depend edge to
|
||||
// climb up and find the nearest framestate for other instructions
|
||||
if (opcode == EcmaOpcode::DEFINEFIELDBYNAME_IMM8_ID16_V8 ||
|
||||
opcode == EcmaOpcode::STOWNBYNAME_IMM8_ID16_V8 ||
|
||||
if (opcode == EcmaOpcode::STOWNBYNAME_IMM8_ID16_V8 ||
|
||||
opcode == EcmaOpcode::STOWNBYNAME_IMM16_ID16_V8) {
|
||||
frameState = acc_.FindNearestFrameState(builder_.GetDepend());
|
||||
} else if (opcode == EcmaOpcode::STOBJBYNAME_IMM8_ID16_V8 ||
|
||||
opcode == EcmaOpcode::STOBJBYNAME_IMM16_ID16_V8 ||
|
||||
opcode == EcmaOpcode::STTHISBYNAME_IMM8_ID16 ||
|
||||
opcode == EcmaOpcode::STTHISBYNAME_IMM16_ID16) {
|
||||
opcode == EcmaOpcode::STTHISBYNAME_IMM16_ID16 ||
|
||||
opcode == EcmaOpcode::DEFINEFIELDBYNAME_IMM8_ID16_V8) {
|
||||
frameState = acc_.GetFrameState(gate);
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
|
@ -2797,7 +2797,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, const uint8_t
|
||||
JSTaggedValue propKey = GET_VREG_VALUE(v1);
|
||||
JSTaggedValue value = GET_ACC();
|
||||
// fast path
|
||||
JSTaggedValue res = FastRuntimeStub::SetPropertyByValue<ObjectFastOperator::Status::UseOwn>
|
||||
JSTaggedValue res = FastRuntimeStub::SetPropertyByValue<ObjectFastOperator::Status::DefineSemantics>
|
||||
(thread, receiver, propKey, value);
|
||||
|
||||
// SetPropertyByValue maybe gc need update the value
|
||||
@ -2838,7 +2838,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, const uint8_t
|
||||
JSTaggedValue value = GET_ACC();
|
||||
// fast path
|
||||
SAVE_ACC();
|
||||
JSTaggedValue res = FastRuntimeStub::SetPropertyByName<ObjectFastOperator::Status::UseOwn>
|
||||
JSTaggedValue res = FastRuntimeStub::SetPropertyByName<ObjectFastOperator::Status::DefineSemantics>
|
||||
(thread, receiver, propKey, value);
|
||||
if (!res.IsHole()) {
|
||||
INTERPRETER_RETURN_IF_ABRUPT(res);
|
||||
@ -6655,7 +6655,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, const uint8_t
|
||||
JSTaggedValue propKey = GET_VREG_VALUE(v1);
|
||||
JSTaggedValue value = GET_ACC();
|
||||
// fast path
|
||||
JSTaggedValue res = FastRuntimeStub::SetPropertyByValue<ObjectFastOperator::Status::UseOwn>
|
||||
JSTaggedValue res = FastRuntimeStub::SetPropertyByValue<ObjectFastOperator::Status::DefineSemantics>
|
||||
(thread, receiver, propKey, value);
|
||||
|
||||
// SetPropertyByValue maybe gc need update the value
|
||||
@ -6697,7 +6697,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, const uint8_t
|
||||
JSTaggedValue value = GET_ACC();
|
||||
// fast path
|
||||
SAVE_ACC();
|
||||
JSTaggedValue res = FastRuntimeStub::SetPropertyByName<ObjectFastOperator::Status::UseOwn>
|
||||
JSTaggedValue res = FastRuntimeStub::SetPropertyByName<ObjectFastOperator::Status::DefineSemantics>
|
||||
(thread, receiver, propKey, value);
|
||||
if (!res.IsHole()) {
|
||||
INTERPRETER_RETURN_IF_ABRUPT(res);
|
||||
|
@ -1614,7 +1614,10 @@ bool JSObject::CreateDataProperty(JSThread *thread, const JSHandle<JSObject> &ob
|
||||
{
|
||||
ASSERT_PRINT(obj->IsECMAObject(), "Obj is not a valid object");
|
||||
ASSERT_PRINT(JSTaggedValue::IsPropertyKey(key), "Key is not a property key");
|
||||
auto result = ObjectFastOperator::SetPropertyByValue<ObjectFastOperator::Status::UseOwn>(
|
||||
if (!JSHandle<JSTaggedValue>::Cast(obj)->IsJSShared()) {
|
||||
sCheckMode = SCheckMode::CHECK;
|
||||
}
|
||||
auto result = ObjectFastOperator::SetPropertyByValue<ObjectFastOperator::Status::DefineSemantics>(
|
||||
thread, obj.GetTaggedValue(), key.GetTaggedValue(), value.GetTaggedValue(), sCheckMode);
|
||||
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, false);
|
||||
if (!result.IsHole()) {
|
||||
@ -1628,7 +1631,7 @@ bool JSObject::CreateDataProperty(JSThread *thread, const JSHandle<JSObject> &ob
|
||||
const JSHandle<JSTaggedValue> &value)
|
||||
{
|
||||
ASSERT_PRINT(obj->IsECMAObject(), "Obj is not a valid object");
|
||||
auto result = ObjectFastOperator::SetPropertyByIndex<ObjectFastOperator::Status::UseOwn>
|
||||
auto result = ObjectFastOperator::SetPropertyByIndex<ObjectFastOperator::Status::DefineSemantics>
|
||||
(thread, obj.GetTaggedValue(), index, value.GetTaggedValue());
|
||||
if (!result.IsHole()) {
|
||||
return !result.IsException();
|
||||
|
@ -214,12 +214,18 @@ JSTaggedValue ObjectFastOperator::SetPropertyByName(JSThread *thread, JSTaggedVa
|
||||
PropertyAttributes attr(layoutInfo->GetAttr(entry));
|
||||
ASSERT(static_cast<int>(attr.GetOffset()) == entry);
|
||||
if (UNLIKELY(attr.IsAccessor())) {
|
||||
if (DefineSemantics(status) && sCheckMode == SCheckMode::CHECK) {
|
||||
return JSTaggedValue::Hole();
|
||||
}
|
||||
auto accessor = JSObject::Cast(holder)->GetProperty(hclass, attr);
|
||||
if (ShouldCallSetter(receiver, holder, accessor, attr)) {
|
||||
return CallSetter(thread, receiver, value, accessor);
|
||||
}
|
||||
}
|
||||
if (UNLIKELY(!attr.IsWritable())) {
|
||||
if (DefineSemantics(status) && sCheckMode == SCheckMode::CHECK) {
|
||||
return JSTaggedValue::Hole();
|
||||
}
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, GET_MESSAGE_STRING(SetReadOnlyProperty),
|
||||
JSTaggedValue::Exception());
|
||||
@ -257,12 +263,18 @@ JSTaggedValue ObjectFastOperator::SetPropertyByName(JSThread *thread, JSTaggedVa
|
||||
if (entry != -1) {
|
||||
auto attr = dict->GetAttributes(entry);
|
||||
if (UNLIKELY(attr.IsAccessor())) {
|
||||
if (DefineSemantics(status) && sCheckMode == SCheckMode::CHECK) {
|
||||
return JSTaggedValue::Hole();
|
||||
}
|
||||
auto accessor = dict->GetValue(entry);
|
||||
if (ShouldCallSetter(receiver, holder, accessor, attr)) {
|
||||
return CallSetter(thread, receiver, value, accessor);
|
||||
}
|
||||
}
|
||||
if (UNLIKELY(!attr.IsWritable())) {
|
||||
if (DefineSemantics(status) && sCheckMode == SCheckMode::CHECK) {
|
||||
return JSTaggedValue::Hole();
|
||||
}
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, GET_MESSAGE_STRING(SetReadOnlyProperty),
|
||||
JSTaggedValue::Exception());
|
||||
@ -280,7 +292,7 @@ JSTaggedValue ObjectFastOperator::SetPropertyByName(JSThread *thread, JSTaggedVa
|
||||
return JSTaggedValue::Undefined();
|
||||
}
|
||||
}
|
||||
if (UseOwn(status)) {
|
||||
if (UseOwn(status) || DefineSemantics(status)) {
|
||||
break;
|
||||
}
|
||||
holder = hclass->GetPrototype();
|
||||
@ -420,6 +432,9 @@ JSTaggedValue ObjectFastOperator::SetPropertyByIndex(JSThread *thread, JSTaggedV
|
||||
break;
|
||||
}
|
||||
if (UNLIKELY(attr.IsAccessor())) {
|
||||
if (DefineSemantics(status)) {
|
||||
return JSTaggedValue::Hole();
|
||||
}
|
||||
auto accessor = dict->GetValue(entry);
|
||||
if (ShouldCallSetter(receiver, holder, accessor, attr)) {
|
||||
return CallSetter(thread, receiver, value, accessor);
|
||||
@ -430,7 +445,7 @@ JSTaggedValue ObjectFastOperator::SetPropertyByIndex(JSThread *thread, JSTaggedV
|
||||
}
|
||||
return JSTaggedValue::Hole();
|
||||
}
|
||||
if (UseOwn(status)) {
|
||||
if (UseOwn(status) || DefineSemantics(status)) {
|
||||
break;
|
||||
}
|
||||
holder = JSObject::Cast(holder)->GetJSHClass()->GetPrototype();
|
||||
|
@ -29,6 +29,7 @@ public:
|
||||
None = 0x00UL,
|
||||
UseOwn = 0x01UL,
|
||||
GetInternal = 0x1UL << 1,
|
||||
DefineSemantics = 0x1UL << 2,
|
||||
};
|
||||
|
||||
static inline bool UseOwn(Status status)
|
||||
@ -41,6 +42,11 @@ public:
|
||||
return (static_cast<int32_t>(status) & static_cast<int32_t>(Status::GetInternal)) > 0;
|
||||
}
|
||||
|
||||
static inline bool DefineSemantics(Status status)
|
||||
{
|
||||
return (static_cast<int32_t>(status) & static_cast<int32_t>(Status::DefineSemantics)) > 0;
|
||||
}
|
||||
|
||||
static inline std::pair<JSTaggedValue, bool> HasOwnProperty(JSThread *thread,
|
||||
JSTaggedValue receiver, JSTaggedValue key);
|
||||
template<Status status = Status::None>
|
||||
|
@ -117,4 +117,12 @@ class Class2024 {
|
||||
#c = foo;
|
||||
}
|
||||
var class2024 = new Class2024();
|
||||
print("test successful!");
|
||||
print("test successful!");
|
||||
|
||||
class StaticTest {
|
||||
static set a(a) {
|
||||
print(a);
|
||||
}
|
||||
static a = 1; // expect no print
|
||||
static length = 1; // expect no TypeError
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user