jobject ObjectManager::GetJavaObjectByIDImpl(uint32_t javaObjectID) { JEnv env; jobject object = env.CallStaticObjectMethod(PlatformClass, GET_JAVAOBJECT_BY_ID_METHOD_ID, javaObjectID); return object; }
jobject NativeScriptRuntime::CreateJavaInstance(int objectID, const std::string& fullClassName, const ArgsWrapper& argWrapper, jclass javaClass, bool isInterface) { SET_PROFILER_FRAME(); jobject instance = nullptr; DEBUG_WRITE("CreateJavaInstance: %s", fullClassName.c_str()); JEnv env; auto& args = argWrapper.args; JsArgToArrayConverter argConverter(args, isInterface, argWrapper.outerThis); if (argConverter.IsValid()) { jobjectArray javaArgs = argConverter.ToJavaArray(); int ctorId = GetCachedConstructorId(env, args, fullClassName, javaArgs, javaClass); jobject obj = env.CallStaticObjectMethod(PlatformClass, CREATE_INSTANCE_METHOD_ID, javaArgs, (jint) objectID, ctorId); instance = obj; } else { JsArgToArrayConverter::Error err = argConverter.GetError(); throw NativeScriptException(err.msg); } return instance; }
vector<string> NativeScriptRuntime::GetTypeMetadata(const string& name, int index) { JEnv env; string canonicalName = Util::ConvertFromJniToCanonicalName(name); JniLocalRef className(env.NewStringUTF(canonicalName.c_str())); jint idx = index; JniLocalRef pubApi(env.CallStaticObjectMethod(PlatformClass, GET_TYPE_METADATA, (jstring) className, idx)); jsize length = env.GetArrayLength(pubApi); assert(length > 0); vector<string> result; for (jsize i=0; i<length; i++) { JniLocalRef s(env.GetObjectArrayElement(pubApi, i)); const char *pc = env.GetStringUTFChars(s, nullptr); result.push_back(string(pc)); env.ReleaseStringUTFChars(s, pc); } return result; }
jclass NativeScriptRuntime::ResolveClass(const std::string& fullClassname, const Local<Object>& implementationObject) { auto itFound = s_classCache.find(fullClassname); jclass globalRefToGeneratedClass; if (itFound != s_classCache.end()) { globalRefToGeneratedClass = itFound->second; } else { JEnv env; //get needed arguments in order to load binding JniLocalRef javaFullClassName(env.NewStringUTF(fullClassname.c_str())); jobjectArray methodOverrides = GetMethodOverrides(env, implementationObject); //create or load generated binding (java class) JniLocalRef generatedClass(env.CallStaticObjectMethod(PlatformClass, RESOLVE_CLASS_METHOD_ID, (jstring)javaFullClassName, methodOverrides)); globalRefToGeneratedClass = reinterpret_cast<jclass>(env.NewGlobalRef(generatedClass)); s_classCache.insert(make_pair(fullClassname, globalRefToGeneratedClass)); } return globalRefToGeneratedClass; }
void NativeScriptRuntime::RequireCallback(const v8::FunctionCallbackInfo<v8::Value>& args) { SET_PROFILER_FRAME(); ASSERT_MESSAGE(args.Length() == 2, "require should be called with two parameters"); ASSERT_MESSAGE(!args[0]->IsUndefined() && !args[0]->IsNull(), "require called with undefined moduleName parameter"); ASSERT_MESSAGE(!args[1]->IsUndefined() && !args[1]->IsNull(), "require called with undefined callingModulePath parameter"); ASSERT_MESSAGE(args[0]->IsString(), "require should be called with string parameter"); ASSERT_MESSAGE(args[1]->IsString(), "require should be called with string parameter"); string moduleName = ConvertToString(args[0].As<String>()); string callingModuleDirName = ConvertToString(args[1].As<String>()); JEnv env; JniLocalRef jsModulename(env.NewStringUTF(moduleName.c_str())); JniLocalRef jsCallingModuleDirName(env.NewStringUTF(callingModuleDirName.c_str())); JniLocalRef jsModulePath(env.CallStaticObjectMethod(RequireClass, GET_MODULE_PATH_METHOD_ID, (jstring) jsModulename, (jstring) jsCallingModuleDirName)); auto isolate = Isolate::GetCurrent(); // cache the required modules by full path, not name only, since there might be some collisions with relative paths and names string modulePath = ArgConverter::jstringToString((jstring) jsModulePath); if(modulePath == ""){ // module not found stringstream ss; ss << "Module \"" << moduleName << "\" not found"; string exception = ss.str(); ExceptionUtil::GetInstance()->ThrowExceptionToJs(exception); return; } if (modulePath == "EXTERNAL_FILE_ERROR") { // module not found stringstream ss; ss << "Module \"" << moduleName << "\" is located on the external storage. Modules can be private application files ONLY"; string exception = ss.str(); ExceptionUtil::GetInstance()->ThrowExceptionToJs(exception); return; } auto it = loadedModules.find(modulePath); Handle<Object> moduleObj; bool hasError = false; if (it == loadedModules.end()) { CompileAndRun(modulePath, hasError, moduleObj, false/*is bootstrap call*/); } else { moduleObj = Local<Object>::New(isolate, *((*it).second)); } if(!hasError){ args.GetReturnValue().Set(moduleObj); } }
jclass NativeScriptRuntime::ResolveClass(const std::string& fullClassname, const Handle<Object>& implementationObject) { JEnv env; //get needed arguments in order to load binding JniLocalRef javaFullClassName(env.NewStringUTF(fullClassname.c_str())); jobjectArray methodOverrides = GetMethodOverrides(env, implementationObject); //create or load generated binding (java class) JniLocalRef generatedClass(env.CallStaticObjectMethod(PlatformClass, RESOLVE_CLASS_METHOD_ID, (jstring)javaFullClassName, methodOverrides)); jclass globalRefToGeneratedClass = reinterpret_cast<jclass>(env.NewGlobalRef(generatedClass)); return globalRefToGeneratedClass; }
Handle<Object> NativeScriptRuntime::FindClass(const string& className) { Handle<Object> clazz; JEnv env; jmethodID mid = env.GetStaticMethodID(PlatformClass, "findClass", "(Ljava/lang/String;)Ljava/lang/Class;"); assert(mid != nullptr); JniLocalRef name(env.NewStringUTF(className.c_str())); jclass c = (jclass)env.CallStaticObjectMethod(PlatformClass, mid, (jstring)name); if (env.ExceptionCheck() == JNI_FALSE) { jint javaObjectID = objectManager->GetOrCreateObjectId(c); clazz = objectManager->GetJsObjectByJavaObject(javaObjectID); if (clazz.IsEmpty()) { clazz = objectManager->CreateJSWrapper(javaObjectID, "Ljava/lang/Class;", c); } env.DeleteLocalRef(c); } return clazz; }
void Module::RequireCallback(const v8::FunctionCallbackInfo<v8::Value>& args) { try { auto isolate = Isolate::GetCurrent(); if (args.Length() != 2) { throw NativeScriptException(string("require should be called with two parameters")); } if (!args[0]->IsString()) { throw NativeScriptException(string("require's first parameter should be string")); } if (!args[1]->IsString()) { throw NativeScriptException(string("require's second parameter should be string")); } string moduleName = ConvertToString(args[0].As<String>()); string callingModuleDirName = ConvertToString(args[1].As<String>()); JEnv env; JniLocalRef jsModulename(env.NewStringUTF(moduleName.c_str())); JniLocalRef jsCallingModuleDirName(env.NewStringUTF(callingModuleDirName.c_str())); JniLocalRef jsModulePath(env.CallStaticObjectMethod(MODULE_CLASS, RESOLVE_PATH_METHOD_ID, (jstring) jsModulename, (jstring) jsCallingModuleDirName)); // cache the required modules by full path, not name only, since there might be some collisions with relative paths and names string modulePath = ArgConverter::jstringToString((jstring) jsModulePath); auto isData = false; auto moduleObj = Load(modulePath, isData); if (isData) { assert(!moduleObj.IsEmpty()); args.GetReturnValue().Set(moduleObj); } else { auto exportsObj = moduleObj->Get(ConvertToV8String("exports")); assert(!exportsObj.IsEmpty()); args.GetReturnValue().Set(exportsObj); } } catch (NativeScriptException& e) { e.ReThrowToV8(); } catch (std::exception e) { stringstream ss; ss << "Error: c++ exception: " << e.what() << endl; NativeScriptException nsEx(ss.str()); nsEx.ReThrowToV8(); } catch (...) { NativeScriptException nsEx(std::string("Error: c++ exception!")); nsEx.ReThrowToV8(); } }