|
13 | 13 | #include <sstream> |
14 | 14 | #include <nan.h> |
15 | 15 |
|
| 16 | +#define DYNAMIC_PROXY_NO_SUCH_METHOD_ERROR -1 |
| 17 | +#define DYNAMIC_PROXY_NOT_A_FUNCTION_ERROR -2 |
| 18 | +#define DYNAMIC_PROXY_NO_ENV_ERROR -3 |
| 19 | + |
16 | 20 | long v8ThreadId; |
17 | 21 |
|
18 | 22 | /*static*/ v8::Persistent<v8::FunctionTemplate> Java::s_ct; |
@@ -1010,60 +1014,67 @@ void EIO_AfterCallJs(uv_work_t* req) { |
1010 | 1014 | int ret = dynamicProxyData->java->getJvm()->GetEnv((void**)&env, JNI_VERSION_1_6); |
1011 | 1015 | if (ret != JNI_OK) { |
1012 | 1016 | printf("ERROR: jvm->GetEnv returned %d\n", ret); |
1013 | | - goto CleanUp; |
| 1017 | + dynamicProxyData->done = DYNAMIC_PROXY_NO_ENV_ERROR; |
| 1018 | + return; |
1014 | 1019 | } |
1015 | 1020 |
|
1016 | | - { |
1017 | | - NanScope(); |
1018 | | - v8::Array* v8Args; |
1019 | | - v8::Function* fn; |
1020 | | - v8::Handle<v8::Value>* argv; |
1021 | | - int argc; |
1022 | | - int i; |
1023 | | - v8::Local<v8::Value> v8Result; |
1024 | | - jobject javaResult; |
1025 | | - |
1026 | | - v8::Local<v8::Object> dynamicProxyDataFunctions = NanNew(dynamicProxyData->functions); |
1027 | | - v8::Local<v8::Value> fnObj = dynamicProxyDataFunctions->Get(NanNew<v8::String>(dynamicProxyData->methodName.c_str())); |
1028 | | - if(fnObj->IsUndefined() || fnObj->IsNull()) { |
1029 | | - printf("ERROR: Could not find method %s\n", dynamicProxyData->methodName.c_str()); |
1030 | | - goto CleanUp; |
1031 | | - } |
1032 | | - if(!fnObj->IsFunction()) { |
1033 | | - printf("ERROR: %s is not a function.\n", dynamicProxyData->methodName.c_str()); |
1034 | | - goto CleanUp; |
1035 | | - } |
1036 | | - |
1037 | | - fn = v8::Function::Cast(*fnObj); |
1038 | | - |
1039 | | - if(dynamicProxyData->args) { |
1040 | | - v8Args = v8::Array::Cast(*javaArrayToV8(dynamicProxyData->java, env, dynamicProxyData->args)); |
1041 | | - argc = v8Args->Length(); |
1042 | | - } else { |
1043 | | - argc = 0; |
1044 | | - } |
1045 | | - argv = new v8::Handle<v8::Value>[argc]; |
1046 | | - for(i=0; i<argc; i++) { |
1047 | | - argv[i] = v8Args->Get(i); |
1048 | | - } |
1049 | | - v8Result = fn->Call(dynamicProxyDataFunctions, argc, argv); |
1050 | | - delete[] argv; |
1051 | | - if(!dynamicProxyDataVerify(dynamicProxyData)) { |
1052 | | - return; |
1053 | | - } |
1054 | | - |
1055 | | - javaResult = v8ToJava(env, v8Result); |
1056 | | - if(javaResult == NULL) { |
1057 | | - dynamicProxyData->result = NULL; |
1058 | | - } else { |
1059 | | - dynamicProxyData->result = env->NewGlobalRef(javaResult); |
1060 | | - } |
| 1021 | + NanScope(); |
| 1022 | + v8::Array* v8Args; |
| 1023 | + v8::Function* fn; |
| 1024 | + v8::Handle<v8::Value>* argv; |
| 1025 | + int argc; |
| 1026 | + int i; |
| 1027 | + v8::Local<v8::Value> v8Result; |
| 1028 | + jobject javaResult; |
| 1029 | + |
| 1030 | + v8::Local<v8::Object> dynamicProxyDataFunctions = NanNew(dynamicProxyData->functions); |
| 1031 | + v8::Local<v8::Value> fnObj = dynamicProxyDataFunctions->Get(NanNew<v8::String>(dynamicProxyData->methodName.c_str())); |
| 1032 | + if(fnObj->IsUndefined() || fnObj->IsNull()) { |
| 1033 | + dynamicProxyData->done = DYNAMIC_PROXY_NO_SUCH_METHOD_ERROR; |
| 1034 | + return; |
| 1035 | + } |
| 1036 | + if(!fnObj->IsFunction()) { |
| 1037 | + dynamicProxyData->done = DYNAMIC_PROXY_NOT_A_FUNCTION_ERROR; |
| 1038 | + return; |
| 1039 | + } |
| 1040 | + |
| 1041 | + fn = v8::Function::Cast(*fnObj); |
| 1042 | + |
| 1043 | + if(dynamicProxyData->args) { |
| 1044 | + v8Args = v8::Array::Cast(*javaArrayToV8(dynamicProxyData->java, env, dynamicProxyData->args)); |
| 1045 | + argc = v8Args->Length(); |
| 1046 | + } else { |
| 1047 | + argc = 0; |
| 1048 | + } |
| 1049 | + argv = new v8::Handle<v8::Value>[argc]; |
| 1050 | + for(i=0; i<argc; i++) { |
| 1051 | + argv[i] = v8Args->Get(i); |
| 1052 | + } |
| 1053 | + v8Result = fn->Call(dynamicProxyDataFunctions, argc, argv); |
| 1054 | + delete[] argv; |
| 1055 | + if(!dynamicProxyDataVerify(dynamicProxyData)) { |
| 1056 | + return; |
| 1057 | + } |
| 1058 | + |
| 1059 | + javaResult = v8ToJava(env, v8Result); |
| 1060 | + if(javaResult == NULL) { |
| 1061 | + dynamicProxyData->result = NULL; |
| 1062 | + } else { |
| 1063 | + dynamicProxyData->result = env->NewGlobalRef(javaResult); |
1061 | 1064 | } |
1062 | 1065 |
|
1063 | | -CleanUp: |
1064 | 1066 | dynamicProxyData->done = true; |
1065 | 1067 | } |
1066 | 1068 |
|
| 1069 | +void throwNewThrowable(JNIEnv* env, const char * excClassName, std::string msg) { |
| 1070 | + jclass newExcCls = env->FindClass(excClassName); |
| 1071 | + jthrowable throwable = env->ExceptionOccurred(); |
| 1072 | + if (throwable != NULL) { |
| 1073 | + env->Throw(throwable); // this should only be Errors, according to the docs |
| 1074 | + } |
| 1075 | + env->ThrowNew(newExcCls, msg.c_str()); |
| 1076 | +} |
| 1077 | + |
1067 | 1078 | JNIEXPORT jobject JNICALL Java_node_NodeDynamicProxyClass_callJs(JNIEnv *env, jobject src, jlong ptr, jobject method, jobjectArray args) { |
1068 | 1079 | long myThreadId = my_getThreadId(); |
1069 | 1080 | bool hasArgsGlobalRef = false; |
@@ -1102,12 +1113,24 @@ JNIEXPORT jobject JNICALL Java_node_NodeDynamicProxyClass_callJs(JNIEnv *env, jo |
1102 | 1113 | } |
1103 | 1114 |
|
1104 | 1115 | if(!dynamicProxyDataVerify(dynamicProxyData)) { |
1105 | | - return NULL; |
| 1116 | + throwNewThrowable(env, "java/lang/IllegalStateException", "dynamicProxyData was corrupted"); |
1106 | 1117 | } |
1107 | 1118 | if(hasArgsGlobalRef) { |
1108 | 1119 | env->DeleteGlobalRef(dynamicProxyData->args); |
1109 | 1120 | } |
1110 | 1121 |
|
| 1122 | + switch (dynamicProxyData->done) { |
| 1123 | + case DYNAMIC_PROXY_NO_SUCH_METHOD_ERROR: |
| 1124 | + throwNewThrowable(env, "java/lang/NoSuchMethodError", "Could not find js function " + dynamicProxyData->methodName); |
| 1125 | + break; |
| 1126 | + case DYNAMIC_PROXY_NOT_A_FUNCTION_ERROR: |
| 1127 | + throwNewThrowable(env, "java/lang/IllegalStateException", dynamicProxyData->methodName + " is not a function"); |
| 1128 | + break; |
| 1129 | + case DYNAMIC_PROXY_NO_ENV_ERROR: |
| 1130 | + throwNewThrowable(env, "java/lang/IllegalStateException", "Could not retrieve JNIEnv"); |
| 1131 | + break; |
| 1132 | + } |
| 1133 | + |
1111 | 1134 | jobject result = NULL; |
1112 | 1135 | if(dynamicProxyData->result) { |
1113 | 1136 | // need to retain a local ref so that we can return it, otherwise the returned object gets corrupted |
|
0 commit comments