|
View:
New views
7 Messages
—
Rating Filter:
Alert me
|
|
|
CoreFoundationJust testing the water... I've been a little bored and started looking at implementing a portion of CoreFoundation on top of libobjc and GNUstep-base, I'm tentatively calling it CoreBase.
At this point I've spent most of my time on the runtime (CFRuntime) and CFBase. I'm not sure if it works, because in CF the runtime requires CFString and CFDictionary and I'll have to at least do some work there before even trying to compile. Because I don't want to have to rewrite/copy parts of what's already in GNUstep-base (like reference counting) I've decided to depend on it. Libobjc is also required because I'm using that as a gateway to -base, and using some of it's features (like the class number stored in class->info to coinside with the CFTypeID). Before continuing with it (because, of course, time is precious) I want to make sure there's at least some interest. I'm also going to need a fairly high degree of help on this project because certain parts are out of my league (I still think it's an interesting learning experience). Anyway, just let me know if it's a project I should keep moving forward. Thanks Stefan _______________________________________________ Gnustep-dev mailing list Gnustep-dev@... http://lists.gnu.org/mailman/listinfo/gnustep-dev |
|
|
Re: CoreFoundationHi Stef,
Having an implementation of Core Foundation would be nice, but I believe your approach is wrong. First, please do not use the info field in the class structure for anything. That field is for the runtime to use. The GCC runtime uses several of them, the GNUstep runtime uses a few more. It should not be used; there is no guarantee that future runtime versions won't use them all. With regard to the CFTypeID, this should be the address of the class structure. For those unfamiliar with how CoreFoundation works: Each of the CF classes has an isa pointer, just like an Objective-C object. Unlike Objective-C objects, this is set to a value below 64KB, which is guaranteed not to be the address of a real class. This number is the CFTypeID, which is a pseudo-class. The reason that is that Apple's CoreFoundation does not depend on libobjc (although it does link to it). If you use CF without libobjc, then you use static dispatch for all of the CF calls. When you call CFSomething() the function checks that the object's isa pointer is set to the magic constant that it expects and if not then it calls another function (via some ugly macros). This is done so CF objects can be used without relying on libobjc having finished loading classes. If you use Objective-C then you get the toll-free bridging. If you send a message to an object with an isa pointer that is less than 2^16, then the runtime uses a special lookup mechanism. If you call a CF function with an object with an isa pointer above 2^16, it bounces it to the Objective-C runtime for looking up the method (this is how, for example, you can use CFString functions on your own NSString subclass). Unless you want to use CF for some very low-level stuff, then there is really no point in copying this. You can just: 1) Define Objective-C classes that implement the CF types (many of these already exist in GNUstep). 2) Write wrapper functions that call the ObjC methods. 3) Return the address of the class as the isa pointer. This will then work with all code that uses CF types unless they either rely on the TypeID < 2^16 thing or uses CF functions in +load or __attribute__((constructor)) functions. Most of the CF equivalents of class methods take a CFAllocator. You can declare this as a typedef from NSZone; they are functionally equivalent. For a first pass, you can just implement most of the CF functions as trivial Objective-C functions, for example: typedef NSArray *CFArrayRef; typedef NSZone *CFAllocatorRef; CFArrayRef CFArrayCreateCopy(CFAllocatorRef allocator, CFArrayRef theArray) { [(NSArray*)theArray copyWithZone: allocator]; } Once this is working, then you can start worrying about optimising it. You might also consider making these in static inline functions in the header wrapped in #ifdef __OBJC__ so that people using CF functions in ObjC call the real methods. I wrote some macros for declaring / defining these CF functions a while back, which I can send you if you're interested, and I'm happy to review any code you're working on. David On 23 Oct 2009, at 21:23, Stef Bidi wrote: > Just testing the water... I've been a little bored and started > looking at implementing a portion of CoreFoundation on top of > libobjc and GNUstep-base, I'm tentatively calling it CoreBase. > > At this point I've spent most of my time on the runtime (CFRuntime) > and CFBase. I'm not sure if it works, because in CF the runtime > requires CFString and CFDictionary and I'll have to at least do some > work there before even trying to compile. Because I don't want to > have to rewrite/copy parts of what's already in GNUstep-base (like > reference counting) I've decided to depend on it. Libobjc is also > required because I'm using that as a gateway to -base, and using > some of it's features (like the class number stored in class->info > to coinside with the CFTypeID). > > Before continuing with it (because, of course, time is precious) I > want to make sure there's at least some interest. I'm also going to > need a fairly high degree of help on this project because certain > parts are out of my league (I still think it's an interesting > learning experience). > > Anyway, just let me know if it's a project I should keep moving > forward. > > Thanks > Stefan > _______________________________________________ > Gnustep-dev mailing list > Gnustep-dev@... > http://lists.gnu.org/mailman/listinfo/gnustep-dev -- Send from my Jacquard Loom _______________________________________________ Gnustep-dev mailing list Gnustep-dev@... http://lists.gnu.org/mailman/listinfo/gnustep-dev |
|
|
Re: CoreFoundationHey guys,
I'm currently working on porting webkit. It would be very nice to have an implementation of corefoundation in gnustep. Currently I'm having to use opencflite. GC On Friday, October 23, 2009, David Chisnall <theraven@...> wrote: > Hi Stef, > > Having an implementation of Core Foundation would be nice, but I believe your approach is wrong. > > First, please do not use the info field in the class structure for anything. That field is for the runtime to use. The GCC runtime uses several of them, the GNUstep runtime uses a few more. It should not be used; there is no guarantee that future runtime versions won't use them all. > > With regard to the CFTypeID, this should be the address of the class structure. For those unfamiliar with how CoreFoundation works: > > Each of the CF classes has an isa pointer, just like an Objective-C object. Unlike Objective-C objects, this is set to a value below 64KB, which is guaranteed not to be the address of a real class. This number is the CFTypeID, which is a pseudo-class. > > The reason that is that Apple's CoreFoundation does not depend on libobjc (although it does link to it). If you use CF without libobjc, then you use static dispatch for all of the CF calls. When you call CFSomething() the function checks that the object's isa pointer is set to the magic constant that it expects and if not then it calls another function (via some ugly macros). This is done so CF objects can be used without relying on libobjc having finished loading classes. > > If you use Objective-C then you get the toll-free bridging. If you send a message to an object with an isa pointer that is less than 2^16, then the runtime uses a special lookup mechanism. If you call a CF function with an object with an isa pointer above 2^16, it bounces it to the Objective-C runtime for looking up the method (this is how, for example, you can use CFString functions on your own NSString subclass). > > Unless you want to use CF for some very low-level stuff, then there is really no point in copying this. You can just: > > 1) Define Objective-C classes that implement the CF types (many of these already exist in GNUstep). > 2) Write wrapper functions that call the ObjC methods. > 3) Return the address of the class as the isa pointer. > > This will then work with all code that uses CF types unless they either rely on the TypeID < 2^16 thing or uses CF functions in +load or __attribute__((constructor)) functions. > > Most of the CF equivalents of class methods take a CFAllocator. You can declare this as a typedef from NSZone; they are functionally equivalent. For a first pass, you can just implement most of the CF functions as trivial Objective-C functions, for example: > > typedef NSArray *CFArrayRef; > typedef NSZone *CFAllocatorRef; > CFArrayRef CFArrayCreateCopy(CFAllocatorRef allocator, CFArrayRef theArray) > { > [(NSArray*)theArray copyWithZone: allocator]; > } > > Once this is working, then you can start worrying about optimising it. You might also consider making these in static inline functions in the header wrapped in #ifdef __OBJC__ so that people using CF functions in ObjC call the real methods. > > I wrote some macros for declaring / defining these CF functions a while back, which I can send you if you're interested, and I'm happy to review any code you're working on. > > David > > On 23 Oct 2009, at 21:23, Stef Bidi wrote: > > > Just testing the water... I've been a little bored and started looking at implementing a portion of CoreFoundation on top of libobjc and GNUstep-base, I'm tentatively calling it CoreBase. > > At this point I've spent most of my time on the runtime (CFRuntime) and CFBase. I'm not sure if it works, because in CF the runtime requires CFString and CFDictionary and I'll have to at least do some work there before even trying to compile. Because I don't want to have to rewrite/copy parts of what's already in GNUstep-base (like reference counting) I've decided to depend on it. Libobjc is also required because I'm using that as a gateway to -base, and using some of it's features (like the class number stored in class->info to coinside with the CFTypeID). > > Before continuing with it (because, of course, time is precious) I want to make sure there's at least some interest. I'm also going to need a fairly high degree of help on this project because certain parts are out of my league (I still think it's an interesting learning experience). > > Anyway, just let me know if it's a project I should keep moving forward. > > Thanks > Stefan > _______________________________________________ > Gnustep-dev mailing list > Gnustep-dev@... > http://lists.gnu.org/mailman/listinfo/gnustep-dev > > > -- Send from my Jacquard Loom > > > > _______________________________________________ > Gnustep-dev mailing list > Gnustep-dev@... > http://lists.gnu.org/mailman/listinfo/gnustep-dev > -- Gregory Casamento Open Logic Corporation, Principal Consultant ## GNUstep Chief Maintainer yahoo/skype: greg_casamento, aol: gjcasa (240)274-9630 (Cell), (301)362-9640 (Home) _______________________________________________ Gnustep-dev mailing list Gnustep-dev@... http://lists.gnu.org/mailman/listinfo/gnustep-dev |
|
|
Re: CoreFoundationOn Fri, Oct 23, 2009 at 4:34 PM, David Chisnall <theraven@...> wrote: Hi Stef, That is a definite possibility! :) These are the requirements I started out with: * Successfully compile the EXRange example in CF-Lite's CFRuntime.h; * Pass CF and NS objects freely (the ones that have corresponding NS classes, at least). First, please do not use the info field in the class structure for anything. That field is for the runtime to use. The GCC runtime uses several of them, the GNUstep runtime uses a few more. It should not be used; there is no guarantee that future runtime versions won't use them all. I guess I should explain, I was only going to use the CLS_GETNUMBER() macro in objc-api.h (that is, only the top half of the info field). I also noticed that this macros, when written out, doing: ((sizeof(long)*8)/2)... wouldn't ((sizeof(long)<<3)>>1) be a lot faster? Specially on RISC archtectures? My C programming book suggests that when multiplying or dividing by a multiple of 2^x a shift is often better than a multiply/divide. With regard to the CFTypeID, this should be the address of the class structure. For those unfamiliar with how CoreFoundation works: That includes me... the only thing I have to go by is CF-Lite's CFRuntime.h and the CF docs. Each of the CF classes has an isa pointer, just like an Objective-C object. Unlike Objective-C objects, this is set to a value below 64KB, which is guaranteed not to be the address of a real class. This number is the CFTypeID, which is a pseudo-class. Hmm... that's an interesting. Unless you want to use CF for some very low-level stuff, then there is really no point in copying this. You can just: And here's where I ran into some problems... apparently, CFAllocatorRef is considered a class (responds to CFGetTypeID()), but isn't one in GNUstep. Also, it allows users to define they're own with CFAllocatorCreate(), which takes a CFAllocatorContext. I might just have to not allow that if this is the case. CFArrayRef CFArrayCreateCopy(CFAllocatorRef allocator, CFArrayRef theArray) I was going with objc_msg_lookup, I figured I could do everything in pure C that way. But I guess this will work, too. This is why I put it out at this stage, so I don't follow the wrong path for too long. Once this is working, then you can start worrying about optimising it. You might also consider making these in static inline functions in the header wrapped in #ifdef __OBJC__ so that people using CF functions in ObjC call the real methods. Definitely, for both those statement! I'll clean up what I have in CFRuntime.c and CFBase.c (I'm pretty sure only I can understand the mess in there), and have you take a look. At this point, I'm really not sure what the correct way ahead should be. I'm hoping I'll get some more feedback so that I can make an informed decision. Stefan _______________________________________________ Gnustep-dev mailing list Gnustep-dev@... http://lists.gnu.org/mailman/listinfo/gnustep-dev |
|
|
Re: CoreFoundationOn 24 Oct 2009, at 02:14, Stef Bidi wrote:
_______________________________________________ Gnustep-dev mailing list Gnustep-dev@... http://lists.gnu.org/mailman/listinfo/gnustep-dev |
|
|
Re: CoreFoundationHi.
I've done quite a bit of work with the source of Apple's CFLite (working with OpenCFLite, and as the basis of my Foundation clone PureFoundation) so I thought I'd just chime in here. On 23 Oct 2009, at 22:34, David Chisnall wrote: > With regard to the CFTypeID, this should be the address of the class > structure. For those unfamiliar with how CoreFoundation works: > > Each of the CF classes has an isa pointer, just like an Objective-C > object. Unlike Objective-C objects, this is set to a value below > 64KB, which is guaranteed not to be the address of a real class. > This number is the CFTypeID, which is a > pseudo-class. Sorry, but this is incorrect. If a CF type is bridged to obj-C/ Foundation, then the ISA operates as in obj-C. If it is not bridged, or (as in CFLite) obj-C/Foundation classes are absent, this is NULL. The actual CFTypeID is stored in the block of header data which follows the ISA, and so is still present even if the ISA is set up as a pointer. Under Apple's CoreFoundation/Foundation, the bridged classes are private end-of-tree subclasses. eg. for NSString, the class is NSCFString (it runs NSString -> NSMutableString -> NSCFString, and whether the NSCFString is mutable or not depends on how it was created, and is flagged internally). Their ivars start with the ISA and then there follows the block of CF-specific fields which I don't believe are mapped/accessible as ivars. If you look at the CFLite source, this is CFRuntimeBase structure defined in CFRuntime.h. Which is all besides the point, because you're not looking to exactly clone Apple's CF here. So, Stef, your best approach is definitely, as David suggested: > 1) Define Objective-C classes that implement the CF types (many of > these already exist in GNUstep). > 2) Write wrapper functions that call the ObjC methods. > 3) Return the address of the class as the isa pointer. You may also want to implement Apple's super-secret - (CFTypeID)_cfTypeID method, which returns the CFTypeID of bridged objects. _sjc_ _______________________________________________ Gnustep-dev mailing list Gnustep-dev@... http://lists.gnu.org/mailman/listinfo/gnustep-dev |
|
|
Re: CoreFoundationOn 24 Oct 2009, at 02:14, Stef Bidi wrote:
> I guess I should explain, I was only going to use the CLS_GETNUMBER > () macro in objc-api.h (that is, only the top half of the info > field). I also noticed that this macros, when written out, doing: > ((sizeof(long)*8)/2)... wouldn't ((sizeof(long)<<3)>>1) be a lot > faster? Specially on RISC archtectures? My C programming book > suggests that when multiplying or dividing by a multiple of 2^x a > shift is often better than a multiply/divide. The CLS_GETNUMBER() macro should be considered private, and won't be exposed in future versions of the runtime. With regard to your optimization question, you might be interested in my article How Not To Optimize: http://www.informit.com/articles/article.aspx?p=1390173 In this case, if it is faster to use shifts then any compiler written in the last 20 years (including the toy that I wrote as an undergrad coursework assignment) will emit shifts for you. However, because this is an expression where all values are known at compile time, the compiler will simply evaluate it at compile time and if you look in the generated assembly you will find that it has become either 16 or 32. Note that, because shifts are relatively rare operations, most modern processors aren't optimized for shift-heavy instruction streams (except ARM, which lets you add a free shift to almost any instruction, which is pretty shiny). Older versions of GCC would expand multiplications to sequences of shift and add instructions, but on a modern x86 chip this will be the same speed in the best case and slower in the worst. >> With regard to the CFTypeID, this should be the address of the >> class structure. For those unfamiliar with how CoreFoundation works: > > That includes me... the only thing I have to go by is CF-Lite's > CFRuntime.h and the CF docs. You might be interested in this example, which talks in a lot more detail: http://ridiculousfish.com/blog/archives/2006/09/09/bridge/ Don't pay too much attention to it though; you want to duplicate the behaviour, not the implementation. Given that Apple now link CF with libobjc, I suspect that they are somewhat unconvinced by the benefit of this approach in the long run. It's only real advantage is that it will work in ObjC++ code if statics are initialized with CF calls and these happen to run before the relevant ObjC load functions (which, I think, can't happen on OS X because they hacked the linker to enforce some stricter ordering). > I was going with objc_msg_lookup, I figured I could do everything in > pure C that way. But I guess this will work, too. This is why I > put it out at this stage, so I don't follow the wrong path for too > long. I'd prefer you not to use objc_msg_lookup(), because it's deprecated in the new ABI. There's an objc_msgSend() macro in the new runtime.h that generates a correct lookup-and-call sequence for either ABI. Or just use Objective-C and let the compiler sort it out for you. > And here's where I ran into some problems... apparently, > CFAllocatorRef is considered a class (responds to CFGetTypeID()), > but isn't one in GNUstep. Also, it allows users to define they're > own with CFAllocatorCreate(), which takes a CFAllocatorContext. I > might just have to not allow that if this is the case. Oh yes, I forgot about that. On OS X, NSZone is an opaque structure. On GNUstep, it is not, and corresponds very closely to the CFAllocator initializer thingy. Of course, you could just create a new, private, CFAllocator class that has a single, public, NSZone ivar. > At this point, I'm really not sure what the correct way ahead should > be. I'm hoping I'll get some more feedback so that I can make an > informed decision. As Richard said, don't be afraid of modifying -base. It might be necessary to modify some of the existing GNUstep classes to better support CF. Stuart was also right that I oversimplified the TypeID thing. This does not change with inheritance; it's the same for any all objects that inherit from it, and only used as the isa pointer on the (opaque) leaf CF classes (this allows them to function before libobjc exists, and to be statically initialized). It's probably best to implement this with a -_cfTypeID method that returns a constant, and only override it in classes like NSArray, not any of their subclasses. > Stefan > -- Sent from my STANTEC-ZEBRA _______________________________________________ Gnustep-dev mailing list Gnustep-dev@... http://lists.gnu.org/mailman/listinfo/gnustep-dev |
| Free embeddable forum powered by Nabble | Forum Help |