JNIEXPORT jobject JNICALL Java_com_squareup_duktape_Duktape_call(JNIEnv *env, jclass type, jlong context, jlong instance, jobject method, jobjectArray args) { // Validate our DuktapeContext first - if the context is null, we can't use the proxy. DuktapeContext* duktape = reinterpret_cast<DuktapeContext*>(context); if (duktape == nullptr) { queueNullPointerException(env, "Null Duktape context - did you close your Duktape?"); return nullptr; } const JavaScriptObject* object = reinterpret_cast<const JavaScriptObject*>(instance); if (object == nullptr) { queueNullPointerException(env, "Invalid JavaScript object"); return nullptr; } try { return object->call(env, method, args); } catch (const std::invalid_argument& e) { queueIllegalArgumentException(env, e.what()); } catch (const std::exception& e) { queueDuktapeException(env, e.what()); } return nullptr; }
jobject JavaScriptObject::call(JNIEnv* env, jobject method, jobjectArray args) const { CHECK_STACK(m_context); if (m_instance == nullptr) { queueDuktapeException(env, "JavaScript object " + m_name + " has been garbage collected"); return nullptr; } const auto methodIter = m_methods.find(env->FromReflectedMethod(method)); if (methodIter != m_methods.end()) { return methodIter->second(env, m_context, m_instance, args); } // Failed to find the method in our map - should be impossible! const jclass methodClass = env->GetObjectClass(method); const jmethodID getName = env->GetMethodID(methodClass, "getName", "()Ljava/lang/String;"); const JString methodName(env, static_cast<jstring>(env->CallObjectMethod(method, getName))); queueDuktapeException(env, "Could not find method " + m_name + "." + methodName.str()); return nullptr; }
JNIEXPORT void JNICALL Java_com_squareup_duktape_Duktape_bind(JNIEnv *env, jclass type, jlong context, jstring name, jobject object, jobjectArray methods) { DuktapeContext* duktape = reinterpret_cast<DuktapeContext*>(context); if (duktape == nullptr) { queueNullPointerException(env, "Null Duktape context - did you close your Duktape?"); return; } try { duktape->bind(env, name, object, methods); } catch (const std::runtime_error& e) { queueDuktapeException(env, e.what()); } }
JNIEXPORT jstring JNICALL Java_com_squareup_duktape_Duktape_evaluate__JLjava_lang_String_2Ljava_lang_String_2( JNIEnv* env, jclass type, jlong context, jstring code, jstring fname) { DuktapeContext* duktape = reinterpret_cast<DuktapeContext*>(context); if (duktape == nullptr) { queueNullPointerException(env, "Null Duktape context - did you close your Duktape?"); return nullptr; } try { return duktape->evaluate(env, code, fname); } catch (const std::runtime_error& e) { queueDuktapeException(env, e.what()); } return nullptr; }
JNIEXPORT void JNICALL Java_com_squareup_duktape_Duktape_set(JNIEnv *env, jclass type, jlong context, jstring name, jobject object, jobjectArray methods) { DuktapeContext* duktape = reinterpret_cast<DuktapeContext*>(context); if (duktape == nullptr) { queueNullPointerException(env, "Null Duktape context - did you close your Duktape?"); return; } try { duktape->set(env, name, object, methods); } catch (const std::invalid_argument& e) { queueIllegalArgumentException(env, e.what()); } catch (const std::exception& e) { queueDuktapeException(env, e.what()); } }
JNIEXPORT jlong JNICALL Java_com_squareup_duktape_Duktape_proxy(JNIEnv *env, jclass type, jlong context, jstring name, jobjectArray methods) { DuktapeContext* duktape = reinterpret_cast<DuktapeContext*>(context); if (duktape == nullptr) { queueNullPointerException(env, "Null Duktape context - did you close your Duktape?"); return 0L; } try { return reinterpret_cast<jlong>(duktape->proxy(env, name, methods)); } catch (const std::invalid_argument& e) { queueIllegalArgumentException(env, e.what()); } catch (const std::runtime_error& e) { queueDuktapeException(env, e.what()); } return 0L; }