]> git.saurik.com Git - cycript.git/blobdiff - Library.cpp
Removed a virtual to avoid an optimizer vtable bug.
[cycript.git] / Library.cpp
index dbb86f243b860b25882a8ed3cc81ff5f41f92129..0a8508efe03a19ae635b85bc997877e1c3904b09 100644 (file)
@@ -186,19 +186,25 @@ const char *CYPoolCString(apr_pool_t *pool, JSContextRef context, JSValueRef val
 /* Index Offsets {{{ */
 size_t CYGetIndex(const CYUTF8String &value) {
     if (value.data[0] != '0') {
-        char *end;
-        size_t index(strtoul(value.data, &end, 10));
-        if (value.data + value.size == end)
-            return index;
-    } else if (value.data[1] == '\0')
+        size_t index(0);
+        for (size_t i(0); i != value.size; ++i) {
+            if (!DigitRange_[value.data[i]])
+                return _not(size_t);
+            index *= 10;
+            index += value.data[i] - '0';
+        }
+        return index;
+    } else if (value.size == 1)
         return 0;
-    return _not(size_t);
+    else
+        return _not(size_t);
 }
 
 size_t CYGetIndex(apr_pool_t *pool, JSContextRef context, JSStringRef value) {
     return CYGetIndex(CYPoolUTF8String(pool, context, value));
 }
 
+// XXX: this isn't actually right
 bool CYGetOffset(const char *value, ssize_t &index) {
     if (value[0] != '0') {
         char *end;
@@ -334,8 +340,19 @@ struct CStringMapLess :
     }
 };
 
