X-Git-Url: https://git.saurik.com/cycript.git/blobdiff_plain/2f51d6ab2c7e56fade7ac6118cf02df9107ca3af..11b0723c033fa7d6452faae6da15d8848e705fbd:/Execute.cpp diff --git a/Execute.cpp b/Execute.cpp index e43cce6..8ac1b14 100644 --- a/Execute.cpp +++ b/Execute.cpp @@ -165,11 +165,14 @@ JSStringRef push_s; JSStringRef splice_s; JSStringRef toCYON_s; JSStringRef toJSON_s; +JSStringRef toPointer_s; static JSStringRef Result_; void CYFinalize(JSObjectRef object) { - delete reinterpret_cast(JSObjectGetPrivate(object)); + CYData *internal(reinterpret_cast(JSObjectGetPrivate(object))); + if (--internal->count_ == 0) + delete internal; } void Structor_(apr_pool_t *pool, sig::Type *&type) { @@ -177,6 +180,7 @@ void Structor_(apr_pool_t *pool, sig::Type *&type) { type->primitive == sig::pointer_P && type->data.data.type != NULL && type->data.data.type->primitive == sig::struct_P && + type->data.data.type->name != NULL && strcmp(type->data.data.type->name, "_objc_class") == 0 ) { type->primitive = sig::typename_P; @@ -485,8 +489,21 @@ JSObjectRef CYMakePointer(JSContextRef context, void *pointer, size_t length, si return JSObjectMake(context, Pointer_, internal); } -static JSObjectRef CYMakeFunctor(JSContextRef context, void (*function)(), const char *type) { - cy::Functor *internal(new cy::Functor(type, function)); +static JSObjectRef CYMakeFunctor(JSContextRef context, void (*function)(), const char *type, void **cache = NULL) { + cy::Functor *internal; + + if (cache != NULL && *cache != NULL) { + internal = reinterpret_cast(*cache); + ++internal->count_; + } else { + internal = new cy::Functor(type, function); + + if (cache != NULL) { + *cache = internal; + ++internal->count_; + } + } + return JSObjectMake(context, Functor_, internal); } @@ -498,12 +515,19 @@ void *CYCastPointer_(JSContextRef context, JSValueRef value) { switch (JSValueGetType(context, value)) { case kJSTypeNull: return NULL; - /*case kJSTypeObject: + case kJSTypeObject: { + JSObjectRef object((JSObjectRef) value); if (JSValueIsObjectOfClass(context, value, Pointer_)) { - Pointer *internal(reinterpret_cast(JSObjectGetPrivate((JSObjectRef) value))); + Pointer *internal(reinterpret_cast(JSObjectGetPrivate(object))); return internal->value_; - }*/ - default: + } + JSValueRef toPointer(CYGetProperty(context, object, toPointer_s)); + if (CYIsCallable(context, toPointer)) { + JSValueRef value(CYCallAsFunction(context, (JSObjectRef) toPointer, object, 0, NULL)); + _assert(value != NULL); + return CYCastPointer_(context, value); + } + } default: double number(CYCastDouble(context, value)); if (std::isnan(number)) throw CYJSError(context, "cannot convert value to pointer"); @@ -953,7 +977,7 @@ static JSValueRef All_getProperty(JSContextRef context, JSObjectRef object, JSSt case '1': if (void (*symbol)() = reinterpret_cast(CYCastSymbol(name.data))) - return CYMakeFunctor(context, symbol, entry->value_); + return CYMakeFunctor(context, symbol, entry->value_, &entry->cache_); else return NULL; case '2': @@ -1292,6 +1316,7 @@ void CYInitializeDynamic() { splice_s = JSStringCreateWithUTF8CString("splice"); toCYON_s = JSStringCreateWithUTF8CString("toCYON"); toJSON_s = JSStringCreateWithUTF8CString("toJSON"); + toPointer_s = JSStringCreateWithUTF8CString("toPointer"); Result_ = JSStringCreateWithUTF8CString("_"); @@ -1413,7 +1438,7 @@ extern "C" void CYSetupContext(JSGlobalContextRef context) { CYSetProperty(context, global, CYJSString("$cyq"), &$cyq); JSObjectRef System(JSObjectMake(context, NULL, NULL)); - CYSetProperty(context, cy, CYJSString("System"), Function); + CYSetProperty(context, cy, CYJSString("System"), System); CYSetProperty(context, global, CYJSString("system"), System); CYSetProperty(context, System, CYJSString("args"), CYJSNull(context));