From: Jay Freeman (saurik) Date: Tue, 17 Nov 2015 05:09:18 +0000 (-0800) Subject: Implement Ctrl-C "cancel" with ExecutionTimeLimit. X-Git-Tag: v0.9.590~313 X-Git-Url: https://git.saurik.com/cycript.git/commitdiff_plain/b0ba908cc33ac5c4281ec27b5f42d560de67b713 Implement Ctrl-C "cancel" with ExecutionTimeLimit. --- diff --git a/Console.cpp b/Console.cpp index 9e84912..a7e0929 100644 --- a/Console.cpp +++ b/Console.cpp @@ -85,7 +85,8 @@ static void sigint(int) { case Parsing: longjmp(ctrlc_, 1); case Running: - throw "*** Ctrl-C"; + CYCancel(); + return; case Sending: return; case Waiting: diff --git a/Execute.cpp b/Execute.cpp index 8c50dcd..1c32d60 100644 --- a/Execute.cpp +++ b/Execute.cpp @@ -1590,30 +1590,32 @@ class ExecutionHandle { } }; +static volatile bool cancel_; + +static bool CYShouldTerminate(JSContextRef context, void *arg) { + return cancel_; +} + const char *CYExecute(JSContextRef context, CYPool &pool, CYUTF8String code) { JSValueRef exception(NULL); + if (false) error: + return CYPoolCString(pool, context, CYJSString(context, exception)); ExecutionHandle handle(context); - JSValueRef result; try { - result = JSEvaluateScript(context, CYJSString(code), NULL, NULL, 0, &exception); - } catch (const char *error) { - return error; - } + cancel_ = false; + if (&JSContextGroupSetExecutionTimeLimit != NULL) + JSContextGroupSetExecutionTimeLimit(JSContextGetGroup(context), 0.5, &CYShouldTerminate, NULL); - if (exception != NULL) error: - return CYPoolCString(pool, context, CYJSString(context, exception)); + JSValueRef result(JSEvaluateScript(context, CYJSString(code), NULL, NULL, 0, &exception)); + if (exception != NULL) + goto error; if (JSValueIsUndefined(context, result)) return NULL; - const char *json; try { - std::set objects; - json = CYPoolCCYON(pool, context, result, objects, &exception); - } catch (const char *error) { - return error; - } - + std::set objects; + const char *json(CYPoolCCYON(pool, context, result, objects, &exception)); if (exception != NULL) goto error; @@ -1622,6 +1624,10 @@ const char *CYExecute(JSContextRef context, CYPool &pool, CYUTF8String code) { return json; } +void CYCancel() { + cancel_ = true; +} + static bool initialized_ = false; void CYInitializeDynamic() { diff --git a/JavaScript.hpp b/JavaScript.hpp index b658a51..bd1bd67 100644 --- a/JavaScript.hpp +++ b/JavaScript.hpp @@ -61,6 +61,7 @@ JSObjectRef CYGetGlobalObject(JSContextRef context); extern "C" void CYSetupContext(JSGlobalContextRef context); const char *CYExecute(JSContextRef context, CYPool &pool, CYUTF8String code); +void CYCancel(); void CYSetArgs(int argc, const char *argv[]); @@ -217,6 +218,9 @@ extern "C" void JSWeakObjectMapSet(JSContextRef ctx, JSWeakObjectMapRef map, voi extern "C" JSObjectRef JSWeakObjectMapGet(JSContextRef ctx, JSWeakObjectMapRef map, void *key) __attribute__((__weak_import__)); extern "C" bool JSWeakObjectMapClear(JSContextRef ctx, JSWeakObjectMapRef map, void *key, JSObjectRef object) __attribute__((__weak_import__)); extern "C" void JSWeakObjectMapRemove(JSContextRef ctx, JSWeakObjectMapRef map, void* key) __attribute__((__weak_import__)); + +typedef bool (*JSShouldTerminateCallback)(JSContextRef ctx, void *context); +extern "C" void JSContextGroupSetExecutionTimeLimit(JSContextGroupRef, double limit, JSShouldTerminateCallback, void *context) __attribute__((__weak_import__)); #endif #endif/*CYCRIPT_JAVASCRIPT_HPP*/