]> git.saurik.com Git - cycript.git/blobdiff - Execute.cpp
Do not use FFI to sel_registerName for [] syntax.
[cycript.git] / Execute.cpp
index 4b01924c274cf71e3124bf55d38606d6169cf696..a145ee0100cdb202b3270de99444bfd44ce2bc57 100644 (file)
@@ -44,8 +44,7 @@
 #include <sstream>
 #include <cmath>
 
-#include "Parser.hpp"
-
+#include "Code.hpp"
 #include "Decode.hpp"
 #include "Error.hpp"
 #include "JavaScript.hpp"
 struct CYHooks *hooks_;
 
 /* JavaScript Properties {{{ */
+bool CYHasProperty(JSContextRef context, JSObjectRef object, JSStringRef name) {
+    return JSObjectHasProperty(context, object, name);
+}
+
 JSValueRef CYGetProperty(JSContextRef context, JSObjectRef object, size_t index) {
     return _jsccall(JSObjectGetPropertyAtIndex, context, object, index);
 }
@@ -991,6 +994,33 @@ JSObjectRef CYMakeType(JSContextRef context, sig::Signature *signature) {
     return CYMakeType(context, &type);
 }
 
+static bool All_hasProperty(JSContextRef context, JSObjectRef object, JSStringRef property) {
+    JSObjectRef global(CYGetGlobalObject(context));
+    JSObjectRef cycript(CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Cycript"))));
+    JSObjectRef alls(CYCastJSObject(context, CYGetProperty(context, cycript, CYJSString("alls"))));
+
+    for (size_t i(0), count(CYArrayLength(context, alls)); i != count; ++i)
+        if (JSObjectRef space = CYCastJSObject(context, CYArrayGet(context, alls, count - i - 1)))
+            if (CYHasProperty(context, space, property))
+                return true;
+
+    CYPool pool;
+    CYUTF8String name(CYPoolUTF8String(pool, context, property));
+
+    size_t length(name.size);
+    char keyed[length + 2];
+    memcpy(keyed + 1, name.data, length + 1);
+
+    static const char *modes = "0124";
+    for (size_t i(0); i != 4; ++i) {
+        keyed[0] = modes[i];
+        if (CYBridgeHash(keyed, length + 1) != NULL)
+            return true;
+    }
+
+    return false;
+}
+
 static JSValueRef All_getProperty(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) { CYTry {
     JSObjectRef global(CYGetGlobalObject(context));
     JSObjectRef cycript(CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Cycript"))));
@@ -1419,6 +1449,10 @@ static JSStaticValue Functor_staticValues[2] = {
     {NULL, NULL, NULL, 0}
 };
 
+namespace cy {
+    JSStaticValue const * const Functor::StaticValues = Functor_staticValues;
+}
+
 static JSStaticValue Type_staticValues[4] = {
     {"alignment", &Type_getProperty_alignment, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
     {"name", &Type_getProperty_name, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
@@ -1534,6 +1568,7 @@ void CYInitializeDynamic() {
 
     definition = kJSClassDefinitionEmpty;
     definition.className = "All";
+    definition.hasProperty = &All_hasProperty;
     definition.getProperty = &All_getProperty;
     definition.getPropertyNames = &All_getPropertyNames;
     All_ = JSClassCreate(&definition);
@@ -1650,8 +1685,9 @@ 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(fd = open(path, O_RDONLY));
+    int fd(_syscall_(open(path, O_RDONLY), 1, {ENOENT}));
+    if (fd == -1)
+        return NULL;
 
     struct stat stat;
     _syscall(fstat(fd, &stat));
@@ -1666,49 +1702,6 @@ void *CYMapFile(const char *path, size_t *psize) {
     return base;
 }
 
-static void CYRunSetups(JSContextRef context) {
-    std::string folder("/etc/cycript/setup.d");
-    DIR *setups(opendir(folder.c_str()));
-    if (setups == NULL)
-        return;
-
-    for (;;) {
-        dirent setup;
-        dirent *result;
-        _syscall(readdir_r(setups, &setup, &result));
-
-        if (result == NULL)
-            break;
-        _assert(result == &setup);
-
-        const char *name(setup.d_name);
-        size_t length(strlen(name));
-        if (length < 4)
-            continue;
-
-        if (name[0] == '.')
-            continue;
-        if (memcmp(name + length - 3, ".cy", 3) != 0)
-            continue;
-
-        std::string script(folder + "/" + name);
-        CYUTF8String utf8;
-        utf8.data = reinterpret_cast<char *>(CYMapFile(script.c_str(), &utf8.size));
-
-        CYPool pool;
-        CYUTF16String utf16(CYPoolUTF16String(pool, utf8));
-        munmap(const_cast<char *>(utf8.data), utf8.size);
-
-        // XXX: this should not be used
-        CydgetMemoryParse(&utf16.data, &utf16.size);
-
-        CYExecute(context, pool, CYPoolUTF8String(pool, utf16));
-        free(const_cast<uint16_t *>(utf16.data));
-    }
-
-    _syscall(closedir(setups));
-}
-
 static JSValueRef require(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
     _assert(count == 1);
     CYPool pool;
@@ -1724,7 +1717,9 @@ static JSValueRef require(JSContextRef context, JSObjectRef object, JSObjectRef
     CYJSString property("exports");
     JSObjectRef module;
 
-    const char *path(pool.strcat(lib, "/cycript/", CYPoolCString(pool, context, arguments[0]), ".cy", NULL));
+    const char *name(CYPoolCString(pool, context, arguments[0]));
+    const char *path(pool.strcat(lib, "/cycript0.9/", name, ".cy", NULL));
+
     CYJSString key(path);
     JSObjectRef modules(CYGetCachedObject(context, CYJSString("modules")));
     JSValueRef cache(CYGetProperty(context, modules, key));
@@ -1735,20 +1730,31 @@ static JSValueRef require(JSContextRef context, JSObjectRef object, JSObjectRef
         CYUTF8String code;
         code.data = reinterpret_cast<char *>(CYMapFile(path, &code.size));
 
-        std::stringstream wrap;
-        wrap << "(function (exports, require, module) { " << code << "\n});";
-        code = CYPoolCode(pool, wrap.str().c_str());
+        if (code.data == NULL) {
+            if (strchr(name, '/') == NULL && (
+                dlopen(pool.strcat("/System/Library/Frameworks/", name, ".framework/", name, NULL), RTLD_LAZY | RTLD_GLOBAL) != NULL ||
+                dlopen(pool.strcat("/System/Library/PrivateFrameworks/", name, ".framework/", name, NULL), RTLD_LAZY | RTLD_GLOBAL) != NULL ||
+            false))
+                return CYJSUndefined(NULL);
 
-        JSValueRef value(_jsccall(JSEvaluateScript, context, CYJSString(code), NULL, NULL, 0));
-        JSObjectRef function(CYCastJSObject(context, value));
+            CYThrow("Can't find module: %s", name);
+        }
 
         module = JSObjectMake(context, NULL, NULL);
+        CYSetProperty(context, modules, key, module);
+
         JSObjectRef exports(JSObjectMake(context, NULL, NULL));
         CYSetProperty(context, module, property, exports);
 
+        std::stringstream wrap;
+        wrap << "(function (exports, require, module) { " << code << "\n});";
+        code = CYPoolCode(pool, wrap);
+
+        JSValueRef value(_jsccall(JSEvaluateScript, context, CYJSString(code), NULL, NULL, 0));
+        JSObjectRef function(CYCastJSObject(context, value));
+
         JSValueRef arguments[3] = { exports, JSObjectMakeFunctionWithCallback(context, CYJSString("require"), &require), module };
         CYCallAsFunction(context, function, NULL, 3, arguments);
-        CYSetProperty(context, modules, key, module);
     }
 
     return CYGetProperty(context, module, property);
@@ -1860,8 +1866,6 @@ extern "C" void CYSetupContext(JSGlobalContextRef context) {
         (*hooks_->SetupContext)(context);
 
     CYArrayPush(context, alls, cycript);
-
-    CYRunSetups(context);
 }
 
 static JSGlobalContextRef context_;