Skip to content

Commit 592a07d

Browse files
committed
fix: Enhance AOT registration and improve superclass handling in generated stubs
- Introduced a thread-safe mechanism for AOT stub registration using std::call_once in NativeScriptAOTBridge.mm to ensure that the registration function is called only once. - Updated the AOT generation script (generate-aot.py) to use class_getSuperclass for obtaining the superclass of a target object instead of directly referencing the class, improving compatibility and correctness. - Added necessary imports for objc/runtime.h in the generated AOT preamble to support the new superclass handling.
1 parent 8eb151c commit 592a07d

3 files changed

Lines changed: 30 additions & 26 deletions

File tree

NativeScript/runtime/AOTDirectCalls.mm

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ static void AOT_NSObject_respondsToSelector(const FunctionCallbackInfo<Value>& i
112112

113113
BOOL result;
114114
if (callSuper) {
115-
objc_super sup = {target, [NSObject class]};
115+
objc_super sup = {target, class_getSuperclass(object_getClass(target))};
116116
result = ((BOOL (*)(objc_super*, SEL, SEL))objc_msgSendSuper)(
117117
&sup, @selector(respondsToSelector:), arg0);
118118
} else {
@@ -137,7 +137,7 @@ static void AOT_NSObject_isKindOfClass(const FunctionCallbackInfo<Value>& info)
137137

138138
BOOL result;
139139
if (callSuper) {
140-
objc_super sup = {target, [NSObject class]};
140+
objc_super sup = {target, class_getSuperclass(object_getClass(target))};
141141
result = ((BOOL (*)(objc_super*, SEL, Class))objc_msgSendSuper)(&sup, @selector(isKindOfClass:),
142142
arg0);
143143
} else {
@@ -158,7 +158,7 @@ static void AOT_NSObject_isEqual(const FunctionCallbackInfo<Value>& info) {
158158

159159
BOOL result;
160160
if (callSuper) {
161-
objc_super sup = {target, [NSObject class]};
161+
objc_super sup = {target, class_getSuperclass(object_getClass(target))};
162162
result = ((BOOL (*)(objc_super*, SEL, id))objc_msgSendSuper)(&sup, @selector(isEqual:), arg0);
163163
} else {
164164
result = [(NSObject*)target isEqual:arg0];
@@ -177,7 +177,7 @@ static void AOT_NSObject_description(const FunctionCallbackInfo<Value>& info) {
177177

178178
id result;
179179
if (callSuper) {
180-
objc_super sup = {target, [NSObject class]};
180+
objc_super sup = {target, class_getSuperclass(object_getClass(target))};
181181
result = ((id (*)(objc_super*, SEL))objc_msgSendSuper)(&sup, @selector(description));
182182
} else {
183183
result = [(NSObject*)target description];
@@ -195,7 +195,7 @@ static void AOT_NSObject_hash(const FunctionCallbackInfo<Value>& info) {
195195

196196
unsigned long result;
197197
if (callSuper) {
198-
objc_super sup = {target, [NSObject class]};
198+
objc_super sup = {target, class_getSuperclass(object_getClass(target))};
199199
result = ((unsigned long (*)(objc_super*, SEL))objc_msgSendSuper)(&sup, @selector(hash));
200200
} else {
201201
result = [(NSObject*)target hash];
@@ -212,7 +212,7 @@ static void AOT_NSMutableArray_removeAllObjects(const FunctionCallbackInfo<Value
212212
if (target == nil) return;
213213

214214
if (callSuper) {
215-
objc_super sup = {target, [NSMutableArray class]};
215+
objc_super sup = {target, class_getSuperclass(object_getClass(target))};
216216
((void (*)(objc_super*, SEL))objc_msgSendSuper)(&sup, @selector(removeAllObjects));
217217
} else {
218218
[(NSMutableArray*)target removeAllObjects];
@@ -229,7 +229,7 @@ static void AOT_NSMutableArray_addObject(const FunctionCallbackInfo<Value>& info
229229
id arg0 = AOTToObject(context, info[0]);
230230

231231
if (callSuper) {
232-
objc_super sup = {target, [NSMutableArray class]};
232+
objc_super sup = {target, class_getSuperclass(object_getClass(target))};
233233
((void (*)(objc_super*, SEL, id))objc_msgSendSuper)(&sup, @selector(addObject:), arg0);
234234
} else {
235235
[(NSMutableArray*)target addObject:arg0];
@@ -247,7 +247,7 @@ static void AOT_NSMutableArray_objectAtIndex(const FunctionCallbackInfo<Value>&
247247

248248
id result;
249249
if (callSuper) {
250-
objc_super sup = {target, [NSMutableArray class]};
250+
objc_super sup = {target, class_getSuperclass(object_getClass(target))};
251251
result = ((id (*)(objc_super*, SEL, unsigned long))objc_msgSendSuper)(
252252
&sup, @selector(objectAtIndex:), arg0);
253253
} else {
@@ -266,7 +266,7 @@ static void AOT_NSMutableArray_count(const FunctionCallbackInfo<Value>& info) {
266266

267267
unsigned long result;
268268
if (callSuper) {
269-
objc_super sup = {target, [NSMutableArray class]};
269+
objc_super sup = {target, class_getSuperclass(object_getClass(target))};
270270
result = ((unsigned long (*)(objc_super*, SEL))objc_msgSendSuper)(&sup, @selector(count));
271271
} else {
272272
result = [(NSMutableArray*)target count];
@@ -286,7 +286,7 @@ static void AOT_NSMutableArray_insertObject_atIndex(const FunctionCallbackInfo<V
286286
unsigned long arg1 = (unsigned long)tns::ToNumber(isolate, info[1]);
287287

288288
if (callSuper) {
289-
objc_super sup = {target, [NSMutableArray class]};
289+
objc_super sup = {target, class_getSuperclass(object_getClass(target))};
290290
((void (*)(objc_super*, SEL, id, unsigned long))objc_msgSendSuper)(
291291
&sup, @selector(insertObject:atIndex:), arg0, arg1);
292292
} else {
@@ -303,7 +303,7 @@ static void AOT_NSMutableArray_removeObjectAtIndex(const FunctionCallbackInfo<Va
303303
unsigned long arg0 = (unsigned long)tns::ToNumber(isolate, info[0]);
304304

305305
if (callSuper) {
306-
objc_super sup = {target, [NSMutableArray class]};
306+
objc_super sup = {target, class_getSuperclass(object_getClass(target))};
307307
((void (*)(objc_super*, SEL, unsigned long))objc_msgSendSuper)(
308308
&sup, @selector(removeObjectAtIndex:), arg0);
309309
} else {
@@ -322,7 +322,7 @@ static void AOT_NSArray_objectAtIndex(const FunctionCallbackInfo<Value>& info) {
322322

323323
id result;
324324
if (callSuper) {
325-
objc_super sup = {target, [NSArray class]};
325+
objc_super sup = {target, class_getSuperclass(object_getClass(target))};
326326
result = ((id (*)(objc_super*, SEL, unsigned long))objc_msgSendSuper)(
327327
&sup, @selector(objectAtIndex:), arg0);
328328
} else {
@@ -341,7 +341,7 @@ static void AOT_NSArray_count(const FunctionCallbackInfo<Value>& info) {
341341

342342
unsigned long result;
343343
if (callSuper) {
344-
objc_super sup = {target, [NSArray class]};
344+
objc_super sup = {target, class_getSuperclass(object_getClass(target))};
345345
result = ((unsigned long (*)(objc_super*, SEL))objc_msgSendSuper)(&sup, @selector(count));
346346
} else {
347347
result = [(NSArray*)target count];
@@ -361,7 +361,7 @@ static void AOT_NSDictionary_objectForKeyedSubscript(const FunctionCallbackInfo<
361361

362362
id result;
363363
if (callSuper) {
364-
objc_super sup = {target, [NSDictionary class]};
364+
objc_super sup = {target, class_getSuperclass(object_getClass(target))};
365365
result = ((id (*)(objc_super*, SEL, id))objc_msgSendSuper)(
366366
&sup, @selector(objectForKeyedSubscript:), arg0);
367367
} else {
@@ -380,7 +380,7 @@ static void AOT_NSDictionary_count(const FunctionCallbackInfo<Value>& info) {
380380

381381
unsigned long result;
382382
if (callSuper) {
383-
objc_super sup = {target, [NSDictionary class]};
383+
objc_super sup = {target, class_getSuperclass(object_getClass(target))};
384384
result = ((unsigned long (*)(objc_super*, SEL))objc_msgSendSuper)(&sup, @selector(count));
385385
} else {
386386
result = [(NSDictionary*)target count];
@@ -400,7 +400,7 @@ static void AOT_NSMutableDictionary_setObject_forKey(const FunctionCallbackInfo<
400400
id arg1 = AOTToObject(context, info[1]);
401401

402402
if (callSuper) {
403-
objc_super sup = {target, [NSMutableDictionary class]};
403+
objc_super sup = {target, class_getSuperclass(object_getClass(target))};
404404
((void (*)(objc_super*, SEL, id, id))objc_msgSendSuper)(&sup, @selector(setObject:forKey:),
405405
arg0, arg1);
406406
} else {
@@ -418,7 +418,7 @@ static void AOT_NSMutableDictionary_removeObjectForKey(const FunctionCallbackInf
418418
id arg0 = AOTToObject(context, info[0]);
419419

420420
if (callSuper) {
421-
objc_super sup = {target, [NSMutableDictionary class]};
421+
objc_super sup = {target, class_getSuperclass(object_getClass(target))};
422422
((void (*)(objc_super*, SEL, id))objc_msgSendSuper)(&sup, @selector(removeObjectForKey:), arg0);
423423
} else {
424424
[(NSMutableDictionary*)target removeObjectForKey:arg0];
@@ -434,7 +434,7 @@ static void AOT_NSString_length(const FunctionCallbackInfo<Value>& info) {
434434

435435
unsigned long result;
436436
if (callSuper) {
437-
objc_super sup = {target, [NSString class]};
437+
objc_super sup = {target, class_getSuperclass(object_getClass(target))};
438438
result = ((unsigned long (*)(objc_super*, SEL))objc_msgSendSuper)(&sup, @selector(length));
439439
} else {
440440
result = [(NSString*)target length];

NativeScript/runtime/NativeScriptAOTBridge.mm

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include <Foundation/Foundation.h>
22
#include <dlfcn.h>
3+
#include <mutex>
34
#include <string>
45
#include <unordered_map>
56
#include "ArgConverter.h"
@@ -39,11 +40,14 @@ void ExternalAOTTrampoline(const FunctionCallbackInfo<Value>& info) {
3940
}
4041

4142
void DiscoverExternalAOTStubs() {
42-
typedef void (*RegistrarFn)(void (*)(const char*, const char*, bool, NSAOTCallHandler));
43-
auto registrar = reinterpret_cast<RegistrarFn>(dlsym(RTLD_DEFAULT, "__ns_register_aot_calls"));
44-
if (registrar) {
45-
registrar(__ns_aot_register);
46-
}
43+
static std::once_flag flag;
44+
std::call_once(flag, [] {
45+
typedef void (*RegistrarFn)(void (*)(const char*, const char*, bool, NSAOTCallHandler));
46+
auto registrar = reinterpret_cast<RegistrarFn>(dlsym(RTLD_DEFAULT, "__ns_register_aot_calls"));
47+
if (registrar) {
48+
registrar(__ns_aot_register);
49+
}
50+
});
4751
}
4852

4953
} // namespace tns

scripts/generate-aot.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ def gen_method_stub(method):
281281
else:
282282
super_call = build_super_call(cls, sel, ret, args)
283283
lines.append(" if (callSuper) {")
284-
lines.append(f" objc_super sup = {{target, [{cls} class]}};")
284+
lines.append(" objc_super sup = {target, class_getSuperclass(object_getClass(target))};")
285285
if is_void:
286286
lines.append(f" {super_call};")
287287
else:
@@ -793,9 +793,8 @@ def gen_external_method_stub(method, swift_classes):
793793
else:
794794
objc_call = build_objc_call(cls, sel, args, is_static=False, class_var=cvar, ret=ret)
795795
super_call = build_super_call(cls, sel, ret, args, struct_tag=True)
796-
cls_ref = cvar if is_swift else f"[{cls} class]"
797796
lines.append(" if (callSuper) {")
798-
lines.append(f" struct objc_super sup = {{target, {cls_ref}}};")
797+
lines.append(" struct objc_super sup = {target, class_getSuperclass(object_getClass(target))};")
799798
if is_void:
800799
lines.append(f" {super_call};")
801800
else:
@@ -847,6 +846,7 @@ def gen_external_registration(methods, swift_classes):
847846

848847
_EXTERNAL_PREAMBLE_TAIL = """\
849848
#import <objc/message.h>
849+
#import <objc/runtime.h>
850850
851851
"""
852852

0 commit comments

Comments
 (0)