diff --git a/NativeScript/runtime/ArgConverter.mm b/NativeScript/runtime/ArgConverter.mm index d5464db8..ed32c9d7 100644 --- a/NativeScript/runtime/ArgConverter.mm +++ b/NativeScript/runtime/ArgConverter.mm @@ -928,19 +928,31 @@ tns::Assert(false, isolate); } } else { - Class knownClass = objc_getClass(meta->name()); - KnownUnknownClassPair pair(knownClass, klass); - Local ctorFuncTemplate = cache->ObjectCtorInitializer( - context, static_cast(meta), pair, additionalProtocols); - Local ctorFunc; - bool success = ctorFuncTemplate->GetFunction(context).ToLocal(&ctorFunc); - tns::Assert(success, isolate); - - Local prototypeValue; - success = - ctorFunc->Get(context, tns::ToV8String(isolate, "prototype")).ToLocal(&prototypeValue); - tns::Assert(success, isolate); - Local prototype = prototypeValue.As(); + auto cached = additionalProtocols.empty() ? cache->MetaInstancePrototypes.find(meta) + : cache->MetaInstancePrototypes.end(); + Local prototype; + bool success; + if (cached != cache->MetaInstancePrototypes.end()) { + prototype = cached->second->Get(isolate); + } else { + Class knownClass = objc_getClass(meta->name()); + KnownUnknownClassPair pair(knownClass, klass); + Local ctorFuncTemplate = cache->ObjectCtorInitializer( + context, static_cast(meta), pair, additionalProtocols); + Local ctorFunc; + success = ctorFuncTemplate->GetFunction(context).ToLocal(&ctorFunc); + tns::Assert(success, isolate); + + Local prototypeValue; + success = + ctorFunc->Get(context, tns::ToV8String(isolate, "prototype")).ToLocal(&prototypeValue); + tns::Assert(success, isolate); + prototype = prototypeValue.As(); + if (additionalProtocols.empty()) { + cache->MetaInstancePrototypes.emplace( + meta, std::make_unique>(isolate, prototype)); + } + } if (!receiver->SetPrototype(context, prototype).To(&success) || !success) { tns::Assert(false, isolate); diff --git a/NativeScript/runtime/Caches.cpp b/NativeScript/runtime/Caches.cpp index dc1a3344..75e42bcb 100644 --- a/NativeScript/runtime/Caches.cpp +++ b/NativeScript/runtime/Caches.cpp @@ -22,6 +22,7 @@ Caches::~Caches() { this->Prototypes.clear(); this->ClassPrototypes.clear(); + this->MetaInstancePrototypes.clear(); this->CtorFuncTemplates.clear(); this->CtorFuncs.clear(); this->ProtocolCtorFuncs.clear(); diff --git a/NativeScript/runtime/Caches.h b/NativeScript/runtime/Caches.h index 666d7e63..be8281a8 100644 --- a/NativeScript/runtime/Caches.h +++ b/NativeScript/runtime/Caches.h @@ -145,6 +145,9 @@ class Caches { std::unique_ptr>, TransparentStringHash, TransparentStringEqual> ClassPrototypes; + robin_hood::unordered_map>> + MetaInstancePrototypes; robin_hood::unordered_map< const BaseClassMeta*, std::unique_ptr>>