]> git.saurik.com Git - cycript.git/commitdiff
Use CoreFoundation in Handler to #ifdef __APPLE__.
authorJay Freeman (saurik) <saurik@saurik.com>
Mon, 9 Nov 2015 04:44:13 +0000 (20:44 -0800)
committerJay Freeman (saurik) <saurik@saurik.com>
Mon, 9 Nov 2015 04:44:13 +0000 (20:44 -0800)
Handler.cpp [new file with mode: 0644]
Handler.mm [deleted file]
Makefile.am
Makefile.in

diff --git a/Handler.cpp b/Handler.cpp
new file mode 100644 (file)
index 0000000..2ceb1fa
--- /dev/null
@@ -0,0 +1,253 @@
+/* Cycript - Optimizing JavaScript Compiler/Runtime
+ * Copyright (C) 2009-2014  Jay Freeman (saurik)
+*/
+
+/* GNU Affero General Public License, Version 3 {{{ */
+/*
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+**/
+/* }}} */
+
+#include <dlfcn.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <sstream>
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <sys/un.h>
+
+#ifdef __APPLE__
+#include <CoreFoundation/CoreFoundation.h>
+#endif
+
+#include "cycript.hpp"
+
+#include "JavaScript.hpp"
+#include "Parser.hpp"
+#include "Pooling.hpp"
+
+#include "Cycript.tab.hh"
+#include "Driver.hpp"
+
+struct CYExecute_ {
+    CYPool &pool_;
+    const char * volatile data_;
+    pthread_mutex_t mutex_;
+    pthread_cond_t condition_;
+};
+
+void CYPerform(void *arg) {
+    CYExecute_ *execute(reinterpret_cast<CYExecute_ *>(arg));
+
+    const char *data(execute->data_);
+    execute->data_ = NULL;
+    execute->data_ = CYExecute(CYGetJSContext(), execute->pool_, CYUTF8String(data));
+
+    pthread_mutex_lock(&execute->mutex_);
+    pthread_cond_signal(&execute->condition_);
+    pthread_mutex_unlock(&execute->mutex_);
+}
+
+struct CYClient :
+    CYData
+{
+    int socket_;
+    pthread_t thread_;
+
+    CYClient(int socket) :
+        socket_(socket)
+    {
+    }
+
+    ~CYClient() {
+        _syscall(close(socket_));
+    }
+
+    void Handle() {
+        bool dispatch;
+#ifdef __APPLE__
+        CFRunLoopRef loop(CFRunLoopGetMain());
+        if (CFStringRef mode = CFRunLoopCopyCurrentMode(loop)) {
+            dispatch = true;
+            CFRelease(mode);
+        } else
+#endif
+            dispatch = false;
+
+        for (;;) {
+            uint32_t size;
+            if (!CYRecvAll(socket_, &size, sizeof(size)))
+                return;
+
+            CYLocalPool pool;
+            char *data(new(pool) char[size + 1]);
+            if (!CYRecvAll(socket_, data, size))
+                return;
+            data[size] = '\0';
+
+            std::string code(data, size);
+            CYExecute_ execute = {pool, code.c_str()};
+
+            pthread_mutex_init(&execute.mutex_, NULL);
+            pthread_cond_init(&execute.condition_, NULL);
+
+            if (!dispatch)
+                CYPerform(&execute);
+#ifdef __APPLE__
+            else {
+                CFRunLoopSourceContext context;
+                memset(&context, 0, sizeof(context));
+                context.version = 0;
+                context.info = &execute;
+                context.perform = &CYPerform;
+
+                CFRunLoopSourceRef source(CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context));
+
+                pthread_mutex_lock(&execute.mutex_);
+
+                CFRunLoopAddSource(loop, source, kCFRunLoopCommonModes);
+                CFRunLoopSourceSignal(source);
+
+                CFRunLoopWakeUp(loop);
+                pthread_cond_wait(&execute.condition_, &execute.mutex_);
+                pthread_mutex_unlock(&execute.mutex_);
+
+                CFRunLoopRemoveSource(loop, source, kCFRunLoopCommonModes);
+                CFRelease(source);
+            }
+#endif
+
+            pthread_cond_destroy(&execute.condition_);
+            pthread_mutex_destroy(&execute.mutex_);
+
+            const char *json(execute.data_);
+            size = json == NULL ? _not(uint32_t) : strlen(json);
+
+            if (!CYSendAll(socket_, &size, sizeof(size)))
+                return;
+            if (json != NULL)
+                if (!CYSendAll(socket_, json, size))
+                    return;
+        }
+    }
+};
+
+static void *OnClient(void *data) {
+    CYClient *client(reinterpret_cast<CYClient *>(data));
+    client->Handle();
+    delete client;
+    return NULL;
+}
+
+extern "C" void CYHandleClient(int socket) {
+    // XXX: this leaks memory... really?
+    CYPool *pool(new CYPool());
+    CYClient *client(new(*pool) CYClient(socket));
+    _assert(pthread_create(&client->thread_, NULL, &OnClient, client) == 0);
+}
+
+static void CYHandleSocket(const char *path) {
+    int socket(_syscall(::socket(PF_UNIX, SOCK_STREAM, 0)));
+
+    struct sockaddr_un address;
+    memset(&address, 0, sizeof(address));
+    address.sun_family = AF_UNIX;
+    strcpy(address.sun_path, path);
+
+    _syscall(connect(socket, reinterpret_cast<sockaddr *>(&address), SUN_LEN(&address)));
+
+    CYInitializeDynamic();
+    CYHandleClient(socket);
+}
+
+extern "C" void CYHandleServer(pid_t pid) { try {
+    char path[1024];
+    sprintf(path, "/tmp/.s.cy.%u", pid);
+    CYHandleSocket(path);
+} catch (const CYException &error) {
+    CYPool pool;
+    fprintf(stderr, "%s\n", error.PoolCString(pool));
+} }
+
+extern "C" char *MSmain0(int argc, char *argv[]) { try {
+    _assert(argc == 2);
+    CYHandleSocket(argv[1]);
+
+    static void *handle(NULL);
+    if (handle == NULL) {
+        Dl_info info;
+        _assert(dladdr(reinterpret_cast<void *>(&MSmain0), &info) != 0);
+        handle = dlopen(info.dli_fname, RTLD_NOLOAD);
+    }
+
+    return NULL;
+} catch (const CYException &error) {
+    CYPool pool;
+    return strdup(error.PoolCString(pool));
+} }
+
+struct CYServer {
+    pthread_t thread_;
+    uint16_t port_;
+    int socket_;
+
+    CYServer(uint16_t port) :
+        port_(port),
+        socket_(-1)
+    {
+    }
+
+    ~CYServer() {
+        if (socket_ != -1)
+            _syscall(close(socket_));
+    }
+
+    void Listen() {
+        socket_ = _syscall(::socket(PF_INET, SOCK_STREAM, 0)); try {
+            sockaddr_in address;
+            address.sin_family = AF_INET;
+            address.sin_addr.s_addr = INADDR_ANY;
+            address.sin_port = htons(port_);
+            _syscall(::bind(socket_, reinterpret_cast<sockaddr *>(&address), sizeof(address)));
+
+            _syscall(::listen(socket_, -1));
+
+            for (;;) {
+                socklen_t length(sizeof(address));
+                int socket(_syscall(::accept(socket_, reinterpret_cast<sockaddr *>(&address), &length)));
+                CYHandleClient(socket);
+            }
+        } catch (const CYException &error) {
+            CYPool pool;
+            fprintf(stderr, "%s\n", error.PoolCString(pool));
+        }
+    }
+};
+
+static void *OnServer(void *data) {
+    CYServer *server(reinterpret_cast<CYServer *>(data));
+    server->Listen();
+    delete server;
+    return NULL;
+}
+
+extern "C" void CYListenServer(short port) {
+    CYInitializeDynamic();
+
+    CYServer *server(new CYServer(port));
+    _assert(pthread_create(&server->thread_, NULL, &OnServer, server) == 0);
+}
diff --git a/Handler.mm b/Handler.mm
deleted file mode 100644 (file)
index bbda7df..0000000
+++ /dev/null
@@ -1,235 +0,0 @@
-/* Cycript - Optimizing JavaScript Compiler/Runtime
- * Copyright (C) 2009-2014  Jay Freeman (saurik)
-*/
-
-/* GNU Affero General Public License, Version 3 {{{ */
-/*
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
-
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
-**/
-/* }}} */
-
-#include <Foundation/Foundation.h>
-#include <dlfcn.h>
-#include <pthread.h>
-#include <unistd.h>
-#include <sstream>
-
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <sys/un.h>
-
-#include "cycript.hpp"
-
-#include "JavaScript.hpp"
-#include "Parser.hpp"
-#include "Pooling.hpp"
-
-#include "Cycript.tab.hh"
-#include "Driver.hpp"
-
-struct CYExecute_ {
-    CYPool &pool_;
-    const char * volatile data_;
-};
-
-// XXX: this is "tre lame"
-@interface CYClient_ : NSObject {
-}
-
-- (void) execute:(NSValue *)value;
-
-@end
-
-@implementation CYClient_
-
-- (void) execute:(NSValue *)value {
-    CYExecute_ *execute(reinterpret_cast<CYExecute_ *>([value pointerValue]));
-    const char *data(execute->data_);
-    execute->data_ = NULL;
-    execute->data_ = CYExecute(CYGetJSContext(), execute->pool_, CYUTF8String(data));
-}
-
-@end
-
-struct CYClient :
-    CYData
-{
-    int socket_;
-    pthread_t thread_;
-
-    CYClient(int socket) :
-        socket_(socket)
-    {
-    }
-
-    ~CYClient() {
-        _syscall(close(socket_));
-    }
-
-    void Handle() {
-        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-
-        CYClient_ *client = [[[CYClient_ alloc] init] autorelease];
-
-        bool dispatch;
-        if (CFStringRef mode = CFRunLoopCopyCurrentMode(CFRunLoopGetMain())) {
-            dispatch = true;
-            CFRelease(mode);
-        } else
-            dispatch = false;
-
-        for (;;) {
-            uint32_t size;
-            if (!CYRecvAll(socket_, &size, sizeof(size)))
-                return;
-
-            CYLocalPool pool;
-            char *data(new(pool) char[size + 1]);
-            if (!CYRecvAll(socket_, data, size))
-                return;
-            data[size] = '\0';
-
-            NSAutoreleasePool *ar = [[NSAutoreleasePool alloc] init];
-
-            std::string code(data, size);
-            CYExecute_ execute = {pool, code.c_str()};
-            NSValue *value([NSValue valueWithPointer:&execute]);
-            if (dispatch)
-                [client performSelectorOnMainThread:@selector(execute:) withObject:value waitUntilDone:YES];
-            else
-                [client execute:value];
-
-            const char *json(execute.data_);
-            size = json == NULL ? _not(uint32_t) : strlen(json);
-
-            [ar release];
-
-            if (!CYSendAll(socket_, &size, sizeof(size)))
-                return;
-            if (json != NULL)
-                if (!CYSendAll(socket_, json, size))
-                    return;
-        }
-
-        [pool release];
-    }
-};
-
-static void *OnClient(void *data) {
-    CYClient *client(reinterpret_cast<CYClient *>(data));
-    client->Handle();
-    delete client;
-    return NULL;
-}
-
-extern "C" void CYHandleClient(int socket) {
-    // XXX: this leaks memory... really?
-    CYPool *pool(new CYPool());
-    CYClient *client(new(*pool) CYClient(socket));
-    _assert(pthread_create(&client->thread_, NULL, &OnClient, client) == 0);
-}
-
-static void CYHandleSocket(const char *path) {
-    int socket(_syscall(::socket(PF_UNIX, SOCK_STREAM, 0)));
-
-    struct sockaddr_un address;
-    memset(&address, 0, sizeof(address));
-    address.sun_family = AF_UNIX;
-    strcpy(address.sun_path, path);
-
-    _syscall(connect(socket, reinterpret_cast<sockaddr *>(&address), SUN_LEN(&address)));
-
-    CYInitializeDynamic();
-    CYHandleClient(socket);
-}
-
-extern "C" void CYHandleServer(pid_t pid) { try {
-    char path[1024];
-    sprintf(path, "/tmp/.s.cy.%u", pid);
-    CYHandleSocket(path);
-} catch (const CYException &error) {
-    CYPool pool;
-    fprintf(stderr, "%s\n", error.PoolCString(pool));
-} }
-
-extern "C" char *MSmain0(int argc, char *argv[]) { try {
-    _assert(argc == 2);
-    CYHandleSocket(argv[1]);
-
-    static void *handle(NULL);
-    if (handle == NULL) {
-        Dl_info info;
-        _assert(dladdr(reinterpret_cast<void *>(&MSmain0), &info) != 0);
-        handle = dlopen(info.dli_fname, RTLD_NOLOAD);
-    }
-
-    return NULL;
-} catch (const CYException &error) {
-    CYPool pool;
-    return strdup(error.PoolCString(pool));
-} }
-
-struct CYServer {
-    pthread_t thread_;
-    uint16_t port_;
-    int socket_;
-
-    CYServer(uint16_t port) :
-        port_(port),
-        socket_(-1)
-    {
-    }
-
-    ~CYServer() {
-        if (socket_ != -1)
-            _syscall(close(socket_));
-    }
-
-    void Listen() {
-        socket_ = _syscall(::socket(PF_INET, SOCK_STREAM, 0)); try {
-            sockaddr_in address;
-            address.sin_family = AF_INET;
-            address.sin_addr.s_addr = INADDR_ANY;
-            address.sin_port = htons(port_);
-            _syscall(::bind(socket_, reinterpret_cast<sockaddr *>(&address), sizeof(address)));
-
-            _syscall(::listen(socket_, -1));
-
-            for (;;) {
-                socklen_t length(sizeof(address));
-                int socket(_syscall(::accept(socket_, reinterpret_cast<sockaddr *>(&address), &length)));
-                CYHandleClient(socket);
-            }
-        } catch (const CYException &error) {
-            CYPool pool;
-            fprintf(stderr, "%s\n", error.PoolCString(pool));
-        }
-    }
-};
-
-static void *OnServer(void *data) {
-    CYServer *server(reinterpret_cast<CYServer *>(data));
-    server->Listen();
-    delete server;
-    return NULL;
-}
-
-extern "C" void CYListenServer(short port) {
-    CYInitializeDynamic();
-
-    CYServer *server(new CYServer(port));
-    _assert(pthread_create(&server->thread_, NULL, &OnServer, server) == 0);
-}
index 56a0518e4661b83c7c2ea2d70523654acb28bbfd..9a4f5d696967c43cbf7e977af6b68ebf3366f9bd 100644 (file)
@@ -82,7 +82,7 @@ libcycript_la_LIBADD += $(LTOBJECTIVEC)
 endif
 
 if CY_MACH
