@@ -39,11 +39,11 @@ void CallbackHandlers::Init(Isolate *isolate, ObjectManager *objectManager)
3939 RESOLVE_CLASS_METHOD_ID = env.GetMethodID (RUNTIME_CLASS, " resolveClass" , " (Ljava/lang/String;[Ljava/lang/String;)Ljava/lang/Class;" );
4040 assert (RESOLVE_CLASS_METHOD_ID != nullptr );
4141
42- CREATE_INSTANCE_METHOD_ID = env.GetMethodID (RUNTIME_CLASS, " createInstance " , " ([Ljava/lang/Object;II)Ljava/lang/Object; " );
43- assert (CREATE_INSTANCE_METHOD_ID != nullptr );
42+ CURRENT_OBJECTID_FIELD_ID = env.GetFieldID (RUNTIME_CLASS, " currentObjectId " , " I " );
43+ assert (CURRENT_OBJECTID_FIELD_ID != nullptr );
4444
45- CACHE_CONSTRUCTOR_METHOD_ID = env.GetMethodID (RUNTIME_CLASS, " cacheConstructor " , " (Ljava/lang/Class;[Ljava/lang/ Object;)I " );
46- assert (CACHE_CONSTRUCTOR_METHOD_ID != nullptr );
45+ MAKE_INSTANCE_STRONG_ID = env.GetMethodID (RUNTIME_CLASS, " makeInstanceStrong " , " (Ljava/lang/Object;I)V " );
46+ assert (MAKE_INSTANCE_STRONG_ID != nullptr );
4747
4848 GET_TYPE_METADATA = env.GetStaticMethodID (RUNTIME_CLASS, " getTypeMetadata" , " (Ljava/lang/String;I)[Ljava/lang/String;" );
4949 assert (GET_TYPE_METADATA != nullptr );
@@ -80,7 +80,31 @@ bool CallbackHandlers::RegisterInstance(Isolate *isolate, const Local<Object>& j
8080 DEBUG_WRITE (" RegisterInstance: Linking new instance" );
8181 objectManager->Link (jsObject, javaObjectID, nullptr );
8282
83- jobject instance = CreateJavaInstance (javaObjectID, fullClassName, argWrapper, generatedJavaClass, isInterface);
83+ // resolve constructor
84+ auto mi = MethodCache::ResolveConstructorSignature (argWrapper, fullClassName, generatedJavaClass, isInterface);
85+
86+ jobject instance;
87+
88+ {
89+ JavaObjectIdScope objIdScope (env, CURRENT_OBJECTID_FIELD_ID, runtime->GetJavaRuntime (), javaObjectID);
90+
91+ if (argWrapper.type == ArgType::Interface)
92+ {
93+ instance = env.NewObject (generatedJavaClass, mi.mid );
94+ }
95+ else
96+ {
97+ // resolve arguments before passing them on to the constructor
98+ JsArgConverter argConverter (argWrapper.args , mi.signature , argWrapper.outerThis );
99+ auto ctorArgs = argConverter.ToArgs ();
100+
101+ instance = env.NewObjectA (generatedJavaClass, mi.mid , ctorArgs);
102+ }
103+ }
104+
105+ env.CallVoidMethod (runtime->GetJavaRuntime (), MAKE_INSTANCE_STRONG_ID, instance, javaObjectID);
106+
107+ AdjustAmountOfExternalAllocatedMemory (env, isolate);
84108
85109 JniLocalRef localInstance (instance);
86110 success = !localInstance.IsNull ();
@@ -113,14 +137,14 @@ jclass CallbackHandlers::ResolveClass(Isolate *isolate, const string& fullClassn
113137 {
114138 JEnv env;
115139
116- // get needed arguments in order to load binding
140+ // get needed arguments in order to load binding
117141 JniLocalRef javaFullClassName (env.NewStringUTF (fullClassname.c_str ()));
118142
119143 jobjectArray methodOverrides = GetMethodOverrides (env, implementationObject);
120144
121145 auto runtime = Runtime::GetRuntime (isolate);
122146
123- // create or load generated binding (java class)
147+ // create or load generated binding (java class)
124148 JniLocalRef generatedClass (env.CallObjectMethod (runtime->GetJavaRuntime (), RESOLVE_CLASS_METHOD_ID, (jstring) javaFullClassName, methodOverrides));
125149 globalRefToGeneratedClass = static_cast <jclass>(env.NewGlobalRef (generatedClass));
126150
@@ -196,8 +220,8 @@ void CallbackHandlers::CallJavaMethod(const Local<Object>& caller, const string&
196220 }
197221
198222 entry->memberId = isStatic ?
199- env.GetStaticMethodID (clazz, methodName, entry->sig ) :
200- env.GetMethodID (clazz, methodName, entry->sig );
223+ env.GetStaticMethodID (clazz, methodName, entry->sig ) :
224+ env.GetMethodID (clazz, methodName, entry->sig );
201225
202226 if (entry->memberId == nullptr )
203227 {
@@ -209,8 +233,8 @@ void CallbackHandlers::CallJavaMethod(const Local<Object>& caller, const string&
209233 else
210234 {
211235 entry->memberId = isStatic ?
212- env.GetStaticMethodID (clazz, methodName, entry->sig ) :
213- env.GetMethodID (clazz, methodName, entry->sig );
236+ env.GetStaticMethodID (clazz, methodName, entry->sig ) :
237+ env.GetMethodID (clazz, methodName, entry->sig );
214238
215239 if (entry->memberId == nullptr )
216240 {
@@ -302,7 +326,7 @@ void CallbackHandlers::CallJavaMethod(const Local<Object>& caller, const string&
302326 switch (retType)
303327 {
304328 case MethodReturnType::Void:
305- {
329+ {
306330 if (isStatic)
307331 {
308332 env.CallStaticVoidMethodA (clazz, mid, javaArgs);
@@ -318,7 +342,7 @@ void CallbackHandlers::CallJavaMethod(const Local<Object>& caller, const string&
318342 break ;
319343 }
320344 case MethodReturnType::Boolean:
321- {
345+ {
322346 jboolean result;
323347 if (isStatic)
324348 {
@@ -336,7 +360,7 @@ void CallbackHandlers::CallJavaMethod(const Local<Object>& caller, const string&
336360 break ;
337361 }
338362 case MethodReturnType::Byte:
339- {
363+ {
340364 jbyte result;
341365 if (isStatic)
342366 {
@@ -354,7 +378,7 @@ void CallbackHandlers::CallJavaMethod(const Local<Object>& caller, const string&
354378 break ;
355379 }
356380 case MethodReturnType::Char:
357- {
381+ {
358382 jchar result;
359383 if (isStatic)
360384 {
@@ -377,7 +401,7 @@ void CallbackHandlers::CallJavaMethod(const Local<Object>& caller, const string&
377401 break ;
378402 }
379403 case MethodReturnType::Short:
380- {
404+ {
381405 jshort result;
382406 if (isStatic)
383407 {
@@ -395,7 +419,7 @@ void CallbackHandlers::CallJavaMethod(const Local<Object>& caller, const string&
395419 break ;
396420 }
397421 case MethodReturnType::Int:
398- {
422+ {
399423 jint result;
400424 if (isStatic)
401425 {
@@ -414,7 +438,7 @@ void CallbackHandlers::CallJavaMethod(const Local<Object>& caller, const string&
414438
415439 }
416440 case MethodReturnType::Long:
417- {
441+ {
418442 jlong result;
419443 if (isStatic)
420444 {
@@ -433,7 +457,7 @@ void CallbackHandlers::CallJavaMethod(const Local<Object>& caller, const string&
433457 break ;
434458 }
435459 case MethodReturnType::Float:
436- {
460+ {
437461 jfloat result;
438462 if (isStatic)
439463 {
@@ -451,7 +475,7 @@ void CallbackHandlers::CallJavaMethod(const Local<Object>& caller, const string&
451475 break ;
452476 }
453477 case MethodReturnType::Double:
454- {
478+ {
455479 jdouble result;
456480 if (isStatic)
457481 {
@@ -469,7 +493,7 @@ void CallbackHandlers::CallJavaMethod(const Local<Object>& caller, const string&
469493 break ;
470494 }
471495 case MethodReturnType::String:
472- {
496+ {
473497 jobject result = nullptr ;
474498 bool exceptionOccurred;
475499
@@ -500,7 +524,7 @@ void CallbackHandlers::CallJavaMethod(const Local<Object>& caller, const string&
500524 break ;
501525 }
502526 case MethodReturnType::Object:
503- {
527+ {
504528 jobject result = nullptr ;
505529 bool exceptionOccurred;
506530
@@ -548,7 +572,7 @@ void CallbackHandlers::CallJavaMethod(const Local<Object>& caller, const string&
548572 break ;
549573 }
550574 default :
551- {
575+ {
552576 assert (false );
553577 break ;
554578 }
@@ -569,9 +593,9 @@ int64_t CallbackHandlers::AdjustAmountOfExternalAllocatedMemory(JEnv& env, Isola
569593 int64_t changeInBytes = env.CallLongMethod (runtime->GetJavaRuntime (), GET_CHANGE_IN_BYTES_OF_USED_MEMORY_METHOD_ID);
570594
571595 int64_t adjustedValue = (changeInBytes != 0 )
572- ? isolate->AdjustAmountOfExternalAllocatedMemory (changeInBytes)
573- :
574- 0 ;
596+ ? isolate->AdjustAmountOfExternalAllocatedMemory (changeInBytes)
597+ :
598+ 0 ;
575599
576600 return adjustedValue;
577601}
@@ -584,68 +608,6 @@ Local<Object> CallbackHandlers::CreateJSWrapper(Isolate *isolate, jint javaObjec
584608 return objectManager->CreateJSWrapper (javaObjectID, typeName);
585609}
586610
587- jobject CallbackHandlers::CreateJavaInstance (int objectID, const std::string& fullClassName, const ArgsWrapper& argWrapper, jclass javaClass, bool isInterface)
588- {
589- SET_PROFILER_FRAME ();
590-
591- jobject instance = nullptr ;
592- DEBUG_WRITE (" CreateJavaInstance: %s" , fullClassName.c_str ());
593-
594- JEnv env;
595- auto & args = argWrapper.args ;
596-
597- JsArgToArrayConverter argConverter (args, isInterface, argWrapper.outerThis );
598- if (argConverter.IsValid ())
599- {
600- jobjectArray javaArgs = argConverter.ToJavaArray ();
601-
602- int ctorId = GetCachedConstructorId (env, args, fullClassName, javaArgs, javaClass);
603-
604- auto runtime = Runtime::GetRuntime (args.GetIsolate ());
605-
606- jobject obj = env.CallObjectMethod (runtime->GetJavaRuntime (),
607- CREATE_INSTANCE_METHOD_ID,
608- javaArgs,
609- (jint) objectID,
610- ctorId);
611-
612- instance = obj;
613- }
614- else
615- {
616- JsArgToArrayConverter::Error err = argConverter.GetError ();
617- throw NativeScriptException (err.msg );
618- }
619-
620- return instance;
621- }
622-
623- int CallbackHandlers::GetCachedConstructorId (JEnv& env, const FunctionCallbackInfo<Value>& args, const string& fullClassName, jobjectArray javaArgs, jclass javaClass)
624- {
625- int ctorId = -1 ;
626- string encodedCtorArgs = MethodCache::EncodeSignature (fullClassName, " <init>" , args, false );
627- auto itFound = s_constructorCache.find (encodedCtorArgs);
628-
629- if (itFound != s_constructorCache.end ())
630- {
631- ctorId = itFound->second ;
632- }
633- else
634- {
635- auto runtime = Runtime::GetRuntime (args.GetIsolate ());
636- jint id = env.CallIntMethod (runtime->GetJavaRuntime (), CACHE_CONSTRUCTOR_METHOD_ID, javaClass, javaArgs);
637-
638- if (env.ExceptionCheck () == JNI_FALSE)
639- {
640- ctorId = id;
641- s_constructorCache.insert (make_pair (encodedCtorArgs, ctorId));
642- }
643- }
644-
645- DEBUG_WRITE (" GetCachedConstructorId: encodedCtorArgs=%s, ctorId=%d" , encodedCtorArgs.c_str (), ctorId);
646- return ctorId;
647- }
648-
649611// delete the returned local reference after use
650612jobjectArray CallbackHandlers::GetMethodOverrides (JEnv& env, const Local<Object>& implementationObject)
651613{
@@ -702,7 +664,7 @@ void CallbackHandlers::LogMethodCallback(const v8::FunctionCallbackInfo<v8::Valu
702664 e.ReThrowToV8 ();
703665 }
704666 catch (std::exception e) {
705- stringstream ss;
667+ stringstream ss;
706668 ss << " Error: c++ exception: " << e.what () << endl;
707669 NativeScriptException nsEx (ss.str ());
708670 nsEx.ReThrowToV8 ();
@@ -738,7 +700,7 @@ void CallbackHandlers::DumpReferenceTablesMethod()
738700 e.ReThrowToV8 ();
739701 }
740702 catch (std::exception e) {
741- stringstream ss;
703+ stringstream ss;
742704 ss << " Error: c++ exception: " << e.what () << endl;
743705 NativeScriptException nsEx (ss.str ());
744706 nsEx.ReThrowToV8 ();
@@ -764,7 +726,7 @@ void CallbackHandlers::EnableVerboseLoggingMethodCallback(const v8::FunctionCall
764726 e.ReThrowToV8 ();
765727 }
766728 catch (std::exception e) {
767- stringstream ss;
729+ stringstream ss;
768730 ss << " Error: c++ exception: " << e.what () << endl;
769731 NativeScriptException nsEx (ss.str ());
770732 nsEx.ReThrowToV8 ();
@@ -790,7 +752,7 @@ void CallbackHandlers::DisableVerboseLoggingMethodCallback(const v8::FunctionCal
790752 e.ReThrowToV8 ();
791753 }
792754 catch (std::exception e) {
793- stringstream ss;
755+ stringstream ss;
794756 ss << " Error: c++ exception: " << e.what () << endl;
795757 NativeScriptException nsEx (ss.str ());
796758 nsEx.ReThrowToV8 ();
@@ -939,9 +901,9 @@ int CallbackHandlers::GetArrayLength(Isolate *isolate, const Local<Object>& arr)
939901
940902jclass CallbackHandlers::RUNTIME_CLASS = nullptr ;
941903jclass CallbackHandlers::JAVA_LANG_STRING = nullptr ;
904+ jfieldID CallbackHandlers::CURRENT_OBJECTID_FIELD_ID = nullptr ;
942905jmethodID CallbackHandlers::RESOLVE_CLASS_METHOD_ID = nullptr ;
943- jmethodID CallbackHandlers::CREATE_INSTANCE_METHOD_ID = nullptr ;
944- jmethodID CallbackHandlers::CACHE_CONSTRUCTOR_METHOD_ID = nullptr ;
906+ jmethodID CallbackHandlers::MAKE_INSTANCE_STRONG_ID = nullptr ;
945907jmethodID CallbackHandlers::GET_TYPE_METADATA = nullptr ;
946908jmethodID CallbackHandlers::ENABLE_VERBOSE_LOGGING_METHOD_ID = nullptr ;
947909jmethodID CallbackHandlers::DISABLE_VERBOSE_LOGGING_METHOD_ID = nullptr ;
0 commit comments