#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 {
{
}
- _finline operator bool() const {
- return value_ != NULL;
+ _finline operator Value_() const {
+ return value_;
}
- _finline operator JNIEnv *() const {
+ _finline JNIEnv *jni() const {
return jni_;
}
- _finline operator Value_() const {
- return value_;
- }
-
+ // 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;
}
};
value_(&value)
{
_assert(value);
- JNIEnv *jni(value);
+ JNIEnv *jni(value.jni());
size = jni->GetStringUTFLength(value);
data = jni->GetStringUTFChars(value, NULL);
}
~CYJavaUTF8String() {
if (value_ != NULL) {
- JNIEnv *jni(*value_);
+ JNIEnv *jni(value_->jni());
jni->ReleaseStringUTFChars(*value_, data);
}
}
return CYPoolCString(pool, CYJavaUTF8String(value_.cast<jobject>()));
}
- virtual JSValueRef CastJSValue(JSContextRef context, const char *name) const {
- return CYCastJSValue(context, value_);
- }
+ virtual JSValueRef CastJSValue(JSContextRef context, const char *name) const;
};
// }}}
operator ()(NULL);
}
+ operator JNIEnv *() const {
+ return jni_;
+ }
+
jobject operator ()(jobject object) {
JNIEnv *jni(jni_);
jni_ = NULL;
{
}
+ template <typename Other_>
+ CYJavaEnv(const CYJavaRef<Other_> &value) :
+ jni(value.jni())
+ {
+ }
+
operator JNIEnv *() const {
return jni;
}
#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)...)); \
}
CYJavaValue(const CYJavaValue &) = delete;
};
+static JSValueRef CYCastJSValue(JSContextRef context, const CYJavaRef<jobject> &value);
+
+template <typename Other_>
+static _finline JSValueRef CYCastJSValue(JSContextRef context, const CYJavaRef<Other_> &value) {
+ return CYCastJSValue(context, value.template cast<jobject>());
+}
+
template <typename Type_>
static _finline JSValueRef CYJavaCastJSValue(JSContextRef context, Type_ value) {
return CYCastJSValue(context, value);
return CYCastJSValue(context, static_cast<bool>(value));
}
+JSValueRef CYJavaError::CastJSValue(JSContextRef context, const char *name) const {
+ return CYCastJSValue(context, value_);
+}
+
static std::map<std::string, CYJavaPrimitive> Primitives_;
static CYJavaPrimitive CYJavaGetPrimitive(JSContextRef context, const CYJavaRef<jclass> &type, jmethodID Class$get$$Name) {
}
}
-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_[] = {