]> git.saurik.com Git - cycript.git/commitdiff
Added getPropertyNames bridging (albeit lame) and fixed exception handling through...
authorJay Freeman (saurik) <saurik@saurik.com>
Wed, 28 Oct 2009 01:27:41 +0000 (01:27 +0000)
committerJay Freeman (saurik) <saurik@saurik.com>
Wed, 28 Oct 2009 01:27:41 +0000 (01:27 +0000)
Handler.mm
Library.cpp
ObjectiveC/Library.mm
cycript.hpp
todo.txt

index 39825fab9bffd60f5ac9ccd268cf7d61b0809422..016f0c8bc1aeebde97ae18728534800041cc5754 100644 (file)
@@ -89,8 +89,9 @@ struct CYClient :
     }
 
     void Handle() {
     }
 
     void Handle() {
-        CYClient_ *client = [[CYClient_ alloc] init];
-        @try {
+        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+        CYClient_ *client = [[[CYClient_ alloc] init] autorelease];
 
         for (;;) {
             size_t size;
 
         for (;;) {
             size_t size;
@@ -133,9 +134,7 @@ struct CYClient :
                     return;
         }
 
                     return;
         }
 
-        } @finally {
-            [client release];
-        }
+        [pool release];
     }
 };
 
     }
 };
 
index 555cd8a2e95ad7b35c31218d680932b3fee03275..eba549acefd6b1d4eca534ed0bb1da0a2a6533ba 100644 (file)
@@ -1036,7 +1036,11 @@ JSValueRef CYCallFunction(apr_pool_t *pool, JSContextRef context, size_t setups,
     }
 
     uint8_t value[cif->rtype->size];
     }
 
     uint8_t value[cif->rtype->size];
-    ffi_call(cif, function, value, values);
+
+    if (hooks_ != NULL && hooks_->CallFunction != NULL)
+        (*hooks_->CallFunction)(context, cif, function, value, values);
+    else
+        ffi_call(cif, function, value, values);
 
     return CYFromFFI(context, signature->elements[0].type, cif->rtype, value, initialize);
 } CYCatch }
 
     return CYFromFFI(context, signature->elements[0].type, cif->rtype, value, initialize);
 } CYCatch }
@@ -1309,7 +1313,7 @@ const char *CYExecute(apr_pool_t *pool, const char *code) {
 
     void *handle;
     if (hooks_ != NULL && hooks_->ExecuteStart != NULL)
 
     void *handle;
     if (hooks_ != NULL && hooks_->ExecuteStart != NULL)
-        handle = (*hooks_->ExecuteStart)();
+        handle = (*hooks_->ExecuteStart)(context);
     else
         handle = NULL;
 
     else
         handle = NULL;
 
@@ -1341,7 +1345,7 @@ const char *CYExecute(apr_pool_t *pool, const char *code) {
     CYSetProperty(context, CYGetGlobalObject(context), Result_, result);
 
     if (hooks_ != NULL && hooks_->ExecuteEnd != NULL)
     CYSetProperty(context, CYGetGlobalObject(context), Result_, result);
 
     if (hooks_ != NULL && hooks_->ExecuteEnd != NULL)
-        (*hooks_->ExecuteEnd)(handle);
+        (*hooks_->ExecuteEnd)(context, handle);
     return json;
 }
 
     return json;
 }
 
index ee511c2e62ca8e3644f3733bb2c77eac082444e0..bec1730e63d85d36fabd85937cfde23b2d7014d0 100644 (file)
@@ -307,6 +307,7 @@ JSObjectRef CYMakeInstance(JSContextRef context, id object, bool transient) {
 - (NSObject *) cy$getProperty:(NSString *)name;
 - (bool) cy$setProperty:(NSString *)name to:(NSObject *)value;
 - (bool) cy$deleteProperty:(NSString *)name;
 - (NSObject *) cy$getProperty:(NSString *)name;
 - (bool) cy$setProperty:(NSString *)name to:(NSObject *)value;
 - (bool) cy$deleteProperty:(NSString *)name;
+- (void) cy$getPropertyNames:(JSPropertyNameAccumulatorRef)names;
 
 @end
 
 
 @end
 
@@ -641,6 +642,19 @@ NSObject *CYCopyNSObject(apr_pool_t *pool, JSContextRef context, JSValueRef valu
         return [self objectAtIndex:index];
 }
 
         return [self objectAtIndex:index];
 }
 