-void Structor_(apr_pool_t *pool, const char *name, const char *types, sig::Type *&type) {
-    if (name == NULL)
+void Structor_(apr_pool_t *pool, sig::Type *&type) {
+    if (
+        type->primitive == sig::pointer_P &&
+        type->data.data.type != NULL &&
+        type->data.data.type->primitive == sig::struct_P &&
+        strcmp(type->data.data.type->name, "_objc_class") == 0
+    ) {
+        type->primitive = sig::typename_P;
+        type->data.data.type = NULL;
+        return;
+    }
+
+    if (type->primitive != sig::struct_P || type->name == NULL)
         return;
 
     sqlite3_stmt *statement;
@@ -351,7 +368,7 @@ void Structor_(apr_pool_t *pool, const char *name, const char *types, sig::Type
         " limit 1"
     , -1, &statement, NULL));
 
-    _sqlcall(sqlite3_bind_text(statement, 1, name, -1, SQLITE_STATIC));
+    _sqlcall(sqlite3_bind_text(statement, 1, type->name, -1, SQLITE_STATIC));
 
     int mode;
     const char *value;
@@ -522,7 +539,7 @@ static size_t Nonce_(0);
 
 static JSValueRef $cyq(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) {
     CYPool pool;
-    const char *name(apr_psprintf(pool, "%s%zu", CYPoolCString(pool, context, arguments[0]), Nonce_++));
+    const char *name(apr_psprintf(pool, "%s%"APR_SIZE_T_FMT"", CYPoolCString(pool, context, arguments[0]), Nonce_++));
     return CYCastJSValue(context, name);
 }
 
@@ -1021,7 +1038,7 @@ static void Struct_getPropertyNames(JSContextRef context, JSObjectRef object, JS
         name = elements[index].name;
 
         if (name == NULL) {
-            sprintf(number, "%lu", index);
+            sprintf(number, "%zu", index);
             name = number;
         }
 
@@ -1118,17 +1135,21 @@ static JSValueRef Runtime_getProperty(JSContextRef context, JSObjectRef object,
 
         case 0:
             return JSEvaluateScript(CYGetJSContext(), CYJSString(value), NULL, NULL, 0, NULL);
-        case 1:
-            return CYMakeFunctor(context, reinterpret_cast<void (*)()>(CYCastSymbol(name.data)), value);
 
-        case 2: {
-            // XXX: this is horrendously inefficient
-            sig::Signature signature;
-            sig::Parse(pool, &signature, value, &Structor_);
-            ffi_cif cif;
-            sig::sig_ffi_cif(pool, &sig::ObjectiveC, &signature, &cif);
-            return CYFromFFI(context, signature.elements[0].type, cif.rtype, CYCastSymbol(name.data));
-        }
+        case 1:
+            if (void (*symbol)() = reinterpret_cast<void (*)()>(CYCastSymbol(name.data)))
+                return CYMakeFunctor(context, symbol, value);
+            else return NULL;
+
+        case 2:
+            if (void *symbol = CYCastSymbol(name.data)) {
+                // XXX: this is horrendously inefficient
+                sig::Signature signature;
+                sig::Parse(pool, &signature, value, &Structor_);
+                ffi_cif cif;
+                sig::sig_ffi_cif(pool, &sig::ObjectiveC, &signature, &cif);
+                return CYFromFFI(context, signature.elements[0].type, cif.rtype, symbol);
+            } else return NULL;
 
         // XXX: implement case 3
         case 4:
@@ -1302,7 +1323,7 @@ static JSStaticFunction Type_staticFunctions[4] = {
     {NULL, NULL, 0}
 };
 
-static JSObjectRef (*$JSObjectMakeArray)(JSContextRef, size_t, const JSValueRef[], JSValueRef *);
+static JSObjectRef (*JSObjectMakeArray$)(JSContextRef, size_t, const JSValueRef[], JSValueRef *);
 
 void CYSetArgs(int argc, const char *argv[]) {
     JSContextRef context(CYGetJSContext());
@@ -1311,9 +1332,9 @@ void CYSetArgs(int argc, const char *argv[]) {
         args[i] = CYCastJSValue(context, argv[i]);
 
     JSObjectRef array;
-    if ($JSObjectMakeArray != NULL) {
+    if (JSObjectMakeArray$ != NULL) {
         JSValueRef exception(NULL);
-        array = (*$JSObjectMakeArray)(context, argc, args, &exception);
+        array = (*JSObjectMakeArray$)(context, argc, args, &exception);
         CYThrow(context, exception);
     } else {
         JSValueRef value(CYCallAsFunction(context, Array_, NULL, argc, args));
@@ -1382,7 +1403,7 @@ void CYInitialize() {
     _aprcall(apr_pool_create(&Pool_, NULL));
     _sqlcall(sqlite3_open("/usr/lib/libcycript.db", &Bridge_));
 
-    $JSObjectMakeArray = reinterpret_cast<JSObjectRef (*)(JSContextRef, size_t, const JSValueRef[], JSValueRef *)>(dlsym(RTLD_DEFAULT, "JSObjectMakeArray"));
+    JSObjectMakeArray$ = reinterpret_cast<JSObjectRef (*)(JSContextRef, size_t, const JSValueRef[], JSValueRef *)>(dlsym(RTLD_DEFAULT, "JSObjectMakeArray"));
 }
 
 apr_pool_t *CYGetGlobalPool() {
@@ -1427,8 +1448,18 @@ CYPoolError::CYPoolError(const char *format, va_list args) {
     message_ = apr_pvsprintf(pool_, format, args);
 }
 
+JSValueRef CYCastJSError(JSContextRef context, const char *message) {
+    JSValueRef arguments[1] = {CYCastJSValue(context, message)};
+
+    JSValueRef exception(NULL);
+    JSValueRef value(JSObjectCallAsConstructor(context, Error_, 1, arguments, &exception));
+    CYThrow(context, exception);
+
+    return value;
+}
+
 JSValueRef CYPoolError::CastJSValue(JSContextRef context) const {
-    return CYCastJSValue(context, message_);
+    return CYCastJSError(context, message_);
 }
 
 CYJSError::CYJSError(JSContextRef context, const char *format, ...) {
@@ -1442,15 +1473,9 @@ CYJSError::CYJSError(JSContextRef context, const char *format, ...) {
     const char *message(apr_pvsprintf(pool, format, args));
     va_end (args);
 
-    JSValueRef arguments[1] = {CYCastJSValue(context, CYJSString(message))};
-
-    JSValueRef exception(NULL);
-    value_ = JSObjectCallAsConstructor(context, Error_, 1, arguments, &exception);
-    CYThrow(context, exception);
+    value_ = CYCastJSError(context, message);
 }
 
-void CYObjectiveC(JSContextRef context, JSObjectRef global);
-
 JSGlobalContextRef CYGetJSContext() {
     CYInitialize();
 
@@ -1569,10 +1594,8 @@ JSGlobalContextRef CYGetJSContext() {
 
         Result_ = JSStringCreateWithUTF8CString("_");
 
-// XXX: this is very wrong and sad
-#ifdef __APPLE__
-        CYObjectiveC(context, global);
-#endif
+        if (hooks_ != NULL && hooks_->SetupContext != NULL)
+            (*hooks_->SetupContext)(context);
     }
 
     return Context_;