|
6 | 6 | #include "node_NodeDynamicProxyClass.h" |
7 | 7 | #include <sstream> |
8 | 8 |
|
| 9 | +std::string nativeBindingLocation; |
| 10 | +int v8ThreadId; |
| 11 | + |
9 | 12 | /*static*/ v8::Persistent<v8::FunctionTemplate> Java::s_ct; |
10 | 13 |
|
| 14 | +void my_sleep(int dur) { |
| 15 | +#ifdef WINDOWS |
| 16 | + Sleep(dur); |
| 17 | +#else |
| 18 | + usleep(dur); |
| 19 | +#endif |
| 20 | +} |
| 21 | + |
| 22 | +int my_getThreadId() { |
| 23 | +#ifdef WINDOWS |
| 24 | + return (int)GetCurrentThreadId(); |
| 25 | +#else |
| 26 | + return (int)pthread_self(); |
| 27 | +#endif |
| 28 | +} |
| 29 | + |
11 | 30 | /*static*/ void Java::Init(v8::Handle<v8::Object> target) { |
12 | 31 | v8::HandleScope scope; |
13 | 32 |
|
| 33 | + v8ThreadId = my_getThreadId(); |
| 34 | + |
14 | 35 | v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(New); |
15 | 36 | s_ct = v8::Persistent<v8::FunctionTemplate>::New(t); |
16 | 37 | s_ct->InstanceTemplate()->SetInternalFieldCount(1); |
17 | 38 | s_ct->SetClassName(v8::String::NewSymbol("Java")); |
18 | 39 |
|
19 | 40 | NODE_SET_PROTOTYPE_METHOD(s_ct, "newInstance", newInstance); |
20 | 41 | NODE_SET_PROTOTYPE_METHOD(s_ct, "newInstanceSync", newInstanceSync); |
21 | | - NODE_SET_PROTOTYPE_METHOD(s_ct, "newDynamicProxy", newDynamicProxy); |
| 42 | + NODE_SET_PROTOTYPE_METHOD(s_ct, "newProxy", newProxy); |
22 | 43 | NODE_SET_PROTOTYPE_METHOD(s_ct, "callStaticMethod", callStaticMethod); |
23 | 44 | NODE_SET_PROTOTYPE_METHOD(s_ct, "callStaticMethodSync", callStaticMethodSync); |
24 | 45 | NODE_SET_PROTOTYPE_METHOD(s_ct, "findClassSync", findClassSync); |
|
38 | 59 |
|
39 | 60 | self->handle_->Set(v8::String::New("classpath"), v8::Array::New()); |
40 | 61 | self->handle_->Set(v8::String::New("options"), v8::Array::New()); |
| 62 | + self->handle_->Set(v8::String::New("nativeBindingLocation"), v8::String::New("Not Set")); |
41 | 63 |
|
42 | 64 | return args.This(); |
43 | 65 | } |
@@ -89,6 +111,11 @@ v8::Handle<v8::Value> Java::createJVM(JavaVM** jvm, JNIEnv** env) { |
89 | 111 | classPath << *arrayItemStr; |
90 | 112 | } |
91 | 113 |
|
| 114 | + // set the native binding location |
| 115 | + v8::Local<v8::Value> v8NativeBindingLocation = handle_->Get(v8::String::New("nativeBindingLocation")); |
| 116 | + v8::String::AsciiValue nativeBindingLocationStr(v8NativeBindingLocation); |
| 117 | + nativeBindingLocation = *nativeBindingLocationStr; |
| 118 | + |
92 | 119 | // get other options |
93 | 120 | v8::Local<v8::Value> optionsValue = handle_->Get(v8::String::New("options")); |
94 | 121 | if(!optionsValue->IsArray()) { |
@@ -202,7 +229,7 @@ v8::Handle<v8::Value> Java::createJVM(JavaVM** jvm, JNIEnv** env) { |
202 | 229 | return scope.Close(result); |
203 | 230 | } |
204 | 231 |
|
205 | | -/*static*/ v8::Handle<v8::Value> Java::newDynamicProxy(const v8::Arguments& args) { |
| 232 | +/*static*/ v8::Handle<v8::Value> Java::newProxy(const v8::Arguments& args) { |
206 | 233 | v8::HandleScope scope; |
207 | 234 | Java* self = node::ObjectWrap::Unwrap<Java>(args.This()); |
208 | 235 | v8::Handle<v8::Value> ensureJvmResults = self->ensureJvm(); |
@@ -232,9 +259,10 @@ v8::Handle<v8::Value> Java::createJVM(JavaVM** jvm, JNIEnv** env) { |
232 | 259 | } |
233 | 260 |
|
234 | 261 | // find constructor |
235 | | - jclass objectClazz = env->FindClass("java/lang/Integer"); |
236 | | - jobjectArray methodArgs = env->NewObjectArray(1, objectClazz, NULL); |
237 | | - env->SetObjectArrayElement(methodArgs, 0, v8ToJava(env, v8::Integer::New((int)dynamicProxyData))); |
| 262 | + jclass objectClazz = env->FindClass("java/lang/Object"); |
| 263 | + jobjectArray methodArgs = env->NewObjectArray(2, objectClazz, NULL); |
| 264 | + env->SetObjectArrayElement(methodArgs, 0, v8ToJava(env, v8::String::New(nativeBindingLocation.c_str()))); |
| 265 | + env->SetObjectArrayElement(methodArgs, 1, v8ToJava(env, v8::Integer::New((int)dynamicProxyData))); |
238 | 266 | jobject method = javaFindConstructor(env, clazz, methodArgs); |
239 | 267 | if(method == NULL) { |
240 | 268 | std::ostringstream errStr; |
@@ -565,31 +593,71 @@ v8::Handle<v8::Value> Java::createJVM(JavaVM** jvm, JNIEnv** env) { |
565 | 593 | return v8::Undefined(); |
566 | 594 | } |
567 | 595 |
|
568 | | -JNIEXPORT jobject JNICALL Java_node_NodeDynamicProxyClass_callJs(JNIEnv *env, jobject src, jint ptr, jobject method, jobjectArray args) { |
569 | | - v8::HandleScope scope; |
| 596 | +void EIO_CallJs(uv_work_t* req) { |
| 597 | +} |
570 | 598 |
|
571 | | - DynamicProxyData* dynamicProxyData = (DynamicProxyData*)ptr; |
572 | | - jclass methodClazz = env->FindClass("java/lang/reflect/Method"); |
573 | | - jmethodID method_getName = env->GetMethodID(methodClazz, "getName", "()Ljava/lang/String;"); |
574 | | - std::string methodName = javaObjectToString(env, env->CallObjectMethod(method, method_getName)); |
| 599 | +void EIO_AfterCallJs(uv_work_t* req) { |
| 600 | + DynamicProxyData* dynamicProxyData = static_cast<DynamicProxyData*>(req->data); |
| 601 | + |
| 602 | + JNIEnv* env = dynamicProxyData->env; |
575 | 603 |
|
576 | | - v8::Local<v8::Value> fnObj = dynamicProxyData->functions->Get(v8::String::New(methodName.c_str())); |
| 604 | + v8::HandleScope scope; |
| 605 | + v8::Array* v8Args; |
| 606 | + v8::Function* fn; |
| 607 | + v8::Handle<v8::Value>* argv; |
| 608 | + int argc; |
| 609 | + int i; |
| 610 | + v8::Local<v8::Value> v8Result; |
| 611 | + |
| 612 | + v8::Local<v8::Value> fnObj = dynamicProxyData->functions->Get(v8::String::New(dynamicProxyData->methodName.c_str())); |
577 | 613 | if(fnObj->IsUndefined() || fnObj->IsNull()) { |
578 | | - printf("ERROR: Could not find method %s", methodName.c_str()); |
| 614 | + printf("ERROR: Could not find method %s", dynamicProxyData->methodName.c_str()); |
| 615 | + goto CleanUp; |
579 | 616 | } |
580 | 617 | if(!fnObj->IsFunction()) { |
581 | | - printf("ERROR: %s is not a function.", methodName.c_str()); |
| 618 | + printf("ERROR: %s is not a function.", dynamicProxyData->methodName.c_str()); |
| 619 | + goto CleanUp; |
582 | 620 | } |
583 | | - v8::Function* fn = v8::Function::Cast(*fnObj); |
| 621 | + fn = v8::Function::Cast(*fnObj); |
584 | 622 |
|
585 | | - v8::Array* v8Args = v8::Array::Cast(*javaArrayToV8(dynamicProxyData->java, env, args)); |
586 | | - int argc = v8Args->Length(); |
587 | | - v8::Handle<v8::Value>* argv = new v8::Handle<v8::Value>[argc]; |
588 | | - for(int i=0; i<argc; i++) { |
| 623 | + v8Args = v8::Array::Cast(*javaArrayToV8(dynamicProxyData->java, env, dynamicProxyData->args)); |
| 624 | + argc = v8Args->Length(); |
| 625 | + argv = new v8::Handle<v8::Value>[argc]; |
| 626 | + for(i=0; i<argc; i++) { |
589 | 627 | argv[i] = v8Args->Get(i); |
590 | 628 | } |
591 | | - v8::Local<v8::Value> result = fn->Call(dynamicProxyData->functions, argc, argv); |
| 629 | + v8Result = fn->Call(dynamicProxyData->functions, argc, argv); |
592 | 630 | delete[] argv; |
593 | 631 |
|
594 | | - return v8ToJava(env, result); |
| 632 | + dynamicProxyData->result = v8ToJava(env, v8Result); |
| 633 | + |
| 634 | +CleanUp: |
| 635 | + dynamicProxyData->done = true; |
| 636 | +} |
| 637 | + |
| 638 | +JNIEXPORT jobject JNICALL Java_node_NodeDynamicProxyClass_callJs(JNIEnv *env, jobject src, jint ptr, jobject method, jobjectArray args) { |
| 639 | + int myThreadId = my_getThreadId(); |
| 640 | + |
| 641 | + DynamicProxyData* dynamicProxyData = (DynamicProxyData*)ptr; |
| 642 | + dynamicProxyData->env = env; |
| 643 | + dynamicProxyData->args = args; |
| 644 | + dynamicProxyData->done = false; |
| 645 | + |
| 646 | + jclass methodClazz = env->FindClass("java/lang/reflect/Method"); |
| 647 | + jmethodID method_getName = env->GetMethodID(methodClazz, "getName", "()Ljava/lang/String;"); |
| 648 | + dynamicProxyData->methodName = javaObjectToString(env, env->CallObjectMethod(method, method_getName)); |
| 649 | + |
| 650 | + uv_work_t* req = new uv_work_t(); |
| 651 | + req->data = dynamicProxyData; |
| 652 | + if(myThreadId == v8ThreadId) { |
| 653 | + EIO_AfterCallJs(req); |
| 654 | + } else { |
| 655 | + uv_queue_work(uv_default_loop(), req, EIO_CallJs, EIO_AfterCallJs); |
| 656 | + |
| 657 | + while(!dynamicProxyData->done) { |
| 658 | + my_sleep(100); |
| 659 | + } |
| 660 | + } |
| 661 | + |
| 662 | + return dynamicProxyData->result; |
595 | 663 | } |
0 commit comments