X-Git-Url: https://git.saurik.com/cycript.git/blobdiff_plain/593830435b859650e766b8d490adff0f23c994e9..20ac42262940be749bcb41139c42bb01878c6c02:/Execute.cpp diff --git a/Execute.cpp b/Execute.cpp index 70751a4..c71bc9f 100644 --- a/Execute.cpp +++ b/Execute.cpp @@ -19,35 +19,33 @@ **/ /* }}} */ -#include "Internal.hpp" +#include "cycript.hpp" + +#include +#include +#include +#include +#include +#include #include #include #include #include -#include "cycript.hpp" - -#include "sig/parse.hpp" -#include "sig/ffi_type.hpp" - -#include "Pooling.hpp" -#include "Execute.hpp" - #include #include -#include -#include -#include -#include -#include -#include +#include "sig/parse.hpp" +#include "sig/ffi_type.hpp" #include "Code.hpp" #include "Decode.hpp" #include "Error.hpp" +#include "Execute.hpp" +#include "Internal.hpp" #include "JavaScript.hpp" +#include "Pooling.hpp" #include "String.hpp" static std::vector &GetHooks() { @@ -348,30 +346,34 @@ void CYArrayPush(JSContextRef context, JSObjectRef array, JSValueRef value) { } static JSValueRef System_print(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry { + FILE *file(stdout); + if (count == 0) - printf("\n"); + fputc('\n', file); else { CYPool pool; - printf("%s\n", CYPoolCString(pool, context, arguments[0])); + CYUTF8String string(CYPoolUTF8String(pool, context, CYJSString(context, arguments[0]))); + fwrite(string.data, string.size, 1, file); } + fflush(file); return CYJSUndefined(context); } CYCatch(NULL) } -static size_t Nonce_(0); - -static JSValueRef $cyq(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry { - CYPool pool; - const char *name(pool.strcat(CYPoolCString(pool, context, arguments[0]), pool.itoa(Nonce_++), NULL)); - return CYCastJSValue(context, name); -} CYCatch(NULL) } - static void (*JSSynchronousGarbageCollectForDebugging$)(JSContextRef); -void CYGarbageCollect(JSContextRef context) { +_visible void CYGarbageCollect(JSContextRef context) { (JSSynchronousGarbageCollectForDebugging$ ?: &JSGarbageCollect)(context); } +static JSValueRef Cycript_compile_callAsFunction(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry { + CYPool pool; + CYUTF8String before(CYPoolUTF8String(pool, context, CYJSString(context, arguments[0]))); + std::stringstream value(std::string(before.data, before.size)); + CYUTF8String after(CYPoolCode(pool, value)); + return CYCastJSValue(context, CYJSString(after)); +} CYCatch_(NULL, "SyntaxError") } + static JSValueRef Cycript_gc_callAsFunction(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry { CYGarbageCollect(context); return CYJSUndefined(context); @@ -536,6 +538,21 @@ static JSValueRef Array_callAsFunction_toCYON(JSContextRef context, JSObjectRef return CYCastJSValue(context, CYJSString(CYUTF8String(value.c_str(), value.size()))); } CYCatch(NULL) } +static JSValueRef Error_callAsFunction_toCYON(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry { + CYPool pool; + std::ostringstream str; + + str << "new " << CYPoolUTF8String(pool, context, CYJSString(context, CYGetProperty(context, _this, name_s))) << "("; + + CYUTF8String string(CYPoolUTF8String(pool, context, CYJSString(context, CYGetProperty(context, _this, message_s)))); + CYStringify(str, string.data, string.size); + + str << ")"; + + std::string value(str.str()); + return CYCastJSValue(context, CYJSString(CYUTF8String(value.c_str(), value.size()))); +} CYCatch(NULL) } + static JSValueRef String_callAsFunction_toCYON(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry { CYPool pool; std::ostringstream str; @@ -1464,7 +1481,7 @@ static JSValueRef Type_callAsFunction_toString(JSContextRef context, JSObjectRef static JSValueRef Type_callAsFunction_toCYON(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry { Type_privateData *internal(reinterpret_cast(JSObjectGetPrivate(_this))); CYLocalPool pool; - std::ostringstream out; + std::stringbuf out; CYOptions options; CYOutput output(out, options); (new(pool) CYEncodedType(Decode(pool, internal->type_)))->Output(output, CYNoFlags); @@ -1538,7 +1555,7 @@ static JSStaticFunction Type_staticFunctions[14] = { static JSObjectRef (*JSObjectMakeArray$)(JSContextRef, size_t, const JSValueRef[], JSValueRef *); -void CYSetArgs(int argc, const char *argv[]) { +_visible void CYSetArgs(int argc, const char *argv[]) { JSContextRef context(CYGetJSContext()); JSValueRef args[argc]; for (int i(0); i != argc; ++i) @@ -1596,35 +1613,29 @@ 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)); - +_visible const char *CYExecute(JSContextRef context, CYPool &pool, CYUTF8String code) { ExecutionHandle handle(context); cancel_ = false; if (&JSContextGroupSetExecutionTimeLimit != NULL) JSContextGroupSetExecutionTimeLimit(JSContextGetGroup(context), 0.5, &CYShouldTerminate, NULL); - JSValueRef result(JSEvaluateScript(context, CYJSString(code), NULL, NULL, 0, &exception)); - if (exception != NULL) - goto error; - - if (JSValueIsUndefined(context, result)) - return NULL; - - std::set objects; - const char *json(CYPoolCCYON(pool, context, result, objects, &exception)); - if (exception != NULL) - goto error; + try { + JSValueRef result(_jsccall(JSEvaluateScript, context, CYJSString(code), NULL, NULL, 0)); + if (JSValueIsUndefined(context, result)) + return NULL; - CYSetProperty(context, CYGetGlobalObject(context), Result_, result); + std::set objects; + const char *json(_jsccall(CYPoolCCYON, pool, context, result, objects)); + CYSetProperty(context, CYGetGlobalObject(context), Result_, result); - return json; + return json; + } catch (const CYException &error) { + return pool.strcat("throw ", error.PoolCString(pool), NULL); + } } -void CYCancel() { +_visible void CYCancel() { cancel_ = true; } @@ -1726,19 +1737,19 @@ const char *CYJSError::PoolCString(CYPool &pool) const { return CYPoolCCYON(pool, context_, value_, objects); } -JSValueRef CYJSError::CastJSValue(JSContextRef context) const { - // XXX: what if the context is different? +JSValueRef CYJSError::CastJSValue(JSContextRef context, const char *name) const { + // XXX: what if the context is different? or the name? I dunno. ("epic" :/) return value_; } -JSValueRef CYCastJSError(JSContextRef context, const char *message) { - JSObjectRef Error(CYGetCachedObject(context, CYJSString("Error"))); +JSValueRef CYCastJSError(JSContextRef context, const char *name, const char *message) { + JSObjectRef Error(CYGetCachedObject(context, CYJSString(name))); JSValueRef arguments[1] = {CYCastJSValue(context, message)}; return _jsccall(JSObjectCallAsConstructor, context, Error, 1, arguments); } -JSValueRef CYPoolError::CastJSValue(JSContextRef context) const { - return CYCastJSError(context, message_); +JSValueRef CYPoolError::CastJSValue(JSContextRef context, const char *name) const { + return CYCastJSError(context, name, message_); } CYJSError::CYJSError(JSContextRef context, const char *format, ...) { @@ -1752,15 +1763,13 @@ CYJSError::CYJSError(JSContextRef context, const char *format, ...) { const char *message(pool.vsprintf(64, format, args)); va_end(args); - value_ = CYCastJSError(context, message); + value_ = CYCastJSError(context, "Error", message); } JSGlobalContextRef CYGetJSContext(JSContextRef context) { return reinterpret_cast(JSObjectGetPrivate(CYCastJSObject(context, CYGetProperty(context, CYGetGlobalObject(context), cy_s))))->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)); if (fd == -1) @@ -1866,6 +1875,9 @@ extern "C" void CYSetupContext(JSGlobalContextRef context) { JSObjectRef Error(CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Error")))); CYSetProperty(context, cy, CYJSString("Error"), Error); + JSObjectRef Error_prototype(CYCastJSObject(context, CYGetProperty(context, Error, prototype_s))); + CYSetProperty(context, cy, CYJSString("Error_prototype"), Error_prototype); + JSObjectRef Function(CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Function")))); CYSetProperty(context, cy, CYJSString("Function"), Function); @@ -1889,13 +1901,18 @@ extern "C" void CYSetupContext(JSGlobalContextRef context) { JSObjectRef String_prototype(CYCastJSObject(context, CYGetProperty(context, String, prototype_s))); CYSetProperty(context, cy, CYJSString("String_prototype"), String_prototype); + + JSObjectRef SyntaxError(CYCastJSObject(context, CYGetProperty(context, global, CYJSString("SyntaxError")))); + CYSetProperty(context, cy, CYJSString("SyntaxError"), SyntaxError); /* }}} */ CYSetProperty(context, Array_prototype, toCYON_s, &Array_callAsFunction_toCYON, kJSPropertyAttributeDontEnum); + CYSetProperty(context, Error_prototype, toCYON_s, &Error_callAsFunction_toCYON, kJSPropertyAttributeDontEnum); CYSetProperty(context, String_prototype, toCYON_s, &String_callAsFunction_toCYON, kJSPropertyAttributeDontEnum); JSObjectRef cycript(JSObjectMake(context, NULL, NULL)); CYSetProperty(context, global, CYJSString("Cycript"), cycript); + CYSetProperty(context, cycript, CYJSString("compile"), &Cycript_compile_callAsFunction); CYSetProperty(context, cycript, CYJSString("gc"), &Cycript_gc_callAsFunction); JSObjectRef Functor(JSObjectMakeConstructor(context, Functor_, &Functor_new)); @@ -1929,8 +1946,6 @@ extern "C" void CYSetupContext(JSGlobalContextRef context) { CYSetPrototype(context, last, all); } - CYSetProperty(context, global, CYJSString("$cyq"), &$cyq, kJSPropertyAttributeDontEnum); - JSObjectRef System(JSObjectMake(context, NULL, NULL)); CYSetProperty(context, cy, CYJSString("System"), System); @@ -1960,7 +1975,7 @@ extern "C" void CYSetupContext(JSGlobalContextRef context) { static JSGlobalContextRef context_; -JSGlobalContextRef CYGetJSContext() { +_visible JSGlobalContextRef CYGetJSContext() { CYInitializeDynamic(); if (context_ == NULL) { @@ -1971,7 +1986,7 @@ JSGlobalContextRef CYGetJSContext() { return context_; } -void CYDestroyContext() { +_visible void CYDestroyContext() { if (context_ == NULL) return; JSGlobalContextRelease(context_);