]> git.saurik.com Git - cycript.git/blobdiff - Execute.cpp
Update copyright for 2015 (and it is almost 2016).
[cycript.git] / Execute.cpp
index 9a2eb95aa1655b327fcc273a7027799bf3738da9..a3c69f5e991989fbd29553dbfb709d96e4d896f5 100644 (file)
@@ -1,5 +1,5 @@
 /* Cycript - Optimizing JavaScript Compiler/Runtime
- * Copyright (C) 2009-2014  Jay Freeman (saurik)
+ * Copyright (C) 2009-2015  Jay Freeman (saurik)
 */
 
 /* GNU Affero General Public License, Version 3 {{{ */
 #include "JavaScript.hpp"
 #include "String.hpp"
 
-std::vector<CYHook *> hooks_;
+static std::vector<CYHook *> &GetHooks() {
+    static std::vector<CYHook *> hooks;
+    return hooks;
+}
 
 CYRegisterHook::CYRegisterHook(CYHook *hook) {
-    hooks_.push_back(hook);
+    GetHooks().push_back(hook);
 }
 
 /* JavaScript Properties {{{ */
@@ -83,7 +86,7 @@ void CYSetProperty(JSContextRef context, JSObjectRef object, JSStringRef name, J
 
 void CYSetPrototype(JSContextRef context, JSObjectRef object, JSValueRef value) {
     JSObjectSetPrototype(context, object, value);
-    _assert(JSObjectGetPrototype(context, object) == value);
+    _assert(CYIsStrictEqual(context, JSObjectGetPrototype(context, object), value));
 }
 /* }}} */
 /* JavaScript Strings {{{ */
@@ -151,6 +154,7 @@ JSStringRef toCYON_s;
 JSStringRef toJSON_s;
 JSStringRef toPointer_s;
 JSStringRef toString_s;
+JSStringRef weak_s;
 
 static JSStringRef Result_;
 
@@ -238,9 +242,6 @@ struct Struct_privateData :
     }
 };
 