+- (void) cy$getPropertyNames:(JSPropertyNameAccumulatorRef)names {
+    [super cy$getPropertyNames:names];
+
+    for (size_t index(0), count([self count]); index != count; ++index) {
+        id object([self objectAtIndex:index]);
+        if (object == nil || [object cy$JSType] != kJSTypeUndefined) {
+            char name[32];
+            sprintf(name, "%zu", index);
+            JSPropertyNameAccumulatorAddName(names, CYJSString(name));
+        }
+    }
+}
+
 @end
 /* }}} */
 /* Bridge: NSDictionary {{{ */
 @end
 /* }}} */
 /* Bridge: NSDictionary {{{ */
@@ -679,6 +693,19 @@ NSObject *CYCopyNSObject(apr_pool_t *pool, JSContextRef context, JSValueRef valu
     return [self objectForKey:name];
 }
 
     return [self objectForKey:name];
 }
 
+- (void) cy$getPropertyNames:(JSPropertyNameAccumulatorRef)names {
+    [super cy$getPropertyNames:names];
+
+#ifdef __APPLE__
+    for (NSString *key in self) {
+#else
+    NSEnumerator *keys([self keyEnumerator]);
+    while (NSString *key = [keys nextObject]) {
+#endif
+        JSPropertyNameAccumulatorAddName(names, CYJSString(key));
+    }
+}
+
 @end
 /* }}} */
 /* Bridge: NSMutableArray {{{ */
 @end
 /* }}} */
 /* Bridge: NSMutableArray {{{ */
@@ -837,6 +864,9 @@ NSObject *CYCopyNSObject(apr_pool_t *pool, JSContextRef context, JSValueRef valu
     return false;
 }
 
     return false;
 }
 
+- (void) cy$getPropertyNames:(JSPropertyNameAccumulatorRef)names {
+}
+
 @end
 /* }}} */
 /* Bridge: NSProxy {{{ */
 @end
 /* }}} */
 /* Bridge: NSProxy {{{ */
@@ -1150,23 +1180,29 @@ static SEL CYCastSEL(JSContextRef context, JSValueRef value) {
         return CYCastPointer<SEL>(context, value);
 }
 
         return CYCastPointer<SEL>(context, value);
 }
 
-void *CYObjectiveC_ExecuteStart() {
+void *CYObjectiveC_ExecuteStart(JSContextRef context) {
+    // XXX: deal with exceptions!
     return (void *) [[NSAutoreleasePool alloc] init];
 }
 
     return (void *) [[NSAutoreleasePool alloc] init];
 }
 
-void CYObjectiveC_ExecuteEnd(void *handle) {
+void CYObjectiveC_ExecuteEnd(JSContextRef context, void *handle) {
+    // XXX: deal with exceptions!
     return [(NSAutoreleasePool *) handle release];
 }
 
     return [(NSAutoreleasePool *) handle release];
 }
 
