]> git.saurik.com Git - cycript.git/commitdiff
Started setting up build environment for Cyrver, fixed Functor prototype, organized...
authorJay Freeman (saurik) <saurik@saurik.com>
Sat, 17 Oct 2009 19:59:34 +0000 (19:59 +0000)
committerJay Freeman (saurik) <saurik@saurik.com>
Sat, 17 Oct 2009 19:59:34 +0000 (19:59 +0000)
Library.mm
Server.cpp [new file with mode: 0644]
Server.mm [deleted file]
com.saurik.Cyrver.plist [new file with mode: 0644]
makefile
todo.txt

index 85638f5aa76f0e3612ce7af5be7365d04f014cd6..04b62b7e34ee2d216aa91426ef2d7afb91c1eb10 100644 (file)
@@ -103,7 +103,9 @@ static JSObjectRef ObjectiveC_;
 static JSClassRef Functor_;
 static JSClassRef Instance_;
 static JSClassRef Internal_;
+static JSClassRef Message_;
 static JSClassRef Pointer_;
+static JSClassRef Prototype_;
 static JSClassRef Runtime_;
 static JSClassRef Selector_;
 static JSClassRef Struct_;
@@ -122,6 +124,7 @@ static JSStringRef Result_;
 static JSStringRef length_;
 static JSStringRef message_;
 static JSStringRef name_;
+static JSStringRef prototype_;
 static JSStringRef toCYON_;
 static JSStringRef toJSON_;
 
@@ -200,7 +203,7 @@ struct Instance :
             [GetValue() performSelector:@selector(release) withObject:nil afterDelay:0];
     }
 
-    static JSObjectRef Make(JSContextRef context, id object, Flags flags) {
+    static JSObjectRef Make(JSContextRef context, id object, Flags flags = None) {
         return JSObjectMake(context, Instance_, new Instance(object, flags));
     }
 
@@ -215,6 +218,23 @@ struct Instance :
     virtual Type_privateData *GetType() const;
 };
 
+struct Prototype :
+    CYValue
+{
+    Prototype(Class value) :
+        CYValue(value)
+    {
+    }
+
+    static JSObjectRef Make(JSContextRef context, Class _class) {
+        return JSObjectMake(context, Prototype_, new Prototype(_class));
+    }
+
+    Class GetValue() const {
+        return reinterpret_cast<Class>(value_);
+    }
+};
+
 struct Internal :
     CYValue
 {
@@ -452,26 +472,43 @@ struct Functor_privateData :
     sig::Signature signature_;
     ffi_cif cif_;
 
+
     Functor_privateData(const char *type, void (*value)()) :
         CYValue(reinterpret_cast<void *>(value))
     {
         sig::Parse(pool_, &signature_, type, &Structor_);
         sig::sig_ffi_cif(pool_, &sig::ObjectiveC, &signature_, &cif_);
     }
+
+    void (*GetValue())() const {
+        return reinterpret_cast<void (*)()>(value_);
+    }
 };
 
-struct ffoData :
+struct Closure_privateData :
     Functor_privateData
 {
     JSContextRef context_;
     JSObjectRef function_;
 
-    ffoData(const char *type) :
+    Closure_privateData(const char *type) :
         Functor_privateData(type, NULL)
     {
     }
 };
 