-libcycript_la_SOURCES += Handler.mm
+libcycript_la_SOURCES += Handler.cpp
 
 if CY_CONSOLE
 cycript_SOURCES += Mach/Inject.cpp
index dc06265e177766ab233a2b4389ded8938e09eeb5..3a82c91ce89e35745cc93fbb6e16b25fa478cf65 100644 (file)
@@ -112,7 +112,7 @@ host_triplet = @host@
 @CY_OBJECTIVEC_TRUE@am__append_9 = ObjectiveC
 @CY_OBJECTIVEC_TRUE@am__append_10 = ObjectiveC/Output.cpp ObjectiveC/Replace.cpp ObjectiveC/Library.mm
 @CY_OBJECTIVEC_TRUE@am__append_11 = $(LTOBJECTIVEC)
-@CY_MACH_TRUE@am__append_12 = Handler.mm
+@CY_MACH_TRUE@am__append_12 = Handler.cpp
 @CY_CONSOLE_TRUE@@CY_MACH_TRUE@am__append_13 = Mach/Inject.cpp
 @CY_CONSOLE_TRUE@@CY_MACH_TRUE@am__append_14 = -DCY_ATTACH
 subdir = .
@@ -176,7 +176,7 @@ am__libcycript_la_SOURCES_DIST = ConvertUTF.c Decode.cpp Driver.cpp \
        Replace.cpp Cycript.tab.cc lex.cy.cpp sig/ffi_type.cpp \
        sig/parse.cpp sig/copy.cpp Bridge.cpp Execute.cpp \
        JavaScriptCore.cpp Java/Execute.cpp ObjectiveC/Output.cpp \
-       ObjectiveC/Replace.cpp ObjectiveC/Library.mm Handler.mm
+       ObjectiveC/Replace.cpp ObjectiveC/Library.mm Handler.cpp
 am__dirstamp = $(am__leading_dot)dirstamp
 @CY_EXECUTE_TRUE@am__objects_1 = sig/ffi_type.lo sig/parse.lo \
 @CY_EXECUTE_TRUE@      sig/copy.lo Bridge.lo Execute.lo \