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;
}
Esempio n. 8
0
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();
	}
}