Skip to content

Commit 850e7ed

Browse files
committed
Rename ObjCBridgeData to ObjCBridgeState, BridgedClass to ObjCClass, BridgedMethod to ObjCClassMethod, improve memory management
1 parent caa0e3e commit 850e7ed

19 files changed

+231
-225
lines changed

include/Class.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@
22
#define BRIDGED_CLASS_H
33

44
#include "MetadataReader.h"
5+
#include "NativeCall.h"
56
#include "node_api_util.h"
67
#include "objc/message.h"
78
#include "objc/runtime.h"
8-
#include <set>
99
#include <string>
10+
#include <unordered_set>
1011

1112
using namespace metagen;
1213

@@ -16,21 +17,22 @@ NAPI_FUNCTION(registerClass);
1617
NAPI_FUNCTION(import);
1718
NAPI_FUNCTION(classGetter);
1819

19-
class BridgedClass {
20+
class ObjCClass {
2021
public:
2122
MDSectionOffset metadataOffset;
2223
std::string name;
2324
Class nativeClass;
2425

25-
BridgedClass *superclass;
26+
ObjCClass *superclass;
27+
std::vector<std::shared_ptr<ObjCClassMember>> members;
2628

2729
napi_env env;
2830
napi_ref constructor;
2931
napi_ref prototype;
3032

31-
BridgedClass() {}
32-
BridgedClass(napi_env env, MDSectionOffset offset);
33-
~BridgedClass();
33+
ObjCClass() {}
34+
ObjCClass(napi_env env, MDSectionOffset offset);
35+
~ObjCClass();
3436
};
3537

3638
} // namespace objc_bridge

include/NativeCall.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#ifndef BRIDGED_METHOD_H
22
#define BRIDGED_METHOD_H
33

4-
#include "ObjCBridge.h"
4+
#include "MethodCif.h"
55
#include "objc/runtime.h"
66

