]> git.saurik.com Git - cycript.git/blobdiff - Handler.mm
Update copyright for 2014 and relicense to AGPLv3.
[cycript.git] / Handler.mm
index d49274a23b74364192f56fd567bcc422829766f0..f4c87053eef0805e1401a088b7e3510dcd46656c 100644 (file)
@@ -1,21 +1,21 @@
 /* Cycript - Optimizing JavaScript Compiler/Runtime
- * Copyright (C) 2009-2013  Jay Freeman (saurik)
+ * Copyright (C) 2009-2014  Jay Freeman (saurik)
 */
 
-/* GNU General Public License, Version 3 {{{ */
+/* GNU Affero General Public License, Version 3 {{{ */
 /*
- * Cycript is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation, either version 3 of the License,
- * or (at your option) any later version.
- *
- * Cycript is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Cycript.  If not, see <http://www.gnu.org/licenses/>.
+ * 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/>.
 **/
 /* }}} */
 
@@ -57,7 +57,7 @@ struct CYExecute_ {
     CYExecute_ *execute(reinterpret_cast<CYExecute_ *>([value pointerValue]));
     const char *data(execute->data_);
     execute->data_ = NULL;
-    execute->data_ = CYExecute(execute->pool_, CYUTF8String(data));
+    execute->data_ = CYExecute(CYGetJSContext(), execute->pool_, CYUTF8String(data));
 }
 
 @end
@@ -100,36 +100,20 @@ struct CYClient :
                 return;
             data[size] = '\0';
 
-            CYStream stream(data, data + size);
-            CYDriver driver(stream);
-
-            cy::parser parser(driver);
-
-            const char *json;
-            if (parser.parse() != 0 || !driver.errors_.empty()) {
-                json = NULL;
-                size = _not(uint32_t);
-            } else {
-                NSAutoreleasePool *ar = [[NSAutoreleasePool alloc] init];
-
-                CYOptions options;
-                CYContext context(options);
-                driver.program_->Replace(context);
-                std::ostringstream str;
-                CYOutput out(str, options);
-                out << *driver.program_;
-                std::string code(str.str());
-                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];
-                json = execute.data_;
-                size = json == NULL ? _not(uint32_t) : strlen(json);
-
-                [ar release];
-            }
+            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;
@@ -149,8 +133,10 @@ static void *OnClient(void *data) {
     return NULL;
 }
 
-extern "C" void CYHandleClient(CYPool &pool, int socket) {
-    CYClient *client(new(pool) CYClient(socket));
+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);
 }
 
@@ -164,11 +150,61 @@ extern "C" void CYHandleServer(pid_t pid) {
         sprintf(address.sun_path, "/tmp/.s.cy.%u", pid);
 
         _syscall(connect(socket, reinterpret_cast<sockaddr *>(&address), SUN_LEN(&address)));
-
-        // XXX: this leaks memory... really?
-        CYHandleClient(*new CYPool(), socket);
+        CYHandleClient(socket);
     } catch (const CYException &error) {
         CYPool pool;
         fprintf(stderr, "%s\n", 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);
+}