- return true;
-} CYSadCatch(false) }
-
-static JSValueRef CYObjectiveC_FromFFI(JSContextRef context, sig::Type *type, ffi_type *ffi, void *data, bool initialize, JSObjectRef owner) { CYPoolTry {
- switch (type->primitive) {
- // XXX: do something epic about blocks
- case sig::block_P:
- case sig::object_P:
- if (NSObject *object = *reinterpret_cast<NSObject **>(data)) {
- JSValueRef value(CYCastJSValue(context, object));
- if (initialize)
- [object release];
- return value;
- } else goto null;
-
- case sig::typename_P:
- return CYMakeInstance(context, *reinterpret_cast<Class *>(data), true);
-
- case sig::selector_P:
- if (SEL sel = *reinterpret_cast<SEL *>(data))
- return CYMakeSelector(context, sel);
- else goto null;
-
- null:
- return CYJSNull(context);
- default:
- return NULL;
+namespace sig {
+
+void Block::PoolFFI(CYPool *pool, JSContextRef context, ffi_type *ffi, void *data, JSValueRef value) const {
+ // XXX: this function actually needs to handle null pools as it is an autorelease
+ _assert(pool != NULL);
+ *reinterpret_cast<id *>(data) = CYCastNSBlock(*pool, context, value, &signature);
+}
+
+// XXX: assigning to an indirect id * works for return values, but not for properties and fields
+void Object::PoolFFI(CYPool *pool, JSContextRef context, ffi_type *ffi, void *data, JSValueRef value) const {
+ *reinterpret_cast<id *>(data) = CYCastNSObject(pool, context, value);
+}
+
+void Meta::PoolFFI(CYPool *pool, JSContextRef context, ffi_type *ffi, void *data, JSValueRef value) const {
+ *reinterpret_cast<id *>(data) = CYCastNSObject(pool, context, value);
+}
+
+void Selector::PoolFFI(CYPool *pool, JSContextRef context, ffi_type *ffi, void *data, JSValueRef value) const {
+ *reinterpret_cast<SEL *>(data) = CYCastSEL(context, value);
+}
+
+JSValueRef Object::FromFFI(JSContextRef context, ffi_type *ffi, void *data, bool initialize, JSObjectRef owner) const {
+ NSObject *value(*reinterpret_cast<NSObject **>(data));
+ if (value == NULL)
+ return CYJSNull(context);
+ JSObjectRef object(CYMakeInstance(context, value));
+
+ if (initialize) {
+ Instance *internal(reinterpret_cast<Instance *>(JSObjectGetPrivate(object)));
+
+ if (internal->IsUninitialized()) {
+ internal->flags_ &= ~Instance::Uninitialized;
+ if (internal->value_ == nil)
+ internal->value_ = value;
+ else
+ _assert(internal->value_ == value);
+ }
+
+ [value release];