77
namespace objc_bridge {
@@ -11,9 +11,11 @@ napi_value JS_BridgedMethod(napi_env env, napi_callback_info cbinfo);
1111
napi_value JS_BridgedGetter(napi_env env, napi_callback_info cbinfo);
1212
napi_value JS_BridgedSetter(napi_env env, napi_callback_info cbinfo);
1313

14-
class BridgedMethod {
14+
class ObjCBridgeState;
15+
16+
class ObjCClassMember {
1517
public:
16-
ObjCBridgeData *bridgeData;
18+
ObjCBridgeState *bridgeState;
1719
// Can be either method selector or property getter selector
1820
SEL selector;
1921
SEL setterSelector;

include/ObjCBridge.h

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,18 +42,18 @@ typedef enum ObjectOwnership {
4242
kBorrowedObject,
4343
} ObjectOwnership;
4444

45-
class ObjCBridgeData {
45+
class ObjCBridgeState {
4646
public:
47-
ObjCBridgeData(napi_env env, const char *metadata_path = nullptr);
48-
~ObjCBridgeData();
47+
ObjCBridgeState(napi_env env, const char *metadata_path = nullptr);
48+
~ObjCBridgeState();
4949

50-
static inline ObjCBridgeData *InstanceData(napi_env env) {
51-
ObjCBridgeData *bridgeData;
52-
napi_status status = napi_get_instance_data(env, (void **)&bridgeData);
50+
static inline ObjCBridgeState *InstanceData(napi_env env) {
51+
ObjCBridgeState *bridgeState;
52+
napi_status status = napi_get_instance_data(env, (void **)&bridgeState);
5353
if (status != napi_ok) {
5454
return nullptr;
5555
}
56-
return bridgeData;
56+
return bridgeState;
5757
}
5858

5959
void registerVarGlobals(napi_env env, napi_value global);
@@ -64,7 +64,7 @@ class ObjCBridgeData {
6464
void registerClassGlobals(napi_env env, napi_value global);
6565
void registerProtocolGlobals(napi_env env, napi_value global);
6666

67-
BridgedClass *getClass(napi_env env, MDSectionOffset offset);
67+
ObjCClass *getClass(napi_env env, MDSectionOffset offset);
6868

6969
BridgedProtocol *getProtocol(napi_env env, MDSectionOffset offset);
7070

@@ -114,9 +114,9 @@ class ObjCBridgeData {
114114
napi_ref pointerClass;
115115
napi_ref referenceClass;
116116

117-
std::unordered_map<MDSectionOffset, BridgedClass *> classes;
117+
std::unordered_map<MDSectionOffset, ObjCClass *> classes;
118118
std::unordered_map<MDSectionOffset, BridgedProtocol *> protocols;
119-
std::unordered_map<Class, BridgedClass *> classesByPointer;
119+
std::unordered_map<Class, ObjCClass *> classesByPointer;
120120
std::unordered_map<Class, MDSectionOffset> mdClassesByPointer;
121121
std::unordered_map<Protocol *, MDSectionOffset> mdProtocolsByPointer;
122122
std::unordered_map<Class, napi_ref> constructorsByPointer;

src/Block.mm

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ id registerBlock(napi_env env, Closure *closure, napi_value callback) {
6464
}
6565
closure->func = ref;
6666

67-
auto bridgeData = ObjCBridgeData::InstanceData(env);
68-
if (napiSupportsThreadsafeFunctions(bridgeData->self_dl)) {
67+
auto bridgeState = ObjCBridgeState::InstanceData(env);
68+
if (napiSupportsThreadsafeFunctions(bridgeState->self_dl)) {
6969
napi_value workName;
7070
napi_create_string_utf8(env, "Block", NAPI_AUTO_LENGTH, &workName);
7171
napi_create_threadsafe_function(env, callback, nullptr, workName, 0, 1,

src/CFunction.mm

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
namespace objc_bridge {
66

7-
void ObjCBridgeData::registerFunctionGlobals(napi_env env, napi_value global) {
7+
void ObjCBridgeState::registerFunctionGlobals(napi_env env, napi_value global) {
88
MDSectionOffset offset = metadata->functionsOffset;
99
while (offset < metadata->protocolsOffset) {
1010
MDSectionOffset originalOffset = offset;
@@ -28,7 +28,7 @@
2828
}
2929
}
3030

31-
CFunction *ObjCBridgeData::getCFunction(napi_env env, MDSectionOffset offset) {
31+
CFunction *ObjCBridgeState::getCFunction(napi_env env, MDSectionOffset offset) {
3232
auto cached = cFunctionCache.find(offset);
3333
if (cached != cFunctionCache.end()) {
3434
return cached->second;

src/Class.mm

Lines changed: 44 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
namespace objc_bridge {
1616

17-
void ObjCBridgeData::registerClassGlobals(napi_env env, napi_value global) {
17+
void ObjCBridgeState::registerClassGlobals(napi_env env, napi_value global) {
1818
MDSectionOffset offset = metadata->classesOffset;
1919
while (offset < metadata->structsOffset) {
2020
MDSectionOffset originalOffset = offset;
@@ -89,22 +89,22 @@
8989
return func;
9090
}
9191

92-
auto bridgeData = ObjCBridgeData::InstanceData(env);
93-
bridgeData->registerClass(env, argv[0]);
92+
auto bridgeState = ObjCBridgeState::InstanceData(env);
93+
bridgeState->registerClass(env, argv[0]);
9494
return nullptr;
9595
}
9696

9797
char class_name[256];
9898

9999
// Get a Bridged Class by metadata offset, creating it if it doesn't exist.
100-
// This is used to cache BridgedClass instances.
101-
BridgedClass *ObjCBridgeData::getClass(napi_env env, MDSectionOffset offset) {
100+
// This is used to cache ObjCClass instances.
101+
ObjCClass *ObjCBridgeState::getClass(napi_env env, MDSectionOffset offset) {
102102
auto find = this->classes[offset];
103103
if (find != nullptr) {
104104
return find;
105105
}
106106

107-
auto bridgedClass = new BridgedClass(env, offset);
107+
auto bridgedClass = new ObjCClass(env, offset);
108108
this->classes[offset] = bridgedClass;
109109

110110
return bridgedClass;
@@ -146,18 +146,18 @@
146146
void *data;
147147
napi_get_cb_info(env, cbinfo, nullptr, nullptr, nullptr, &data);
148148
MDSectionOffset offset = (MDSectionOffset)((size_t)data);
149-
auto bridgeData = ObjCBridgeData::InstanceData(env);
149+
auto bridgeState = ObjCBridgeState::InstanceData(env);
150150

151-
auto cached = bridgeData->mdValueCache[offset];
151+
auto cached = bridgeState->mdValueCache[offset];
152152
if (cached != nullptr) {
153153
return get_ref_value(env, cached);
154154
}
155155

156-
// std::string name = bridgeData->metadata->getString(offset);
157-
auto cls = bridgeData->getClass(env, offset);
156+
// std::string name = bridgeState->metadata->getString(offset);
157+
auto cls = bridgeState->getClass(env, offset);
158158

159159
if (cls != nullptr) {
160-
bridgeData->mdValueCache[offset] = cls->constructor;
160+
bridgeState->mdValueCache[offset] = cls->constructor;
161161
} else {
162162
return nullptr;
163163
}
@@ -204,8 +204,8 @@
204204
napi_get_cb_info(env, cbinfo, nil, nil, &jsThis, &data);
205205
id self;
206206
napi_unwrap(env, jsThis, (void **)&self);
207-
auto bridgeData = ObjCBridgeData::InstanceData(env);
208-
bridgeData->unregisterObject(self);
207+
auto bridgeState = ObjCBridgeState::InstanceData(env);
208+
bridgeState->unregisterObject(self);
209209
return nullptr;
210210
}
211211

@@ -220,14 +220,14 @@
220220
// extended by a JS class.
221221
// Every Bridged Class extends the NativeObject class.
222222

223-
BridgedClass::BridgedClass(napi_env env, MDSectionOffset offset) {
223+
ObjCClass::ObjCClass(napi_env env, MDSectionOffset offset) {
224224
NAPI_PREAMBLE
225225

226226
this->env = env;
227227

228228
metadataOffset = offset;
229229

230-
auto bridgeData = ObjCBridgeData::InstanceData(env);
230+
auto bridgeState = ObjCBridgeState::InstanceData(env);
231231

232232
bool isNativeObject = offset == MD_SECTION_OFFSET_NULL;
233233

@@ -239,20 +239,20 @@
239239
name = NativeObjectName;
240240
nativeClass = nil;
241241
} else {
242-
auto nameOffset = bridgeData->metadata->getOffset(offset);
242+
auto nameOffset = bridgeState->metadata->getOffset(offset);
243243
offset += sizeof(MDSectionOffset);
244244
bool hasProtocols = (nameOffset & mdSectionOffsetNext) != 0;
245245
nameOffset &= ~mdSectionOffsetNext;
246-
name = bridgeData->metadata->resolveString(nameOffset);
246+
name = bridgeState->metadata->resolveString(nameOffset);
247247
while (hasProtocols) {
248-
auto protocolOffset = bridgeData->metadata->getOffset(offset);
248+
auto protocolOffset = bridgeState->metadata->getOffset(offset);
249249
offset += sizeof(MDSectionOffset);
250250
hasProtocols = (protocolOffset & mdSectionOffsetNext) != 0;
251251
protocolOffset &= ~mdSectionOffsetNext;
252252
if (protocolOffset != MD_SECTION_OFFSET_NULL)
253253
protocolOffsets.push_back(protocolOffset);
254254
}
255-
superClassOffset = bridgeData->metadata->getOffset(offset);
255+
superClassOffset = bridgeState->metadata->getOffset(offset);
256256
hasMembers = (superClassOffset & mdSectionOffsetNext) != 0;
257257
superClassOffset &= ~mdSectionOffsetNext;
258258
offset += sizeof(MDSectionOffset);
@@ -277,20 +277,20 @@
277277
// exists.
278278
if (!isNativeObject) {
279279
for (auto protocolOffset : protocolOffsets) {
280-
auto protocol = bridgeData->getProtocol(
281-
env, protocolOffset + bridgeData->metadata->protocolsOffset);
280+
auto protocol = bridgeState->getProtocol(
281+
env, protocolOffset + bridgeState->metadata->protocolsOffset);
282282
if (protocol == nil)
283283
continue;
284284
defineProtocolMembers(env, protocol->membersOffset, constructor);
285285
}
286286

287287
if (superClassOffset != MD_SECTION_OFFSET_NULL) {
288-
superClassOffset += bridgeData->metadata->classesOffset;
288+
superClassOffset += bridgeState->metadata->classesOffset;
289289
}
290290

291291
// If class offset is 0, it means that the class doesn't have a super class.
292292
// But we just inherit NativeObject class in that case.
293-
superclass = bridgeData->getClass(env, superClassOffset);
293+
superclass = bridgeState->getClass(env, superClassOffset);
294294
if (superclass != nil) {
295295
superConstructor = get_ref_value(env, superclass->constructor);
296296
superPrototype = get_ref_value(env, superclass->prototype);
@@ -334,14 +334,14 @@
334334
return;
335335
}
336336

337-
bridgeData->classesByPointer[nativeClass] = this;
337+
bridgeState->classesByPointer[nativeClass] = this;
338338

339339
if (!hasMembers)
340340
return;
341341

342342
bool next = true;
343343
while (next) {
344-
auto flags = bridgeData->metadata->getMemberFlag(offset);
344+
auto flags = bridgeState->metadata->getMemberFlag(offset);
345345
next = (flags & mdMemberNext) != 0;
346346
offset += sizeof(flags);
347347

@@ -354,38 +354,39 @@
354354

355355
if ((flags & mdMemberProperty) != 0) {
356356
bool readonly = (flags & mdMemberReadonly) != 0;
357-
auto name = bridgeData->metadata->getString(offset);
357+
auto name = bridgeState->metadata->getString(offset);
358358
offset += sizeof(MDSectionOffset); // name
359359

360360
MDSectionOffset getterSignature, setterSignature;
361361

362-
auto getterSelector = bridgeData->metadata->getString(offset);
362+
auto getterSelector = bridgeState->metadata->getString(offset);
363363
offset += sizeof(MDSectionOffset); // getterSelector
364364

365-
getterSignature = bridgeData->metadata->getOffset(offset);
365+
getterSignature = bridgeState->metadata->getOffset(offset);
366366
offset += sizeof(MDSectionOffset); // getterSignature
367367

368368
const char *setterSelector = nullptr;
369369
if (!readonly) {
370-
setterSelector = bridgeData->metadata->getString(offset);
370+
setterSelector = bridgeState->metadata->getString(offset);
371371
offset += sizeof(MDSectionOffset); // setterSelector
372372

373-
setterSignature = bridgeData->metadata->getOffset(offset);
373+
setterSignature = bridgeState->metadata->getOffset(offset);
374374
offset += sizeof(MDSectionOffset); // setterSignature
375375
}
376376

377-
auto prop = new BridgedMethod();
378-
prop->bridgeData = bridgeData;
377+
std::shared_ptr<ObjCClassMember> prop =
378+
std::make_shared<ObjCClassMember>();
379+
prop->bridgeState = bridgeState;
379380
prop->classMethod = (flags & mdMemberStatic) != 0;
380381
prop->selector = sel_registerName(getterSelector);
381382
prop->setterSelector =
382383
setterSelector == nullptr ? nil : sel_registerName(setterSelector);
383384
prop->signature =
384-
getterSignature + bridgeData->metadata->signaturesOffset;
385+
getterSignature + bridgeState->metadata->signaturesOffset;
385386
prop->setterSignature =
386387
setterSelector == nullptr
387388
? 0
388-
: setterSignature + bridgeData->metadata->signaturesOffset;
389+
: setterSignature + bridgeState->metadata->signaturesOffset;
389390

390391
napi_property_descriptor property = {
391392
.utf8name = name,
@@ -396,14 +397,14 @@
396397
.value = nil,
397398
.attributes =
398399
(napi_property_attributes)(napi_configurable | napi_enumerable),
399-
.data = prop,
400+
.data = members.emplace_back(prop).get(),
400401
};
401402

402403
napi_define_properties(env, jsObject, 1, &property);
403404
} else {
404-
auto selector = bridgeData->metadata->getString(offset);
405+
auto selector = bridgeState->metadata->getString(offset);
405406
offset += sizeof(MDSectionOffset); // selector
406-
auto signature = bridgeData->metadata->getOffset(offset);
407+
auto signature = bridgeState->metadata->getOffset(offset);
407408
offset += sizeof(MDSectionOffset); // signature
408409

409410
auto name = jsifySelector(selector);
@@ -414,11 +415,12 @@
414415
continue;
415416
}
416417

417-
auto method = new BridgedMethod();
418-
method->bridgeData = bridgeData;
418+
std::shared_ptr<ObjCClassMember> method =
419+
std::make_shared<ObjCClassMember>();
420+
method->bridgeState = bridgeState;
419421
method->classMethod = (flags & mdMemberStatic) != 0;
420422
method->selector = sel_registerName(selector);
421-
method->signature = signature + bridgeData->metadata->signaturesOffset;
423+
method->signature = signature + bridgeState->metadata->signaturesOffset;
422424
method->returnOwned = (flags & mdMemberReturnOwned) != 0;
423425

424426
napi_property_descriptor property = {
@@ -431,15 +433,15 @@
431433
.attributes =
432434
(napi_property_attributes)(napi_configurable | napi_writable |
433435
napi_enumerable),
434-
.data = method,
436+
.data = members.emplace_back(method).get(),
435437
};
436438

437439
napi_define_properties(env, jsObject, 1, &property);
438440
}
439441
}
440442
}
441443

442-
BridgedClass::~BridgedClass() {
444+
ObjCClass::~ObjCClass() {
443445
napi_delete_reference(env, constructor);
444446
napi_delete_reference(env, prototype);
445447
}

0 commit comments

Comments
 (0)