Skip to content

Commit bb02623

Browse files
authored
fix: x86 simulators and add better failsafe around generated class names (#303)
1 parent e89067c commit bb02623

File tree

5 files changed

+15
-47
lines changed

5 files changed

+15
-47
lines changed
Lines changed: 4 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,18 @@
11
#include "ClassBuilder.h"
2-
#if TARGET_CPU_X86_64 || TARGET_CPU_X86
3-
#include "SpinLock.h"
4-
#endif
52

63
namespace tns {
74

85
// Moved this method in a separate .cpp file because ARC destroys the class
96
// created with objc_allocateClassPair when the control leaves this method scope
10-
// TODO: revist this as there are x86 simulator issues, so maybe a lock is
11-
// needed regardless
7+
// TODO: revist this. Maybe a lock is needed regardless
128
Class ClassBuilder::GetExtendedClass(std::string baseClassName,
13-
std::string staticClassName) {
14-
#if TARGET_CPU_X86_64 || TARGET_CPU_X86
15-
// X86 simulators have this bugged, so we fallback to old behavior
16-
static SpinMutex m;
17-
SpinLock lock(m);
9+
std::string staticClassName,
10+
std::string suffix) {
1811
Class baseClass = objc_getClass(baseClassName.c_str());
1912
std::string name =
2013
!staticClassName.empty()
2114
? staticClassName
22-
: baseClassName + "_" +
23-
std::to_string(++ClassBuilder::classNameCounter_);
24-
Class clazz = objc_getClass(name.c_str());
25-
26-
if (clazz != nil) {
27-
int i = 1;
28-
std::string initialName = name;
29-
while (clazz != nil) {
30-
name = initialName + std::to_string(i++);
31-
clazz = objc_getClass(name.c_str());
32-
}
33-
}
34-
35-
clazz = objc_allocateClassPair(baseClass, name.c_str(), 0);
36-
37-
objc_registerClassPair(clazz);
38-
return clazz;
39-
#else
40-
Class baseClass = objc_getClass(baseClassName.c_str());
41-
std::string name =
42-
!staticClassName.empty()
43-
? staticClassName
44-
: baseClassName + "_" +
15+
: baseClassName + suffix + "_" +
4516
std::to_string(++ClassBuilder::classNameCounter_);
4617
// here we could either call objc_getClass with the name to see if the class
4718
// already exists or we can just try allocating it, which will return nil if
@@ -60,7 +31,6 @@ Class ClassBuilder::GetExtendedClass(std::string baseClassName,
6031

6132
objc_registerClassPair(clazz);
6233
return clazz;
63-
#endif
6434
}
6535

6636
} // namespace tns

NativeScript/runtime/ClassBuilder.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,13 @@ struct PropertyCallbackContext {
2323
class ClassBuilder {
2424
public:
2525
static v8::Local<v8::FunctionTemplate> GetExtendFunction(v8::Isolate* isolate, const InterfaceMeta* interfaceMeta);
26-
static Class GetExtendedClass(std::string baseClassName, std::string staticClassName);
26+
static Class GetExtendedClass(std::string baseClassName, std::string staticClassName, std::string suffix);
2727

2828
static void RegisterBaseTypeScriptExtendsFunction(v8::Local<v8::Context> context);
2929
static void RegisterNativeTypeScriptExtendsFunction(v8::Local<v8::Context> context);
3030
static std::string GetTypeEncoding(const TypeEncoding* typeEncoding, int argsCount);
3131
private:
32-
static unsigned long long classNameCounter_;
32+
static std::atomic<unsigned long long> classNameCounter_;
3333

3434
static void ExtendCallback(const v8::FunctionCallbackInfo<v8::Value>& info);
3535
static void SuperAccessorGetterCallback(v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info);

NativeScript/runtime/ClassBuilder.mm

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,10 @@
5757
staticClassName = tns::ToString(isolate, explicitClassName);
5858
}
5959
}
60+
auto cache = Caches::Get(isolate);
61+
auto isolateId = cache->getIsolateId();
6062

61-
Class extendedClass = ClassBuilder::GetExtendedClass(baseClassName, staticClassName);
63+
Class extendedClass = ClassBuilder::GetExtendedClass(baseClassName, staticClassName, std::to_string(isolateId) + "_");
6264
class_addProtocol(extendedClass, @protocol(TNSDerivedClass));
6365
class_addProtocol(object_getClass(extendedClass), @protocol(TNSDerivedClass));
6466

@@ -70,7 +72,6 @@
7072
implementationObject);
7173
}
7274

73-
auto cache = Caches::Get(isolate);
7475
Local<v8::Function> baseCtorFunc =
7576
cache->CtorFuncs.find(item->meta_->name())->second->Get(isolate);
7677

@@ -212,8 +213,9 @@
212213
Local<v8::Function> extendedClassCtorFunc = info[0].As<v8::Function>();
213214
std::string extendedClassName = tns::ToString(isolate, extendedClassCtorFunc->GetName());
214215

216+
auto isolateId = cache->getIsolateId();
215217
__block Class extendedClass =
216-
ClassBuilder::GetExtendedClass(baseClassName, extendedClassName);
218+
ClassBuilder::GetExtendedClass(baseClassName, extendedClassName, std::to_string(isolateId) + "_");
217219
class_addProtocol(extendedClass, @protocol(TNSDerivedClass));
218220
class_addProtocol(object_getClass(extendedClass), @protocol(TNSDerivedClass));
219221

@@ -984,6 +986,6 @@
984986
return class_getMethodImplementation(klass, method);
985987
}
986988

987-
unsigned long long ClassBuilder::classNameCounter_ = 0;
989+
std::atomic<unsigned long long> ClassBuilder::classNameCounter_{0};
988990

989991
} // namespace tns

NativeScript/runtime/Helpers.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,8 +219,7 @@ bool IsArrayOrArrayLike(v8::Isolate* isolate,
219219
void* TryGetBufferFromArrayBuffer(const v8::Local<v8::Value>& value,
220220
bool& isArrayBuffer);
221221

222-
void ExecuteOnRunLoop(CFRunLoopRef queue, std::function<void()> func,
223-
bool async = true);
222+
void ExecuteOnRunLoop(CFRunLoopRef queue, void (^func)(void), bool async = true);
224223
void ExecuteOnDispatchQueue(dispatch_queue_t queue, std::function<void()> func,
225224
bool async = true);
226225
void ExecuteOnMainThread(std::function<void()> func, bool async = true);

NativeScript/runtime/Helpers.mm

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@
331331
std::condition_variable cv;
332332
};
333333

334-
void tns::ExecuteOnRunLoop(CFRunLoopRef queue, std::function<void ()> func, bool async) {
334+
void tns::ExecuteOnRunLoop(CFRunLoopRef queue, void (^func)(void), bool async) {
335335
if(!async) {
336336
bool __block finished = false;
337337
auto v = new LockAndCV;
@@ -350,12 +350,9 @@
350350
}
351351
delete v;
352352
} else {
353-
CFRunLoopPerformBlock(queue, kCFRunLoopCommonModes, ^(void) {
354-
func();
355-
});
353+
CFRunLoopPerformBlock(queue, kCFRunLoopCommonModes, func);
356354
CFRunLoopWakeUp(queue);
357355
}
358-
359356
}
360357

361358
void tns::ExecuteOnDispatchQueue(dispatch_queue_t queue, std::function<void ()> func, bool async) {

0 commit comments

Comments
 (0)