#undef CYJavaForEachPrimitive_
};
+template <typename Type_>
+struct IsJavaPrimitive { static const bool value = false; };
+
+#define CYJavaForEachPrimitive_(T, t, Typ, Type, type) \
+ template <> \
+ struct IsJavaPrimitive<j ## type> { static const bool value = true; };
+CYJavaForEachPrimitive
+#undef CYJavaForEachPrimitive_
+
// Java References {{{
template <typename Value_>
struct CYJavaRef {
return jni_;
}
+ // XXX: this is only needed to support CYJavaEnv relying on C variadics
_finline Value_ get() const {
return value_;
}
return {jni_, static_cast<Other_>(value_)};
}
+ // XXX: this should be tied into CYJavaFrame
Value_ leak() {
Value_ value(value_);
value_ = NULL;
{
}
- ~CYJavaDelete() {
+ void clear() {
if (this->value_ != NULL)
(this->jni_->*Delete_)(this->value_);
+ this->value_ = NULL;
+ }
+
+ ~CYJavaDelete() {
+ clear();
}
};
{
}
- CYJavaLocal(CYJavaLocal &&value) :
- CYJavaLocal(value.jni_, value.value_)
+ template <typename Other_>
+ CYJavaLocal(CYJavaRef<Other_> &&other) :
+ CYJavaLocal(other.jni_, other.value_)
{
- value.value_ = NULL;
+ other.value_ = NULL;
}
- CYJavaLocal &operator =(CYJavaLocal<Value_> &&other) {
- std::swap(this->jni_, other.jni_);
- std::swap(this->value_, other.value_);
+ CYJavaLocal(CYJavaLocal &&other) :
+ CYJavaLocal(static_cast<CYJavaRef<Value_> &&>(other))
+ {
+ }
+
+ template <typename Other_>
+ CYJavaLocal &operator =(CYJavaLocal<Other_> &&other) {
+ this->clear();
+ this->jni_ = other.jni_;
+ this->value_ = other.value_;
+ other.value_ = NULL;
return *this;
}
};
operator ()(NULL);
}
+ operator JNIEnv *() const {
+ return jni_;
+ }
+
jobject operator ()(jobject object) {
JNIEnv *jni(jni_);
jni_ = NULL;
#define CYJavaEnv_(Code) \
template <typename... Args_> \
- auto Code(Args_ &&... args) const -> decltype(jni->Code(args...)) { \
+ auto Code(Args_ &&... args) const -> decltype(jni->Code(cy::Forward<Args_>(args)...)) { \
return _envcall(jni, Code(cy::Forward<Args_>(args)...)); \
}
}
}
-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));
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;
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_) {
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_) {
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<jobject>(Cycript$, Cycript$Make, _class, reinterpret_cast<jlong>(protect)));
+ auto Cycript$Make(jni.GetStaticMethodID(Cycript$, "proxy", "(Ljava/lang/Class;LCycript$Wrapper;)Ljava/lang/Object;"));
+ return CYCastJSObject(context, jni.CallObjectMethod<jobject>(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));
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<jobject>(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_[] = {