1
1
#include " Block.h"
2
+ #import < Foundation/Foundation.h>
3
+ #include " js_native_api_types.h"
2
4
#include " Interop.h"
3
5
#include " ObjCBridge.h"
4
6
#include " js_native_api.h"
5
7
#include " node_api_util.h"
6
8
#include " objc/runtime.h"
7
- #import < Foundation/Foundation.h>
8
9
9
10
struct Block_descriptor_1 {
10
- unsigned long int reserved; // NULL
11
- unsigned long int size; // sizeof(struct Block_literal_1)
11
+ unsigned long int reserved; // NULL
12
+ unsigned long int size; // sizeof(struct Block_literal_1)
12
13
// optional helper functions
13
- void (*copy_helper)(void * dst, void * src); // IFF (1<<25)
14
- void (*dispose_helper)(void * src); // IFF (1<<25)
14
+ void (*copy_helper)(void * dst, void * src); // IFF (1<<25)
15
+ void (*dispose_helper)(void * src); // IFF (1<<25)
15
16
// required ABI.2010.3.16
16
- const char * signature; // IFF (1<<30)
17
+ const char * signature; // IFF (1<<30)
17
18
};
18
19
19
20
struct Block_literal_1 {
20
- void * isa; // initialized to &_NSConcreteStackBlock or &_NSConcreteGlobalBlock
21
+ void * isa; // initialized to &_NSConcreteStackBlock or &_NSConcreteGlobalBlock
21
22
int flags;
22
23
int reserved;
23
- void * invoke;
24
- Block_descriptor_1 * descriptor;
24
+ void * invoke;
25
+ Block_descriptor_1* descriptor;
25
26
// imported variables
26
- objc_bridge::Closure * closure;
27
+ objc_bridge::Closure* closure;
27
28
};
28
29
29
- void block_copy (void * dest, void * src) {}
30
- void block_release (void * src) {}
30
+ void block_copy (void * dest, void * src) {}
31
+ void block_release (void * src) {}
31
32
32
- void block_finalize (napi_env env, void * data, void * hint) {
33
- auto block = (Block_literal_1 *)data;
33
+ void block_finalize (napi_env env, void * data, void * hint) {
34
+ auto block = (Block_literal_1*)data;
34
35
delete block->closure ;
35
36
delete block;
36
37
}
37
38
38
39
namespace objc_bridge {
39
40
40
- void * stackBlockISA = nullptr ;
41
+ void * stackBlockISA = nullptr ;
41
42
42
- id registerBlock (napi_env env, Closure * closure, napi_value callback) {
43
+ id registerBlock (napi_env env, Closure* closure, napi_value callback) {
43
44
auto block = new Block_literal_1 ();
44
45
if (stackBlockISA == nullptr ) {
45
46
stackBlockISA = dlsym (RTLD_DEFAULT, " _NSConcreteStackBlock" );
@@ -59,22 +60,24 @@ id registerBlock(napi_env env, Closure *closure, napi_value callback) {
59
60
60
61
napi_remove_wrap (env, callback, nullptr );
61
62
napi_ref ref = nullptr ;
62
- napi_wrap (env, callback, block, block_finalize, nullptr , &ref);
63
- if (ref == nullptr ) {
63
+ // TODO: fix memory management of objc blocks here
64
+ // napi_wrap(env, callback, block, block_finalize, nullptr, &ref);
65
+ // if (ref == nullptr) {
64
66
// Deno doesn't handle napi_wrap properly.
65
- ref = make_ref (env, callback, 0 );
66
- }
67
+ ref = make_ref (env, callback, 1 );
68
+ // } else {
69
+ // uint32_t refCount;
70
+ // napi_reference_ref(env, ref, &refCount);
71
+ // }
67
72
closure->func = ref;
68
73
69
74
auto bridgeState = ObjCBridgeState::InstanceData (env);
70
75
if (napiSupportsThreadsafeFunctions (bridgeState->self_dl )) {
71
76
napi_value workName;
72
77
napi_create_string_utf8 (env, " Block" , NAPI_AUTO_LENGTH, &workName);
73
- napi_create_threadsafe_function (
74
- env, callback, nullptr , workName, 0 , 1 , nullptr , nullptr , closure,
75
- Closure::callBlockFromMainThread, &closure->tsfn );
76
- if (closure->tsfn )
77
- napi_unref_threadsafe_function (env, closure->tsfn );
78
+ napi_create_threadsafe_function (env, callback, nullptr , workName, 0 , 1 , nullptr , nullptr ,
79
+ closure, Closure::callBlockFromMainThread, &closure->tsfn );
80
+ if (closure->tsfn ) napi_unref_threadsafe_function (env, closure->tsfn );
78
81
}
79
82
80
83
return (id )block;
@@ -98,14 +101,13 @@ id registerBlock(napi_env env, Closure *closure, napi_value callback) {
98
101
return callback;
99
102
}
100
103
101
- napi_value FunctionPointer::wrap (napi_env env, void *function,
102
- metagen::MDSectionOffset offset,
104
+ napi_value FunctionPointer::wrap (napi_env env, void * function, metagen::MDSectionOffset offset,
103
105
bool isBlock) {
104
- FunctionPointer * ref = new FunctionPointer ();
106
+ FunctionPointer* ref = new FunctionPointer ();
105
107
ref->function = function;
106
108
ref->offset = offset;
107
109
108
- ObjCBridgeState * bridgeState = ObjCBridgeState::InstanceData (env);
110
+ ObjCBridgeState* bridgeState = ObjCBridgeState::InstanceData (env);
109
111
110
112
if (isBlock) {
111
113
ref->cif = bridgeState->getBlockCif (env, offset);
@@ -114,36 +116,32 @@ id registerBlock(napi_env env, Closure *closure, napi_value callback) {
114
116
}
115
117
116
118
napi_value result;
117
- napi_create_function (
118
- env, isBlock ? " objcBlockWrapper" : " cFunctionWrapper" , NAPI_AUTO_LENGTH,
119
- isBlock ? jsCallAsBlock : jsCallAsCFunction, ref, &result);
119
+ napi_create_function (env, isBlock ? " objcBlockWrapper" : " cFunctionWrapper" , NAPI_AUTO_LENGTH,
120
+ isBlock ? jsCallAsBlock : jsCallAsCFunction, ref, &result);
120
121
121
122
napi_ref jsRef;
122
- napi_add_finalizer (env, result, ref, FunctionPointer::finalize, nullptr ,
123
- &jsRef);
123
+ napi_add_finalizer (env, result, ref, FunctionPointer::finalize, nullptr , &jsRef);
124
124
125
125
return result;
126
126
}
127
127
128
- void FunctionPointer::finalize (napi_env env, void *finalize_data,
129
- void *finalize_hint) {
130
- auto ref = (FunctionPointer *)finalize_data;
128
+ void FunctionPointer::finalize (napi_env env, void * finalize_data, void * finalize_hint) {
129
+ auto ref = (FunctionPointer*)finalize_data;
131
130
delete ref;
132
131
}
133
132
134
- napi_value FunctionPointer::jsCallAsCFunction (napi_env env,
135
- napi_callback_info cbinfo) {
136
- FunctionPointer *ref;
133
+ napi_value FunctionPointer::jsCallAsCFunction (napi_env env, napi_callback_info cbinfo) {
134
+ FunctionPointer* ref;
137
135
138
- napi_get_cb_info (env, cbinfo, nullptr , nullptr , nullptr , (void **)&ref);
136
+ napi_get_cb_info (env, cbinfo, nullptr , nullptr , nullptr , (void **)&ref);
139
137
140
138
auto cif = ref->cif ;
141
139
142
140
size_t argc = cif->argc ;
143
141
napi_get_cb_info (env, cbinfo, &argc, cif->argv , nullptr , nullptr );
144
142
145
- void * avalues[cif->argc];
146
- void * rvalue = cif->rvalue ;
143
+ void * avalues[cif->argc];
144
+ void * rvalue = cif->rvalue ;
147
145
148
146
bool shouldFreeAny = false ;
149
147
bool shouldFree[cif->argc];
@@ -152,8 +150,7 @@ id registerBlock(napi_env env, Closure *closure, napi_value callback) {
152
150
for (unsigned int i = 0 ; i < cif->argc ; i++) {
153
151
shouldFree[i] = false ;
154
152
avalues[i] = cif->avalues [i];
155
- cif->argTypes [i]->toNative (env, cif->argv [i], avalues[i], &shouldFree[i],
156
- &shouldFreeAny);
153
+ cif->argTypes [i]->toNative (env, cif->argv [i], avalues[i], &shouldFree[i], &shouldFreeAny);
157
154
}
158
155
}
159
156
@@ -162,28 +159,27 @@ id registerBlock(napi_env env, Closure *closure, napi_value callback) {
162
159
if (shouldFreeAny) {
163
160
for (unsigned int i = 0 ; i < cif->argc ; i++) {
164
161
if (shouldFree[i]) {
165
- cif->argTypes [i]->free (env, *((void **)avalues[i]));
162
+ cif->argTypes [i]->free (env, *((void **)avalues[i]));
166
163
}
167
164
}
168
165
}
169
166
170
167
return cif->returnType ->toJS (env, rvalue);
171
168
}
172
169
173
- napi_value FunctionPointer::jsCallAsBlock (napi_env env,
174
- napi_callback_info cbinfo) {
175
- FunctionPointer *ref;
170
+ napi_value FunctionPointer::jsCallAsBlock (napi_env env, napi_callback_info cbinfo) {
171
+ FunctionPointer* ref;
176
172
177
- napi_get_cb_info (env, cbinfo, nullptr , nullptr , nullptr , (void **)&ref);
173
+ napi_get_cb_info (env, cbinfo, nullptr , nullptr , nullptr , (void **)&ref);
178
174
179
- Block_literal_1 * block = (Block_literal_1 *)ref->function ;
175
+ Block_literal_1* block = (Block_literal_1*)ref->function ;
180
176
auto cif = ref->cif ;
181
177
182
178
size_t argc = cif->argc ;
183
179
napi_get_cb_info (env, cbinfo, &argc, cif->argv , nullptr , nullptr );
184
180
185
- void * avalues[cif->cif.nargs];
186
- void * rvalue = cif->rvalue ;
181
+ void * avalues[cif->cif.nargs];
182
+ void * rvalue = cif->rvalue ;
187
183
188
184
bool shouldFreeAny = false ;
189
185
bool shouldFree[cif->argc];
@@ -194,8 +190,7 @@ id registerBlock(napi_env env, Closure *closure, napi_value callback) {
194
190
for (unsigned int i = 0 ; i < cif->argc ; i++) {
195
191
shouldFree[i] = false ;
196
192
avalues[i + 1 ] = cif->avalues [i];
197
- cif->argTypes [i]->toNative (env, cif->argv [i], avalues[i + 1 ],
198
- &shouldFree[i], &shouldFreeAny);
193
+ cif->argTypes [i]->toNative (env, cif->argv [i], avalues[i + 1 ], &shouldFree[i], &shouldFreeAny);
199
194
}
200
195
}
201
196
@@ -204,12 +199,12 @@ id registerBlock(napi_env env, Closure *closure, napi_value callback) {
204
199
if (shouldFreeAny) {
205
200
for (unsigned int i = 0 ; i < cif->argc ; i++) {
206
201
if (shouldFree[i]) {
207
- cif->argTypes [i]->free (env, *((void **)avalues[i + 1 ]));
202
+ cif->argTypes [i]->free (env, *((void **)avalues[i + 1 ]));
208
203
}
209
204
}
210
205
}
211
206
212
207
return cif->returnType ->toJS (env, rvalue);
213
208
}
214
209
215
- } // namespace objc_bridge
210
+ } // namespace objc_bridge
0 commit comments