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_;
static JSStringRef length_;
static JSStringRef message_;
static JSStringRef name_;
+static JSStringRef prototype_;
static JSStringRef toCYON_;
static JSStringRef toJSON_;
[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));
}
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
{
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;
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());
}
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));
}
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)
}
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));
{
} 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;
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;
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) {
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
}
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
}
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());
} 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)));
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
}
{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}
};
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;
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;
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));
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_;
--- /dev/null
+/* 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");
+ }
+}
+++ /dev/null
-/* 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);
-}