From: Jay Freeman (saurik) Date: Sun, 26 Jan 2014 16:59:33 +0000 (-0800) Subject: Add hasProperty for All and ObjectiveC::Classes. X-Git-Tag: v0.9.501~11 X-Git-Url: https://git.saurik.com/cycript.git/commitdiff_plain/58321c0afd977fa7a47f5d81ee0674ca7582c309 Add hasProperty for All and ObjectiveC::Classes. --- diff --git a/Execute.cpp b/Execute.cpp index b4614c4..2bdd59f 100644 --- a/Execute.cpp +++ b/Execute.cpp @@ -54,6 +54,10 @@ struct CYHooks *hooks_; /* JavaScript Properties {{{ */ +bool CYHasProperty(JSContextRef context, JSObjectRef object, JSStringRef name) { + return JSObjectHasProperty(context, object, name); +} + JSValueRef CYGetProperty(JSContextRef context, JSObjectRef object, size_t index) { return _jsccall(JSObjectGetPropertyAtIndex, context, object, index); } @@ -991,6 +995,33 @@ JSObjectRef CYMakeType(JSContextRef context, sig::Signature *signature) { return CYMakeType(context, &type); } +static bool All_hasProperty(JSContextRef context, JSObjectRef object, JSStringRef property) { + JSObjectRef global(CYGetGlobalObject(context)); + JSObjectRef cycript(CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Cycript")))); + JSObjectRef alls(CYCastJSObject(context, CYGetProperty(context, cycript, CYJSString("alls")))); + + for (size_t i(0), count(CYArrayLength(context, alls)); i != count; ++i) + if (JSObjectRef space = CYCastJSObject(context, CYArrayGet(context, alls, count - i - 1))) + if (CYHasProperty(context, space, property)) + return true; + + CYPool pool; + CYUTF8String name(CYPoolUTF8String(pool, context, property)); + + size_t length(name.size); + char keyed[length + 2]; + memcpy(keyed + 1, name.data, length + 1); + + static const char *modes = "0124"; + for (size_t i(0); i != 4; ++i) { + keyed[0] = modes[i]; + if (CYBridgeHash(keyed, length + 1) != NULL) + return true; + } + + return false; +} + static JSValueRef All_getProperty(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) { CYTry { JSObjectRef global(CYGetGlobalObject(context)); JSObjectRef cycript(CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Cycript")))); @@ -1538,6 +1569,7 @@ void CYInitializeDynamic() { definition = kJSClassDefinitionEmpty; definition.className = "All"; + definition.hasProperty = &All_hasProperty; definition.getProperty = &All_getProperty; definition.getPropertyNames = &All_getPropertyNames; All_ = JSClassCreate(&definition); diff --git a/JavaScript.hpp b/JavaScript.hpp index c8a8fd8..3fb2e6c 100644 --- a/JavaScript.hpp +++ b/JavaScript.hpp @@ -67,6 +67,7 @@ double CYCastDouble(JSContextRef context, JSValueRef value); CYUTF8String CYPoolUTF8String(CYPool &pool, JSContextRef context, JSStringRef value); const char *CYPoolCString(CYPool &pool, JSContextRef context, JSStringRef value); +bool CYHasProperty(JSContextRef context, JSObjectRef object, JSStringRef name); JSValueRef CYGetProperty(JSContextRef context, JSObjectRef object, size_t index); JSValueRef CYGetProperty(JSContextRef context, JSObjectRef object, JSStringRef name); diff --git a/ObjectiveC/Library.mm b/ObjectiveC/Library.mm index 43e592b..e8579cd 100644 --- a/ObjectiveC/Library.mm +++ b/ObjectiveC/Library.mm @@ -2143,6 +2143,11 @@ static JSValueRef Internal_callAsFunction_$cya(JSContextRef context, JSObjectRef return internal->GetOwner(); } CYCatch(NULL) } +static bool ObjectiveC_Classes_hasProperty(JSContextRef context, JSObjectRef object, JSStringRef property) { + CYPool pool; + return objc_getClass(CYPoolCString(pool, context, property)) != Nil; +} + static JSValueRef ObjectiveC_Classes_getProperty(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) { CYTry { CYPool pool; NSString *name(CYCastNSString(&pool, context, property)); @@ -2931,6 +2936,7 @@ void CYObjectiveC_Initialize() { /*XXX*/ JSContextRef context(NULL); CYPoolTry { definition = kJSClassDefinitionEmpty; definition.className = "ObjectiveC::Classes"; + definition.hasProperty = &ObjectiveC_Classes_hasProperty; definition.getProperty = &ObjectiveC_Classes_getProperty; definition.getPropertyNames = &ObjectiveC_Classes_getPropertyNames; ObjectiveC_Classes_ = JSClassCreate(&definition);