static id (*$objc_getAssociatedObject)(id object, void *key);
static void (*$objc_removeAssociatedObjects)(id object);
+struct BlockLiteral {
+ Class isa;
+ int flags;
+ int reserved;
+ void (*invoke)(void *, ...);
+ void *descriptor;
+};
+
+struct BlockDescriptor1 {
+ unsigned long int reserved;
+ unsigned long int size;
+};
+
+struct BlockDescriptor2 {
+ void (*copy_helper)(BlockLiteral *dst, BlockLiteral *src);
+ void (*dispose_helper)(BlockLiteral *src);
+};
+
+struct BlockDescriptor3 {
+ const char *signature;
+ const char *layout;
+};
+
+enum {
+ BLOCK_DEALLOCATING = 0x0001,
+ BLOCK_REFCOUNT_MASK = 0xfffe,
+ BLOCK_NEEDS_FREE = 1 << 24,
+ BLOCK_HAS_COPY_DISPOSE = 1 << 25,
+ BLOCK_HAS_CTOR = 1 << 26,
+ BLOCK_IS_GC = 1 << 27,
+ BLOCK_IS_GLOBAL = 1 << 28,
+ BLOCK_HAS_STRET = 1 << 29,
+ BLOCK_HAS_SIGNATURE = 1 << 30,
+};
+
JSValueRef CYSendMessage(apr_pool_t *pool, JSContextRef context, id self, Class super, SEL _cmd, size_t count, const JSValueRef arguments[], bool initialize, JSValueRef *exception);
/* Objective-C Pool Release {{{ */
static JSClassRef FunctionInstance_;
static JSClassRef ObjectInstance_;
static JSClassRef StringInstance_;
-static JSClassRef TypeInstance_;
+static JSClassRef Class_;
static JSClassRef Internal_;
static JSClassRef Message_;
static JSClassRef Messages_;
if (self == nil)
return CYGetCachedObject(context, CYJSString("Instance_prototype"));
else if (meta && !class_isMetaClass(self))
- return CYGetCachedObject(context, CYJSString("TypeInstance_prototype"));
+ return CYGetCachedObject(context, CYJSString("Class_prototype"));
JSObjectRef global(CYGetGlobalObject(context));
JSObjectRef cy(CYCastJSObject(context, CYGetProperty(context, global, cy_s)));
return is;
}
+NSObject *CYMakeBlock(void (*invoke)(), sig::Signature &signature) {
+ BlockLiteral *literal(reinterpret_cast<BlockLiteral *>(malloc(sizeof(BlockLiteral))));
+
+ struct Descriptor {
+ struct {
+ BlockDescriptor1 one_;
+ BlockDescriptor2 two_;
+ BlockDescriptor3 three_;
+ } d_;
+
+ CYPool pool_;
+ };
+
+ Descriptor *descriptor(new Descriptor);
+ memset(&descriptor->d_, 0, sizeof(descriptor->d_));
+
+ literal->isa = objc_getClass("__NSGlobalBlock__");
+ literal->flags = BLOCK_HAS_SIGNATURE | BLOCK_HAS_COPY_DISPOSE | BLOCK_IS_GLOBAL;
+ literal->reserved = 0;
+ literal->invoke = reinterpret_cast<void (*)(void *, ...)>(invoke);
+ literal->descriptor = descriptor;
+
+ descriptor->d_.one_.size = sizeof(descriptor->d_);
+ descriptor->d_.three_.signature = sig::Unparse(descriptor->pool_, &signature);
+
+ return reinterpret_cast<NSObject *>(literal);
+}
+
NSObject *CYCastNSObject(apr_pool_t *pool, JSContextRef context, JSObjectRef object) {
if (CYJSValueIsNSObject(context, object)) {
Instance *internal(reinterpret_cast<Instance *>(JSObjectGetPrivate(object)));
return internal->GetValue();
}
+ if (JSValueIsObjectOfClass(context, object, Functor_)) {
+ cy::Functor *internal(reinterpret_cast<cy::Functor *>(JSObjectGetPrivate(object)));
+ return CYMakeBlock(internal->GetValue(), internal->signature_);
+ }
+
bool array(CYJSValueIsInstanceOfCachedConstructor(context, object, Array_s));
id value(array ? [CYJSArray alloc] : [CYJSObject alloc]);
return CYPoolRelease(pool, [value initWithJSObject:object inContext:context]);
return NULL;
}
-static void MessageClosure_(ffi_cif *cif, void *result, void **arguments, void *arg) {
- Closure_privateData *internal(reinterpret_cast<Closure_privateData *>(arg));
-
- JSContextRef context(internal->context_);
-
- size_t count(internal->cif_.nargs);
- JSValueRef values[count];
-
- for (size_t index(0); index != count; ++index)
- values[index] = CYFromFFI(context, internal->signature_.elements[1 + index].type, internal->cif_.arg_types[index], arguments[index]);
-
+static JSValueRef MessageAdapter_(JSContextRef context, size_t count, JSValueRef values[], JSObjectRef function) {
JSObjectRef _this(CYCastJSObject(context, values[0]));
+ return CYCallAsFunction(context, function, _this, count - 2, values + 2);
+}
- JSValueRef value(CYCallAsFunction(context, internal->function_, _this, count - 2, values + 2));
- CYPoolFFI(NULL, context, internal->signature_.elements[0].type, internal->cif_.rtype, result, value);
+static void MessageClosure_(ffi_cif *cif, void *result, void **arguments, void *arg) {
+ CYExecuteClosure(cif, result, arguments, arg, &MessageAdapter_);
}
static JSObjectRef CYMakeMessage(JSContextRef context, SEL sel, IMP imp, const char *type) {
// to do /that/, generalize the various "is exactly Instance_" checks
// then, move Instance_callAsFunction to only be on FunctionInstance
- struct BlockDescriptor1 {
- unsigned long int reserved;
- unsigned long int size;
- };
-
- struct BlockDescriptor2 {
- void (*copy_helper)(void *dst, void *src);
- void (*dispose_helper)(void *src);
- };
-
- struct BlockDescriptor3 {
- const char *signature;
- const char *layout;
- };
-
- struct BlockLiteral {
- Class isa;
- int flags;
- int reserved;
- void (*invoke)(void *, ...);
- void *descriptor;
- } *literal = reinterpret_cast<BlockLiteral *>(self);
-
- enum {
- BLOCK_DEALLOCATING = 0x0001,
- BLOCK_REFCOUNT_MASK = 0xfffe,
- BLOCK_NEEDS_FREE = 1 << 24,
- BLOCK_HAS_COPY_DISPOSE = 1 << 25,
- BLOCK_HAS_CTOR = 1 << 26,
- BLOCK_IS_GC = 1 << 27,
- BLOCK_IS_GLOBAL = 1 << 28,
- BLOCK_HAS_STRET = 1 << 29,
- BLOCK_HAS_SIGNATURE = 1 << 30,
- };
+ BlockLiteral *literal(reinterpret_cast<BlockLiteral *>(self));
if ((literal->flags & BLOCK_HAS_SIGNATURE) != 0) {
uint8_t *descriptor(reinterpret_cast<uint8_t *>(literal->descriptor));
} CYPoolCatch(NULL)
} CYCatch return /*XXX*/ NULL; }
-static JSValueRef Instance_callAsFunction_typeOf(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
+static JSValueRef Class_callAsFunction_pointerTo(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
if (!CYJSValueIsNSObject(context, _this))
return NULL;
{NULL, NULL, NULL, 0}
};
-static JSStaticFunction Instance_staticFunctions[8] = {
+static JSStaticFunction Instance_staticFunctions[7] = {
{"$cya", &CYValue_callAsFunction_$cya, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
{"toCYON", &Instance_callAsFunction_toCYON, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
{"toJSON", &Instance_callAsFunction_toJSON, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
{"valueOf", &Instance_callAsFunction_valueOf, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
{"toPointer", &Instance_callAsFunction_toPointer, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
{"toString", &Instance_callAsFunction_toString, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
- {"typeOf", &Instance_callAsFunction_typeOf, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
+ {NULL, NULL, 0}
+};
+
+static JSStaticFunction Class_staticFunctions[2] = {
+ {"pointerTo", &Class_callAsFunction_pointerTo, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
{NULL, NULL, 0}
};
definition.className = "StringInstance";
StringInstance_ = JSClassCreate(&definition);
- definition.className = "TypeInstance";
- TypeInstance_ = JSClassCreate(&definition);
+ definition = kJSClassDefinitionEmpty;
+ definition.className = "Class";
+ definition.staticFunctions = Class_staticFunctions;
+ Class_ = JSClassCreate(&definition);
definition = kJSClassDefinitionEmpty;
definition.className = "Internal";
CYSetProperty(context, ObjectiveC, CYJSString("images"), JSObjectMake(context, ObjectiveC_Images_, NULL));
#endif
+ JSObjectRef Class(JSObjectMakeConstructor(context, Class_, NULL));
JSObjectRef Instance(JSObjectMakeConstructor(context, Instance_, &Instance_new));
JSObjectRef Message(JSObjectMakeConstructor(context, Message_, NULL));
JSObjectRef Selector(JSObjectMakeConstructor(context, Selector_, &Selector_new));
JSObjectRef String_prototype(CYGetCachedObject(context, CYJSString("String_prototype")));
JSObjectSetPrototype(context, StringInstance_prototype, String_prototype);
- JSObjectRef TypeInstance(JSObjectMakeConstructor(context, TypeInstance_, NULL));
- JSObjectRef TypeInstance_prototype(CYCastJSObject(context, CYGetProperty(context, TypeInstance, prototype_s)));
- CYSetProperty(context, cy, CYJSString("TypeInstance_prototype"), TypeInstance_prototype);
- JSObjectRef Type_prototype(CYGetCachedObject(context, CYJSString("Type_prototype")));
- JSObjectSetPrototype(context, TypeInstance_prototype, Type_prototype);
+ JSObjectRef Class_prototype(CYCastJSObject(context, CYGetProperty(context, Class, prototype_s)));
+ CYSetProperty(context, cy, CYJSString("Class_prototype"), Class_prototype);
+ JSObjectSetPrototype(context, Class_prototype, Instance_prototype);
CYSetProperty(context, cycript, CYJSString("Instance"), Instance);
CYSetProperty(context, cycript, CYJSString("Selector"), Selector);