+struct Message_privateData :
+    Functor_privateData
+{
+    SEL sel_;
+
+    Message_privateData(SEL sel, const char *type, IMP value = NULL) :
+        Functor_privateData(type, reinterpret_cast<void (*)()>(value)),
+        sel_(sel)
+    {
+    }
+};
+
 JSObjectRef CYMakeInstance(JSContextRef context, id object, bool transient) {
     Instance::Flags flags;
 
@@ -1734,6 +1771,190 @@ static bool CYImplements(id object, Class _class, SEL selector, bool devoid) {
     return false;
 }
 
+const char *CYPoolTypeEncoding(apr_pool_t *pool, Class _class, SEL sel, Method method) {
+    if (method != NULL)
+        return method_getTypeEncoding(method);
+    else if (NSString *type = [[Bridge_ objectAtIndex:1] objectForKey:CYCastNSString(pool, sel_getName(sel))])
+        return CYPoolCString(pool, type);
+    else
+        return NULL;
+}
+
+void FunctionClosure_(ffi_cif *cif, void *result, void **arguments, void *arg) {
+    Closure_privateData *data(reinterpret_cast<Closure_privateData *>(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, data->cif_.arg_types[index], arguments[index]);
+
+    JSValueRef value(CYCallAsFunction(context, data->function_, NULL, count, values));
+    CYPoolFFI(NULL, context, data->signature_.elements[0].type, data->cif_.rtype, result, value);
+}
+
+void MessageClosure_(ffi_cif *cif, void *result, void **arguments, void *arg) {
+    Closure_privateData *data(reinterpret_cast<Closure_privateData *>(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, data->cif_.arg_types[index], arguments[index]);
+
+    JSObjectRef _this(CYCastJSObject(context, values[0]));
+
+    JSValueRef value(CYCallAsFunction(context, data->function_, _this, count - 2, values + 2));
+    CYPoolFFI(NULL, context, data->signature_.elements[0].type, data->cif_.rtype, result, value);
+}
+
+Closure_privateData *CYMakeFunctor_(JSContextRef context, JSObjectRef function, const char *type, void (*callback)(ffi_cif *, void *, void **, void *)) {
+    // XXX: in case of exceptions this will leak
+    // XXX: in point of fact, this may /need/ to leak :(
+    Closure_privateData *internal(new Closure_privateData(type));
+
+    ffi_closure *closure((ffi_closure *) _syscall(mmap(
+        NULL, sizeof(ffi_closure),
+        PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE,
+        -1, 0
+    )));
+
+    ffi_status status(ffi_prep_closure(closure, &internal->cif_, callback, internal));
+    _assert(status == FFI_OK);
+
+    _syscall(mprotect(closure, sizeof(*closure), PROT_READ | PROT_EXEC));
+
+    internal->value_ = closure;
+
+    internal->context_ = CYGetJSContext();
+    internal->function_ = function;
+
+    return internal;
+}
+
+JSObjectRef CYMakeFunctor(JSContextRef context, JSObjectRef function, const char *type) {
+    Closure_privateData *internal(CYMakeFunctor_(context, function, type, &FunctionClosure_));
+    return JSObjectMake(context, Functor_, internal);
+}
+
+static JSObjectRef CYMakeFunctor(JSContextRef context, JSValueRef value, const char *type) {
+    JSValueRef exception(NULL);
+    bool function(JSValueIsInstanceOfConstructor(context, value, Function_, &exception));
+    CYThrow(context, exception);
+
+    if (function) {
+        JSObjectRef function(CYCastJSObject(context, value));
+        return CYMakeFunctor(context, function, type);
+    } else {
+        void (*function)()(CYCastPointer<void (*)()>(context, value));
+        return CYMakeFunctor(context, function, type);
+    }
+}
+
+static JSObjectRef CYMakeMessage(JSContextRef context, SEL sel, IMP imp, const char *type) {
+    Message_privateData *internal(new Message_privateData(sel, type, imp));
+    return JSObjectMake(context, Message_, internal);
+}
+
+static IMP CYMakeMessage(JSContextRef context, JSValueRef value, const char *type) {
+    JSObjectRef function(CYCastJSObject(context, value));
+    Closure_privateData *internal(CYMakeFunctor_(context, function, type, &MessageClosure_));
+    return reinterpret_cast<IMP>(internal->GetValue());
+}
+
+static bool Prototype_hasProperty(JSContextRef context, JSObjectRef object, JSStringRef property) {
+    Prototype *internal(reinterpret_cast<Prototype *>(JSObjectGetPrivate(object)));
+    Class _class(internal->GetValue());
+
+    CYPool pool;
+    const char *name(CYPoolCString(pool, property));
+
+    if (SEL sel = sel_getUid(name))
+        if (class_getInstanceMethod(_class, sel) != NULL)
+            return true;
+
+    return false;
+}
+
+static JSValueRef Prototype_getProperty(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) {
+    Prototype *internal(reinterpret_cast<Prototype *>(JSObjectGetPrivate(object)));
+    Class _class(internal->GetValue());
+
+    CYPool pool;
+    const char *name(CYPoolCString(pool, property));
+
+    if (SEL sel = sel_getUid(name))
+        if (Method method = class_getInstanceMethod(_class, sel))
+            return CYMakeMessage(context, sel, method_getImplementation(method), method_getTypeEncoding(method));
+
+    return NULL;
+}
+
+static bool Prototype_setProperty(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef value, JSValueRef *exception) {
+    Prototype *internal(reinterpret_cast<Prototype *>(JSObjectGetPrivate(object)));
+    Class _class(internal->GetValue());
+
+    CYPool pool;
+    const char *name(CYPoolCString(pool, property));
+
+    SEL sel(sel_registerName(name));
+
+    Method method(class_getInstanceMethod(_class, sel));
+
+    const char *type;
+    IMP imp;
+
+    if (JSValueIsObjectOfClass(context, value, Message_)) {
+        Message_privateData *message(reinterpret_cast<Message_privateData *>(JSObjectGetPrivate((JSObjectRef) value)));
+        type = sig::Unparse(pool, &message->signature_);
+        imp = reinterpret_cast<IMP>(message->GetValue());
+    } else {
+        type = CYPoolTypeEncoding(pool, _class, sel, method);
+        imp = CYMakeMessage(context, value, type);
+    }
+
+    if (method != NULL)
+        method_setImplementation(method, imp);
+    else
+        class_replaceMethod(_class, sel, imp, type);
+
+    return true;
+}
+
+#if !__OBJC2__
+static bool Prototype_deleteProperty(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) {
+    Prototype *internal(reinterpret_cast<Prototype *>(JSObjectGetPrivate(object)));
+    Class _class(internal->GetValue());
+
+    CYPool pool;
+    const char *name(CYPoolCString(pool, property));
+
+    if (SEL sel = sel_getUid(name))
+        if (Method method = class_getInstanceMethod(_class, sel)) {
+            objc_method_list list = {NULL, 1, {method}};
+            class_removeMethods(_class, &list);
+            return true;
+        }
+
+    return false;
+}
+#endif
+
+static void Prototype_getPropertyNames(JSContextRef context, JSObjectRef object, JSPropertyNameAccumulatorRef names) {
+    Prototype *internal(reinterpret_cast<Prototype *>(JSObjectGetPrivate(object)));
+    Class _class(internal->GetValue());
+
+    unsigned int size;
+    Method *data(class_copyMethodList(_class, &size));
+    for (size_t i(0); i != size; ++i)
+        JSPropertyNameAccumulatorAddName(names, CYJSString(sel_getName(method_getName(data[i]))));
+    free(data);
+}
+
 static bool Instance_hasProperty(JSContextRef context, JSObjectRef object, JSStringRef property) {
     Instance *internal(reinterpret_cast<Instance *>(JSObjectGetPrivate(object)));
     id self(internal->GetValue());
@@ -1804,10 +2025,12 @@ static JSValueRef Instance_getProperty(JSContextRef context, JSObjectRef object,
 }
 
 static bool Instance_setProperty(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef value, JSValueRef *exception) {
+    Instance *internal(reinterpret_cast<Instance *>(JSObjectGetPrivate(object)));
+    id self(internal->GetValue());
+
     CYPool pool;
 
     CYTry {
-        id self(CYCastNSObject(pool, context, object));
         NSString *name(CYCastNSString(pool, property));
         NSString *data(CYCastNSObject(pool, context, value));
 
@@ -1861,9 +2084,11 @@ static bool Instance_setProperty(JSContextRef context, JSObjectRef object, JSStr
 }
 
 static bool Instance_deleteProperty(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) {
+    Instance *internal(reinterpret_cast<Instance *>(JSObjectGetPrivate(object)));
+    id self(internal->GetValue());
+
     CYTry {
         CYPoolTry {
-            id self(CYCastNSObject(NULL, context, object));
             NSString *name(CYCastNSString(NULL, property));
             return [self cy$deleteProperty:name];
         } CYPoolCatch(NULL)
@@ -1871,8 +2096,10 @@ static bool Instance_deleteProperty(JSContextRef context, JSObjectRef object, JS
 }
 
 static void Instance_getPropertyNames(JSContextRef context, JSObjectRef object, JSPropertyNameAccumulatorRef names) {
+    Instance *internal(reinterpret_cast<Instance *>(JSObjectGetPrivate(object)));
+    id self(internal->GetValue());
+
     CYPool pool;
-    NSString *self(CYCastNSObject(pool, context, object));
     Class _class(object_getClass(self));
 
     {
@@ -2164,44 +2391,6 @@ JSValueRef CYCallFunction(apr_pool_t *pool, JSContextRef context, size_t setups,
     } CYCatch
 }
 
-void Closure_(ffi_cif *cif, void *result, void **arguments, void *arg) {
-    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, data->cif_.arg_types[index], arguments[index]);
-
-    JSValueRef value(CYCallAsFunction(context, data->function_, NULL, count, values));
-    CYPoolFFI(NULL, context, data->signature_.elements[0].type, data->cif_.rtype, 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((ffi_closure *) _syscall(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 ObjectiveC_Classes_getProperty(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) {
     CYTry {
         CYPool pool;
@@ -2316,7 +2505,7 @@ static void ObjectiveC_Protocols_getPropertyNames(JSContextRef context, JSObject
 
 static JSValueRef Runtime_getProperty(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) {
     if (JSStringIsEqualToUTF8CString(property, "nil"))
-        return Instance::Make(context, nil, Instance::None);
+        return Instance::Make(context, nil);
 
     CYTry {
         CYPool pool;
@@ -2461,10 +2650,24 @@ static JSValueRef Selector_callAsFunction(JSContextRef context, JSObjectRef obje
     return $objc_msgSend(context, NULL, NULL, count + 2, setup, exception);
 }
 
+static JSValueRef Message_callAsFunction(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) {
+    CYPool pool;
+    Message_privateData *internal(reinterpret_cast<Message_privateData *>(JSObjectGetPrivate(object)));
+
+    // XXX: handle Instance::Uninitialized?
+    id self(CYCastNSObject(pool, context, _this));
+
+    void *setup[2];
+    setup[0] = &self;
+    setup[1] = &internal->sel_;
+
+    return CYCallFunction(pool, context, 2, setup, count, arguments, false, exception, &internal->signature_, &internal->cif_, internal->GetValue());
+}
+
 static JSValueRef Functor_callAsFunction(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) {
     CYPool pool;
-    Functor_privateData *data(reinterpret_cast<Functor_privateData *>(JSObjectGetPrivate(object)));
-    return CYCallFunction(pool, context, 0, NULL, count, arguments, false, exception, &data->signature_, &data->cif_, reinterpret_cast<void (*)()>(data->value_));
+    Functor_privateData *internal(reinterpret_cast<Functor_privateData *>(JSObjectGetPrivate(object)));
+    return CYCallFunction(pool, context, 0, NULL, count, arguments, false, exception, &internal->signature_, &internal->cif_, internal->GetValue());
 }
 
 JSObjectRef Selector_new(JSContextRef context, JSObjectRef object, size_t count, const JSValueRef arguments[], JSValueRef *exception) {
@@ -2539,7 +2742,7 @@ JSObjectRef Instance_new(JSContextRef context, JSObjectRef object, size_t count,
         if (count > 1)
             @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"incorrect number of arguments to Instance constructor" userInfo:nil];
         id self(count == 0 ? nil : CYCastPointer<id>(context, arguments[0]));
-        return Instance::Make(context, self, Instance::None);
+        return Instance::Make(context, self);
     } CYCatch
 }
 
@@ -2548,16 +2751,7 @@ JSObjectRef Functor_new(JSContextRef context, JSObjectRef object, size_t count,
         if (count != 2)
             @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"incorrect number of arguments to Functor constructor" userInfo:nil];
         const char *type(CYCastCString(context, arguments[1]));
-        JSValueRef exception(NULL);
-        if (JSValueIsInstanceOfConstructor(context, arguments[0], Function_, &exception)) {
-            JSObjectRef function(CYCastJSObject(context, arguments[0]));
-            return CYMakeFunctor(context, function, type);
-        } else if (exception != NULL) {
-            return NULL;
-        } else {
-            void (*function)()(CYCastPointer<void (*)()>(context, arguments[0]));
-            return CYMakeFunctor(context, function, type);
-        }
+        return CYMakeFunctor(context, arguments[0], type);
     } CYCatch
 }
 
@@ -2566,10 +2760,6 @@ JSValueRef CYValue_getProperty_value(JSContextRef context, JSObjectRef object, J
     return CYCastJSValue(context, reinterpret_cast<uintptr_t>(internal->value_));
 }
 
-JSValueRef Selector_getProperty_prototype(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) {
-    return Function_;
-}
-
 static JSValueRef CYValue_callAsFunction_$cya(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) {
     CYValue *internal(reinterpret_cast<CYValue *>(JSObjectGetPrivate(_this)));
     Type_privateData *typical(internal->GetType());
@@ -2610,6 +2800,20 @@ static JSValueRef CYValue_callAsFunction_toCYON(JSContextRef context, JSObjectRe
     } CYCatch
 }
 
+static JSValueRef Instance_getProperty_constructor(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) {
+    Instance *internal(reinterpret_cast<Instance *>(JSObjectGetPrivate(object)));
+    return Instance::Make(context, object_getClass(internal->GetValue()));
+}
+
+static JSValueRef Instance_getProperty_prototype(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) {
+    Instance *internal(reinterpret_cast<Instance *>(JSObjectGetPrivate(object)));
+    id self(internal->GetValue());
+    // XXX: this is a lame object_isClass
+    if (class_getInstanceMethod(object_getClass(self), @selector(alloc)) == NULL)
+        return CYJSUndefined(context);
+    return Prototype::Make(context, self);
+}
+
 static JSValueRef Instance_callAsFunction_toCYON(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) {
     Instance *internal(reinterpret_cast<Instance *>(JSObjectGetPrivate(_this)));
 
@@ -2672,12 +2876,9 @@ static JSValueRef Selector_callAsFunction_type(JSContextRef context, JSObjectRef
         Selector_privateData *internal(reinterpret_cast<Selector_privateData *>(JSObjectGetPrivate(_this)));
         Class _class(CYCastNSObject(pool, context, arguments[0]));
         SEL sel(internal->GetValue());
-        if (Method method = class_getInstanceMethod(_class, sel))
-            return CYCastJSValue(context, method_getTypeEncoding(method));
-        else if (NSString *type = [[Bridge_ objectAtIndex:1] objectForKey:CYCastNSString(pool, sel_getName(sel))])
-            return CYCastJSValue(context, CYJSString(type));
-        else
-            return CYJSNull(context);
+        Method method(class_getInstanceMethod(_class, sel));
+        const char *type(CYPoolTypeEncoding(pool, _class, sel, method));
+        return type == NULL ? CYJSNull(context) : CYCastJSValue(context, CYJSString(type));
     } CYCatch
 }
 
@@ -2736,12 +2937,9 @@ static JSStaticFunction Functor_staticFunctions[4] = {
     {NULL, NULL, 0}
 };
 
-/*static JSStaticValue Selector_staticValues[2] = {
-    {"prototype", &Selector_getProperty_prototype, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete},
-    {NULL, NULL, NULL, 0}
-};*/
-
-static JSStaticValue Instance_staticValues[2] = {
+static JSStaticValue Instance_staticValues[4] = {
+    {"constructor", &Instance_getProperty_constructor, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete},
+    {"prototype", &Instance_getProperty_prototype, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete},
     {"value", &CYValue_getProperty_value, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete},
     {NULL, NULL, NULL, 0}
 };
@@ -3003,6 +3201,13 @@ JSGlobalContextRef CYGetJSContext() {
         definition.finalize = &Finalize;
         Internal_ = JSClassCreate(&definition);
 
+        definition = kJSClassDefinitionEmpty;
+        definition.className = "Message";
+        definition.staticFunctions = Functor_staticFunctions;
+        definition.callAsFunction = &Message_callAsFunction;
+        definition.finalize = &Finalize;
+        Message_ = JSClassCreate(&definition);
+
         definition = kJSClassDefinitionEmpty;
         definition.className = "Pointer";
         definition.staticValues = Pointer_staticValues;
@@ -3012,10 +3217,21 @@ JSGlobalContextRef CYGetJSContext() {
         definition.finalize = &Finalize;
         Pointer_ = JSClassCreate(&definition);
 
+        definition = kJSClassDefinitionEmpty;
+        definition.className = "Prototype";
+        definition.hasProperty = &Prototype_hasProperty;
+        definition.getProperty = &Prototype_getProperty;
+        definition.setProperty = &Prototype_setProperty;
+#if !__OBJC2__
+        definition.deleteProperty = &Prototype_deleteProperty;
+#endif
+        definition.getPropertyNames = &Prototype_getPropertyNames;
+        definition.finalize = &Finalize;
+        Prototype_ = JSClassCreate(&definition);
+
         definition = kJSClassDefinitionEmpty;
         definition.className = "Selector";
         definition.staticValues = CYValue_staticValues;
-        //definition.staticValues = Selector_staticValues;
         definition.staticFunctions = Selector_staticFunctions;
         definition.callAsFunction = &Selector_callAsFunction;
         definition.finalize = &Finalize;
@@ -3086,7 +3302,24 @@ JSGlobalContextRef CYGetJSContext() {
         CYSetProperty(context, ObjectiveC_, CYJSString("images"), JSObjectMake(context, ObjectiveC_Images_, NULL));
         CYSetProperty(context, ObjectiveC_, CYJSString("protocols"), JSObjectMake(context, ObjectiveC_Protocols_, NULL));
 
-        CYSetProperty(context, global, CYJSString("Functor"), JSObjectMakeConstructor(context, Functor_, &Functor_new));
+        Array_ = CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Array")));
+        Function_ = CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Function")));
+
+        length_ = JSStringCreateWithUTF8CString("length");
+        message_ = JSStringCreateWithUTF8CString("message");
+        name_ = JSStringCreateWithUTF8CString("name");
+        prototype_ = JSStringCreateWithUTF8CString("prototype");
+        toCYON_ = JSStringCreateWithUTF8CString("toCYON");
+        toJSON_ = JSStringCreateWithUTF8CString("toJSON");
+
+        JSObjectRef Functor(JSObjectMakeConstructor(context, Functor_, &Functor_new));
+        JSObjectRef Message(JSObjectMakeConstructor(context, Message_, NULL));
+
+        JSValueRef function(CYGetProperty(context, Function_, prototype_));
+        JSObjectSetPrototype(context, (JSObjectRef) CYGetProperty(context, Message, prototype_), function);
+        JSObjectSetPrototype(context, (JSObjectRef) CYGetProperty(context, Functor, prototype_), function);
+
+        CYSetProperty(context, global, CYJSString("Functor"), Functor);
         CYSetProperty(context, global, CYJSString("Instance"), JSObjectMakeConstructor(context, Instance_, &Instance_new));
         CYSetProperty(context, global, CYJSString("Pointer"), JSObjectMakeConstructor(context, Pointer_, &Pointer_new));
         CYSetProperty(context, global, CYJSString("Selector"), JSObjectMakeConstructor(context, Selector_, &Selector_new));
@@ -3107,15 +3340,6 @@ JSGlobalContextRef CYGetJSContext() {
         CYSetProperty(context, System_, CYJSString("print"), JSObjectMakeFunctionWithCallback(context, CYJSString("print"), &System_print));
 
         Result_ = JSStringCreateWithUTF8CString("_");
-
-        length_ = JSStringCreateWithUTF8CString("length");
-        message_ = JSStringCreateWithUTF8CString("message");
-        name_ = JSStringCreateWithUTF8CString("name");
-        toCYON_ = JSStringCreateWithUTF8CString("toCYON");
-        toJSON_ = JSStringCreateWithUTF8CString("toJSON");
-
-        Array_ = CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Array")));
-        Function_ = CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Function")));
     }
 
     return Context_;
diff --git a/Server.cpp b/Server.cpp
new file mode 100644 (file)
index 0000000..bf7c17c
--- /dev/null
@@ -0,0 +1,160 @@
+/* Cycript - Remove Execution Server and Disassembler
+ * Copyright (C) 2009  Jay Freeman (saurik)
+*/
+
+/* Modified BSD License {{{ */
+/*
+ *        Redistribution and use in source and binary
+ * forms, with or without modification, are permitted
+ * provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the
+ *    above copyright notice, this list of conditions
+ *    and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the
+ *    above copyright notice, this list of conditions
+ *    and the following disclaimer in the documentation
+ *    and/or other materials provided with the
+ *    distribution.
+ * 3. The name of the author may not be used to endorse
+ *    or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/* }}} */
+
+#include <Pooling.hpp>
+
+#include <apr-1/apr_thread_proc.h>
+
+#include <CoreFoundation/CFLogUtilities.h>
+#include <CFNetwork/CFNetwork.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <sys/un.h>
+
+struct Client {
+    CFHTTPMessageRef message_;
+    CFSocketRef socket_;
+};
+
+static void OnData(CFSocketRef socket, CFSocketCallBackType type, CFDataRef address, const void *value, void *info) {
+    switch (type) {
+        case kCFSocketDataCallBack:
+            CFDataRef data(reinterpret_cast<CFDataRef>(value));
+            Client *client(reinterpret_cast<Client *>(info));
+
+            if (client->message_ == NULL)
+                client->message_ = CFHTTPMessageCreateEmpty(kCFAllocatorDefault, TRUE);
+
+            if (!CFHTTPMessageAppendBytes(client->message_, CFDataGetBytePtr(data), CFDataGetLength(data)))
+                CFLog(kCFLogLevelError, CFSTR("CFHTTPMessageAppendBytes()"));
+            else if (CFHTTPMessageIsHeaderComplete(client->message_)) {
+                CFURLRef url(CFHTTPMessageCopyRequestURL(client->message_));
+                Boolean absolute;
+                CFStringRef path(CFURLCopyStrictPath(url, &absolute));
+                CFRelease(client->message_);
+
+                CFStringRef code(CFURLCreateStringByReplacingPercentEscapes(kCFAllocatorDefault, path, CFSTR("")));
+                CFRelease(path);
+
+                JSStringRef script(JSStringCreateWithCFString(code));
+                CFRelease(code);
+
+                JSValueRef result(JSEvaluateScript(CYGetJSContext(), script, NULL, NULL, 0, NULL));
+                JSStringRelease(script);
+
+                CFHTTPMessageRef response(CFHTTPMessageCreateResponse(kCFAllocatorDefault, 200, NULL, kCFHTTPVersion1_1));
+                CFHTTPMessageSetHeaderFieldValue(response, CFSTR("Content-Type"), CFSTR("application/json; charset=utf-8"));
+
+                CFStringRef json(CYCopyJSONString(CYGetJSContext(), result, NULL));
+                CFDataRef body(CFStringCreateExternalRepresentation(kCFAllocatorDefault, json, kCFStringEncodingUTF8, NULL));
+                CFRelease(json);
+
+                CFStringRef length(CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%u"), CFDataGetLength(body)));
+                CFHTTPMessageSetHeaderFieldValue(response, CFSTR("Content-Length"), length);
+                CFRelease(length);
+
+                CFHTTPMessageSetBody(response, body);
+                CFRelease(body);
+
+                CFDataRef serialized(CFHTTPMessageCopySerializedMessage(response));
+                CFRelease(response);
+
+                CFSocketSendData(socket, NULL, serialized, 0);
+                CFRelease(serialized);
+
+                CFRelease(url);
+            }
+        break;
+    }
+}
+
+static void OnAccept(CFSocketRef socket, CFSocketCallBackType type, CFDataRef address, const void *value, void *info) {
+    switch (type) {
+        case kCFSocketAcceptCallBack:
+            Client *client(new Client());
+
+            client->message_ = NULL;
+
+            CFSocketContext context;
+            context.version = 0;
+            context.info = client;
+            context.retain = NULL;
+            context.release = NULL;
+            context.copyDescription = NULL;
+
+            client->socket_ = CFSocketCreateWithNative(kCFAllocatorDefault, *reinterpret_cast<const CFSocketNativeHandle *>(value), kCFSocketDataCallBack, &OnData, &context);
+
+            CFRunLoopAddSource(CFRunLoopGetCurrent(), CFSocketCreateRunLoopSource(kCFAllocatorDefault, client->socket_, 0), kCFRunLoopDefaultMode);
+        break;
+    }
+}
+
+int main(int argc, char *argv[]) {
+    {
+        struct sockaddr_in address;
+        address.sin_len = sizeof(address);
+        address.sin_family = AF_INET;
+        address.sin_addr.s_addr = INADDR_ANY;
+        address.sin_port = htons(787);
+
+        CFDataRef data(CFDataCreate(kCFAllocatorDefault, reinterpret_cast<UInt8 *>(&address), sizeof(address)));
+
+        CFSocketSignature signature;
+        signature.protocolFamily = AF_INET;
+        signature.socketType = SOCK_STREAM;
+        signature.protocol = IPPROTO_TCP;
+        signature.address = data;
+
+        CFSocketRef socket(CFSocketCreateWithSocketSignature(kCFAllocatorDefault, &signature, kCFSocketAcceptCallBack, &OnAccept, NULL));
+        CFRunLoopAddSource(CFRunLoopGetCurrent(), CFSocketCreateRunLoopSource(kCFAllocatorDefault, socket, 0), kCFRunLoopDefaultMode);
+    }
+
+    {
+        CYServer *server(new CYServer());
+        server->socket_ = _syscall(socket(PF_UNIX, SOCK_STREAM, 0));
+
+        struct sockaddr_un address;
+        memset(&address, 0, sizeof(address));
+        address.sun_family = AF_UNIX;
+
+        sprintf(address.sun_path, "/tmp/.s.cy");
+    }
+}
diff --git a/Server.mm b/Server.mm
deleted file mode 100644 (file)
index 8ce7811..0000000
--- a/Server.mm
+++ /dev/null
@@ -1,139 +0,0 @@
-/* Cycript - Remove Execution Server and Disassembler
- * Copyright (C) 2009  Jay Freeman (saurik)
-*/
-
-/* Modified BSD License {{{ */
-/*
- *        Redistribution and use in source and binary
- * forms, with or without modification, are permitted
- * provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the
- *    above copyright notice, this list of conditions
- *    and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the
- *    above copyright notice, this list of conditions
- *    and the following disclaimer in the documentation
- *    and/or other materials provided with the
- *    distribution.
- * 3. The name of the author may not be used to endorse
- *    or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-/* }}} */
-
-#include <CFNetwork/CFNetwork.h>
-
-struct Client {
-    CFHTTPMessageRef message_;
-    CFSocketRef socket_;
-};
-
-static void OnData(CFSocketRef socket, CFSocketCallBackType type, CFDataRef address, const void *value, void *info) {
-    switch (type) {
-        case kCFSocketDataCallBack:
-            CFDataRef data(reinterpret_cast<CFDataRef>(value));
-            Client *client(reinterpret_cast<Client *>(info));
-
-            if (client->message_ == NULL)
-                client->message_ = CFHTTPMessageCreateEmpty(kCFAllocatorDefault, TRUE);
-
-            if (!CFHTTPMessageAppendBytes(client->message_, CFDataGetBytePtr(data), CFDataGetLength(data)))
-                CFLog(kCFLogLevelError, CFSTR("CFHTTPMessageAppendBytes()"));
-            else if (CFHTTPMessageIsHeaderComplete(client->message_)) {
-                CFURLRef url(CFHTTPMessageCopyRequestURL(client->message_));
-                Boolean absolute;
-                CFStringRef path(CFURLCopyStrictPath(url, &absolute));
-                CFRelease(client->message_);
-
-                CFStringRef code(CFURLCreateStringByReplacingPercentEscapes(kCFAllocatorDefault, path, CFSTR("")));
-                CFRelease(path);
-
-                JSStringRef script(JSStringCreateWithCFString(code));
-                CFRelease(code);
-
-                JSValueRef result(JSEvaluateScript(CYGetJSContext(), script, NULL, NULL, 0, NULL));
-                JSStringRelease(script);
-
-                CFHTTPMessageRef response(CFHTTPMessageCreateResponse(kCFAllocatorDefault, 200, NULL, kCFHTTPVersion1_1));
-                CFHTTPMessageSetHeaderFieldValue(response, CFSTR("Content-Type"), CFSTR("application/json; charset=utf-8"));
-
-                CFStringRef json(CYCopyJSONString(CYGetJSContext(), result, NULL));
-                CFDataRef body(CFStringCreateExternalRepresentation(kCFAllocatorDefault, json, kCFStringEncodingUTF8, NULL));
-                CFRelease(json);
-
-                CFStringRef length(CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%u"), CFDataGetLength(body)));
-                CFHTTPMessageSetHeaderFieldValue(response, CFSTR("Content-Length"), length);
-                CFRelease(length);
-
-                CFHTTPMessageSetBody(response, body);
-                CFRelease(body);
-
-                CFDataRef serialized(CFHTTPMessageCopySerializedMessage(response));
-                CFRelease(response);
-
-                CFSocketSendData(socket, NULL, serialized, 0);
-                CFRelease(serialized);
-
-                CFRelease(url);
-            }
-        break;
-    }
-}
-
-static void OnAccept(CFSocketRef socket, CFSocketCallBackType type, CFDataRef address, const void *value, void *info) {
-    switch (type) {
-        case kCFSocketAcceptCallBack:
-            Client *client(new Client());
-
-            client->message_ = NULL;
-
-            CFSocketContext context;
-            context.version = 0;
-            context.info = client;
-            context.retain = NULL;
-            context.release = NULL;
-            context.copyDescription = NULL;
-
-            client->socket_ = CFSocketCreateWithNative(kCFAllocatorDefault, *reinterpret_cast<const CFSocketNativeHandle *>(value), kCFSocketDataCallBack, &OnData, &context);
-
-            CFRunLoopAddSource(CFRunLoopGetCurrent(), CFSocketCreateRunLoopSource(kCFAllocatorDefault, client->socket_, 0), kCFRunLoopDefaultMode);
-        break;
-    }
-}
-
-MSInitialize {
-    pid_t pid(getpid());
-
-    struct sockaddr_in address;
-    address.sin_len = sizeof(address);
-    address.sin_family = AF_INET;
-    address.sin_addr.s_addr = INADDR_ANY;
-    address.sin_port = htons(10000 + pid);
-
-    CFDataRef data(CFDataCreate(kCFAllocatorDefault, reinterpret_cast<UInt8 *>(&address), sizeof(address)));
-
-    CFSocketSignature signature;
-    signature.protocolFamily = AF_INET;
-    signature.socketType = SOCK_STREAM;
-    signature.protocol = IPPROTO_TCP;
-    signature.address = data;
-
-    CFSocketRef socket(CFSocketCreateWithSocketSignature(kCFAllocatorDefault, &signature, kCFSocketAcceptCallBack, &OnAccept, NULL));
-    CFRunLoopAddSource(CFRunLoopGetCurrent(), CFSocketCreateRunLoopSource(kCFAllocatorDefault, socket, 0), kCFRunLoopDefaultMode);
-}
diff --git a/com.saurik.Cyrver.plist b/com.saurik.Cyrver.plist
new file mode 100644 (file)
index 0000000..4c3cada
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+    <key>Label</key>
+    <string>com.saurik.Cyrver</string>
+
+    <key>ProgramArguments</key>
+    <array>
+        <string>/usr/sbin/cyrver</string>
+    </array>
+
+    <key>OnDemand</key>
+    <false/>
+</dict>
+</plist>
index 7ed35d28151ae31fe531dd3f392ee139b6e91c36..b153d52123f32700423732b137b7879631a42be4 100644 (file)
--- a/makefile
+++ b/makefile
@@ -9,7 +9,7 @@ flags += -F${PKG_ROOT}/System/Library/PrivateFrameworks
 
 svn := $(shell svnversion)
 deb := $(shell grep ^Package: control | cut -d ' ' -f 2-)_$(shell grep ^Version: control | cut -d ' ' -f 2 | sed -e 's/\#/$(svn)/')_iphoneos-arm.deb
-all := cycript libcycript.dylib libcycript.plist Cycript.dylib
+all := cycript libcycript.dylib libcycript.plist Cycript.dylib #cyrver
 
 header := Cycript.tab.hh Parser.hpp Pooling.hpp Struct.hpp cycript.hpp
 
@@ -58,6 +58,12 @@ lex.cy.o: lex.cy.c Cycript.tab.hh Parser.hpp Pooling.hpp
 %.o: %.mm $(header)
        $(target)g++ $(flags) -c -o $@ $<
 
+cyrver: Server.o
+       $(target)g++ $(flags) -o $@ $(filter %.o,$^) \
+           -lobjc -lapr-1 -lsubstrate \
+           -framework CoreFoundation -framework CFNetwork
+       ldid -S $@
+
 Cycript.dylib: Connector.o
        $(target)g++ $(flags) -dynamiclib -o $@ $(filter %.o,$^) \
            -lobjc -lapr-1 -lsubstrate \
@@ -85,6 +91,8 @@ $(deb): $(all)
        rm -rf package
        mkdir -p package/DEBIAN
        sed -e 's/#/$(svn)/' control >package/DEBIAN/control
+       mkdir -p package/System/Library/LaunchDaemons
+       cp -a com.saurik.Cyrver.plist package/System/Library/LaunchDaemons
        mkdir -p package/Library/MobileSubstrate/DynamicLibraries
        if [[ -e Settings.plist ]]; then \
            mkdir -p package/Library/PreferenceLoader/Preferences; \
@@ -93,9 +101,10 @@ $(deb): $(all)
        fi
        if [[ -e Tweak.plist ]]; then cp -a Tweak.plist package/Library/MobileSubstrate/DynamicLibraries/Cycript.plist; fi
        cp -a Cycript.dylib package/Library/MobileSubstrate/DynamicLibraries
-       mkdir -p package/usr/{bin,lib}
+       mkdir -p package/usr/{bin,lib,sbin}
        cp -a libcycript.dylib package/usr/lib
        cp -a cycript package/usr/bin
+       #cp -a cyrver package/usr/sbin
        cp -a libcycript.plist package/usr/lib
        dpkg-deb -b package $(deb)
 
index 93b78136c7a4e3658e74be741f4d88eee6a4262f..313eb14949da0b2fabcb345d31aa170a38f48bd2 100644 (file)
--- a/todo.txt
+++ b/todo.txt
@@ -1,7 +1,8 @@
 labelled statements don't get labelled
 blocks and empty statements are poorly factored
-functors use both ffiData and ffoData...
+Message : Function, Closure : Function !!
 rename "data" variables to "internal"
 unicode identifier support (native and \u)
 object literal compilation should use numerify strings
 support unions (right now 0-1 fields parsed as struct)
+Prototype's prototype needs to be the superclass Prototype