diff --git a/binding.gyp b/binding.gyp index 9ca09dfb..b0aad255 100644 --- a/binding.gyp +++ b/binding.gyp @@ -13,6 +13,7 @@ "sources": [ "src/java.cpp", "src/javaObject.cpp", + "src/javaScope.cpp", "src/methodCallBaton.cpp", "src/nodeJavaBridge.cpp", "src/utils.cpp" diff --git a/src/java.cpp b/src/java.cpp index 0f4ff0a6..81a1332e 100644 --- a/src/java.cpp +++ b/src/java.cpp @@ -6,6 +6,7 @@ #include #endif #include "javaObject.h" +#include "javaScope.h" #include "methodCallBaton.h" #include "node_NodeDynamicProxyClass.h" #include @@ -265,6 +266,7 @@ v8::Handle Java::createJVM(JavaVM** jvm, JNIEnv** env) { int argsStart = 0; int argsEnd = args.Length(); + UNUSED_VARIABLE(argsEnd); ARGS_FRONT_STRING(interfaceName); ARGS_FRONT_OBJECT(functions); @@ -402,6 +404,7 @@ v8::Handle Java::createJVM(JavaVM** jvm, JNIEnv** env) { int argsStart = 0; int argsEnd = args.Length(); + UNUSED_VARIABLE(argsEnd); // arguments ARGS_FRONT_CLASSNAME(); @@ -522,7 +525,7 @@ v8::Handle Java::createJVM(JavaVM** jvm, JNIEnv** env) { return ensureJvmResults; } JNIEnv* env = self->getJavaEnv(); - PUSH_LOCAL_JAVA_FRAME(); + JavaScope javaScope(env); int argsStart = 0; int argsEnd = args.Length(); @@ -537,7 +540,7 @@ v8::Handle Java::createJVM(JavaVM** jvm, JNIEnv** env) { if(clazz == NULL) { std::ostringstream errStr; errStr << "Could not create class " << className.c_str(); - POP_LOCAL_JAVA_FRAME_AND_RETURN(ThrowException(javaExceptionToV8(env, errStr.str()))); + return ThrowException(javaExceptionToV8(env, errStr.str())); } // get the field @@ -545,7 +548,7 @@ v8::Handle Java::createJVM(JavaVM** jvm, JNIEnv** env) { if(field == NULL) { std::ostringstream errStr; errStr << "Could not find field " << fieldName.c_str() << " on class " << className.c_str(); - POP_LOCAL_JAVA_FRAME_AND_RETURN(ThrowException(javaExceptionToV8(env, errStr.str()))); + return ThrowException(javaExceptionToV8(env, errStr.str())); } jclass fieldClazz = env->FindClass("java/lang/reflect/Field"); @@ -556,10 +559,10 @@ v8::Handle Java::createJVM(JavaVM** jvm, JNIEnv** env) { if(env->ExceptionOccurred()) { std::ostringstream errStr; errStr << "Could not get field " << fieldName.c_str() << " on class " << className.c_str(); - POP_LOCAL_JAVA_FRAME_AND_RETURN(ThrowException(javaExceptionToV8(env, errStr.str()))); + return ThrowException(javaExceptionToV8(env, errStr.str())); } - POP_LOCAL_JAVA_FRAME_AND_RETURN(scope.Close(javaToV8(self, env, val))); + return scope.Close(javaToV8(self, env, val)); } /*static*/ v8::Handle Java::setStaticFieldValue(const v8::Arguments& args) { @@ -570,7 +573,7 @@ v8::Handle Java::createJVM(JavaVM** jvm, JNIEnv** env) { return ensureJvmResults; } JNIEnv* env = self->getJavaEnv(); - PUSH_LOCAL_JAVA_FRAME(); + JavaScope javaScope(env); int argsStart = 0; int argsEnd = args.Length(); @@ -583,7 +586,7 @@ v8::Handle Java::createJVM(JavaVM** jvm, JNIEnv** env) { if(args.Length() < argsStart+1) { std::ostringstream errStr; errStr << "setStaticFieldValue requires " << (argsStart+1) << " arguments"; - POP_LOCAL_JAVA_FRAME_AND_RETURN(ThrowException(v8::Exception::TypeError(v8::String::New(errStr.str().c_str())))); + return ThrowException(v8::Exception::TypeError(v8::String::New(errStr.str().c_str()))); } jobject newValue = v8ToJava(env, args[argsStart]); argsStart++; @@ -595,7 +598,7 @@ v8::Handle Java::createJVM(JavaVM** jvm, JNIEnv** env) { if(clazz == NULL) { std::ostringstream errStr; errStr << "Could not create class " << className.c_str(); - POP_LOCAL_JAVA_FRAME_AND_RETURN(ThrowException(javaExceptionToV8(env, errStr.str()))); + return ThrowException(javaExceptionToV8(env, errStr.str())); } // get the field @@ -603,7 +606,7 @@ v8::Handle Java::createJVM(JavaVM** jvm, JNIEnv** env) { if(field == NULL) { std::ostringstream errStr; errStr << "Could not find field " << fieldName.c_str() << " on class " << className.c_str(); - POP_LOCAL_JAVA_FRAME_AND_RETURN(ThrowException(javaExceptionToV8(env, errStr.str()))); + return ThrowException(javaExceptionToV8(env, errStr.str())); } jclass fieldClazz = env->FindClass("java/lang/reflect/Field"); @@ -616,10 +619,10 @@ v8::Handle Java::createJVM(JavaVM** jvm, JNIEnv** env) { if(env->ExceptionOccurred()) { std::ostringstream errStr; errStr << "Could not set field " << fieldName.c_str() << " on class " << className.c_str(); - POP_LOCAL_JAVA_FRAME_AND_RETURN(ThrowException(javaExceptionToV8(env, errStr.str()))); + return ThrowException(javaExceptionToV8(env, errStr.str())); } - POP_LOCAL_JAVA_FRAME_AND_RETURN(v8::Undefined()); + return v8::Undefined(); } void EIO_CallJs(uv_work_t* req) { diff --git a/src/javaObject.cpp b/src/javaObject.cpp index 79ee7b80..ed6e669e 100644 --- a/src/javaObject.cpp +++ b/src/javaObject.cpp @@ -1,6 +1,7 @@ #include "javaObject.h" #include "java.h" +#include "javaScope.h" #include "utils.h" #include #include @@ -15,8 +16,7 @@ JNIEnv *env = java->getJavaEnv(); obj = env->NewGlobalRef(obj); - - PUSH_LOCAL_JAVA_FRAME(); + JavaScope javaScope(env); jclass objClazz = env->GetObjectClass(obj); jclass classClazz = env->FindClass("java/lang/Class"); @@ -77,8 +77,6 @@ JavaObject *self = new JavaObject(java, obj); self->Wrap(javaObjectObj); - POP_LOCAL_JAVA_FRAME(); - return scope.Close(javaObjectObj); } @@ -109,8 +107,7 @@ JavaObject::~JavaObject() { v8::HandleScope scope; JavaObject* self = node::ObjectWrap::Unwrap(args.This()); JNIEnv *env = self->m_java->getJavaEnv(); - - PUSH_LOCAL_JAVA_FRAME(); + JavaScope javaScope(env); v8::String::AsciiValue methodName(args.Data()); std::string methodNameStr = *methodName; @@ -122,7 +119,6 @@ JavaObject::~JavaObject() { ARGS_BACK_CALLBACK(); if(!callbackProvided && methodNameStr == "toString") { - POP_LOCAL_JAVA_FRAME(); return methodCallSync(args); } @@ -132,7 +128,6 @@ JavaObject::~JavaObject() { if(method == NULL) { std::string msg = methodNotFoundToString(env, self->m_class, methodNameStr, false, args, argsStart, argsEnd); EXCEPTION_CALL_CALLBACK(msg); - POP_LOCAL_JAVA_FRAME(); return v8::Undefined(); } @@ -140,8 +135,6 @@ JavaObject::~JavaObject() { InstanceMethodCallBaton* baton = new InstanceMethodCallBaton(self->m_java, self, method, methodArgs, callback); baton->run(); - POP_LOCAL_JAVA_FRAME(); - END_CALLBACK_FUNCTION("\"Method '" << methodNameStr << "' called without a callback did you mean to use the Sync version?\""); } @@ -149,8 +142,7 @@ JavaObject::~JavaObject() { v8::HandleScope scope; JavaObject* self = node::ObjectWrap::Unwrap(args.This()); JNIEnv *env = self->m_java->getJavaEnv(); - - PUSH_LOCAL_JAVA_FRAME(); + JavaScope javaScope(env); v8::String::AsciiValue methodName(args.Data()); std::string methodNameStr = *methodName; @@ -164,7 +156,6 @@ JavaObject::~JavaObject() { if(method == NULL) { std::string msg = methodNotFoundToString(env, self->m_class, methodNameStr, false, args, argsStart, argsEnd); v8::Handle ex = javaExceptionToV8(env, msg); - POP_LOCAL_JAVA_FRAME(); return ThrowException(ex); } @@ -174,8 +165,6 @@ JavaObject::~JavaObject() { v8::Handle result = baton->runSync(); delete baton; - POP_LOCAL_JAVA_FRAME(); - if(result->IsNativeError()) { return ThrowException(result); } @@ -187,8 +176,7 @@ JavaObject::~JavaObject() { v8::HandleScope scope; JavaObject* self = node::ObjectWrap::Unwrap(info.This()); JNIEnv *env = self->m_java->getJavaEnv(); - - PUSH_LOCAL_JAVA_FRAME(); + JavaScope javaScope(env); v8::String::AsciiValue propertyCStr(property); std::string propertyStr = *propertyCStr; @@ -197,7 +185,6 @@ JavaObject::~JavaObject() { std::ostringstream errStr; errStr << "Could not find field " << propertyStr; v8::Handle ex = javaExceptionToV8(env, errStr.str()); - POP_LOCAL_JAVA_FRAME(); return ThrowException(ex); } @@ -210,14 +197,11 @@ JavaObject::~JavaObject() { std::ostringstream errStr; errStr << "Could not get field " << propertyStr; v8::Handle ex = javaExceptionToV8(env, errStr.str()); - POP_LOCAL_JAVA_FRAME(); return ThrowException(ex); } v8::Handle result = javaToV8(self->m_java, env, val); - POP_LOCAL_JAVA_FRAME(); - return scope.Close(result); } @@ -225,8 +209,8 @@ JavaObject::~JavaObject() { v8::HandleScope scope; JavaObject* self = node::ObjectWrap::Unwrap(info.This()); JNIEnv *env = self->m_java->getJavaEnv(); + JavaScope javaScope(env); - PUSH_LOCAL_JAVA_FRAME(); jobject newValue = v8ToJava(env, value); v8::String::AsciiValue propertyCStr(property); @@ -236,7 +220,6 @@ JavaObject::~JavaObject() { std::ostringstream errStr; errStr << "Could not find field " << propertyStr; v8::Handle ex = javaExceptionToV8(env, errStr.str()); - POP_LOCAL_JAVA_FRAME(); ThrowException(ex); return; } @@ -252,10 +235,7 @@ JavaObject::~JavaObject() { std::ostringstream errStr; errStr << "Could not set field " << propertyStr; v8::Handle ex = javaExceptionToV8(env, errStr.str()); - POP_LOCAL_JAVA_FRAME(); ThrowException(ex); return; } - - POP_LOCAL_JAVA_FRAME(); } diff --git a/src/javaScope.cpp b/src/javaScope.cpp new file mode 100644 index 00000000..7074fb64 --- /dev/null +++ b/src/javaScope.cpp @@ -0,0 +1,17 @@ + +#include "javaScope.h" + +JavaScope::JavaScope(JNIEnv *env) { + m_env = env; + m_result = NULL; + m_env->PushLocalFrame(LOCAL_FRAME_SIZE); +} + +JavaScope::~JavaScope() { + m_env->PopLocalFrame(m_result); +} + +jobject JavaScope::Close(jobject result) { + m_result = result; + return m_result; +} \ No newline at end of file diff --git a/src/javaScope.h b/src/javaScope.h new file mode 100644 index 00000000..033457a5 --- /dev/null +++ b/src/javaScope.h @@ -0,0 +1,20 @@ + +#ifndef _javaScope_h_ +#define _javaScope_h_ + +#include + +#define LOCAL_FRAME_SIZE 500 + +class JavaScope { +public: + JavaScope(JNIEnv *env); + ~JavaScope(); + jobject Close(jobject result); + +private: + JNIEnv *m_env; + jobject m_result; +}; + +#endif diff --git a/src/methodCallBaton.cpp b/src/methodCallBaton.cpp index f2db1221..3bf605c6 100644 --- a/src/methodCallBaton.cpp +++ b/src/methodCallBaton.cpp @@ -124,8 +124,6 @@ void StaticMethodCallBaton::execute(JNIEnv *env) { } void InstanceMethodCallBaton::execute(JNIEnv *env) { - PUSH_LOCAL_JAVA_FRAME(); - jclass methodClazz = env->FindClass("java/lang/reflect/Method"); jmethodID method_invoke = env->GetMethodID(methodClazz, "invoke", "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;"); @@ -144,7 +142,6 @@ void InstanceMethodCallBaton::execute(JNIEnv *env) { m_error = (jthrowable)env->NewGlobalRef(err); m_errorString = "Error running instance method"; env->ExceptionClear(); - POP_LOCAL_JAVA_FRAME(); return; } @@ -154,7 +151,6 @@ void InstanceMethodCallBaton::execute(JNIEnv *env) { m_result = env->NewGlobalRef(result); env->DeleteLocalRef(result); } - POP_LOCAL_JAVA_FRAME(); } NewInstanceBaton::NewInstanceBaton( diff --git a/src/utils.cpp b/src/utils.cpp index a417a9de..38a224d7 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -397,10 +397,9 @@ v8::Handle javaArrayToV8(Java* java, JNIEnv* env, jobjectArray objArr v8::Handle javaToV8(Java* java, JNIEnv* env, jobject obj) { v8::HandleScope scope; - PUSH_LOCAL_JAVA_FRAME(); if(obj == NULL) { - POP_LOCAL_JAVA_FRAME_AND_RETURN(v8::Null()); + return v8::Null(); } jclass objClazz = env->GetObjectClass(obj); @@ -412,67 +411,65 @@ v8::Handle javaToV8(Java* java, JNIEnv* env, jobject obj) { case TYPE_ARRAY: { v8::Handle result = javaArrayToV8(java, env, (jobjectArray)obj); - POP_LOCAL_JAVA_FRAME_AND_RETURN(scope.Close(result)); + return scope.Close(result); } case TYPE_VOID: - POP_LOCAL_JAVA_FRAME_AND_RETURN(v8::Undefined()); + return v8::Undefined(); case TYPE_BOOLEAN: { jclass booleanClazz = env->FindClass("java/lang/Boolean"); jmethodID boolean_booleanValue = env->GetMethodID(booleanClazz, "booleanValue", "()Z"); bool result = env->CallBooleanMethod(obj, boolean_booleanValue); - POP_LOCAL_JAVA_FRAME_AND_RETURN(scope.Close(v8::Boolean::New(result))); + return scope.Close(v8::Boolean::New(result)); } case TYPE_BYTE: { jclass byteClazz = env->FindClass("java/lang/Byte"); jmethodID byte_byteValue = env->GetMethodID(byteClazz, "byteValue", "()B"); jbyte result = env->CallByteMethod(obj, byte_byteValue); - POP_LOCAL_JAVA_FRAME_AND_RETURN(scope.Close(v8::Number::New(result))); + return scope.Close(v8::Number::New(result)); } case TYPE_LONG: { jclass longClazz = env->FindClass("java/lang/Long"); jmethodID long_longValue = env->GetMethodID(longClazz, "longValue", "()J"); jlong result = env->CallLongMethod(obj, long_longValue); - POP_LOCAL_JAVA_FRAME_AND_RETURN(scope.Close(v8::Number::New(result))); + return scope.Close(v8::Number::New(result)); } case TYPE_INT: { jclass integerClazz = env->FindClass("java/lang/Integer"); jmethodID integer_intValue = env->GetMethodID(integerClazz, "intValue", "()I"); jint result = env->CallIntMethod(obj, integer_intValue); - POP_LOCAL_JAVA_FRAME_AND_RETURN(scope.Close(v8::Integer::New(result))); + return scope.Close(v8::Integer::New(result)); } case TYPE_DOUBLE: { jclass doubleClazz = env->FindClass("java/lang/Double"); jmethodID double_doubleValue = env->GetMethodID(doubleClazz, "doubleValue", "()D"); jdouble result = env->CallDoubleMethod(obj, double_doubleValue); - POP_LOCAL_JAVA_FRAME_AND_RETURN(scope.Close(v8::Number::New(result))); + return scope.Close(v8::Number::New(result)); } case TYPE_FLOAT: { jclass floatClazz = env->FindClass("java/lang/Float"); jmethodID float_floatValue = env->GetMethodID(floatClazz, "floatValue", "()F"); jfloat result = env->CallFloatMethod(obj, float_floatValue); - POP_LOCAL_JAVA_FRAME_AND_RETURN(scope.Close(v8::Number::New(result))); + return scope.Close(v8::Number::New(result)); } case TYPE_STRING: - POP_LOCAL_JAVA_FRAME_AND_RETURN(scope.Close(v8::String::New(javaObjectToString(env, obj).c_str()))); + return scope.Close(v8::String::New(javaObjectToString(env, obj).c_str())); case TYPE_OBJECT: - POP_LOCAL_JAVA_FRAME_AND_RETURN(scope.Close(JavaObject::New(java, obj))); + return scope.Close(JavaObject::New(java, obj)); default: printf("javaToV8: unhandled type: 0x%03x\n", resultType); - POP_LOCAL_JAVA_FRAME_AND_RETURN(scope.Close(JavaObject::New(java, obj))); + return scope.Close(JavaObject::New(java, obj)); } - POP_LOCAL_JAVA_FRAME_AND_RETURN(v8::Undefined()); + return v8::Undefined(); } jobjectArray javaObjectArrayToClasses(JNIEnv *env, jobjectArray objs) { - PUSH_LOCAL_JAVA_FRAME(); - jclass clazzClazz = env->FindClass("java/lang/Class"); jsize objsLength = env->GetArrayLength(objs); jobjectArray results = env->NewObjectArray(objsLength, clazzClazz, NULL); @@ -486,12 +483,10 @@ jobjectArray javaObjectArrayToClasses(JNIEnv *env, jobjectArray objs) { } } - POP_LOCAL_JAVA_FRAME_AND_RETURN_JAVA(results); + return results; } jobject javaFindMethod(JNIEnv *env, jclass clazz, std::string& methodName, jobjectArray methodArgs) { - PUSH_LOCAL_JAVA_FRAME(); - jclass methodUtilsClazz = env->FindClass("com/nearinfinity/org/apache/commons/lang3/reflect/MethodUtils"); jmethodID methodUtils_getMatchingAccessibleMethod = env->GetStaticMethodID(methodUtilsClazz, "getMatchingAccessibleMethod", "(Ljava/lang/Class;Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;"); const char *methodNameCStr = methodName.c_str(); @@ -499,7 +494,7 @@ jobject javaFindMethod(JNIEnv *env, jclass clazz, std::string& methodName, jobje jobjectArray methodArgClasses = javaObjectArrayToClasses(env, methodArgs); jobject method = env->CallStaticObjectMethod(methodUtilsClazz, methodUtils_getMatchingAccessibleMethod, clazz, methodNameJavaStr, methodArgClasses); - POP_LOCAL_JAVA_FRAME_AND_RETURN_JAVA(method); + return method; } jobject javaFindConstructor(JNIEnv *env, jclass clazz, jobjectArray methodArgs) { diff --git a/src/utils.h b/src/utils.h index d22d4c9c..358252a0 100644 --- a/src/utils.h +++ b/src/utils.h @@ -39,8 +39,6 @@ struct DynamicProxyData { unsigned int markerEnd; }; -#define LOCAL_FRAME_SIZE 500 - #define DYNAMIC_PROXY_DATA_MARKER_START 0x12345678 #define DYNAMIC_PROXY_DATA_MARKER_END 0x87654321 @@ -127,18 +125,8 @@ std::string methodNotFoundToString(JNIEnv *env, jclass clazz, std::string method return scope.Close(v8::String::New(str.str().c_str())); \ } -#define PUSH_LOCAL_JAVA_FRAME() \ - env->PushLocalFrame(LOCAL_FRAME_SIZE); - -#define POP_LOCAL_JAVA_FRAME() \ - env->PopLocalFrame(NULL); - -#define POP_LOCAL_JAVA_FRAME_AND_RETURN(r) \ - env->PopLocalFrame(NULL); \ - return r; - -#define POP_LOCAL_JAVA_FRAME_AND_RETURN_JAVA(r) \ - env->PopLocalFrame(r); \ - return r; +#ifndef UNUSED_VARIABLE + #define UNUSED_VARIABLE(a) a = a; +#endif #endif