From: Jay Freeman (saurik) Date: Tue, 7 Jan 2014 09:38:40 +0000 (-0800) Subject: Support Internal_getProperty with bitfield types. X-Git-Tag: v0.9.500~98 X-Git-Url: https://git.saurik.com/cycript.git/commitdiff_plain/ad22d2f8fdbd2325105dc5f32642118c455286b6 Support Internal_getProperty with bitfield types. --- diff --git a/ObjectiveC/Library.mm b/ObjectiveC/Library.mm index 3fa5c70..c72212e 100644 --- a/ObjectiveC/Library.mm +++ b/ObjectiveC/Library.mm @@ -1977,9 +1977,32 @@ static JSValueRef Internal_getProperty(JSContextRef context, JSObjectRef object, #endif if (objc_ivar *ivar = object_getInstanceVariable(self, name, NULL)) { - Type_privateData type(pool, ivar_getTypeEncoding(ivar)); - // XXX: if this fails and throws an exception the person we are throwing it to gets the wrong exception - return CYFromFFI(context, type.type_, type.GetFFI(), reinterpret_cast(self) + ivar_getOffset(ivar)); + ptrdiff_t offset(ivar_getOffset(ivar)); + void *data(reinterpret_cast(self) + offset); + + const char *encoding(ivar_getTypeEncoding(ivar)); + if (encoding[0] == 'b') { + unsigned length(CYCastDouble(encoding + 1)); + unsigned shift(0); + + unsigned int size; + objc_ivar **ivars(class_copyIvarList(object_getClass(self), &size)); + for (size_t i(0); i != size; ++i) + if (ivars[i] == ivar) + break; + else if (ivar_getOffset(ivars[i]) == offset) { + const char *encoding(ivar_getTypeEncoding(ivars[i])); + _assert(encoding[0] == 'b'); + shift += CYCastDouble(encoding + 1); + } + free(ivars); + + _assert(shift + length <= sizeof(uintptr_t) * 8); + return CYCastJSValue(context, (*reinterpret_cast(data) >> shift) & (1 << length) - 1); + } else { + Type_privateData type(pool, ivar_getTypeEncoding(ivar)); + return CYFromFFI(context, type.type_, type.GetFFI(), data); + } } return NULL;