-JSValueRef CYObjectiveC_RuntimeProperty(JSContextRef context, CYUTF8String name) {
+JSValueRef CYObjectiveC_RuntimeProperty(JSContextRef context, CYUTF8String name) { CYObjectiveTry_(context) {
     if (name == "nil")
         return Instance::Make(context, nil);
     if (Class _class = objc_getClass(name.data))
         return CYMakeInstance(context, _class, true);
     return NULL;
     if (name == "nil")
         return Instance::Make(context, nil);
     if (Class _class = objc_getClass(name.data))
         return CYMakeInstance(context, _class, true);
     return NULL;
-}
+} CYObjectiveCatch }
+
+static void CYObjectiveC_CallFunction(JSContextRef context, ffi_cif *cif, void (*function)(), uint8_t *value, void **values) { CYObjectiveTry_(context) {
+    ffi_call(cif, function, value, values);
+} CYObjectiveCatch }
 
 
-static bool CYObjectiveC_PoolFFI(apr_pool_t *pool, JSContextRef context, sig::Type *type, ffi_type *ffi, void *data, JSValueRef value) {
+static bool CYObjectiveC_PoolFFI(apr_pool_t *pool, JSContextRef context, sig::Type *type, ffi_type *ffi, void *data, JSValueRef value) { CYObjectiveTry_(context) {
     switch (type->primitive) {
         case sig::object_P:
         case sig::typename_P:
     switch (type->primitive) {
         case sig::object_P:
         case sig::typename_P:
@@ -1182,9 +1218,9 @@ static bool CYObjectiveC_PoolFFI(apr_pool_t *pool, JSContextRef context, sig::Ty
     }
 
     return true;
     }
 
     return true;
-}
+} CYObjectiveCatch }
 
 
-static JSValueRef CYObjectiveC_FromFFI(JSContextRef context, sig::Type *type, ffi_type *ffi, void *data, bool initialize, JSObjectRef owner) {
+static JSValueRef CYObjectiveC_FromFFI(JSContextRef context, sig::Type *type, ffi_type *ffi, void *data, bool initialize, JSObjectRef owner) { CYObjectiveTry_(context) {
     switch (type->primitive) {
         case sig::object_P:
             if (id object = *reinterpret_cast<id *>(data)) {
     switch (type->primitive) {
         case sig::object_P:
             if (id object = *reinterpret_cast<id *>(data)) {
@@ -1207,12 +1243,13 @@ static JSValueRef CYObjectiveC_FromFFI(JSContextRef context, sig::Type *type, ff
         default:
             return NULL;
     }
         default:
             return NULL;
     }
-}
+} CYObjectiveCatch }
 
 
-CYHooks CYObjectiveCHooks = {
+static CYHooks CYObjectiveCHooks = {
     &CYObjectiveC_ExecuteStart,
     &CYObjectiveC_ExecuteEnd,
     &CYObjectiveC_RuntimeProperty,
     &CYObjectiveC_ExecuteStart,
     &CYObjectiveC_ExecuteEnd,
     &CYObjectiveC_RuntimeProperty,
+    &CYObjectiveC_CallFunction,
     &CYObjectiveC_PoolFFI,
     &CYObjectiveC_FromFFI,
 };
     &CYObjectiveC_PoolFFI,
     &CYObjectiveC_FromFFI,
 };
@@ -1543,6 +1580,12 @@ static void Instance_getPropertyNames(JSContextRef context, JSObjectRef object,
         free(data);
     }
 #endif
         free(data);
     }
 #endif
+
+    CYPoolTry {
+        // XXX: this is an evil hack to deal with NSProxy; fix elsewhere
+        if (CYImplements(self, _class, @selector(cy$getPropertyNames:), false))
+            [self cy$getPropertyNames:names];
+    } CYPoolCatch()
 }
 
 static JSObjectRef Instance_callAsConstructor(JSContextRef context, JSObjectRef object, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
 }
 
 static JSObjectRef Instance_callAsConstructor(JSContextRef context, JSObjectRef object, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
index 316a37dbf987d1a2472b0f5ef22144cad9c9e6b0..87d8d2c4950ae05131c715bea482ffdb0ba57dec 100644 (file)
@@ -119,9 +119,12 @@ JSValueRef CYCallAsFunction(JSContextRef context, JSObjectRef function, JSObject
 const char *CYPoolCCYON(apr_pool_t *pool, JSContextRef context, JSObjectRef object);
 
 struct CYHooks {
 const char *CYPoolCCYON(apr_pool_t *pool, JSContextRef context, JSObjectRef object);
 
 struct CYHooks {
-    void *(*ExecuteStart)();
-    void (*ExecuteEnd)(void *);
+    void *(*ExecuteStart)(JSContextRef);
+    void (*ExecuteEnd)(JSContextRef, void *);
+
     JSValueRef (*RuntimeProperty)(JSContextRef, CYUTF8String);
     JSValueRef (*RuntimeProperty)(JSContextRef, CYUTF8String);
+    void (*CallFunction)(JSContextRef, ffi_cif *, void (*)(), uint8_t *, void **);
+
     bool (*PoolFFI)(apr_pool_t *, JSContextRef, sig::Type *, ffi_type *, void *, JSValueRef);
     JSValueRef (*FromFFI)(JSContextRef, sig::Type *, ffi_type *, void *, bool, JSObjectRef);
 };
     bool (*PoolFFI)(apr_pool_t *, JSContextRef, sig::Type *, ffi_type *, void *, JSValueRef);
     JSValueRef (*FromFFI)(JSContextRef, sig::Type *, ffi_type *, void *, bool, JSObjectRef);
 };
index b6ee18d87fa55f7c6c32754beb9afe1d45a2663d..2308e3da8c6f34a0eb0b8f8af7ed5e4197f440da 100644 (file)
--- a/todo.txt
+++ b/todo.txt
@@ -4,4 +4,5 @@ support unions (right now 0-1 fields parsed as struct)
 \\\n escapes in strings aren't handled in the console
 look into what String is, and whether to bridge it
 the console frontend's error handling, well, doesn't
 \\\n escapes in strings aren't handled in the console
 look into what String is, and whether to bridge it
 the console frontend's error handling, well, doesn't
-Objective-C needs to be able to hook ffi_call for errors
+setup a default hook mechanism for ffi_call passthrough
+some JS callbacks don't use exception pointers at all...