@@ -217,6 +217,7 @@ class NativeInfo {
217217 static T* GetNativeInfo (JSContextRef ctx, JSObjectRef obj, const char * propertyKey) {
218218 JSValueRef exception {};
219219 JSValueRef native_info = JSObjectGetProperty (ctx, obj, JSString (propertyKey), &exception);
220+
220221 NativeInfo* info = Get<NativeInfo>(JSValueToObject (ctx, native_info, &exception));
221222 if (info != nullptr && info->Type () == T::StaticType) {
222223 return reinterpret_cast <T*>(info);
@@ -349,6 +350,11 @@ class ConstructorInfo : public NativeInfo {
349350 JSClassRef _class;
350351};
351352
353+ namespace xyz {
354+ static std::once_flag functionInfoOnceFlag;
355+ JSClassRef functionInfoClass {};
356+ }
357+
352358class FunctionInfo : public NativeInfo {
353359 public:
354360 static const NativeType StaticType = NativeType::Function;
@@ -363,35 +369,44 @@ class FunctionInfo : public NativeInfo {
363369 if (info == nullptr ) {
364370 return napi_set_last_error (env, napi_generic_failure);
365371 }
366-
367- JSObjectRef function{JSObjectMakeFunctionWithCallback (env->context , JSString (utf8name), CallAsFunction)};
368- // JSObjectRef prototype{JSObjectMake(env->context, info->_class, info)};
369- //
370- //
371- // JSObjectSetPrototype(env->context, prototype, JSObjectGetPrototype(env->context, function));
372- // JSObjectSetPrototype(env->context, function, prototype);
373-
374- NativeInfo::SetNativeInfo (env->context , function, info->_class , " [[jsc_function_info]]" , info);
375-
372+ JSObjectRef function = JSObjectMake (env->context , xyz::functionInfoClass, info);
376373 *result = ToNapi (function);
377374 return napi_ok;
378375 }
379376
377+
380378 private:
381379 FunctionInfo (napi_env env, napi_callback cb, void * data)
382380 : NativeInfo{NativeType::Function}
383381 , _env{env}
384382 , _cb{cb}
385383 , _data{data} {
386- JSClassDefinition definition{kJSClassDefinitionEmpty };
387- definition.className = " Native" ;
388- definition.finalize = Finalize;
389- _class = JSClassCreate (&definition);
384+ std::call_once (xyz::functionInfoOnceFlag, []() {
385+ JSClassDefinition definition{kJSClassDefinitionEmpty };
386+ definition.className = " NapiFunctionCallback" ;
387+ definition.callAsFunction = FunctionInfo::CallAsFunction;
388+ definition.attributes = kJSClassAttributeNoAutomaticPrototype ;
389+ definition.initialize = FunctionInfo::initialize;
390+ definition.finalize = Finalize;
391+ xyz::functionInfoClass = JSClassCreate (&definition);
392+ });
393+
390394 }
391395
392- ~FunctionInfo () {
393- JSClassRelease (_class);
396+ ~FunctionInfo () {}
397+
398+ static void initialize (JSContextRef ctx, JSObjectRef object) {
399+ JSObjectRef global = JSContextGetGlobalObject (ctx);
400+ JSValueRef value =
401+ JSObjectGetProperty (ctx, global, JSString (" Function" ), nullptr );
402+ JSObjectRef funcCtor = JSValueToObject (ctx, value, nullptr );
403+ if (!funcCtor) {
404+ // We can't do anything if Function is not an object
405+ return ;
394406 }
407+ JSValueRef funcProto = JSObjectGetPrototype (ctx, funcCtor);
408+ JSObjectSetPrototype (ctx, object, funcProto);
409+ }
395410
396411 // JSObjectCallAsFunctionCallback
397412 static JSValueRef CallAsFunction (JSContextRef ctx,
@@ -401,7 +416,7 @@ class FunctionInfo : public NativeInfo {
401416 const JSValueRef arguments[],
402417 JSValueRef* exception) {
403418// FunctionInfo* info = NativeInfo::Get<FunctionInfo>(function);
404- FunctionInfo* info = NativeInfo::GetNativeInfo <FunctionInfo>(ctx, function, " [[jsc_function_info]] " );
419+ FunctionInfo* info = reinterpret_cast <FunctionInfo *>( JSObjectGetPrivate ( function) );
405420
406421 // Make sure any errors encountered last time we were in N-API are gone.
407422 napi_clear_last_error (info->_env );
@@ -411,6 +426,7 @@ class FunctionInfo : public NativeInfo {
411426 cbinfo.newTarget = nullptr ;
412427 cbinfo.argc = argumentCount;
413428 cbinfo.argv = ToNapi (arguments);
429+
414430 cbinfo.data = info->_data ;
415431
416432 napi_value result = info->_cb (info->_env , &cbinfo);
@@ -433,9 +449,9 @@ class FunctionInfo : public NativeInfo {
433449 napi_env _env;
434450 napi_callback _cb;
435451 void * _data;
436- JSClassRef _class;
437452};
438453
454+
439455template <typename T, NativeType TType>
440456class BaseInfoT : public NativeInfo {
441457 public:
@@ -715,6 +731,15 @@ void NapiEnvironment::deinit_refs() {
715731 }
716732}
717733
734+ void NapiEnvironment::init_symbol (JSValueRef &symbol, const char *description) {
735+ symbol = JSValueMakeSymbol (context, JSString (description));
736+ JSValueProtect (context, symbol);
737+ }
738+
739+ void NapiEnvironment::deinit_symbol (JSValueRef symbol) {
740+ JSValueUnprotect (context, symbol);
741+ }
742+
718743// Warning: Keep in-sync with napi_status enum
719744static const char * error_messages[] = {
720745 nullptr ,
0 commit comments