]> git.saurik.com Git - cycript.git/commitdiff
Protect bash glob expansions while generating libcycript.plist (thanks to kennytm...
authorJay Freeman (saurik) <saurik@saurik.com>
Mon, 12 Oct 2009 19:32:44 +0000 (19:32 +0000)
committerJay Freeman (saurik) <saurik@saurik.com>
Mon, 12 Oct 2009 19:32:44 +0000 (19:32 +0000)
Library.mm
makefile
sig/parse.hpp

index 6605c567a007a5055274d0ee912480506e66211a..e66f58195c65cdb7384e7720b8daaa78febdfe82 100644 (file)
@@ -366,7 +366,7 @@ JSObjectRef CYMakeStruct(JSContextRef context, void *data, sig::Type *type, ffi_
     return JSObjectMake(context, Struct_, internal);
 }
 
-void Structor_(apr_pool_t *pool, const char *name, const char *types, sig::Type *type) {
+void Structor_(apr_pool_t *pool, const char *name, const char *types, sig::Type *&type) {
     if (name == NULL)
         return;
 
@@ -408,7 +408,7 @@ struct ffoData :
     }
 };
 
-JSValueRef CYMakeInstance(JSContextRef context, id object, bool transient) {
+JSObjectRef CYMakeInstance(JSContextRef context, id object, bool transient) {
     Instance::Flags flags;
 
     if (transient)
@@ -487,14 +487,16 @@ bool CYGetIndex(apr_pool_t *pool, NSString *value, ssize_t &index) {
 - (NSString *) cy$toCYON;
 - (NSString *) cy$toKey;
 
-- (JSValueRef) cy$JSValueInContext:(JSContextRef)context;
-
 - (NSObject *) cy$getProperty:(NSString *)name;
 - (bool) cy$setProperty:(NSString *)name to:(NSObject *)value;
 - (bool) cy$deleteProperty:(NSString *)name;
 
 @end
 
+@protocol Cycript
+- (JSValueRef) cy$JSValueInContext:(JSContextRef)context;
+@end
+
 @interface NSString (Cycript)
 - (void *) cy$symbol;
 @end
@@ -607,10 +609,6 @@ struct PropertyAttributes {
     return [self cy$toCYON];
 }
 
-- (JSValueRef) cy$JSValueInContext:(JSContextRef)context {
-    return CYMakeInstance(context, self, false);
-}
-
 - (NSObject *) cy$getProperty:(NSString *)name {
     /*if (![name isEqualToString:@"prototype"])
         NSLog(@"get:%@", name);*/
@@ -1144,7 +1142,12 @@ JSValueRef CYCastJSValue(JSContextRef context, const char *value) {
 }
 
 JSValueRef CYCastJSValue(JSContextRef context, id value) {
-    return value == nil ? CYJSNull(context) : [value cy$JSValueInContext:context];
+    if (value == nil)
+        return CYJSNull(context);
+    else if ([value respondsToSelector:@selector(cy$JSValueInContext:)])
+        return [value cy$JSValueInContext:context];
+    else
+        return CYMakeInstance(context, value, false);
 }
 
 JSObjectRef CYCastJSObject(JSContextRef context, JSValueRef value) {
@@ -1864,25 +1867,6 @@ static JSValueRef System_print(JSContextRef context, JSObjectRef object, JSObjec
     } CYCatch
 }
 
-static JSValueRef CYApplicationMain(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) {
-    CYTry {
-        CYPool pool;
-
-        int argc(CYCastDouble(context, arguments[0]));
-        char **argv(CYCastPointer<char **>(context, arguments[1]));
-        NSString *principal(CYCastNSObject(pool, context, arguments[2]));
-        NSString *delegate(CYCastNSObject(pool, context, arguments[3]));
-
-        argc = *_NSGetArgc() - 1;
-        argv = *_NSGetArgv() + 1;
-        for (int i(0); i != argc; ++i)
-            NSLog(@"argv[%i]=%s", i, argv[i]);
-
-        _pooled
-        return CYCastJSValue(context, UIApplicationMain(argc, argv, principal, delegate));
-    } CYCatch
-}
-
 JSValueRef CYSendMessage(apr_pool_t *pool, JSContextRef context, id self, SEL _cmd, size_t count, const JSValueRef arguments[], bool initialize, JSValueRef *exception) {
     const char *type;
 
@@ -1944,6 +1928,35 @@ static JSValueRef $objc_msgSend(JSContextRef context, JSObjectRef object, JSObje
     return CYSendMessage(pool, context, self, _cmd, count - 2, arguments + 2, uninitialized, exception);
 }
 
+static JSValueRef CYJSValueInContext(id self, SEL _cmd, JSContextRef context) {
+    // XXX: the offset of this Ivar could be recomputed and stored in some form of closure during $objc_registerClassPair
+
+    JSObjectRef value;
+    object_getInstanceVariable(self, "cy$value_", reinterpret_cast<void **>(&value));
+
+    if (value == NULL) {
+        value = CYMakeInstance(context, self, false);
+        object_setInstanceVariable(self, "cy$value_", value);
+    }
+
+    return value;
+}
+
+static JSValueRef $objc_registerClassPair(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) {
+    CYTry {
+        CYPool pool;
+
+        Class _class(CYCastNSObject(pool, context, object));
+        if (class_getInstanceMethod(_class, @selector(cy$JSValueInContext:)) == NULL) {
+            class_addIvar(_class, "cy$value_", sizeof(JSObjectRef), log2(sizeof(JSObjectRef)), "^v");
+            class_addMethod(_class, @selector(cy$JSValueInContext:), reinterpret_cast<IMP>(&CYJSValueInContext), "^v12@0:4^v8");
+        }
+
+        objc_registerClassPair(_class);
+        return CYJSUndefined(context);
+    } CYCatch
+}
+
 static JSValueRef Selector_callAsFunction(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) {
     JSValueRef setup[count + 2];
     setup[0] = _this;
@@ -1967,6 +1980,23 @@ JSObjectRef Selector_new(JSContextRef context, JSObjectRef object, size_t count,
     } CYCatch
 }
 
+JSObjectRef Pointer_new(JSContextRef context, JSObjectRef object, size_t count, const JSValueRef arguments[], JSValueRef *exception) {
+    CYTry {
+        if (count != 2)
+            @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"incorrect number of arguments to Functor constructor" userInfo:nil];
+
+        void *value(CYCastPointer<void *>(context, arguments[0]));
+        const char *type(CYCastCString(context, arguments[1]));
+
+        CYPool pool;
+
+        sig::Signature signature;
+        sig::Parse(pool, &signature, type, &Structor_);
+
+        return CYMakePointer(context, value, signature.elements[0].type, NULL);
+    } CYCatch
+}
+
 JSObjectRef Functor_new(JSContextRef context, JSObjectRef object, size_t count, const JSValueRef arguments[], JSValueRef *exception) {
     CYTry {
         if (count != 2)
@@ -2225,10 +2255,11 @@ MSInitialize { _pooled
     JSObjectSetPrototype(context, global, JSObjectMake(context, Runtime_, NULL));
     CYSetProperty(context, global, CYJSString("ObjectiveC"), JSObjectMake(context, Runtime_, NULL));
 
-    CYSetProperty(context, global, CYJSString("Selector"), JSObjectMakeConstructor(context, Selector_, &Selector_new));
     CYSetProperty(context, global, CYJSString("Functor"), JSObjectMakeConstructor(context, Functor_, &Functor_new));
+    CYSetProperty(context, global, CYJSString("Pointer"), JSObjectMakeConstructor(context, Pointer_, &Pointer_new));
+    CYSetProperty(context, global, CYJSString("Selector"), JSObjectMakeConstructor(context, Selector_, &Selector_new));
 
-    CYSetProperty(context, global, CYJSString("CYApplicationMain"), JSObjectMakeFunctionWithCallback(context, CYJSString("CYApplicationMain"), &CYApplicationMain));
+    CYSetProperty(context, global, CYJSString("objc_registerClassPair"), JSObjectMakeFunctionWithCallback(context, CYJSString("objc_registerClassPair"), &$objc_registerClassPair));
     CYSetProperty(context, global, CYJSString("objc_msgSend"), JSObjectMakeFunctionWithCallback(context, CYJSString("objc_msgSend"), &$objc_msgSend));
 
     System_ = JSObjectMake(context, NULL, NULL);
index 3b3229d399d140938f68f21906023fba10312ac9..20c4123aa2b614ebfcfb8987bd9d5b7f5a8aef08 100644 (file)
--- a/makefile
+++ b/makefile
@@ -12,6 +12,8 @@ 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
 
+header := Cycript.tab.hh Parser.hpp Pooling.hpp Struct.hpp cycript.hpp
+
 all: cycript libcycript.dylib libcycript.plist
 
 clean:
@@ -20,20 +22,11 @@ clean:
 libcycript.plist: Bridge.def
        { \
            echo '({'; \
-           grep '^[CFV]' Bridge.def | sed -e 's/^C/0/;s/^F/1/;s/^V/2/' | while read -r line; do \
-               if [[ $$line == '' ]]; then \
-                   continue; \
-               fi; \
-               set $$line; \
-               echo "$$2 = ($$1, \"$${3//\"/\\\"}\");";  \
-           done; \
+           grep '^[CFV]' Bridge.def | sed -e 's/^C/0/;s/^F/1/;s/^V/2/' | sed -e 's/"/\\"/g;s/^\([^ ]*\) \([^ ]*\) \(.*\)$$/\2 = (\1, \"\3\");/'; \
            echo '},{'; \
            grep '^:' Bridge.def | sed -e 's/^: \([^ ]*\) \(.*\)/"\1" = "\2";/'; \
            echo '},{'; \
-           grep '^S' Bridge.def | sed -e 's/^S/0/' | while read -r line; do \
-               set $$line; \
-               echo "$$2 = ($$1, \"$${3//\"/\\\"}\");";  \
-           done; \
+           grep '^S' Bridge.def | sed -e 's/^S/0/' | sed -e 's/"/\\"/g;s/^\([^ ]*\) \([^ ]*\) \(.*\)$$/\2 = (\1, \"\3\");/'; \
            echo '})'; \
        } >$@
 
@@ -58,21 +51,27 @@ Cycript.tab.o: Cycript.tab.cc Cycript.tab.hh Parser.hpp Pooling.hpp
 lex.cy.o: lex.cy.c Cycript.tab.hh Parser.hpp Pooling.hpp
        $(target)g++ $(flags) -c -o $@ $<
 
-Output.o: Output.cpp Parser.hpp Pooling.hpp
-       $(target)g++ $(flags) -c -o $@ $<
-
-Library.o: Library.mm Cycript.tab.hh Parser.hpp Pooling.hpp Struct.hpp cycript.hpp
+%.o: %.cpp $(header)
        $(target)g++ $(flags) -c -o $@ $<
 
-Application.o: Application.mm Cycript.tab.hh Parser.hpp Pooling.hpp cycript.hpp
+%.o: %.mm $(header)
        $(target)g++ $(flags) -c -o $@ $<
 
 libcycript.dylib: ffi_type.o parse.o Output.o Cycript.tab.o lex.cy.o Library.o
-       $(target)g++ $(flags) -dynamiclib -o $@ $(filter %.o,$^) -lobjc -framework CFNetwork -framework JavaScriptCore -framework WebCore -install_name /usr/lib/libcycript.dylib -framework CoreFoundation -framework Foundation -L$(menes)/mobilesubstrate -lsubstrate -lapr-1 -lffi -framework UIKit
+       $(target)g++ $(flags) -dynamiclib -o $@ $(filter %.o,$^) \
+           -install_name /usr/lib/libcycript.dylib \
+           -lobjc -lapr-1 -lffi \
+           -framework CoreFoundation -framework Foundation \
+           -framework CFNetwork \
+           -framework JavaScriptCore -framework WebCore
        ldid -S $@
 
 cycript: Application.o libcycript.dylib
-       $(target)g++ $(flags) -o $@ $(filter %.o,$^) -framework UIKit -framework Foundation -framework CoreFoundation -lobjc libcycript.dylib -lreadline -framework JavaScriptCore -lapr-1
+       $(target)g++ $(flags) -o $@ $(filter %.o,$^) \
+           -lobjc -lapr-1 -lreadline \
+           -L. -lcycript \
+           -framework Foundation -framework CoreFoundation \
+           -framework JavaScriptCore -framework UIKit
        ldid -S cycript
 
 package: all
index 230d9b6fa5ba79a2d465d923e194d8595dd4f5d5..5607ad31f1994f8efad665dee39c8a0d0262e078 100644 (file)
@@ -46,7 +46,7 @@
 
 namespace sig {
 
-typedef void (*Callback)(apr_pool_t *pool, const char *name, const char *types, Type *type);
+typedef void (*Callback)(apr_pool_t *pool, const char *name, const char *types, Type *&type);
 void Parse(apr_pool_t *pool, struct Signature *signature, const char *name, Callback callback);
 
 const char *Unparse(apr_pool_t *pool, struct Signature *signature);