+void Closure_(ffi_cif *cif, void *result, void **arguments, void *arg) {
+ NSLog(@"Closure()");
+ ffoData *data(reinterpret_cast<ffoData *>(arg));
+
+ JSContextRef context(data->context_);
+
+ size_t count(data->cif_.nargs);
+ JSValueRef values[count];
+
+ for (size_t index(0); index != count; ++index)
+ values[index] = CYFromFFI(context, data->signature_.elements[1 + index].type, arguments[index]);
+
+ JSValueRef exception(NULL);
+ JSValueRef value(JSObjectCallAsFunction(context, data->function_, NULL, count, values, &exception));
+ CYThrow(context, exception);
+
+ CYPoolFFI(NULL, context, data->signature_.elements[0].type, result, value);
+}
+
+JSObjectRef CYMakeFunctor(JSContextRef context, JSObjectRef function, const char *type) {
+ // XXX: in case of exceptions this will leak
+ ffoData *data(new ffoData(type));
+
+ ffi_closure *closure;
+ _syscall(closure = (ffi_closure *) mmap(
+ NULL, sizeof(ffi_closure),
+ PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE,
+ -1, 0
+ ));
+
+ ffi_status status(ffi_prep_closure(closure, &data->cif_, &Closure_, data));
+ _assert(status == FFI_OK);
+
+ _syscall(mprotect(closure, sizeof(*closure), PROT_READ | PROT_EXEC));
+
+ data->value_ = closure;
+
+ data->context_ = CYGetJSContext();
+ data->function_ = function;
+
+ return JSObjectMake(context, Functor_, data);
+}
+
+static JSValueRef Global_getProperty(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) {