Skip to content

Commit 019d263

Browse files
committed
feat: implement interop.FunctionReference
1 parent a6a0d89 commit 019d263

File tree

3 files changed

+84
-5
lines changed

3 files changed

+84
-5
lines changed

include/Interop.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#ifndef INTEROP_H
22
#define INTEROP_H
33

4+
#include "Closure.h"
45
#include "TypeConv.h"
56
#include "js_native_api.h"
67

@@ -61,6 +62,26 @@ class Reference {
6162
napi_ref initValue = nullptr;
6263
};
6364

65+
class FunctionReference {
66+
public:
67+
static napi_value defineJSClass(napi_env env);
68+
69+
static FunctionReference *unwrap(napi_env env, napi_value value);
70+
71+
static napi_value constructor(napi_env env, napi_callback_info info);
72+
73+
static void finalize(napi_env env, void *data, void *hint);
74+
75+
FunctionReference(napi_env env, napi_ref ref) : env(env), ref(ref){};
76+
~FunctionReference();
77+
78+
void *getFunctionPointer(MDSectionOffset offset);
79+
80+
napi_env env;
81+
napi_ref ref;
82+
std::shared_ptr<Closure> closure = nullptr;
83+
};
84+
6485
} // namespace objc_bridge
6586

6687
#endif /* INTEROP_H */

src/Interop.mm

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
#include "Interop.h"
2+
#include "Metadata.h"
23
#include "ObjCBridge.h"
34
#include "Util.h"
45
#include "js_native_api.h"
56
#include "js_native_api_types.h"
67
#include "node_api_util.h"
78

89
#import <Foundation/Foundation.h>
10+
#include <memory>
911

1012
namespace objc_bridge {
1113

@@ -63,6 +65,8 @@ void registerInterop(napi_env env, napi_value global) {
6365
napi_value Reference = Reference::defineJSClass(env);
6466
bridgeState->referenceClass = make_ref(env, Reference);
6567

68+
napi_value FunctionReference = FunctionReference::defineJSClass(env);
69+
6670
const napi_property_descriptor properties[] = {
6771
{
6872
.utf8name = "Pointer",
@@ -82,6 +86,15 @@ void registerInterop(napi_env env, napi_value global) {
8286
.data = nullptr,
8387
.method = nullptr,
8488
},
89+
{
90+
.utf8name = "FunctionReference",
91+
.attributes = napi_enumerable,
92+
.getter = nullptr,
93+
.setter = nullptr,
94+
.value = FunctionReference,
95+
.data = nullptr,
96+
.method = nullptr,
97+
},
8598
{
8699
.utf8name = "types",
87100
.attributes = napi_enumerable,
@@ -600,4 +613,52 @@ napi_value interop_bufferFromData(napi_env env, napi_callback_info info) {
600613
}
601614
}
602615

616+
napi_value FunctionReference::defineJSClass(napi_env env) {
617+
napi_value constructor;
618+
napi_define_class(env, "FunctionReference", NAPI_AUTO_LENGTH,
619+
FunctionReference::constructor, nullptr, 0, nullptr,
620+
&constructor);
621+
622+
return constructor;
623+
}
624+
625+
FunctionReference *FunctionReference::unwrap(napi_env env, napi_value value) {
626+
FunctionReference *ref = nullptr;
627+
napi_unwrap(env, value, (void **)&ref);
628+
return ref;
629+
}
630+
631+
void FunctionReference::finalize(napi_env env, void *data, void *hint) {
632+
FunctionReference *ref = (FunctionReference *)data;
633+
delete ref;
634+
}
635+
636+
napi_value FunctionReference::constructor(napi_env env,
637+
napi_callback_info info) {
638+
napi_value jsThis;
639+
size_t argc = 1;
640+
napi_value arg;
641+
napi_get_cb_info(env, info, &argc, &arg, &jsThis, nullptr);
642+
643+
FunctionReference *reference = new FunctionReference(env, make_ref(env, arg));
644+
645+
napi_ref ref;
646+
napi_wrap(env, jsThis, reference, FunctionReference::finalize, nullptr, &ref);
647+
648+
return jsThis;
649+
}
650+
651+
FunctionReference::~FunctionReference() { napi_delete_reference(env, ref); }
652+
653+
void *FunctionReference::getFunctionPointer(MDSectionOffset offset) {
654+
if (closure == nullptr) {
655+
closure = std::make_shared<Closure>(
656+
ObjCBridgeState::InstanceData(env)->metadata, offset, true);
657+
closure->env = env;
658+
closure->func = ref;
659+
}
660+
661+
return closure->fnptr;
662+
}
663+
603664
} // namespace objc_bridge

src/TypeConv.mm

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -767,11 +767,8 @@ void toNative(napi_env env, napi_value value, void *result, bool *shouldFree,
767767
}
768768

769769
case napi_object: {
770-
NAPI_GUARD(napi_unwrap(env, value, res)) {
771-
NAPI_THROW_LAST_ERROR
772-
*res = nullptr;
773-
return;
774-
}
770+
FunctionReference *ref = FunctionReference::unwrap(env, value);
771+
*res = ref->getFunctionPointer(signatureOffset);
775772
}
776773

777774
case napi_function: {

0 commit comments

Comments
 (0)