+static void Cycript_delete(JNIEnv *env, jclass api, jlong jprotect) { CYJavaTry {
+ delete &protect;
+} CYJavaCatch() }
+
+static jobject Cycript_handle(JNIEnv *env, jclass api, jlong jprotect, jstring property, jobjectArray jarguments) { CYJavaTry {
+ JSValueRef function(CYGetProperty(context, object, CYJSString(CYJavaRef<jstring>(jni, property))));
+ if (JSValueIsUndefined(context, function))
+ return NULL;
+
+ size_t count(jarguments == NULL ? 0 : jni.GetArrayLength(jarguments));
+ JSValueRef arguments[count];
+ for (size_t index(0); index != count; ++index)
+ arguments[index] = CYCastJSValue(context, jni.GetObjectArrayElement<jobject>(jarguments, index));
+
+ return CYCastJavaObject(jni, context, CYCallAsFunction(context, CYCastJSObject(context, function), object, count, arguments)).leak();
+} CYJavaCatch(NULL) }
+
+static JNINativeMethod Cycript_[] = {
+ {(char *) "delete", (char *) "(J)V", (void *) &Cycript_delete},
+ {(char *) "handle", (char *) "(JLjava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;", (void *) &Cycript_handle},
+};
+
+JNIEnv *GetJNI(JSContextRef context) {
+ static JavaVM *jvm(NULL);
+ static JNIEnv *jni(NULL);
+
+ if (jni != NULL)
+ return jni;
+ jint version(JNI_VERSION_1_4);
+
+ jsize capacity(16);
+ JavaVM *jvms[capacity];
+ jsize size;
+ _jnicall(JNI_GetCreatedJavaVMs(jvms, capacity, &size));
+
+ if (size != 0) {
+ jvm = jvms[0];
+ _jnicall(jvm->GetEnv(reinterpret_cast<void **>(&jni), version));
+ } else {
+ CYPool pool;
+ std::vector<JavaVMOption> options;
+
+ {
+ std::ostringstream option;
+ option << "-Djava.class.path=";
+ option << CYPoolLibraryPath(pool) << "/libcycript.jar";
+ if (const char *classpath = getenv("CLASSPATH"))
+ option << ':' << classpath;
+ options.push_back(JavaVMOption{pool.strdup(option.str().c_str()), NULL});
+ }
+
+ JavaVMInitArgs args;
+ memset(&args, 0, sizeof(args));
+ args.version = version;
+ args.nOptions = options.size();
+ args.options = options.data();
+ _jnicall(JNI_CreateJavaVM(&jvm, reinterpret_cast<void **>(&jni), &args));
+ }
+
+ auto Cycript$(CYJavaEnv(jni).FindClass("Cycript"));
+ _envcall(jni, RegisterNatives(Cycript$, Cycript_, sizeof(Cycript_) / sizeof(Cycript_[0])));
+
+ return jni;
+}
+