From 6b71e0b044ec98e45e641fea43f3c2b4dc0aea72 Mon Sep 17 00:00:00 2001 From: lichenshuai Date: Tue, 27 Feb 2024 15:30:29 +0800 Subject: [PATCH] =?UTF-8?q?[Bug]:=20CreateDataProperty=E5=BF=AB=E9=80=9F?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=E5=AF=BC=E8=87=B4static=E6=9C=AA=E8=B5=B0def?= =?UTF-8?q?ine=E8=AF=AD=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 对于static的情况,走define语义。 Issue: #I8XNRO Signed-off-by: lichenshuai Change-Id: I271926b42288035e14c63763f207d52a3358dad6 --- .../compiler/access_object_stub_builder.cpp | 4 +- .../snapshot_constantpool_data.cpp | 1 + ecmascript/compiler/bytecodes.cpp | 1 + ecmascript/compiler/bytecodes.h | 1 + ecmascript/compiler/interpreter_stub.cpp | 8 ++-- ecmascript/compiler/stub_builder.cpp | 43 ++++++++++++------- ecmascript/compiler/stub_builder.h | 6 +-- ecmascript/compiler/ts_inline_lowering.cpp | 1 + .../initialization_analysis.cpp | 5 ++- .../type_inference/method_type_infer.cpp | 1 + .../type_inference/pgo_type_infer.cpp | 1 + .../compiler/typed_bytecode_lowering.cpp | 6 +-- ecmascript/interpreter/interpreter-inl.h | 8 ++-- ecmascript/js_object.cpp | 7 ++- ecmascript/object_fast_operator-inl.h | 19 +++++++- ecmascript/object_fast_operator.h | 6 +++ test/moduletest/class/class.js | 10 ++++- 17 files changed, 90 insertions(+), 38 deletions(-) diff --git a/ecmascript/compiler/access_object_stub_builder.cpp b/ecmascript/compiler/access_object_stub_builder.cpp index 71cdcbdb3c..d48f3807bb 100644 --- a/ecmascript/compiler/access_object_stub_builder.cpp +++ b/ecmascript/compiler/access_object_stub_builder.cpp @@ -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); { diff --git a/ecmascript/compiler/aot_snapshot/snapshot_constantpool_data.cpp b/ecmascript/compiler/aot_snapshot/snapshot_constantpool_data.cpp index d23adb50aa..e2834cfc93 100644 --- a/ecmascript/compiler/aot_snapshot/snapshot_constantpool_data.cpp +++ b/ecmascript/compiler/aot_snapshot/snapshot_constantpool_data.cpp @@ -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: diff --git a/ecmascript/compiler/bytecodes.cpp b/ecmascript/compiler/bytecodes.cpp index caabe5c01d..134ce6b248 100644 --- a/ecmascript/compiler/bytecodes.cpp +++ b/ecmascript/compiler/bytecodes.cpp @@ -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: diff --git a/ecmascript/compiler/bytecodes.h b/ecmascript/compiler/bytecodes.h index f743eff51f..d8317d701e 100644 --- a/ecmascript/compiler/bytecodes.h +++ b/ecmascript/compiler/bytecodes.h @@ -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: diff --git a/ecmascript/compiler/interpreter_stub.cpp b/ecmascript/compiler/interpreter_stub.cpp index fec8d3ba04..b079a445a9 100644 --- a/ecmascript/compiler/interpreter_stub.cpp +++ b/ecmascript/compiler/interpreter_stub.cpp @@ -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); { diff --git a/ecmascript/compiler/stub_builder.cpp b/ecmascript/compiler/stub_builder.cpp index 8a62a084e3..c4607ea6f6 100644 --- a/ecmascript/compiler/stub_builder.cpp +++ b/ecmascript/compiler/stub_builder.cpp @@ -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(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(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); } } diff --git a/ecmascript/compiler/stub_builder.h b/ecmascript/compiler/stub_builder.h index e3ecd5d1e2..52a4d2a00f 100644 --- a/ecmascript/compiler/stub_builder.h +++ b/ecmascript/compiler/stub_builder.h @@ -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); diff --git a/ecmascript/compiler/ts_inline_lowering.cpp b/ecmascript/compiler/ts_inline_lowering.cpp index 5b74fd14da..e8000e3877 100644 --- a/ecmascript/compiler/ts_inline_lowering.cpp +++ b/ecmascript/compiler/ts_inline_lowering.cpp @@ -82,6 +82,7 @@ void TSInlineLowering::CandidateInlineCall(GateRef gate, ChunkQueue + JSTaggedValue res = FastRuntimeStub::SetPropertyByValue (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 + JSTaggedValue res = FastRuntimeStub::SetPropertyByName (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 + JSTaggedValue res = FastRuntimeStub::SetPropertyByValue (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 + JSTaggedValue res = FastRuntimeStub::SetPropertyByName (thread, receiver, propKey, value); if (!res.IsHole()) { INTERPRETER_RETURN_IF_ABRUPT(res); diff --git a/ecmascript/js_object.cpp b/ecmascript/js_object.cpp index 5f1a0d6bb3..a3e5447abf 100644 --- a/ecmascript/js_object.cpp +++ b/ecmascript/js_object.cpp @@ -1614,7 +1614,10 @@ bool JSObject::CreateDataProperty(JSThread *thread, const JSHandle &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( + if (!JSHandle::Cast(obj)->IsJSShared()) { + sCheckMode = SCheckMode::CHECK; + } + auto result = ObjectFastOperator::SetPropertyByValue( 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 &ob const JSHandle &value) { ASSERT_PRINT(obj->IsECMAObject(), "Obj is not a valid object"); - auto result = ObjectFastOperator::SetPropertyByIndex + auto result = ObjectFastOperator::SetPropertyByIndex (thread, obj.GetTaggedValue(), index, value.GetTaggedValue()); if (!result.IsHole()) { return !result.IsException(); diff --git a/ecmascript/object_fast_operator-inl.h b/ecmascript/object_fast_operator-inl.h index c71191b37b..82cddbfb8c 100644 --- a/ecmascript/object_fast_operator-inl.h +++ b/ecmascript/object_fast_operator-inl.h @@ -214,12 +214,18 @@ JSTaggedValue ObjectFastOperator::SetPropertyByName(JSThread *thread, JSTaggedVa PropertyAttributes attr(layoutInfo->GetAttr(entry)); ASSERT(static_cast(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(); diff --git a/ecmascript/object_fast_operator.h b/ecmascript/object_fast_operator.h index 01dd7288b4..4ecea8f5fa 100644 --- a/ecmascript/object_fast_operator.h +++ b/ecmascript/object_fast_operator.h @@ -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(status) & static_cast(Status::GetInternal)) > 0; } + static inline bool DefineSemantics(Status status) + { + return (static_cast(status) & static_cast(Status::DefineSemantics)) > 0; + } + static inline std::pair HasOwnProperty(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key); template diff --git a/test/moduletest/class/class.js b/test/moduletest/class/class.js index 7b29b79644..ea4880b8e7 100644 --- a/test/moduletest/class/class.js +++ b/test/moduletest/class/class.js @@ -117,4 +117,12 @@ class Class2024 { #c = foo; } var class2024 = new Class2024(); -print("test successful!"); \ No newline at end of file +print("test successful!"); + +class StaticTest { + static set a(a) { + print(a); + } + static a = 1; // expect no print + static length = 1; // expect no TypeError +}