]> 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() {
-        CYClient_ *client = [[CYClient_ alloc] init];
-        @try {
+        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+        CYClient_ *client = [[[CYClient_ alloc] init] autorelease];
 
         for (;;) {
             size_t size;
@@ -133,9 +134,7 @@ struct CYClient :
                     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];
-    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 }
@@ -1309,7 +1313,7 @@ const char *CYExecute(apr_pool_t *pool, const char *code) {
 
     void *handle;
     if (hooks_ != NULL && hooks_->ExecuteStart != NULL)
-        handle = (*hooks_->ExecuteStart)();
+        handle = (*hooks_->ExecuteStart)(context);
     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)
-        (*hooks_->ExecuteEnd)(handle);
+        (*hooks_->ExecuteEnd)(context, handle);
     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;
+- (void) cy$getPropertyNames:(JSPropertyNameAccumulatorRef)names;
 
 @end
 
@@ -641,6 +642,19 @@ NSObject *CYCopyNSObject(apr_pool_t *pool, JSContextRef context, JSValueRef valu
         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 {{{ */
@@ -679,6 +693,19 @@ NSObject *CYCopyNSObject(apr_pool_t *pool, JSContextRef context, JSValueRef valu
     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 {{{ */
@@ -837,6 +864,9 @@ NSObject *CYCopyNSObject(apr_pool_t *pool, JSContextRef context, JSValueRef valu
     return false;
 }
 
+- (void) cy$getPropertyNames:(JSPropertyNameAccumulatorRef)names {
+}
+
 @end
 /* }}} */
 /* Bridge: NSProxy {{{ */
@@ -1150,23 +1180,29 @@ static SEL CYCastSEL(JSContextRef context, JSValueRef value) {
         return CYCastPointer<SEL>(context, value);
 }
 
-void *CYObjectiveC_ExecuteStart() {
+void *CYObjectiveC_ExecuteStart(JSContextRef context) {
+    // XXX: deal with exceptions!
     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];
 }
 
-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;
-}
+} 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:
@@ -1182,9 +1218,9 @@ static bool CYObjectiveC_PoolFFI(apr_pool_t *pool, JSContextRef context, sig::Ty
     }
 
     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)) {
@@ -1207,12 +1243,13 @@ static JSValueRef CYObjectiveC_FromFFI(JSContextRef context, sig::Type *type, ff
         default:
             return NULL;
     }
-}
+} CYObjectiveCatch }
 
-CYHooks CYObjectiveCHooks = {
+static CYHooks CYObjectiveCHooks = {
     &CYObjectiveC_ExecuteStart,
     &CYObjectiveC_ExecuteEnd,
     &CYObjectiveC_RuntimeProperty,
+    &CYObjectiveC_CallFunction,
     &CYObjectiveC_PoolFFI,
     &CYObjectiveC_FromFFI,
 };
@@ -1543,6 +1580,12 @@ static void Instance_getPropertyNames(JSContextRef context, JSObjectRef object,
         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 {
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 {
-    void *(*ExecuteStart)();
-    void (*ExecuteEnd)(void *);
+    void *(*ExecuteStart)(JSContextRef);
+    void (*ExecuteEnd)(JSContextRef, void *);
+
     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);
 };
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
-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...