X-Git-Url: https://git.saurik.com/cycript.git/blobdiff_plain/5587a93f98c158ab5e71c1f1c6b318690271d335..e78a4755a100b5c18594a068c7c2aa7456331111:/ObjectiveC/Library.mm diff --git a/ObjectiveC/Library.mm b/ObjectiveC/Library.mm index fe8933c..a8c3b33 100644 --- a/ObjectiveC/Library.mm +++ b/ObjectiveC/Library.mm @@ -370,7 +370,7 @@ JSValueRef CYGetClassPrototype(JSContextRef context, Class self, bool meta) { prototype = CYGetClassPrototype(context, class_getSuperclass(self), meta); JSObjectRef object(JSObjectMake(context, _class, NULL)); - JSObjectSetPrototype(context, object, prototype); + CYSetPrototype(context, object, prototype); CYSetProperty(context, cy, name, object); return object; @@ -383,7 +383,7 @@ _finline JSValueRef CYGetClassPrototype(JSContextRef context, Class self) { JSObjectRef Messages::Make(JSContextRef context, Class _class) { JSObjectRef value(JSObjectMake(context, Messages_, new Messages(_class))); if (Class super = class_getSuperclass(_class)) - JSObjectSetPrototype(context, value, Messages::Make(context, super)); + CYSetPrototype(context, value, Messages::Make(context, super)); return value; } @@ -406,7 +406,7 @@ bool CYIsKindOfClass(id object, Class _class) { JSObjectRef Instance::Make(JSContextRef context, id object, Flags flags) { JSObjectRef value(JSObjectMake(context, CYIsKindOfClass(object, NSBlock_) ? FunctionInstance_ : Instance_, new Instance(object, flags))); - JSObjectSetPrototype(context, value, CYGetClassPrototype(context, object_getClass(object))); + CYSetPrototype(context, value, CYGetClassPrototype(context, object_getClass(object))); return value; } @@ -1470,8 +1470,10 @@ static SEL CYCastSEL(JSContextRef context, JSValueRef value) { if (JSValueIsObjectOfClass(context, value, Selector_)) { Selector_privateData *internal(reinterpret_cast(JSObjectGetPrivate((JSObjectRef) value))); return reinterpret_cast(internal->value_); - } else - return CYCastPointer(context, value); + } else { + CYPool pool; + return sel_registerName(CYPoolCString(pool, context, value)); + } } void *CYObjectiveC_ExecuteStart(JSContextRef context) { CYSadTry { @@ -1601,24 +1603,6 @@ static bool CYImplements(id object, Class _class, SEL selector, bool devoid = fa return false; } -static const char *CYPoolTypeEncoding(CYPool &pool, JSContextRef context, SEL sel, objc_method *method) { - if (method != NULL) - return method_getTypeEncoding(method); - - const char *name(sel_getName(sel)); - size_t length(strlen(name)); - - char keyed[length + 2]; - keyed[0] = '6'; - keyed[length + 1] = '\0'; - memcpy(keyed + 1, name, length); - - if (CYBridgeEntry *entry = CYBridgeHash(keyed, length + 1)) - return entry->value_; - - return NULL; -} - static JSValueRef MessageAdapter_(JSContextRef context, size_t count, JSValueRef values[], JSObjectRef function) { JSObjectRef _this(CYCastJSObject(context, values[0])); return CYCallAsFunction(context, function, _this, count - 2, values + 2); @@ -1686,11 +1670,10 @@ static bool Messages_setProperty(JSContextRef context, JSObjectRef object, JSStr Message_privateData *message(reinterpret_cast(JSObjectGetPrivate((JSObjectRef) value))); type = sig::Unparse(pool, &message->signature_); imp = reinterpret_cast(message->GetValue()); - } else { - objc_method *method(class_getInstanceMethod(_class, sel)); - type = CYPoolTypeEncoding(pool, context, sel, method); + } else if (objc_method *method = class_getInstanceMethod(_class, sel)) { + type = method_getTypeEncoding(method); imp = CYMakeMessage(context, value, type); - } + } else _assert(false); objc_method *method(NULL); #if OBJC_API_VERSION >= 2 @@ -2065,6 +2048,7 @@ static void CYBitField(unsigned &length, unsigned &shift, id self, Ivar ivar, co break; else if (ivar_getOffset(ivars[i]) == offset) { const char *encoding(ivar_getTypeEncoding(ivars[i])); + _assert(encoding != NULL); _assert(encoding[0] == 'b'); shift += CYCastDouble(encoding + 1); } @@ -2088,6 +2072,7 @@ static JSValueRef Internal_getProperty(JSContextRef context, JSObjectRef object, void *data(reinterpret_cast(self) + offset); const char *encoding(ivar_getTypeEncoding(ivar)); + _assert(encoding != NULL); if (encoding[0] == 'b') { unsigned length, shift; CYBitField(length, shift, self, ivar, encoding, offset); @@ -2116,6 +2101,7 @@ static bool Internal_setProperty(JSContextRef context, JSObjectRef object, JSStr void *data(reinterpret_cast(self) + offset); const char *encoding(ivar_getTypeEncoding(ivar)); + _assert(encoding != NULL); if (encoding[0] == 'b') { unsigned length, shift; CYBitField(length, shift, self, ivar, encoding, offset); @@ -2351,7 +2337,12 @@ static void choose_(task_t task, void *baton, unsigned type, vm_range_t *ranges, size_t needed(class_getInstanceSize(*result)); // XXX: if (size < needed) - if (needed <= 496 && (needed + 15) / 16 * 16 != size || needed > 496 && (needed + 511) / 512 * 512 != size) + + size_t boundary(496); +#ifdef __LP64__ + boundary *= 2; +#endif + if (needed <= boundary && (needed + 15) / 16 * 16 != size || needed > boundary && (needed + 511) / 512 * 512 != size) continue; CYArrayPush(context, choice->results_, CYCastJSValue(context, reinterpret_cast(data))); } @@ -2760,15 +2751,9 @@ static JSValueRef Selector_callAsFunction_type(JSContextRef context, JSObjectRef Selector_privateData *internal(reinterpret_cast(JSObjectGetPrivate(_this))); SEL sel(internal->GetValue()); - objc_method *method; - if (Class _class = CYCastClass(pool, context, arguments[0])) - method = class_getInstanceMethod(_class, sel); - else - method = NULL; - - const char *encoding(CYPoolTypeEncoding(pool, context, sel, method)); - if (encoding == NULL) - return CYJSNull(context); + Class _class(_require(CYCastClass(pool, context, arguments[0]))); + objc_method *method(_require(class_getInstanceMethod(_class, sel))); + const char *encoding(method_getTypeEncoding(method)); sig::Signature signature; sig::Parse(pool, &signature, encoding, &Structor_); @@ -2990,12 +2975,14 @@ void CYObjectiveC_Initialize() { /*XXX*/ JSContextRef context(NULL); CYPoolTry { ObjectiveC_Protocols_ = JSClassCreate(&definition); #ifdef __APPLE__ -// XXX: this is horrible; there has to be a better way to do this -#ifdef __LP64__ - class_addMethod(NSCFType_, @selector(cy$toJSON:inContext:), reinterpret_cast(&NSCFType$cy$toJSON$inContext$), "^{OpaqueJSValue=}32@0:8@16^{OpaqueJSContext=}24"); -#else - class_addMethod(NSCFType_, @selector(cy$toJSON:inContext:), reinterpret_cast(&NSCFType$cy$toJSON$inContext$), "^{OpaqueJSValue=}16@0:4@8^{OpaqueJSContext=}12"); -#endif + class_addMethod(NSCFType_, @selector(cy$toJSON:inContext:), reinterpret_cast(&NSCFType$cy$toJSON$inContext$), + // XXX: this is horrible; there has to be a better way to do this + #ifdef __LP64__ + "^{OpaqueJSValue=}32@0:8@16^{OpaqueJSContext=}24" + #else + "^{OpaqueJSValue=}16@0:4@8^{OpaqueJSContext=}12" + #endif + ); #endif } CYPoolCatch() } @@ -3038,41 +3025,41 @@ void CYObjectiveC_SetupContext(JSContextRef context) { CYPoolTry { JSObjectRef ArrayInstance_prototype(CYCastJSObject(context, CYGetProperty(context, ArrayInstance, prototype_s))); CYSetProperty(context, cy, CYJSString("ArrayInstance_prototype"), ArrayInstance_prototype); JSObjectRef Array_prototype(CYGetCachedObject(context, CYJSString("Array_prototype"))); - JSObjectSetPrototype(context, ArrayInstance_prototype, Array_prototype); + CYSetPrototype(context, ArrayInstance_prototype, Array_prototype); JSObjectRef BooleanInstance(JSObjectMakeConstructor(context, BooleanInstance_, NULL)); JSObjectRef BooleanInstance_prototype(CYCastJSObject(context, CYGetProperty(context, BooleanInstance, prototype_s))); CYSetProperty(context, cy, CYJSString("BooleanInstance_prototype"), BooleanInstance_prototype); JSObjectRef Boolean_prototype(CYGetCachedObject(context, CYJSString("Boolean_prototype"))); - JSObjectSetPrototype(context, BooleanInstance_prototype, Boolean_prototype); + CYSetPrototype(context, BooleanInstance_prototype, Boolean_prototype); JSObjectRef FunctionInstance(JSObjectMakeConstructor(context, FunctionInstance_, NULL)); JSObjectRef FunctionInstance_prototype(CYCastJSObject(context, CYGetProperty(context, FunctionInstance, prototype_s))); CYSetProperty(context, cy, CYJSString("FunctionInstance_prototype"), FunctionInstance_prototype); JSObjectRef Function_prototype(CYGetCachedObject(context, CYJSString("Function_prototype"))); - JSObjectSetPrototype(context, FunctionInstance_prototype, Function_prototype); + CYSetPrototype(context, FunctionInstance_prototype, Function_prototype); JSObjectRef NumberInstance(JSObjectMakeConstructor(context, NumberInstance_, NULL)); JSObjectRef NumberInstance_prototype(CYCastJSObject(context, CYGetProperty(context, NumberInstance, prototype_s))); CYSetProperty(context, cy, CYJSString("NumberInstance_prototype"), NumberInstance_prototype); JSObjectRef Number_prototype(CYGetCachedObject(context, CYJSString("Number_prototype"))); - JSObjectSetPrototype(context, NumberInstance_prototype, Number_prototype); + CYSetPrototype(context, NumberInstance_prototype, Number_prototype); JSObjectRef ObjectInstance(JSObjectMakeConstructor(context, ObjectInstance_, NULL)); JSObjectRef ObjectInstance_prototype(CYCastJSObject(context, CYGetProperty(context, ObjectInstance, prototype_s))); CYSetProperty(context, cy, CYJSString("ObjectInstance_prototype"), ObjectInstance_prototype); JSObjectRef Object_prototype(CYGetCachedObject(context, CYJSString("Object_prototype"))); - JSObjectSetPrototype(context, ObjectInstance_prototype, Object_prototype); + CYSetPrototype(context, ObjectInstance_prototype, Object_prototype); JSObjectRef StringInstance(JSObjectMakeConstructor(context, StringInstance_, NULL)); JSObjectRef StringInstance_prototype(CYCastJSObject(context, CYGetProperty(context, StringInstance, prototype_s))); CYSetProperty(context, cy, CYJSString("StringInstance_prototype"), StringInstance_prototype); JSObjectRef String_prototype(CYGetCachedObject(context, CYJSString("String_prototype"))); - JSObjectSetPrototype(context, StringInstance_prototype, String_prototype); + CYSetPrototype(context, StringInstance_prototype, String_prototype); JSObjectRef Class_prototype(CYCastJSObject(context, CYGetProperty(context, Class, prototype_s))); CYSetProperty(context, cy, CYJSString("Class_prototype"), Class_prototype); - JSObjectSetPrototype(context, Class_prototype, Instance_prototype); + CYSetPrototype(context, Class_prototype, Instance_prototype); CYSetProperty(context, cycript, CYJSString("Instance"), Instance); CYSetProperty(context, cycript, CYJSString("Selector"), Selector); @@ -3087,8 +3074,8 @@ void CYObjectiveC_SetupContext(JSContextRef context) { CYPoolTry { CYSetProperty(context, all, CYJSString("objc_msgSend"), &$objc_msgSend, kJSPropertyAttributeDontEnum); - JSObjectSetPrototype(context, CYCastJSObject(context, CYGetProperty(context, Message, prototype_s)), Function_prototype); - JSObjectSetPrototype(context, CYCastJSObject(context, CYGetProperty(context, Selector, prototype_s)), Function_prototype); + CYSetPrototype(context, CYCastJSObject(context, CYGetProperty(context, Message, prototype_s)), Function_prototype); + CYSetPrototype(context, CYCastJSObject(context, CYGetProperty(context, Selector, prototype_s)), Function_prototype); } CYPoolCatch() } static CYHooks CYObjectiveCHooks = {