diff --git a/ecmascript/napi/include/jsnapi.h b/ecmascript/napi/include/jsnapi.h index 7cfe6e059ba193d35b1fc9e63d49164f9bce2e0b..60a61960124c9db29771b0b22b36d09f991e85a9 100644 --- a/ecmascript/napi/include/jsnapi.h +++ b/ecmascript/napi/include/jsnapi.h @@ -533,6 +533,7 @@ class PUBLIC_API FunctionRef : public ObjectRef { public: static Local New(EcmaVM *vm, FunctionCallback nativeFunc, void *data); static Local New(EcmaVM *vm, FunctionCallback nativeFunc, Deleter deleter, void *data); + static Local NewWithProperty(EcmaVM *vm, FunctionCallback nativeFunc, void *data); static Local NewClassFunction(EcmaVM *vm, FunctionCallbackWithNewTarget nativeFunc, Deleter deleter, void *data); Local Call(const EcmaVM *vm, Local thisObj, const Local argv[], diff --git a/ecmascript/napi/jsnapi.cpp b/ecmascript/napi/jsnapi.cpp index d0a1a458e5f94b0e76af8b2d927eafac2897e556..37a8eaae34c304df617fbf1faf1e12eb807bc0ac 100644 --- a/ecmascript/napi/jsnapi.cpp +++ b/ecmascript/napi/jsnapi.cpp @@ -765,6 +765,20 @@ Local FunctionRef::New(EcmaVM *vm, FunctionCallback nativeFunc, Del return JSNApiHelper::ToLocal(JSHandle(current)); } +Local FunctionRef::NewWithProperty(EcmaVM *vm, FunctionCallback nativeFunc, void *data) +{ + JSThread *thread = vm->GetJSThread(); + ObjectFactory *factory = vm->GetFactory(); + JSHandle env = vm->GetGlobalEnv(); + JSHandle current = + factory->NewJSFunction(env, reinterpret_cast(Callback::RegisterCallbackWithProperty)); + JSHandle funcCallback = factory->NewJSNativePointer(reinterpret_cast(nativeFunc)); + JSHandle dataCaddress = factory->NewJSNativePointer(data); + JSHandle extraInfo(factory->NewFunctionExtraInfo(funcCallback, dataCaddress)); + current->SetFunctionExtraInfo(thread, extraInfo.GetTaggedValue()); + return JSNApiHelper::ToLocal(JSHandle(current)); +} + Local FunctionRef::NewClassFunction(EcmaVM *vm, FunctionCallbackWithNewTarget nativeFunc, Deleter deleter, void *data) { @@ -1301,6 +1315,58 @@ JSTaggedValue Callback::RegisterCallback(ecmascript::EcmaRuntimeCallInfo *info) return JSNApiHelper::ToJSHandle(result).GetTaggedValue(); } +JSTaggedValue Callback::RegisterCallbackWithProperty(ecmascript::EcmaRuntimeCallInfo *info) +{ + // Constructor + JSThread *thread = info->GetThread(); + JSHandle constructor = BuiltinsBase::GetConstructor(info); + if (!constructor->IsJSFunction()) { + return JSTaggedValue::False(); + } + JSHandle function(constructor); + JSHandle extraInfoValue(thread, function->GetFunctionExtraInfo()); + if (!extraInfoValue->IsJSFunctionExtraInfo()) { + return JSTaggedValue::False(); + } + JSHandle extraInfo(extraInfoValue); + // vm + Region *region = Region::ObjectAddressToRange(extraInfo.GetTaggedValue().GetTaggedObject()); + if (region == nullptr) { + return JSTaggedValue::False(); + } + EcmaVM *vm = region->GetSpace()->GetHeap()->GetEcmaVM(); + // data + JSHandle data(thread, extraInfo->GetData()); + if (!data->IsHeapObject()) { + return JSTaggedValue::False(); + } + JSHandle dataObj(data); + // callBack + JSHandle callBack(thread, extraInfo->GetCallback()); + if (!callBack->IsHeapObject()) { + return JSTaggedValue::False(); + } + JSHandle callBackObj(callBack); + FunctionCallback nativeFunc = (reinterpret_cast(callBackObj->GetExternalPointer())); + + // constructor + JSHandle thisValue(BuiltinsBase::GetConstructor(info)); + + // arguments + std::vector> arguments; + array_size_t length = info->GetArgsNumber(); + for (array_size_t i = 0; i < length; ++i) { + arguments.emplace_back(JSNApiHelper::ToLocal(BuiltinsBase::GetCallArg(info, i))); + } + + Local result = nativeFunc(vm, + JSNApiHelper::ToLocal(thisValue), + arguments.data(), + arguments.size(), + dataObj->GetExternalPointer()); + return JSNApiHelper::ToJSHandle(result).GetTaggedValue(); +} + JSTaggedValue Callback::RegisterCallbackWithNewTarget(ecmascript::EcmaRuntimeCallInfo *info) { // Constructor diff --git a/ecmascript/napi/jsnapi_helper.h b/ecmascript/napi/jsnapi_helper.h index bd377a35151ea82092b456b66b61f5467d6f73bc..53b1cb627f794ee086cd3cf05c2e97c91d5eec18 100644 --- a/ecmascript/napi/jsnapi_helper.h +++ b/ecmascript/napi/jsnapi_helper.h @@ -74,6 +74,7 @@ public: class Callback { public: static ecmascript::JSTaggedValue RegisterCallback(ecmascript::EcmaRuntimeCallInfo *info); + static ecmascript::JSTaggedValue RegisterCallbackWithProperty(ecmascript::EcmaRuntimeCallInfo *info); static ecmascript::JSTaggedValue RegisterCallbackWithNewTarget(ecmascript::EcmaRuntimeCallInfo *info); }; } // namespace panda