@@ -25,7 +25,7 @@ void MetadataNode::Init(Isolate *isolate)
2525}
2626
2727MetadataNode::MetadataNode (MetadataTreeNode *treeNode) :
28- m_treeNode(treeNode)
28+ m_treeNode(treeNode), m_poCtorFunc( nullptr )
2929{
3030 uint8_t nodeType = s_metadataReader.GetNodeType (treeNode);
3131
@@ -453,17 +453,21 @@ void MetadataNode::SuperAccessorGetterCallback(Local<String> property, const Pro
453453 }
454454}
455455
456- Local<Function> MetadataNode::SetMembers (Isolate *isolate, Local<FunctionTemplate>& ctorFuncTemplate, Local<ObjectTemplate>& prototypeTemplate, vector<MethodCallbackData*>& instanceMethodsCallbackData, const vector<MethodCallbackData*>& baseInstanceMethodsCallbackData, MetadataTreeNode *treeNode)
456+ void MetadataNode::SetInstanceMembers (Isolate *isolate, Local<FunctionTemplate>& ctorFuncTemplate, Local<ObjectTemplate>& prototypeTemplate, vector<MethodCallbackData*>& instanceMethodsCallbackData, const vector<MethodCallbackData*>& baseInstanceMethodsCallbackData, MetadataTreeNode *treeNode)
457457{
458458 auto hasCustomMetadata = treeNode->metadata != nullptr ;
459459
460- return hasCustomMetadata
461- ? SetMembersFromRuntimeMetadata (isolate, ctorFuncTemplate, prototypeTemplate, instanceMethodsCallbackData, baseInstanceMethodsCallbackData, treeNode)
462- :
463- SetMembersFromStaticMetadata (isolate, ctorFuncTemplate, prototypeTemplate, instanceMethodsCallbackData, baseInstanceMethodsCallbackData, treeNode);
460+ if (hasCustomMetadata)
461+ {
462+ SetInstanceMembersFromRuntimeMetadata (isolate, ctorFuncTemplate, prototypeTemplate, instanceMethodsCallbackData, baseInstanceMethodsCallbackData, treeNode);
463+ }
464+ else
465+ {
466+ SetInstanceMembersFromStaticMetadata (isolate, ctorFuncTemplate, prototypeTemplate, instanceMethodsCallbackData, baseInstanceMethodsCallbackData, treeNode);
467+ }
464468}
465469
466- Local<Function> MetadataNode::SetMembersFromStaticMetadata (Isolate *isolate, Local<FunctionTemplate>& ctorFuncTemplate, Local<ObjectTemplate>& prototypeTemplate, vector<MethodCallbackData*>& instanceMethodsCallbackData, const vector<MethodCallbackData*>& baseInstanceMethodsCallbackData, MetadataTreeNode *treeNode)
470+ void MetadataNode::SetInstanceMembersFromStaticMetadata (Isolate *isolate, Local<FunctionTemplate>& ctorFuncTemplate, Local<ObjectTemplate>& prototypeTemplate, vector<MethodCallbackData*>& instanceMethodsCallbackData, const vector<MethodCallbackData*>& baseInstanceMethodsCallbackData, MetadataTreeNode *treeNode)
467471{
468472 SET_PROFILER_FRAME ();
469473
@@ -511,8 +515,7 @@ Local<Function> MetadataNode::SetMembersFromStaticMetadata(Isolate *isolate, Loc
511515 auto funcTemplate = FunctionTemplate::New (isolate, MethodCallback, funcData);
512516 auto func = funcTemplate->GetFunction ();
513517 auto funcName = ConvertToV8String (entry.name );
514- func->SetName (funcName);
515- prototypeTemplate->Set (funcName, func);
518+ prototypeTemplate->Set (funcName, Wrap (isolate, func, entry.name , false /* isCtorFunc */ ));
516519 lastMethodName = entry.name ;
517520 }
518521
@@ -532,59 +535,9 @@ Local<Function> MetadataNode::SetMembersFromStaticMetadata(Isolate *isolate, Loc
532535 auto fieldData = External::New (isolate, fieldInfo);
533536 prototypeTemplate->SetAccessor (fieldName, FieldAccessorGetterCallback, FieldAccessorSetterCallback, fieldData, AccessControl::DEFAULT, PropertyAttribute::DontDelete);
534537 }
535-
536- ctorFunction = ctorFuncTemplate->GetFunction ();
537-
538- // get candidates from static methods metadata
539- callbackData = nullptr ;
540- lastMethodName.clear ();
541- auto staticMethodCout = *reinterpret_cast <uint16_t *>(curPtr);
542- curPtr += sizeof (uint16_t );
543- for (auto i = 0 ; i < staticMethodCout; i++)
544- {
545- auto entry = s_metadataReader.ReadStaticMethodEntry (&curPtr);
546- if (entry.name != lastMethodName)
547- {
548- callbackData = new MethodCallbackData (this );
549- auto funcData = External::New (isolate, callbackData);
550- auto funcTemplate = FunctionTemplate::New (isolate, MethodCallback, funcData);
551- auto func = funcTemplate->GetFunction ();
552- auto funcName = ConvertToV8String (entry.name );
553- func->SetName (funcName);
554- ctorFunction->Set (funcName, func);
555- lastMethodName = entry.name ;
556- }
557- callbackData->candidates .push_back (entry);
558- }
559-
560- // attach .extend function
561- auto extendFuncName = V8StringConstants::GetExtend ();
562- auto extendFuncTemplate = FunctionTemplate::New (isolate, ExtendCallMethodCallback, External::New (isolate, this ));
563- ctorFunction->Set (extendFuncName, extendFuncTemplate->GetFunction ());
564-
565- // get candidates from static fields metadata
566- auto staticFieldCout = *reinterpret_cast <uint16_t *>(curPtr);
567- curPtr += sizeof (uint16_t );
568- for (auto i = 0 ; i < staticFieldCout; i++)
569- {
570- auto entry = s_metadataReader.ReadStaticFieldEntry (&curPtr);
571-
572- auto fieldName = ConvertToV8String (entry.name );
573- auto fieldData = External::New (isolate, new FieldCallbackData (entry));
574- ctorFunction->SetAccessor (fieldName, FieldAccessorGetterCallback, FieldAccessorSetterCallback, fieldData, AccessControl::DEFAULT, PropertyAttribute::DontDelete);
575- }
576-
577- auto nullObjectName = V8StringConstants::GetNullObject ();
578-
579- Local<Value> nullObjectData = External::New (isolate, this );
580- ctorFunction->SetAccessor (nullObjectName, NullObjectAccessorGetterCallback, nullptr , nullObjectData);
581-
582- SetClassAccessor (ctorFunction);
583-
584- return ctorFunction;
585538}
586539
587- Local<Function> MetadataNode::SetMembersFromRuntimeMetadata (Isolate *isolate, Local<FunctionTemplate>& ctorFuncTemplate, Local<ObjectTemplate>& prototypeTemplate, vector<MethodCallbackData*>& instanceMethodsCallbackData, const vector<MethodCallbackData*>& baseInstanceMethodsCallbackData, MetadataTreeNode *treeNode)
540+ void MetadataNode::SetInstanceMembersFromRuntimeMetadata (Isolate *isolate, Local<FunctionTemplate>& ctorFuncTemplate, Local<ObjectTemplate>& prototypeTemplate, vector<MethodCallbackData*>& instanceMethodsCallbackData, const vector<MethodCallbackData*>& baseInstanceMethodsCallbackData, MetadataTreeNode *treeNode)
588541{
589542 SET_PROFILER_FRAME ();
590543
@@ -642,7 +595,6 @@ Local<Function> MetadataNode::SetMembersFromRuntimeMetadata(Isolate *isolate, Lo
642595 auto funcTemplate = FunctionTemplate::New (isolate, MethodCallback, funcData);
643596 auto func = funcTemplate->GetFunction ();
644597 auto funcName = ConvertToV8String (entry.name );
645- func->SetName (funcName);
646598 prototypeTemplate->Set (funcName, func);
647599 lastMethodName = entry.name ;
648600 }
@@ -656,12 +608,85 @@ Local<Function> MetadataNode::SetMembersFromRuntimeMetadata(Isolate *isolate, Lo
656608 prototypeTemplate->SetAccessor (fieldName, FieldAccessorGetterCallback, FieldAccessorSetterCallback, fieldData, access, PropertyAttribute::DontDelete);
657609 }
658610 }
611+ }
612+
613+ void MetadataNode::SetStaticMembers (Isolate *isolate, Local<Function>& ctorFunction, MetadataTreeNode *treeNode)
614+ {
615+ auto hasCustomMetadata = treeNode->metadata != nullptr ;
616+
617+ if (!hasCustomMetadata)
618+ {
619+ uint8_t *curPtr = s_metadataReader.GetValueData () + treeNode->offsetValue + 1 ;
620+ auto nodeType = s_metadataReader.GetNodeType (treeNode);
621+ auto curType = s_metadataReader.ReadTypeName (treeNode);
622+ curPtr += sizeof (uint16_t /* baseClassId */ );
623+ if (s_metadataReader.IsNodeTypeInterface (nodeType))
624+ {
625+ curPtr += sizeof (uint8_t ) + sizeof (uint32_t );
626+ }
627+ auto instanceMethodCout = *reinterpret_cast <uint16_t *>(curPtr);
628+ curPtr += sizeof (uint16_t );
629+ for (auto i = 0 ; i < instanceMethodCout; i++)
630+ {
631+ auto entry = s_metadataReader.ReadInstanceMethodEntry (&curPtr);
632+ }
633+ auto instanceFieldCout = *reinterpret_cast <uint16_t *>(curPtr);
634+ curPtr += sizeof (uint16_t );
635+ for (auto i = 0 ; i < instanceFieldCout; i++)
636+ {
637+ auto entry = s_metadataReader.ReadInstanceFieldEntry (&curPtr);
638+ }
639+
640+ string lastMethodName;
641+ MethodCallbackData *callbackData = nullptr ;
642+
643+ // get candidates from static methods metadata
644+ auto staticMethodCout = *reinterpret_cast <uint16_t *>(curPtr);
645+ curPtr += sizeof (uint16_t );
646+ for (auto i = 0 ; i < staticMethodCout; i++)
647+ {
648+ auto entry = s_metadataReader.ReadStaticMethodEntry (&curPtr);
649+ if (entry.name != lastMethodName)
650+ {
651+ callbackData = new MethodCallbackData (this );
652+ auto funcData = External::New (isolate, callbackData);
653+ auto funcTemplate = FunctionTemplate::New (isolate, MethodCallback, funcData);
654+ auto func = funcTemplate->GetFunction ();
655+ auto funcName = ConvertToV8String (entry.name );
656+ ctorFunction->Set (funcName, Wrap (isolate, func, entry.name , false /* isCtorFunc */ ));
657+ lastMethodName = entry.name ;
658+ }
659+ callbackData->candidates .push_back (entry);
660+ }
661+
662+ // attach .extend function
663+ auto extendFuncName = V8StringConstants::GetExtend ();
664+ auto extendFuncTemplate = FunctionTemplate::New (isolate, ExtendCallMethodCallback, External::New (isolate, this ));
665+ ctorFunction->Set (extendFuncName, extendFuncTemplate->GetFunction ());
666+
667+ // get candidates from static fields metadata
668+ auto staticFieldCout = *reinterpret_cast <uint16_t *>(curPtr);
669+ curPtr += sizeof (uint16_t );
670+ for (auto i = 0 ; i < staticFieldCout; i++)
671+ {
672+ auto entry = s_metadataReader.ReadStaticFieldEntry (&curPtr);
659673
660- auto ctorFunction = ctorFuncTemplate->GetFunction ();
674+ auto fieldName = ConvertToV8String (entry.name );
675+ auto fieldData = External::New (isolate, new FieldCallbackData (entry));
676+ ctorFunction->SetAccessor (fieldName, FieldAccessorGetterCallback, FieldAccessorSetterCallback, fieldData, AccessControl::DEFAULT, PropertyAttribute::DontDelete);
677+ }
678+
679+ auto nullObjectName = V8StringConstants::GetNullObject ();
661680
662- return ctorFunction;
681+ Local<Value> nullObjectData = External::New (isolate, this );
682+ ctorFunction->SetAccessor (nullObjectName, NullObjectAccessorGetterCallback, nullptr , nullObjectData);
683+
684+ SetClassAccessor (ctorFunction);
685+ }
663686}
664687
688+
689+
665690void MetadataNode::InnerClassConstructorCallback (const v8::FunctionCallbackInfo<v8::Value>& info)
666691{
667692 try
@@ -760,7 +785,7 @@ void MetadataNode::SetInnnerTypes(Isolate *isolate, Local<Function>& ctorFunctio
760785 if (isStatic)
761786 {
762787 auto innerTypeCtorFuncTemplate = childNode->GetConstructorFunctionTemplate (isolate, curChild);
763- auto innerTypeCtorFunc = innerTypeCtorFuncTemplate-> GetFunction ( );
788+ auto innerTypeCtorFunc = Local<Function>:: New (isolate, * GetOrCreateInternal (curChild)-> m_poCtorFunc );
764789 auto innerTypeName = ConvertToV8String (curChild->name );
765790 ctorFunction->Set (innerTypeName, innerTypeCtorFunc);
766791 }
@@ -804,42 +829,50 @@ Local<FunctionTemplate> MetadataNode::GetConstructorFunctionTemplate(Isolate *is
804829 ctorFuncTemplate = FunctionTemplate::New (isolate, funcCallback, ctorCallbackData);
805830 ctorFuncTemplate->InstanceTemplate ()->SetInternalFieldCount (static_cast <int >(ObjectManager::MetadataNodeKeys::END));
806831
807- auto baseClass = s_metadataReader.GetBaseClassNode (treeNode);
832+ auto baseTreeNode = s_metadataReader.GetBaseClassNode (treeNode);
808833 Local<Function> baseCtorFunc;
809834 vector<MethodCallbackData*> baseInstanceMethodsCallbackData;
810- if ((baseClass != treeNode) && (baseClass != nullptr ) && (baseClass ->offsetValue > 0 ))
835+ if ((baseTreeNode != treeNode) && (baseTreeNode != nullptr ) && (baseTreeNode ->offsetValue > 0 ))
811836 {
812- auto baseFuncTemplate = GetConstructorFunctionTemplate (isolate, baseClass , baseInstanceMethodsCallbackData);
837+ auto baseFuncTemplate = GetConstructorFunctionTemplate (isolate, baseTreeNode , baseInstanceMethodsCallbackData);
813838 if (!baseFuncTemplate.IsEmpty ())
814839 {
815840 ctorFuncTemplate->Inherit (baseFuncTemplate);
816- baseCtorFunc = baseFuncTemplate-> GetFunction ( );
841+ baseCtorFunc = Local<Function>:: New (isolate, * GetOrCreateInternal (baseTreeNode)-> m_poCtorFunc );
817842 }
818843 }
819844
820845 auto prototypeTemplate = ctorFuncTemplate->PrototypeTemplate ();
821846
822- auto ctorFunc = node->SetMembers (isolate, ctorFuncTemplate, prototypeTemplate, instanceMethodsCallbackData, baseInstanceMethodsCallbackData, treeNode);
847+ node->SetInstanceMembers (isolate, ctorFuncTemplate, prototypeTemplate, instanceMethodsCallbackData, baseInstanceMethodsCallbackData, treeNode);
848+
849+ auto ctorFunc = ctorFuncTemplate->GetFunction ();
850+
851+ auto wrappedCtorFunc = Wrap (isolate, ctorFunc, node->m_treeNode ->name , true /* isCtorFunc */ );
852+
853+ node->SetStaticMembers (isolate, wrappedCtorFunc, treeNode);
854+
855+ node->m_poCtorFunc = new Persistent<Function>(isolate, wrappedCtorFunc);
823856 if (!baseCtorFunc.IsEmpty ())
824857 {
825- ctorFunc ->SetPrototype (baseCtorFunc);
858+ wrappedCtorFunc ->SetPrototype (baseCtorFunc);
826859 }
827860
828861 auto pft = new Persistent<FunctionTemplate>(isolate, ctorFuncTemplate);
829862 CtorCacheItem ctorCacheItem (pft, instanceMethodsCallbackData);
830863 cache->CtorFuncCache .insert (make_pair (treeNode, ctorCacheItem));
831864
832- SetInnnerTypes (isolate, ctorFunc , treeNode);
865+ SetInnnerTypes (isolate, wrappedCtorFunc , treeNode);
833866
834- SetTypeMetadata (isolate, ctorFunc , new TypeMetadata (s_metadataReader.ReadTypeName (treeNode)));
867+ SetTypeMetadata (isolate, wrappedCtorFunc , new TypeMetadata (s_metadataReader.ReadTypeName (treeNode)));
835868
836869 return ctorFuncTemplate;
837870}
838871
839872Local<Function> MetadataNode::GetConstructorFunction (Isolate *isolate)
840873{
841874 auto ctorFuncTemplate = GetConstructorFunctionTemplate (isolate, m_treeNode);
842- auto ctorFunc = ctorFuncTemplate-> GetFunction ( );
875+ auto ctorFunc = Local<Function>:: New (isolate, *m_poCtorFunc );
843876 return ctorFunc;
844877}
845878
@@ -1775,9 +1808,104 @@ MetadataNode::MetadataNodeCache* MetadataNode::GetCache(Isolate *isolate)
17751808 return cache;
17761809}
17771810
1811+ void MetadataNode::EnableProfiler (bool enableProfiler)
1812+ {
1813+ s_profilerEnabled = enableProfiler;
1814+ }
1815+
1816+ Local<Function> MetadataNode::Wrap (Isolate* isolate, const Local<Function>& f, const string& name, bool isCtorFunc)
1817+ {
1818+ if (!s_profilerEnabled)
1819+ {
1820+ return f;
1821+ }
1822+
1823+ static set<string> keywords;
1824+
1825+ if (keywords.empty ())
1826+ {
1827+ string kw[] { " abstract" , " arguments" , " boolean" , " break" , " byte" , " case" , " catch" , " char" , " class" , " const" , " continue" , " debugger" , " default" , " delete" , " do" ,
1828+ " double" , " else" , " enum" , " eval" , " export" , " extends" , " false" , " final" , " finally" , " float" , " for" , " function" , " goto" , " if" , " implements" ,
1829+ " import" , " in" , " instanceof" , " int" , " interface" , " let" , " long" , " native" , " new" , " null" , " package" , " private" , " protected" , " public" , " return" ,
1830+ " short" , " static" , " super" , " switch" , " synchronized" , " this" , " throw" , " throws" , " transient" , " true" , " try" , " typeof" , " var" , " void" , " volatile" , " while" , " with" , " yield" };
1831+
1832+ keywords = set<string>(kw, kw + sizeof (kw)/sizeof (kw[0 ]));
1833+ }
1834+
1835+ if (name == " <init>" )
1836+ {
1837+ return f;
1838+ }
1839+
1840+ string actualName = name;
1841+ while (keywords.find (actualName) != keywords.end ())
1842+ {
1843+ actualName.append (" _" );
1844+ }
1845+
1846+ Local<Function> ret;
1847+
1848+ stringstream ss;
1849+ ss << " (function() { " ;
1850+ ss << " function " << actualName << " () { " ;
1851+ if (isCtorFunc)
1852+ {
1853+ ss << " var args = [null]; for (var i=0; i<arguments.length; i++) { args.push(arguments[i]); }; " ;
1854+ ss << " return new (Function.prototype.bind.apply(" << actualName << " .__func, args)); " ;
1855+ }
1856+ else
1857+ {
1858+ ss << " return " << actualName << " .__func.apply(this, arguments); " ;
1859+ }
1860+ ss << " } " ;
1861+ ss << " return " << actualName << " ; " ;
1862+ ss << " })()" ;
1863+
1864+ auto str = ss.str ();
1865+ auto source = ConvertToV8String (str);
1866+ auto context = isolate->GetCurrentContext ();
1867+
1868+ TryCatch tc;
1869+
1870+ Local<Script> script;
1871+ ScriptOrigin origin (ConvertToV8String (Constants::APP_ROOT_FOLDER_PATH + m_name));
1872+ auto maybeScript = Script::Compile (context, source, &origin).ToLocal (&script);
1873+
1874+ if (tc.HasCaught ())
1875+ {
1876+ throw NativeScriptException (tc, " Cannot compile wrapper" );
1877+ }
1878+
1879+ if (!script.IsEmpty ())
1880+ {
1881+ Local<Value> result;
1882+ auto maybeResult = script->Run (context).ToLocal (&result);
1883+
1884+ if (!result.IsEmpty ())
1885+ {
1886+ ret = result.As <Function>();
1887+ ret->Set (ConvertToV8String (" __func" ), f);
1888+
1889+ auto prototypePropName = ConvertToV8String (" prototype" );
1890+ ret->Set (prototypePropName, f->Get (prototypePropName));
1891+ }
1892+ else
1893+ {
1894+ throw NativeScriptException (" Cannot create wrapper function" );
1895+ }
1896+ }
1897+ else
1898+ {
1899+ throw NativeScriptException (str);
1900+ }
1901+
1902+ return ret;
1903+ }
1904+
17781905string MetadataNode::TNS_PREFIX = " com/tns/gen/" ;
17791906MetadataReader MetadataNode::s_metadataReader;
17801907std::map<std::string, MetadataNode*> MetadataNode::s_name2NodeCache;
17811908std::map<std::string, MetadataTreeNode*> MetadataNode::s_name2TreeNodeCache;
17821909std::map<MetadataTreeNode*, MetadataNode*> MetadataNode::s_treeNode2NodeCache;
17831910map<Isolate*, MetadataNode::MetadataNodeCache*> MetadataNode::s_cache;
1911+ bool MetadataNode::s_profilerEnabled = false ;
0 commit comments