+} CYCatch(NULL) }
+
+static JSValueRef Instance_callAsFunction(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
+ Instance *internal(reinterpret_cast<Instance *>(JSObjectGetPrivate(object)));
+ id self(internal->GetValue());
+
+ if (![self isKindOfClass:NSBlock_])
+ CYThrow("non-NSBlock object is not a function");
+ // XXX: replace above logic with the following assertion
+ //_assert([self isKindOfClass:NSBlock_]);
+ // to do this, make it so FunctionInstance_ is the class of blocks
+ // to do /that/, generalize the various "is exactly Instance_" checks
+ // then, move Instance_callAsFunction to only be on FunctionInstance
+
+ BlockLiteral *literal(reinterpret_cast<BlockLiteral *>(self));
+
+ if ((literal->flags & BLOCK_HAS_SIGNATURE) != 0) {
+ uint8_t *descriptor(reinterpret_cast<uint8_t *>(literal->descriptor));
+ descriptor += sizeof(BlockDescriptor1);
+ if ((literal->flags & BLOCK_HAS_COPY_DISPOSE) != 0)
+ descriptor += sizeof(BlockDescriptor2);
+ BlockDescriptor3 *descriptor3(reinterpret_cast<BlockDescriptor3 *>(descriptor));
+
+ if (const char *type = descriptor3->signature) {
+ CYPool pool;
+
+ void *setup[1];
+ setup[0] = &self;
+
+ sig::Signature signature;
+ sig::Parse(pool, &signature, type, &Structor_);
+
+ ffi_cif cif;
+ sig::sig_ffi_cif(pool, &sig::ObjectiveC, &signature, &cif);
+
+ void (*function)() = reinterpret_cast<void (*)()>(literal->invoke);
+ return CYCallFunction(pool, context, 1, setup, count, arguments, false, exception, &signature, &cif, function);
+ }
+ }
+
+ if (count != 0)
+ CYThrow("NSBlock without signature field passed arguments");
+
+ CYPoolTry {
+ [self invoke];
+ } CYPoolCatch(NULL);
+
+ return NULL;
+} CYCatch(NULL) }