X-Git-Url: https://git.saurik.com/cycript.git/blobdiff_plain/477549f502f5350425ab6547564852bcfd6940ae..5154ab8dbb5374da04cd9f8e2004279700a40881:/Java/Execute.cpp diff --git a/Java/Execute.cpp b/Java/Execute.cpp index bca2e98..2156045 100644 --- a/Java/Execute.cpp +++ b/Java/Execute.cpp @@ -97,6 +97,15 @@ CYJavaForEachPrimitive #undef CYJavaForEachPrimitive_ }; +template +struct IsJavaPrimitive { static const bool value = false; }; + +#define CYJavaForEachPrimitive_(T, t, Typ, Type, type) \ + template <> \ + struct IsJavaPrimitive { static const bool value = true; }; +CYJavaForEachPrimitive +#undef CYJavaForEachPrimitive_ + // Java References {{{ template struct CYJavaRef { @@ -117,6 +126,7 @@ struct CYJavaRef { return jni_; } + // XXX: this is only needed to support CYJavaEnv relying on C variadics _finline Value_ get() const { return value_; } @@ -126,6 +136,7 @@ struct CYJavaRef { return {jni_, static_cast(value_)}; } + // XXX: this should be tied into CYJavaFrame Value_ leak() { Value_ value(value_); value_ = NULL; @@ -142,9 +153,14 @@ struct CYJavaDelete : { } - ~CYJavaDelete() { + void clear() { if (this->value_ != NULL) (this->jni_->*Delete_)(this->value_); + this->value_ = NULL; + } + + ~CYJavaDelete() { + clear(); } }; @@ -199,15 +215,24 @@ struct CYJavaLocal : { } - CYJavaLocal(CYJavaLocal &&value) : - CYJavaLocal(value.jni_, value.value_) + template + CYJavaLocal(CYJavaRef &&other) : + CYJavaLocal(other.jni_, other.value_) { - value.value_ = NULL; + other.value_ = NULL; } - CYJavaLocal &operator =(CYJavaLocal &&other) { - std::swap(this->jni_, other.jni_); - std::swap(this->value_, other.value_); + CYJavaLocal(CYJavaLocal &&other) : + CYJavaLocal(static_cast &&>(other)) + { + } + + template + CYJavaLocal &operator =(CYJavaLocal &&other) { + this->clear(); + this->jni_ = other.jni_; + this->value_ = other.value_; + other.value_ = NULL; return *this; } }; @@ -292,6 +317,10 @@ struct CYJavaFrame { operator ()(NULL); } + operator JNIEnv *() const { + return jni_; + } + jobject operator ()(jobject object) { JNIEnv *jni(jni_); jni_ = NULL; @@ -375,7 +404,7 @@ CYJavaForEachPrimitive #define CYJavaEnv_(Code) \ template \ - auto Code(Args_ &&... args) const -> decltype(jni->Code(args...)) { \ + auto Code(Args_ &&... args) const -> decltype(jni->Code(cy::Forward(args)...)) { \ return _envcall(jni, Code(cy::Forward(args)...)); \ } @@ -855,7 +884,9 @@ CYJavaForEachPrimitive } } -static bool CYCastJavaArguments(const CYJavaEnv &jni, const CYJavaShorty &shorty, JSContextRef context, const JSValueRef arguments[], jvalue *array) { +static bool CYCastJavaArguments(const CYJavaFrame &frame, const CYJavaShorty &shorty, JSContextRef context, const JSValueRef arguments[], jvalue *array) { + CYJavaEnv jni(frame); + for (size_t index(0); index != shorty.size(); ++index) { JSValueRef argument(arguments[index]); JSType type(JSValueGetType(context, argument)); @@ -863,6 +894,7 @@ static bool CYCastJavaArguments(const CYJavaEnv &jni, const CYJavaShorty &shorty switch (CYJavaPrimitive primitive = shorty[index]) { case CYJavaPrimitiveObject: + // XXX: figure out a way to tie this in to the CYJavaFrame value.l = CYCastJavaObject(jni, context, argument).leak(); break; @@ -912,9 +944,9 @@ static JSValueRef JavaMethod_callAsFunction(JSContextRef context, JSObjectRef ob CYJavaSignature bound(count); for (auto overload(internal->overload_.lower_bound(bound)), e(internal->overload_.upper_bound(bound)); overload != e; ++overload) { - CYJavaFrame(jni, count + 16); + CYJavaFrame frame(jni, count + 16); jvalue array[count]; - if (!CYCastJavaArguments(jni, overload->shorty_, context, arguments, array)) + if (!CYCastJavaArguments(frame, overload->shorty_, context, arguments, array)) continue; jvalue *values(array); switch (overload->primitive_) { @@ -942,9 +974,9 @@ static JSValueRef JavaStaticMethod_callAsFunction(JSContextRef context, JSObject CYJavaSignature bound(count); for (auto overload(internal->overload_.lower_bound(bound)), e(internal->overload_.upper_bound(bound)); overload != e; ++overload) { - CYJavaFrame(jni, count + 16); + CYJavaFrame frame(jni, count + 16); jvalue array[count]; - if (!CYCastJavaArguments(jni, overload->shorty_, context, arguments, array)) + if (!CYCastJavaArguments(frame, overload->shorty_, context, arguments, array)) continue; jvalue *values(array); switch (overload->primitive_) { @@ -971,18 +1003,16 @@ static JSObjectRef JavaClass_callAsConstructor(JSContextRef context, JSObjectRef jclass _class(table->value_); if (table->interface_ && count == 1) { - JSObjectRef target(CYCastJSObject(context, arguments[0])); auto Cycript$(jni.FindClass("Cycript")); - auto Cycript$Make(jni.GetStaticMethodID(Cycript$, "proxy", "(Ljava/lang/Class;J)Ljava/lang/Object;")); - auto protect(new CYProtect(context, target)); - return CYCastJSObject(context, jni.CallObjectMethod(Cycript$, Cycript$Make, _class, reinterpret_cast(protect))); + auto Cycript$Make(jni.GetStaticMethodID(Cycript$, "proxy", "(Ljava/lang/Class;LCycript$Wrapper;)Ljava/lang/Object;")); + return CYCastJSObject(context, jni.CallObjectMethod(Cycript$, Cycript$Make, _class, CYCastJavaObject(jni, context, CYCastJSObject(context, arguments[0])).get())); } CYJavaSignature bound(count); for (auto overload(table->overload_.lower_bound(bound)), e(table->overload_.upper_bound(bound)); overload != e; ++overload) { - CYJavaFrame(jni, count + 16); + CYJavaFrame frame(jni, count + 16); jvalue array[count]; - if (!CYCastJavaArguments(jni, overload->shorty_, context, arguments, array)) + if (!CYCastJavaArguments(frame, overload->shorty_, context, arguments, array)) continue; jvalue *values(array); auto object(jni.NewObjectA(_class, overload->method_, values)); @@ -1258,11 +1288,10 @@ static jobject Cycript_handle(JNIEnv *env, jclass api, jlong jprotect, jstring p size_t count(jarguments == NULL ? 0 : jni.GetArrayLength(jarguments)); JSValueRef arguments[count]; - for (size_t index(0); index != count; ++index) { + for (size_t index(0); index != count; ++index) arguments[index] = CYCastJSValue(context, jni.GetObjectArrayElement(jarguments, index)); - } - return CYCastJavaObject(jni, context, CYCallAsFunction(context, CYCastJSObject(context, function), object, count, arguments)); + return CYCastJavaObject(jni, context, CYCallAsFunction(context, CYCastJSObject(context, function), object, count, arguments)).leak(); } CYJavaCatch(NULL) } static JNINativeMethod Cycript_[] = {