Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 4 additions & 34 deletions NativeScript/runtime/ClassBuilder.cpp
Original file line number Diff line number Diff line change
@@ -1,47 +1,18 @@
#include "ClassBuilder.h"
#if TARGET_CPU_X86_64 || TARGET_CPU_X86
#include "SpinLock.h"
#endif

namespace tns {

// Moved this method in a separate .cpp file because ARC destroys the class
// created with objc_allocateClassPair when the control leaves this method scope
// TODO: revist this as there are x86 simulator issues, so maybe a lock is
// needed regardless
// TODO: revist this. Maybe a lock is needed regardless
Class ClassBuilder::GetExtendedClass(std::string baseClassName,
std::string staticClassName) {
#if TARGET_CPU_X86_64 || TARGET_CPU_X86
// X86 simulators have this bugged, so we fallback to old behavior
static SpinMutex m;
SpinLock lock(m);
std::string staticClassName,
std::string suffix) {
Class baseClass = objc_getClass(baseClassName.c_str());
std::string name =
!staticClassName.empty()
? staticClassName
: baseClassName + "_" +
std::to_string(++ClassBuilder::classNameCounter_);
Class clazz = objc_getClass(name.c_str());

if (clazz != nil) {
int i = 1;
std::string initialName = name;
while (clazz != nil) {
name = initialName + std::to_string(i++);
clazz = objc_getClass(name.c_str());
}
}

clazz = objc_allocateClassPair(baseClass, name.c_str(), 0);

objc_registerClassPair(clazz);
return clazz;
#else
Class baseClass = objc_getClass(baseClassName.c_str());
std::string name =
!staticClassName.empty()
? staticClassName
: baseClassName + "_" +
: baseClassName + suffix + "_" +
std::to_string(++ClassBuilder::classNameCounter_);
// here we could either call objc_getClass with the name to see if the class
// already exists or we can just try allocating it, which will return nil if
Expand All @@ -60,7 +31,6 @@ Class ClassBuilder::GetExtendedClass(std::string baseClassName,

objc_registerClassPair(clazz);
return clazz;
#endif
}

} // namespace tns
4 changes: 2 additions & 2 deletions NativeScript/runtime/ClassBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ struct PropertyCallbackContext {
class ClassBuilder {
public:
static v8::Local<v8::FunctionTemplate> GetExtendFunction(v8::Isolate* isolate, const InterfaceMeta* interfaceMeta);
static Class GetExtendedClass(std::string baseClassName, std::string staticClassName);
static Class GetExtendedClass(std::string baseClassName, std::string staticClassName, std::string suffix);

static void RegisterBaseTypeScriptExtendsFunction(v8::Local<v8::Context> context);
static void RegisterNativeTypeScriptExtendsFunction(v8::Local<v8::Context> context);
static std::string GetTypeEncoding(const TypeEncoding* typeEncoding, int argsCount);
private:
static unsigned long long classNameCounter_;
static std::atomic<unsigned long long> classNameCounter_;

static void ExtendCallback(const v8::FunctionCallbackInfo<v8::Value>& info);
static void SuperAccessorGetterCallback(v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info);
Expand Down
10 changes: 6 additions & 4 deletions NativeScript/runtime/ClassBuilder.mm
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,10 @@
staticClassName = tns::ToString(isolate, explicitClassName);
}
}
auto cache = Caches::Get(isolate);
auto isolateId = cache->getIsolateId();

Class extendedClass = ClassBuilder::GetExtendedClass(baseClassName, staticClassName);
Class extendedClass = ClassBuilder::GetExtendedClass(baseClassName, staticClassName, std::to_string(isolateId) + "_");
class_addProtocol(extendedClass, @protocol(TNSDerivedClass));
class_addProtocol(object_getClass(extendedClass), @protocol(TNSDerivedClass));

Expand All @@ -70,7 +72,6 @@
implementationObject);
}

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

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

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

Expand Down Expand Up @@ -984,6 +986,6 @@
return class_getMethodImplementation(klass, method);
}

unsigned long long ClassBuilder::classNameCounter_ = 0;
std::atomic<unsigned long long> ClassBuilder::classNameCounter_{0};

} // namespace tns
3 changes: 1 addition & 2 deletions NativeScript/runtime/Helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -219,8 +219,7 @@ bool IsArrayOrArrayLike(v8::Isolate* isolate,
void* TryGetBufferFromArrayBuffer(const v8::Local<v8::Value>& value,
bool& isArrayBuffer);

void ExecuteOnRunLoop(CFRunLoopRef queue, std::function<void()> func,
bool async = true);
void ExecuteOnRunLoop(CFRunLoopRef queue, void (^func)(void), bool async = true);
void ExecuteOnDispatchQueue(dispatch_queue_t queue, std::function<void()> func,
bool async = true);
void ExecuteOnMainThread(std::function<void()> func, bool async = true);
Expand Down
7 changes: 2 additions & 5 deletions NativeScript/runtime/Helpers.mm
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@
std::condition_variable cv;
};

void tns::ExecuteOnRunLoop(CFRunLoopRef queue, std::function<void ()> func, bool async) {
void tns::ExecuteOnRunLoop(CFRunLoopRef queue, void (^func)(void), bool async) {
if(!async) {
bool __block finished = false;
auto v = new LockAndCV;
Expand All @@ -350,12 +350,9 @@
}
delete v;
} else {
CFRunLoopPerformBlock(queue, kCFRunLoopCommonModes, ^(void) {
func();
});
CFRunLoopPerformBlock(queue, kCFRunLoopCommonModes, func);
CFRunLoopWakeUp(queue);
}

}

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