Remove JSNativePointer in InternalAccessor

Issue: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/IAJ4G8
Signed-off-by: Gymee <yumeijie@huawei.com>
Change-Id: I85d4677b4aa7041c63ec0bb1592a6e6c2abb3785
This commit is contained in:
Gymee 2024-06-12 18:02:48 +08:00
parent 93b2ba8990
commit 25d4d5d9ef
7 changed files with 72 additions and 65 deletions

View File

@ -26,11 +26,27 @@
#include "ecmascript/record.h" #include "ecmascript/record.h"
namespace panda::ecmascript { namespace panda::ecmascript {
class AccessorData final : public Record { class InternalAccessor final : public Record {
public: public:
using InternalGetFunc = JSTaggedValue (*)(JSThread *, const JSHandle<JSObject> &); using InternalGetFunc = JSTaggedValue (*)(JSThread *, const JSHandle<JSObject> &);
using InternalSetFunc = bool (*)(JSThread *, const JSHandle<JSObject> &, const JSHandle<JSTaggedValue> &, bool); using InternalSetFunc = bool (*)(JSThread *, const JSHandle<JSObject> &, const JSHandle<JSTaggedValue> &, bool);
CAST_CHECK(InternalAccessor, IsInternalAccessor);
inline bool HasSetter() const
{
return GetSetter() != nullptr;
}
static constexpr size_t GETTER_OFFSET = Record::SIZE;
ACCESSORS_FIXED_SIZE_FIELD(Getter, InternalGetFunc, JSTaggedType, GETTER_OFFSET, SETTER_OFFSET)
ACCESSORS_FIXED_SIZE_FIELD(Setter, InternalSetFunc, JSTaggedType, SETTER_OFFSET, SIZE)
DECL_VISIT_NATIVE_FIELD(GETTER_OFFSET, SIZE)
};
class AccessorData final : public Record {
public:
static AccessorData *Cast(TaggedObject *object) static AccessorData *Cast(TaggedObject *object)
{ {
ASSERT(JSTaggedValue(object).IsAccessorData() || JSTaggedValue(object).IsInternalAccessor()); ASSERT(JSTaggedValue(object).IsAccessorData() || JSTaggedValue(object).IsInternalAccessor());
@ -44,23 +60,23 @@ public:
inline bool HasSetter() const inline bool HasSetter() const
{ {
return !GetSetter().IsUndefined(); auto setter = GetSetter();
// When the raw data is 0, means the InternalAccessor's setter is nullptr.
return !(setter.IsUndefined() || setter.GetRawData() == 0U);
} }
JSTaggedValue CallInternalGet(JSThread *thread, const JSHandle<JSObject> &obj) const JSTaggedValue CallInternalGet(JSThread *thread, const JSHandle<JSObject> &obj) const
{ {
ASSERT(GetGetter().IsJSNativePointer()); ASSERT(IsInternal());
JSNativePointer *getter = JSNativePointer::Cast(GetGetter().GetTaggedObject()); auto getFunc = InternalAccessor::ConstCast(this)->GetGetter();
auto getFunc = reinterpret_cast<InternalGetFunc>(getter->GetExternalPointer());
return getFunc(thread, obj); return getFunc(thread, obj);
} }
bool CallInternalSet(JSThread *thread, const JSHandle<JSObject> &obj, const JSHandle<JSTaggedValue> &value, bool CallInternalSet(JSThread *thread, const JSHandle<JSObject> &obj, const JSHandle<JSTaggedValue> &value,
bool mayThrow = false) const bool mayThrow = false) const
{ {
ASSERT(GetSetter().IsJSNativePointer()); ASSERT(IsInternal());
JSNativePointer *setter = JSNativePointer::Cast(GetSetter().GetTaggedObject()); auto setFunc = InternalAccessor::ConstCast(this)->GetSetter();
auto setFunc = reinterpret_cast<InternalSetFunc>(setter->GetExternalPointer());
return setFunc(thread, obj, value, mayThrow); return setFunc(thread, obj, value, mayThrow);
} }
@ -72,6 +88,10 @@ public:
DECL_VISIT_OBJECT(GETTER_OFFSET, SIZE) DECL_VISIT_OBJECT(GETTER_OFFSET, SIZE)
}; };
static_assert(AccessorData::SIZE == InternalAccessor::SIZE &&
AccessorData::GETTER_OFFSET == InternalAccessor::GETTER_OFFSET &&
AccessorData::SETTER_OFFSET == InternalAccessor::SETTER_OFFSET);
enum class CompletionRecordType : uint8_t { enum class CompletionRecordType : uint8_t {
NORMAL = 0U, NORMAL = 0U,
BREAK, BREAK,

View File

@ -1603,8 +1603,8 @@ void AccessorData::Dump(std::ostream &os) const
{ {
auto *hclass = GetClass(); auto *hclass = GetClass();
if (hclass->GetObjectType() == JSType::INTERNAL_ACCESSOR) { if (hclass->GetObjectType() == JSType::INTERNAL_ACCESSOR) {
os << " - Getter: " << reinterpret_cast<void *>(GetGetter().GetTaggedObject()) << "\n"; os << " - Getter: " << InternalAccessor::ConstCast(this)->GetGetter() << "\n";
os << " - Setter: " << reinterpret_cast<void *>(GetSetter().GetTaggedObject()) << "\n"; os << " - Setter: " << InternalAccessor::ConstCast(this)->GetSetter() << "\n";
return; return;
} }
@ -5297,6 +5297,12 @@ void JSSymbol::DumpForSnapshot(std::vector<Reference> &vec) const
void AccessorData::DumpForSnapshot(std::vector<Reference> &vec) const void AccessorData::DumpForSnapshot(std::vector<Reference> &vec) const
{ {
if (GetClass()->GetObjectType() == JSType::INTERNAL_ACCESSOR) {
vec.emplace_back(CString("getter"), JSTaggedValue(InternalAccessor::ConstCast(this)->GetGetter()));
vec.emplace_back(CString("setter"), JSTaggedValue(InternalAccessor::ConstCast(this)->GetSetter()));
return;
}
vec.emplace_back(CString("getter"), GetGetter()); vec.emplace_back(CString("getter"), GetGetter());
vec.emplace_back(CString("setter"), GetSetter()); vec.emplace_back(CString("setter"), GetSetter());
} }

View File

@ -472,9 +472,13 @@ public:
GlobalEnv::Cast(object)->VisitRangeSlot<visitType>(visitor); GlobalEnv::Cast(object)->VisitRangeSlot<visitType>(visitor);
break; break;
case JSType::ACCESSOR_DATA: case JSType::ACCESSOR_DATA:
case JSType::INTERNAL_ACCESSOR:
AccessorData::Cast(object)->VisitRangeSlot<visitType>(visitor); AccessorData::Cast(object)->VisitRangeSlot<visitType>(visitor);
break; break;
case JSType::INTERNAL_ACCESSOR:
if constexpr (visitType == VisitType::ALL_VISIT) {
InternalAccessor::Cast(object)->VisitRangeSlot<visitType>(visitor);
}
break;
case JSType::SYMBOL: case JSType::SYMBOL:
JSSymbol::Cast(object)->VisitRangeSlot<visitType>(visitor); JSSymbol::Cast(object)->VisitRangeSlot<visitType>(visitor);
break; break;

View File

@ -2389,20 +2389,11 @@ JSHandle<AccessorData> ObjectFactory::NewInternalAccessor(void *setter, void *ge
NewObjectHook(); NewObjectHook();
TaggedObject *header = heap_->AllocateNonMovableOrHugeObject( TaggedObject *header = heap_->AllocateNonMovableOrHugeObject(
JSHClass::Cast(thread_->GlobalConstants()->GetInternalAccessorClass().GetTaggedObject())); JSHClass::Cast(thread_->GlobalConstants()->GetInternalAccessorClass().GetTaggedObject()));
JSHandle<AccessorData> obj(thread_, AccessorData::Cast(header)); JSHandle<InternalAccessor> obj(thread_, InternalAccessor::Cast(header));
obj->SetGetter(thread_, JSTaggedValue::Undefined());
obj->SetSetter(thread_, JSTaggedValue::Undefined()); obj->SetSetter(reinterpret_cast<InternalAccessor::InternalSetFunc>(setter));
if (setter != nullptr) { obj->SetGetter(reinterpret_cast<InternalAccessor::InternalGetFunc>(getter));
JSHandle<JSNativePointer> setFunc = NewJSNativePointer(setter, nullptr, nullptr, true); return JSHandle<AccessorData>::Cast(obj);
obj->SetSetter(thread_, setFunc.GetTaggedValue());
} else {
JSTaggedValue setFunc = JSTaggedValue::Undefined();
obj->SetSetter(thread_, setFunc);
ASSERT(!obj->HasSetter());
}
JSHandle<JSNativePointer> getFunc = NewJSNativePointer(getter, nullptr, nullptr, true);
obj->SetGetter(thread_, getFunc);
return obj;
} }
JSHandle<PromiseCapability> ObjectFactory::NewPromiseCapability() JSHandle<PromiseCapability> ObjectFactory::NewPromiseCapability()

View File

@ -521,18 +521,11 @@ JSHandle<AccessorData> ObjectFactory::NewSInternalAccessor(void *setter, void *g
NewSObjectHook(); NewSObjectHook();
TaggedObject *header = sHeap_->AllocateReadOnlyOrHugeObject(thread_, TaggedObject *header = sHeap_->AllocateReadOnlyOrHugeObject(thread_,
JSHClass::Cast(thread_->GlobalConstants()->GetInternalAccessorClass().GetTaggedObject())); JSHClass::Cast(thread_->GlobalConstants()->GetInternalAccessorClass().GetTaggedObject()));
JSHandle<AccessorData> obj(thread_, AccessorData::Cast(header)); JSHandle<InternalAccessor> obj(thread_, InternalAccessor::Cast(header));
obj->SetGetter(thread_, JSTaggedValue::Undefined());
obj->SetSetter(thread_, JSTaggedValue::Undefined()); obj->SetSetter(reinterpret_cast<InternalAccessor::InternalSetFunc>(setter));
if (setter != nullptr) { obj->SetGetter(reinterpret_cast<InternalAccessor::InternalGetFunc>(getter));
JSHandle<JSNativePointer> setFunc = NewSReadOnlyJSNativePointer(setter); return JSHandle<AccessorData>::Cast(obj);
obj->SetSetter(thread_, setFunc.GetTaggedValue());
}
if (getter != nullptr) {
JSHandle<JSNativePointer> getFunc = NewSReadOnlyJSNativePointer(getter);
obj->SetGetter(thread_, getFunc);
}
return obj;
} }
JSHandle<ConstantPool> ObjectFactory::NewSConstantPool(uint32_t capacity) JSHandle<ConstantPool> ObjectFactory::NewSConstantPool(uint32_t capacity)

View File

@ -48,8 +48,8 @@ HWTEST_F_L0(AccessorDataTest, AccessorData_Cast)
JSHandle<JSHClass> internalAccClassHandle = JSHandle<JSHClass> internalAccClassHandle =
factory->NewEcmaHClass(JSObject::SIZE, JSType::INTERNAL_ACCESSOR, nullHandle); factory->NewEcmaHClass(JSObject::SIZE, JSType::INTERNAL_ACCESSOR, nullHandle);
TaggedObject *internalAccObject = factory->NewObject(internalAccClassHandle); TaggedObject *internalAccObject = factory->NewObject(internalAccClassHandle);
AccessorData::Cast(internalAccObject)->SetGetter(thread, JSTaggedValue::Undefined()); InternalAccessor::Cast(internalAccObject)->SetGetter(nullptr);
AccessorData::Cast(internalAccObject)->SetSetter(thread, JSTaggedValue::Undefined()); InternalAccessor::Cast(internalAccObject)->SetSetter(nullptr);
EXPECT_TRUE(JSTaggedValue(internalAccObject).IsInternalAccessor()); EXPECT_TRUE(JSTaggedValue(internalAccObject).IsInternalAccessor());
AccessorData *internalAcc = AccessorData::Cast(internalAccObject); AccessorData *internalAcc = AccessorData::Cast(internalAccObject);
EXPECT_TRUE(JSTaggedValue(internalAcc).IsInternalAccessor()); EXPECT_TRUE(JSTaggedValue(internalAcc).IsInternalAccessor());
@ -83,8 +83,8 @@ HWTEST_F_L0(AccessorDataTest, IsInternal)
JSHandle<JSHClass> internalAccClass = JSHandle<JSHClass> internalAccClass =
factory->NewEcmaHClass(JSObject::SIZE, JSType::INTERNAL_ACCESSOR, nullHandle); factory->NewEcmaHClass(JSObject::SIZE, JSType::INTERNAL_ACCESSOR, nullHandle);
TaggedObject *internalAccObject = factory->NewObject(internalAccClass); TaggedObject *internalAccObject = factory->NewObject(internalAccClass);
AccessorData::Cast(internalAccObject)->SetGetter(thread, JSTaggedValue::Undefined()); InternalAccessor::Cast(internalAccObject)->SetGetter(nullptr);
AccessorData::Cast(internalAccObject)->SetSetter(thread, JSTaggedValue::Undefined()); InternalAccessor::Cast(internalAccObject)->SetSetter(nullptr);
AccessorData *internalAcc = AccessorData::Cast(internalAccObject); AccessorData *internalAcc = AccessorData::Cast(internalAccObject);
EXPECT_EQ(internalAcc->IsInternal(), true); EXPECT_EQ(internalAcc->IsInternal(), true);
} }
@ -112,11 +112,12 @@ HWTEST_F_L0(AccessorDataTest, HasSetter)
// 2.Create internal AccessorData object by NewInternalAccessor function. // 2.Create internal AccessorData object by NewInternalAccessor function.
void *setter = nullptr; void *setter = nullptr;
void *getter = nullptr; void *getter = nullptr;
JSHandle<AccessorData> internalAccHandle = factory->NewInternalAccessor(setter, getter); JSHandle<InternalAccessor> internalAccHandle = JSHandle<InternalAccessor>::Cast(
factory->NewInternalAccessor(setter, getter));
EXPECT_EQ(internalAccHandle->HasSetter(), false); EXPECT_EQ(internalAccHandle->HasSetter(), false);
internalAccHandle->SetSetter(thread, JSTaggedValue::Undefined()); internalAccHandle->SetSetter(nullptr);
EXPECT_EQ(internalAccHandle->HasSetter(), false); EXPECT_EQ(internalAccHandle->HasSetter(), false);
internalAccHandle->SetSetter(thread, normalFunction); internalAccHandle->SetSetter(JSFunction::PrototypeSetter);
EXPECT_EQ(internalAccHandle->HasSetter(), true); EXPECT_EQ(internalAccHandle->HasSetter(), true);
// 3.Create normal AccessorData object from dynamic class. // 3.Create normal AccessorData object from dynamic class.
@ -125,7 +126,6 @@ HWTEST_F_L0(AccessorDataTest, HasSetter)
TaggedObject *accObject = factory->NewObject(accClass); TaggedObject *accObject = factory->NewObject(accClass);
AccessorData *acc = AccessorData::Cast(accObject); AccessorData *acc = AccessorData::Cast(accObject);
acc->SetGetter(thread, JSTaggedValue::Undefined()); acc->SetGetter(thread, JSTaggedValue::Undefined());
EXPECT_EQ(acc->HasSetter(), true);
acc->SetSetter(thread, JSTaggedValue::Undefined()); acc->SetSetter(thread, JSTaggedValue::Undefined());
EXPECT_EQ(acc->HasSetter(), false); EXPECT_EQ(acc->HasSetter(), false);
acc->SetSetter(thread, normalFunction); acc->SetSetter(thread, normalFunction);
@ -135,12 +135,11 @@ HWTEST_F_L0(AccessorDataTest, HasSetter)
JSHandle<JSHClass> internalAccClass = JSHandle<JSHClass> internalAccClass =
factory->NewEcmaHClass(JSObject::SIZE, JSType::INTERNAL_ACCESSOR, nullHandle); factory->NewEcmaHClass(JSObject::SIZE, JSType::INTERNAL_ACCESSOR, nullHandle);
TaggedObject *internalAccObject = factory->NewObject(internalAccClass); TaggedObject *internalAccObject = factory->NewObject(internalAccClass);
AccessorData *internalAcc = AccessorData::Cast(internalAccObject); InternalAccessor *internalAcc = InternalAccessor::Cast(internalAccObject);
internalAcc->SetGetter(thread, JSTaggedValue::Undefined()); internalAcc->SetGetter(nullptr);
EXPECT_EQ(internalAcc->HasSetter(), true); internalAcc->SetSetter(nullptr);
internalAcc->SetSetter(thread, JSTaggedValue::Undefined());
EXPECT_EQ(internalAcc->HasSetter(), false); EXPECT_EQ(internalAcc->HasSetter(), false);
internalAcc->SetSetter(thread, normalFunction); internalAcc->SetSetter(JSFunction::PrototypeSetter);
EXPECT_EQ(internalAcc->HasSetter(), true); EXPECT_EQ(internalAcc->HasSetter(), true);
} }
@ -165,21 +164,16 @@ HWTEST_F_L0(AccessorDataTest, CallInternalSet)
JSHandle<JSTaggedValue> nullPrototypeHandle(thread, JSTaggedValue::Null()); JSHandle<JSTaggedValue> nullPrototypeHandle(thread, JSTaggedValue::Null());
JSHandle<JSHClass> accClass1 = JSHandle<JSHClass> accClass1 =
factory->NewEcmaHClass(JSObject::SIZE, JSType::INTERNAL_ACCESSOR, nullPrototypeHandle); factory->NewEcmaHClass(JSObject::SIZE, JSType::INTERNAL_ACCESSOR, nullPrototypeHandle);
JSHandle<AccessorData> accObject1(thread, factory->NewObject(accClass1)); JSHandle<InternalAccessor> internal(thread, factory->NewObject(accClass1));
accObject1->SetGetter(thread, JSTaggedValue::Undefined()); JSHandle<AccessorData> accObject1 = JSHandle<AccessorData>::Cast(internal);
accObject1->SetSetter(thread, JSTaggedValue::Undefined()); internal->SetGetter(JSFunction::PrototypeGetter);
JSHandle<JSNativePointer> prototypeGetterFuncNativePtrHandle =
factory->NewJSNativePointer(reinterpret_cast<void *>(JSFunction::PrototypeGetter), nullptr, nullptr, true);
accObject1->SetGetter(thread, prototypeGetterFuncNativePtrHandle);
JSTaggedValue valNullPrototype = accObject1->CallInternalGet(thread, JSHandle<JSObject>::Cast(funcTagVal1)); JSTaggedValue valNullPrototype = accObject1->CallInternalGet(thread, JSHandle<JSObject>::Cast(funcTagVal1));
EXPECT_NE(valNullPrototype.GetRawData(), JSTaggedValue::Undefined().GetRawData()); EXPECT_NE(valNullPrototype.GetRawData(), JSTaggedValue::Undefined().GetRawData());
// Call the CallInternalSet method to set new prototype. // Call the CallInternalSet method to set new prototype.
JSHandle<JSTaggedValue> undefPrototypeHandle(thread, JSTaggedValue::Undefined()); JSHandle<JSTaggedValue> undefPrototypeHandle(thread, JSTaggedValue::Undefined());
JSHandle<JSNativePointer> prototypeSetterFuncNativePtrHandle = internal->SetSetter(JSFunction::PrototypeSetter);
factory->NewJSNativePointer(reinterpret_cast<void *>(JSFunction::PrototypeSetter), nullptr, nullptr, true);
accObject1->SetSetter(thread, prototypeSetterFuncNativePtrHandle);
bool res1 = accObject1->CallInternalSet(thread, JSHandle<JSObject>::Cast(funcTagVal1), undefPrototypeHandle); bool res1 = accObject1->CallInternalSet(thread, JSHandle<JSObject>::Cast(funcTagVal1), undefPrototypeHandle);
EXPECT_TRUE(res1); EXPECT_TRUE(res1);

View File

@ -43,8 +43,8 @@ static JSFunction *JSObjectTestCreate(JSThread *thread)
} }
bool TestBoolSetter([[maybe_unused]] JSThread *thread, bool TestBoolSetter([[maybe_unused]] JSThread *thread,
[[maybe_unused]] JSHandle<JSObject> &jsObject, [[maybe_unused]] const JSHandle<JSObject> &jsObject,
[[maybe_unused]] JSHandle<JSTaggedValue> &value, [[maybe_unused]] const JSHandle<JSTaggedValue> &value,
[[maybe_unused]] bool success) [[maybe_unused]] bool success)
{ {
return true; return true;
@ -183,10 +183,9 @@ HWTEST_F_L0(ObjectOperatorTest, UpdateDateValue_001)
auto *resultDict = NumberDictionary::Cast(handleObject->GetElements().GetTaggedObject()); auto *resultDict = NumberDictionary::Cast(handleObject->GetElements().GetTaggedObject());
EXPECT_EQ(resultDict->GetValue(objectOperator1.GetIndex()).GetInt(), 5); EXPECT_EQ(resultDict->GetValue(objectOperator1.GetIndex()).GetInt(), 5);
// objcet value is InternalAccessor // object value is InternalAccessor
JSHandle<AccessorData> handleAccessorData = factory->NewAccessorData(); JSHandle<AccessorData> handleAccessorData = factory->NewInternalAccessor(
JSHandle<JSNativePointer> handleSetter = factory->NewJSNativePointer(reinterpret_cast<void *>(TestBoolSetter)); reinterpret_cast<void*>(TestBoolSetter), nullptr);
handleAccessorData->SetSetter(thread, handleSetter.GetTaggedValue());
JSHandle<JSTaggedValue> handleValue2(handleAccessorData); JSHandle<JSTaggedValue> handleValue2(handleAccessorData);
ObjectOperator objectOperator2(thread, handleKey); ObjectOperator objectOperator2(thread, handleKey);
objectOperator2.SetValue(handleAccessorData.GetTaggedValue()); objectOperator2.SetValue(handleAccessorData.GetTaggedValue());