-typedef std::map<const char *, Type_privateData *, CYCStringLess> TypeMap;
-static TypeMap Types_;
-
 JSObjectRef CYMakeStruct(JSContextRef context, void *data, sig::Type *type, ffi_type *ffi, JSObjectRef owner) {
     Struct_privateData *internal(new Struct_privateData(context, owner));
     CYPool &pool(*internal->pool_);
@@ -260,6 +261,10 @@ JSObjectRef CYMakeStruct(JSContextRef context, void *data, sig::Type *type, ffi_
 }
 
 static void *CYCastSymbol(const char *name) {
+    for (CYHook *hook : GetHooks())
+        if (hook->CastSymbol != NULL)
+            if (void *value = (*hook->CastSymbol)(name))
+                return value;
     return dlsym(RTLD_DEFAULT, name);
 }
 
@@ -319,6 +324,14 @@ bool CYIsCallable(JSContextRef context, JSValueRef value) {
     return value != NULL && JSValueIsObject(context, value) && JSObjectIsFunction(context, (JSObjectRef) value);
 }
 
+bool CYIsEqual(JSContextRef context, JSValueRef lhs, JSValueRef rhs) {
+    return _jsccall(JSValueIsEqual, context, lhs, rhs);
+}
+
+bool CYIsStrictEqual(JSContextRef context, JSValueRef lhs, JSValueRef rhs) {
+    return JSValueIsStrictEqual(context, lhs, rhs);
+}
+
 size_t CYArrayLength(JSContextRef context, JSObjectRef array) {
     return CYCastDouble(context, CYGetProperty(context, array, length_s));
 }
@@ -565,7 +578,9 @@ static bool CYGetOffset(CYPool &pool, JSContextRef context, JSStringRef value, s
 }
 
 void *CYCastPointer_(JSContextRef context, JSValueRef value) {
-    switch (JSValueGetType(context, value)) {
+    if (value == NULL)
+        return NULL;
+    else switch (JSValueGetType(context, value)) {
         case kJSTypeNull:
             return NULL;
         case kJSTypeObject: {
@@ -674,7 +689,7 @@ void CYPoolFFI(CYPool *pool, JSContextRef context, sig::Type *type, ffi_type *ff
         break;
 
         default:
-            for (CYHook *hook : hooks_)
+            for (CYHook *hook : GetHooks())
                 if (hook->PoolFFI != NULL)
                     if ((*hook->PoolFFI)(pool, context, type, ffi, data, value))
                         return;
@@ -728,7 +743,7 @@ JSValueRef CYFromFFI(JSContextRef context, sig::Type *type, ffi_type *ffi, void
         null:
             return CYJSNull(context);
         default:
-            for (CYHook *hook : hooks_)
+            for (CYHook *hook : GetHooks())
                 if (hook->FromFFI != NULL)
                     if (JSValueRef value = (*hook->FromFFI)(context, type, ffi, data, initialize, owner))
                         return value;
@@ -799,8 +814,12 @@ static JSObjectRef CYMakeFunctor(JSContextRef context, JSObjectRef function, con
     return object;
 }
 
+JSValueRef CYGetCachedValue(JSContextRef context, JSStringRef name) {
+    return CYGetProperty(context, CYCastJSObject(context, CYGetProperty(context, CYGetGlobalObject(context), cy_s)), name);
+}
+
 JSObjectRef CYGetCachedObject(JSContextRef context, JSStringRef name) {
-    return CYCastJSObject(context, CYGetProperty(context, CYCastJSObject(context, CYGetProperty(context, CYGetGlobalObject(context), cy_s)), name));
+    return CYCastJSObject(context, CYGetCachedValue(context, name));
 }
 
 static JSObjectRef CYMakeFunctor(JSContextRef context, JSValueRef value, const sig::Signature &signature) {
@@ -993,7 +1012,7 @@ JSValueRef CYCallFunction(CYPool &pool, JSContextRef context, size_t setups, voi
 
     uint8_t value[cif->rtype->size];
 
-    for (CYHook *hook : hooks_)
+    for (CYHook *hook : GetHooks())
         if (hook->CallFunction != NULL) {
             // XXX: this only supports one hook, but it is a bad idea anyway
             (*hook->CallFunction)(context, cif, function, value, values);
@@ -1554,9 +1573,9 @@ class ExecutionHandle {
     ExecutionHandle(JSContextRef context) :
         context_(context)
     {
-        handles_.resize(hooks_.size());
-        for (size_t i(0); i != hooks_.size(); ++i) {
-            CYHook *hook(hooks_[i]);
+        handles_.resize(GetHooks().size());
+        for (size_t i(0); i != GetHooks().size(); ++i) {
+            CYHook *hook(GetHooks()[i]);
             if (hook->ExecuteStart != NULL)
                 handles_[i] = (*hook->ExecuteStart)(context_);
             else
@@ -1565,8 +1584,8 @@ class ExecutionHandle {
     }
 
     ~ExecutionHandle() {
-        for (size_t i(hooks_.size()); i != 0; --i) {
-            CYHook *hook(hooks_[i-1]);
+        for (size_t i(GetHooks().size()); i != 0; --i) {
+            CYHook *hook(GetHooks()[i-1]);
             if (hook->ExecuteEnd != NULL)
                 (*hook->ExecuteEnd)(context_, handles_[i-1]);
         }
@@ -1683,10 +1702,11 @@ void CYInitializeDynamic() {
     toJSON_s = JSStringCreateWithUTF8CString("toJSON");
     toPointer_s = JSStringCreateWithUTF8CString("toPointer");
     toString_s = JSStringCreateWithUTF8CString("toString");
+    weak_s = JSStringCreateWithUTF8CString("weak");
 
     Result_ = JSStringCreateWithUTF8CString("_");
 
-    for (CYHook *hook : hooks_)
+    for (CYHook *hook : GetHooks())
         if (hook->Initialize != NULL)
             (*hook->Initialize)();
 }
@@ -1738,7 +1758,7 @@ JSGlobalContextRef CYGetJSContext(JSContextRef context) {
 extern "C" bool CydgetMemoryParse(const uint16_t **data, size_t *size);
 
 void *CYMapFile(const char *path, size_t *psize) {
-    int fd(_syscall_(open(path, O_RDONLY), 1, {ENOENT}));
+    int fd(_syscall_(open(path, O_RDONLY), 1, ENOENT));
     if (fd == -1)
         return NULL;
 
@@ -1914,10 +1934,17 @@ extern "C" void CYSetupContext(JSGlobalContextRef context) {
     //CYSetProperty(context, System, CYJSString("global"), global);
     CYSetProperty(context, System, CYJSString("print"), &System_print);
 
+#ifdef __APPLE__
+    if (&JSWeakObjectMapCreate != NULL) {
+        JSWeakObjectMapRef weak(JSWeakObjectMapCreate(context, NULL, NULL));
+        CYSetProperty(context, cy, weak_s, CYCastJSValue(context, reinterpret_cast<uintptr_t>(weak)));
+    }
+#endif
+
     if (CYBridgeEntry *entry = CYBridgeHash("1dlerror", 8))
         entry->cache_ = new cy::Functor(entry->value_, reinterpret_cast<void (*)()>(&dlerror));
 
-    for (CYHook *hook : hooks_)
+    for (CYHook *hook : GetHooks())
         if (hook->SetupContext != NULL)
             (*hook->SetupContext)(context);