X-Git-Url: https://git.saurik.com/cycript.git/blobdiff_plain/8fab8594db1ad0dd8d0cfe1270993d5aa49215f5..3fe283c53edc2a98d0164d893a4a667245da8e78:/Execute.cpp diff --git a/Execute.cpp b/Execute.cpp index b2e0e0a..5baca2a 100644 --- a/Execute.cpp +++ b/Execute.cpp @@ -342,8 +342,14 @@ static JSValueRef $cyq(JSContextRef context, JSObjectRef object, JSObjectRef _th return CYCastJSValue(context, name); } CYCatch(NULL) } +static void (*JSSynchronousGarbageCollectForDebugging$)(JSContextRef); + +void CYGarbageCollect(JSContextRef context) { + (JSSynchronousGarbageCollectForDebugging$ ?: &JSGarbageCollect)(context); +} + static JSValueRef Cycript_gc_callAsFunction(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry { - JSGarbageCollect(context); + CYGarbageCollect(context); return CYJSUndefined(context); } CYCatch(NULL) } @@ -1140,6 +1146,78 @@ static JSValueRef Type_callAsFunction_constant(JSContextRef context, JSObjectRef return CYMakeType(context, &type); } CYCatch(NULL) } +static JSValueRef Type_callAsFunction_long(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry { + if (count != 0) + throw CYJSError(context, "incorrect number of arguments to Type.long"); + Type_privateData *internal(reinterpret_cast(JSObjectGetPrivate(_this))); + + sig::Type type(*internal->type_); + + switch (type.primitive) { + case sig::short_P: type.primitive = sig::int_P; break; + case sig::int_P: type.primitive = sig::long_P; break; + case sig::long_P: type.primitive = sig::longlong_P; break; + default: throw CYJSError(context, "invalid type argument to Type.long"); + } + + return CYMakeType(context, &type); +} CYCatch(NULL) } + +static JSValueRef Type_callAsFunction_short(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry { + if (count != 0) + throw CYJSError(context, "incorrect number of arguments to Type.short"); + Type_privateData *internal(reinterpret_cast(JSObjectGetPrivate(_this))); + + sig::Type type(*internal->type_); + + switch (type.primitive) { + case sig::int_P: type.primitive = sig::short_P; break; + case sig::long_P: type.primitive = sig::int_P; break; + case sig::longlong_P: type.primitive = sig::long_P; break; + default: throw CYJSError(context, "invalid type argument to Type.short"); + } + + return CYMakeType(context, &type); +} CYCatch(NULL) } + +static JSValueRef Type_callAsFunction_signed(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry { + if (count != 0) + throw CYJSError(context, "incorrect number of arguments to Type.signed"); + Type_privateData *internal(reinterpret_cast(JSObjectGetPrivate(_this))); + + sig::Type type(*internal->type_); + + switch (type.primitive) { + case sig::char_P: case sig::uchar_P: type.primitive = sig::char_P; break; + case sig::short_P: case sig::ushort_P: type.primitive = sig::short_P; break; + case sig::int_P: case sig::uint_P: type.primitive = sig::int_P; break; + case sig::long_P: case sig::ulong_P: type.primitive = sig::long_P; break; + case sig::longlong_P: case sig::ulonglong_P: type.primitive = sig::longlong_P; break; + default: throw CYJSError(context, "invalid type argument to Type.signed"); + } + + return CYMakeType(context, &type); +} CYCatch(NULL) } + +static JSValueRef Type_callAsFunction_unsigned(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry { + if (count != 0) + throw CYJSError(context, "incorrect number of arguments to Type.unsigned"); + Type_privateData *internal(reinterpret_cast(JSObjectGetPrivate(_this))); + + sig::Type type(*internal->type_); + + switch (type.primitive) { + case sig::char_P: case sig::uchar_P: type.primitive = sig::uchar_P; break; + case sig::short_P: case sig::ushort_P: type.primitive = sig::ushort_P; break; + case sig::int_P: case sig::uint_P: type.primitive = sig::uint_P; break; + case sig::long_P: case sig::ulong_P: type.primitive = sig::ulong_P; break; + case sig::longlong_P: case sig::ulonglong_P: type.primitive = sig::ulonglong_P; break; + default: throw CYJSError(context, "invalid type argument to Type.unsigned"); + } + + return CYMakeType(context, &type); +} CYCatch(NULL) } + static JSValueRef Type_callAsFunction_functionWith(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { return Type_callAsFunction_$With(context, object, _this, count, arguments, sig::function_P, exception); } @@ -1349,16 +1427,20 @@ static JSStaticValue Type_staticValues[4] = { {NULL, NULL, NULL, 0} }; -static JSStaticFunction Type_staticFunctions[10] = { +static JSStaticFunction Type_staticFunctions[14] = { {"arrayOf", &Type_callAsFunction_arrayOf, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete}, {"blockWith", &Type_callAsFunction_blockWith, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete}, {"constant", &Type_callAsFunction_constant, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete}, {"functionWith", &Type_callAsFunction_functionWith, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete}, + {"long", &Type_callAsFunction_long, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete}, {"pointerTo", &Type_callAsFunction_pointerTo, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete}, + {"short", &Type_callAsFunction_short, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete}, + {"signed", &Type_callAsFunction_signed, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete}, {"withName", &Type_callAsFunction_withName, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete}, {"toCYON", &Type_callAsFunction_toCYON, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete}, {"toJSON", &Type_callAsFunction_toJSON, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete}, {"toString", &Type_callAsFunction_toString, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete}, + {"unsigned", &Type_callAsFunction_unsigned, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete}, {NULL, NULL, 0} }; @@ -1387,19 +1469,33 @@ JSObjectRef CYGetGlobalObject(JSContextRef context) { return JSContextGetGlobalObject(context); } +class ExecutionHandle { + private: + JSContextRef context_; + void *handle_; + + public: + ExecutionHandle(JSContextRef context) : + context_(context) + { + if (hooks_ != NULL && hooks_->ExecuteStart != NULL) + handle_ = (*hooks_->ExecuteStart)(context_); + else + handle_ = NULL; + } + + ~ExecutionHandle() { + if (hooks_ != NULL && hooks_->ExecuteEnd != NULL) + (*hooks_->ExecuteEnd)(context_, handle_); + } +}; + const char *CYExecute(JSContextRef context, CYPool &pool, CYUTF8String code) { JSValueRef exception(NULL); - void *handle; - if (hooks_ != NULL && hooks_->ExecuteStart != NULL) - handle = (*hooks_->ExecuteStart)(context); - else - handle = NULL; - - try { + ExecutionHandle handle(context); - JSValueRef result; - try { + JSValueRef result; try { result = JSEvaluateScript(context, CYJSString(code), NULL, NULL, 0, &exception); } catch (const char *error) { return error; @@ -1411,8 +1507,7 @@ const char *CYExecute(JSContextRef context, CYPool &pool, CYUTF8String code) { if (JSValueIsUndefined(context, result)) return NULL; - const char *json; - try { + const char *json; try { json = CYPoolCCYON(pool, context, result, &exception); } catch (const char *error) { return error; @@ -1424,12 +1519,6 @@ const char *CYExecute(JSContextRef context, CYPool &pool, CYUTF8String code) { CYSetProperty(context, CYGetGlobalObject(context), Result_, result); return json; - - } catch (...) { - if (hooks_ != NULL && hooks_->ExecuteEnd != NULL) - (*hooks_->ExecuteEnd)(context, handle); - throw; - } } static bool initialized_ = false; @@ -1440,6 +1529,7 @@ void CYInitializeDynamic() { else return; JSObjectMakeArray$ = reinterpret_cast(dlsym(RTLD_DEFAULT, "JSObjectMakeArray")); + JSSynchronousGarbageCollectForDebugging$ = reinterpret_cast(dlsym(RTLD_DEFAULT, "JSSynchronousGarbageCollectForDebugging")); JSClassDefinition definition;