mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-11-23 10:09:54 +00:00
Add sendable napi
Issue: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I9O3XT?from=project-issue Signed-off-by: liu-zelin <liuzelin8@huawei.com> Change-Id: I6f361f4e3dd454d14ac9ef22a924118c7a41844b
This commit is contained in:
parent
c5738ee27e
commit
76cbb82b9d
@ -334,16 +334,13 @@ void JSObject::OptimizeAsFastProperties(const JSThread *thread, JSHandle<JSObjec
|
||||
obj->SetProperties(thread, array);
|
||||
}
|
||||
|
||||
void JSObject::SetSProperties(JSThread *thread,
|
||||
JSHandle<JSObject> obj,
|
||||
JSHandle<JSHClass> hclass,
|
||||
const std::vector<PropertyDescriptor> &descs)
|
||||
void JSObject::SetSProperties(JSThread *thread, JSHandle<JSObject> obj, const std::vector<PropertyDescriptor> &descs)
|
||||
{
|
||||
uint32_t length = descs.size();
|
||||
JSMutableHandle<JSTaggedValue> propKey(thread, JSTaggedValue::Undefined());
|
||||
JSMutableHandle<JSTaggedValue> propValue(thread, JSTaggedValue::Undefined());
|
||||
|
||||
if (LIKELY(!hclass->IsDictionaryMode())) {
|
||||
if (LIKELY(!obj->GetJSHClass()->IsDictionaryMode())) {
|
||||
for (uint32_t i = 0; i < length; ++i) {
|
||||
propValue.Update(descs[i].GetValue());
|
||||
// note(lzl): IsSAccessor?
|
||||
|
@ -749,10 +749,7 @@ public:
|
||||
static void TryOptimizeAsFastElements(const JSThread *thread, JSHandle<JSObject> obj);
|
||||
static void OptimizeAsFastProperties(const JSThread *thread, JSHandle<JSObject> obj);
|
||||
|
||||
static void SetSProperties(JSThread *thread,
|
||||
JSHandle<JSObject> obj,
|
||||
JSHandle<JSHClass> hclass,
|
||||
const std::vector<PropertyDescriptor> &descs);
|
||||
static void SetSProperties(JSThread *thread, JSHandle<JSObject> obj, const std::vector<PropertyDescriptor> &descs);
|
||||
|
||||
protected:
|
||||
static void ElementsToDictionary(const JSThread *thread, JSHandle<JSObject> obj);
|
||||
|
@ -28,6 +28,7 @@ JSNapiSendable::JSNapiSendable(JSThread *thread, FunctionRef::SendableProperties
|
||||
{
|
||||
InitStaticDescription(thread, staticDescs_, name);
|
||||
InitNonStaticDescription(thread, nonStaticDescs_);
|
||||
InitInstanceDescription(thread, instanceDescs_);
|
||||
InitWithPropertiesInfo(thread, infos.staticPropertiesInfo, staticDescs_);
|
||||
InitWithPropertiesInfo(thread, infos.nonStaticPropertiesInfo, nonStaticDescs_);
|
||||
InitWithPropertiesInfo(thread, infos.instancePropertiesInfo, instanceDescs_);
|
||||
@ -71,6 +72,18 @@ void JSNapiSendable::InitNonStaticDescription(JSThread *thread, std::vector<Prop
|
||||
descs.push_back(constructorDesc);
|
||||
}
|
||||
|
||||
void JSNapiSendable::InitInstanceDescription(JSThread *thread, std::vector<PropertyDescriptor> &descs)
|
||||
{
|
||||
const GlobalEnvConstants *globalConst = thread->GlobalConstants();
|
||||
|
||||
JSHandle<JSTaggedValue> napiWrapperKey = globalConst->GetHandledNapiWrapperString();
|
||||
PropertyDescriptor napiWrapperDesc(thread, true, false, false);
|
||||
napiWrapperDesc.SetKey(napiWrapperKey);
|
||||
napiWrapperDesc.SetSharedFieldType(SharedFieldType::SENDABLE);
|
||||
napiWrapperDesc.SetValue(globalConst->GetHandledNull());
|
||||
descs.push_back(napiWrapperDesc);
|
||||
}
|
||||
|
||||
void JSNapiSendable::InitWithPropertiesInfo(JSThread *thread,
|
||||
FunctionRef::SendablePropertiesInfo &info,
|
||||
std::vector<PropertyDescriptor> &descs)
|
||||
|
@ -37,6 +37,9 @@ public:
|
||||
{
|
||||
return instanceDescs_;
|
||||
}
|
||||
static void InitWithPropertiesInfo(JSThread *thread,
|
||||
FunctionRef::SendablePropertiesInfo &info,
|
||||
std::vector<PropertyDescriptor> &descs);
|
||||
|
||||
private:
|
||||
std::vector<PropertyDescriptor> staticDescs_;
|
||||
@ -45,9 +48,7 @@ private:
|
||||
|
||||
static void InitStaticDescription(JSThread *thread, std::vector<PropertyDescriptor> &descs, Local<StringRef> &name);
|
||||
static void InitNonStaticDescription(JSThread *thread, std::vector<PropertyDescriptor> &descs);
|
||||
static void InitWithPropertiesInfo(JSThread *thread,
|
||||
FunctionRef::SendablePropertiesInfo &info,
|
||||
std::vector<PropertyDescriptor> &descs);
|
||||
static void InitInstanceDescription(JSThread *thread, std::vector<PropertyDescriptor> &descs);
|
||||
static SharedFieldType GetSharedFieldType(JSThread *thread,
|
||||
FunctionRef::SendableType type,
|
||||
Local<JSValueRef> value);
|
||||
|
@ -491,6 +491,7 @@ public:
|
||||
bool IsTreeSet();
|
||||
bool IsVector();
|
||||
bool IsSharedObject();
|
||||
bool IsSharedFunction();
|
||||
bool IsJSShared();
|
||||
bool IsSharedArray();
|
||||
bool IsSharedTypedArray();
|
||||
@ -642,14 +643,25 @@ public:
|
||||
|
||||
class ECMA_PUBLIC_API ObjectRef : public JSValueRef {
|
||||
public:
|
||||
enum class SendableType {
|
||||
NONE,
|
||||
OBJECT,
|
||||
};
|
||||
struct SendablePropertiesInfo {
|
||||
std::vector<Local<JSValueRef>> keys;
|
||||
std::vector<SendableType> types;
|
||||
std::vector<PropertyAttribute> attributes;
|
||||
};
|
||||
static constexpr int MAX_PROPERTIES_ON_STACK = 32;
|
||||
static inline ObjectRef *Cast(JSValueRef *value)
|
||||
{
|
||||
return static_cast<ObjectRef *>(value);
|
||||
}
|
||||
static Local<ObjectRef> New(const EcmaVM *vm);
|
||||
static Local<ObjectRef> NewS(const EcmaVM *vm);
|
||||
static Local<ObjectRef> NewWithProperties(const EcmaVM *vm, size_t propertyCount, const Local<JSValueRef> *keys,
|
||||
const PropertyAttribute *attributes);
|
||||
static Local<ObjectRef> NewSWithProperties(const EcmaVM *vm, SendablePropertiesInfo &info);
|
||||
static Local<ObjectRef> NewWithNamedProperties(const EcmaVM *vm, size_t propertyCount, const char **keys,
|
||||
const Local<JSValueRef> *values);
|
||||
static Local<ObjectRef> CreateAccessorData(const EcmaVM *vm, Local<FunctionRef> getter, Local<FunctionRef> setter);
|
||||
@ -703,15 +715,6 @@ using FunctionCallback = Local<JSValueRef>(*)(JsiRuntimeCallInfo*);
|
||||
using InternalFunctionCallback = JSValueRef(*)(JsiRuntimeCallInfo*);
|
||||
class ECMA_PUBLIC_API FunctionRef : public ObjectRef {
|
||||
public:
|
||||
enum class SendableType {
|
||||
NONE,
|
||||
OBJECT,
|
||||
};
|
||||
struct SendablePropertiesInfo {
|
||||
std::vector<Local<JSValueRef>> keys;
|
||||
std::vector<SendableType> types;
|
||||
std::vector<PropertyAttribute> attributes;
|
||||
};
|
||||
struct SendablePropertiesInfos {
|
||||
SendablePropertiesInfo instancePropertiesInfo;
|
||||
SendablePropertiesInfo staticPropertiesInfo;
|
||||
|
@ -820,6 +820,11 @@ bool JSValueRef::IsSharedObject()
|
||||
return JSNApiHelper::ToJSTaggedValue(this).IsJSSharedObject();
|
||||
}
|
||||
|
||||
bool JSValueRef::IsSharedFunction()
|
||||
{
|
||||
return JSNApiHelper::ToJSTaggedValue(this).IsJSSharedFunction();
|
||||
}
|
||||
|
||||
bool JSValueRef::IsJSShared()
|
||||
{
|
||||
return JSNApiHelper::ToJSTaggedValue(this).IsJSShared();
|
||||
@ -1720,6 +1725,17 @@ Local<ObjectRef> ObjectRef::New(const EcmaVM *vm)
|
||||
return JSNApiHelper::ToLocal<ObjectRef>(object);
|
||||
}
|
||||
|
||||
Local<ObjectRef> ObjectRef::NewS(const EcmaVM *vm)
|
||||
{
|
||||
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
|
||||
ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
|
||||
ObjectFactory *factory = vm->GetFactory();
|
||||
JSHandle<GlobalEnv> globalEnv = vm->GetGlobalEnv();
|
||||
JSHandle<JSFunction> constructor(globalEnv->GetSObjectFunction());
|
||||
JSHandle<JSTaggedValue> object(factory->NewJSObjectByConstructor(constructor));
|
||||
return JSNApiHelper::ToLocal<ObjectRef>(object);
|
||||
}
|
||||
|
||||
Local<ObjectRef> ObjectRef::NewWithProperties(const EcmaVM *vm, size_t propertyCount,
|
||||
const Local<JSValueRef> *keys,
|
||||
const PropertyAttribute *attributes)
|
||||
@ -1754,6 +1770,19 @@ Local<ObjectRef> ObjectRef::NewWithProperties(const EcmaVM *vm, size_t propertyC
|
||||
return scope.Escape(JSNApiHelper::ToLocal<ObjectRef>(obj));
|
||||
}
|
||||
|
||||
Local<ObjectRef> ObjectRef::NewSWithProperties(const EcmaVM *vm, SendablePropertiesInfo &info)
|
||||
{
|
||||
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
|
||||
ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
|
||||
EscapeLocalScope scope(vm);
|
||||
ObjectFactory *factory = vm->GetFactory();
|
||||
std::vector<PropertyDescriptor> descs;
|
||||
JSNapiSendable::InitWithPropertiesInfo(thread, info, descs);
|
||||
auto obj = factory->CreateSObjectWithProperties(descs);
|
||||
RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
|
||||
return scope.Escape(JSNApiHelper::ToLocal<ObjectRef>(obj));
|
||||
}
|
||||
|
||||
Local<ObjectRef> ObjectRef::NewWithNamedProperties(const EcmaVM *vm, size_t propertyCount,
|
||||
const char **keys, const Local<JSValueRef> *values)
|
||||
{
|
||||
@ -2519,9 +2548,8 @@ Local<FunctionRef> FunctionRef::NewSendableClassFunction(const EcmaVM *vm,
|
||||
reinterpret_cast<void *>(nativeFunc), constructorHClass, ecmascript::FunctionKind::CLASS_CONSTRUCTOR);
|
||||
|
||||
sendable.SetSConstructor(constructor);
|
||||
JSObject::SetSProperties(thread, prototype, prototypeHClass, sendable.GetNonStaticDescs());
|
||||
JSObject::SetSProperties(thread, JSHandle<JSObject>::Cast(constructor), constructorHClass,
|
||||
sendable.GetStaticDescs());
|
||||
JSObject::SetSProperties(thread, prototype, sendable.GetNonStaticDescs());
|
||||
JSObject::SetSProperties(thread, JSHandle<JSObject>::Cast(constructor), sendable.GetStaticDescs());
|
||||
|
||||
if (!parent->IsNull()) {
|
||||
auto parentPrototype = parent->GetFunctionPrototype(vm);
|
||||
|
@ -347,4 +347,19 @@ HWTEST_F_L0(JSNApiTests, NewSendableClassFunctionGetterSetter)
|
||||
ASSERT_EQ("getterSetter0", constructor->Get(vm_, staticKey)->ToString(vm_)->ToString());
|
||||
}
|
||||
|
||||
HWTEST_F_L0(JSNApiTests, NewObjectWithProperties)
|
||||
{
|
||||
LocalScope scope(vm_);
|
||||
|
||||
FunctionRef::SendablePropertiesInfo info;
|
||||
Local<StringRef> str = StringRef::NewFromUtf8(vm_, "str");
|
||||
info.keys.push_back(str);
|
||||
info.types.push_back(FunctionRef::SendableType::NONE);
|
||||
info.attributes.push_back(PropertyAttribute(str, true, true, true));
|
||||
|
||||
Local<ObjectRef> object = ObjectRef::NewSWithProperties(vm_, info);
|
||||
Local<JSValueRef> value = object->Get(vm_, str);
|
||||
EXPECT_TRUE(str->IsStrictEquals(vm_, value));
|
||||
}
|
||||
|
||||
} // namespace panda::test
|
||||
|
@ -704,6 +704,8 @@ public:
|
||||
|
||||
TaggedObject *NewSharedOldSpaceObject(const JSHandle<JSHClass> &hclass);
|
||||
|
||||
JSHandle<JSTaggedValue> CreateSObjectWithProperties(std::vector<PropertyDescriptor> &descs);
|
||||
|
||||
JSHandle<JSHClass> PUBLIC_API NewSEcmaHClass(uint32_t size, JSType type, uint32_t inlinedProps);
|
||||
|
||||
JSHandle<JSHClass> PUBLIC_API NewSEcmaHClass(JSHClass *hclass, uint32_t size, JSType type,
|
||||
|
@ -291,6 +291,18 @@ JSHandle<JSObject> ObjectFactory::NewSharedOldSpaceJSObject(const JSHandle<JSHCl
|
||||
return obj;
|
||||
}
|
||||
|
||||
JSHandle<JSTaggedValue> ObjectFactory::CreateSObjectWithProperties(std::vector<PropertyDescriptor> &descs)
|
||||
{
|
||||
JSHandle<JSHClass> hclass = JSHClass::CreateSHClass(thread_, descs);
|
||||
JSHandle<JSObject> object = NewSharedOldSpaceJSObject(hclass);
|
||||
JSObject::SetSProperties(thread_, object, descs);
|
||||
JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
|
||||
JSHandle<JSTaggedValue> objFuncProto = env->GetSObjectFunctionPrototype();
|
||||
hclass->SetPrototype(thread_, objFuncProto);
|
||||
hclass->SetExtensible(false);
|
||||
return JSHandle<JSTaggedValue>(object);
|
||||
}
|
||||
|
||||
JSHandle<TaggedArray> ObjectFactory::SharedEmptyArray() const
|
||||
{
|
||||
return JSHandle<TaggedArray>(thread_->GlobalConstants()->GetHandledEmptyArray());
|
||||
|
Loading…
Reference in New Issue
Block a user