Hello, I've been trying to get some OSX code to execute within the JIT, and it's been causing me some major headaches! I'm attempting to JIT-compile some code which uses external OSX obj-C classes (Cocoa, etc), and also contains its own embedded obj-C classes. My first hurdle in doing this was that when the code tried to call Cocoa classes, the obj-C selectors weren't being recognised by the host process's objc_msgSend function.. After quite a bit of hair-pulling, I copied a trick from the lldb::IRForTarget class, which scans the compiled module and replaces any selector constants with explicit function calls to sel_registerName().. By applying a similar transformation to my own modules, I've now managed to successfully invoke selectors on Cocoa classes. But now I've hit a brick wall trying to use internal obj-C classes (i.e. classes that are defined within the JIT-ed code itself). With these, even trying to alloc them causes a crash. Does anyone have enough of a grasp of what's going on in the JIT and obj-C ABI to be able to give me some pointers here!? Thanks!
Le 7 mai 2012 à 17:07, Jules a écrit :> Hello, I've been trying to get some OSX code to execute within the JIT, > and it's been causing me some major headaches! > > I'm attempting to JIT-compile some code which uses external OSX obj-C > classes (Cocoa, etc), and also contains its own embedded obj-C classes. > > My first hurdle in doing this was that when the code tried to call Cocoa > classes, the obj-C selectors weren't being recognised by the host > process's objc_msgSend function.. After quite a bit of hair-pulling, I > copied a trick from the lldb::IRForTarget class, which scans the compiled > module and replaces any selector constants with explicit function calls > to sel_registerName().. By applying a similar transformation to my own > modules, I've now managed to successfully invoke selectors on Cocoa classes. > > But now I've hit a brick wall trying to use internal obj-C classes (i.e. > classes that are defined within the JIT-ed code itself). With these, even > trying to alloc them causes a crash. Does anyone have enough of a grasp of > what's going on in the JIT and obj-C ABI to be able to give me some > pointers here!? > > Thanks!Obj-C classes are registered by the runtime at module load time. When a module is loaded, the Obj-C runtime create classes and register them by parsing the module Obj-C data segments. My guess is that as you are using JIT, the runtime hook used to detect loading of new module is never called, and your classes are not registered. You can try to load them manually by using the runtime functions (see https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html ) and if it's not enough, you may have to download the runtime source code (http://opensource.apple.com/source/objc4/objc4-493.11/) to see what it does when a new module is loaded. -- Jean-Daniel
Thanks for the info! Yes, the problem is certainly that the JITed code isn't registering its classes, but even after digging through all the runtime code I can't find anything that seems suitable for doing this.. The nearest function I could find was _objc_init_image, but that seems to be for win32! I assume that the way it works must be that clang creates some static data structures defining all the class's methods and ivars, and then these data structures are picked up automatically (somehow) by the runtime, which parses them and dynamically registers the classes appropriately..? So the worst-case here seems to be that I might need to write my own utility to do this parsing/registering.. But it'd be nice to at least be able to see some code from the runtime that does this job, so I can understand what's going on, but I can't find anything like that! On 7 May 2012 22:17, Jean-Daniel Dupas <devlists at shadowlab.org> wrote:> > > Le 7 mai 2012 à 17:07, Jules a écrit : > > > Hello, I've been trying to get some OSX code to execute within the JIT, > > and it's been causing me some major headaches! > > > > I'm attempting to JIT-compile some code which uses external OSX obj-C > > classes (Cocoa, etc), and also contains its own embedded obj-C classes. > > > > My first hurdle in doing this was that when the code tried to call Cocoa > > classes, the obj-C selectors weren't being recognised by the host > > process's objc_msgSend function.. After quite a bit of hair-pulling, I > > copied a trick from the lldb::IRForTarget class, which scans the compiled > > module and replaces any selector constants with explicit function calls > > to sel_registerName().. By applying a similar transformation to my own > > modules, I've now managed to successfully invoke selectors on Cocoa classes. > > > > But now I've hit a brick wall trying to use internal obj-C classes (i.e. > > classes that are defined within the JIT-ed code itself). With these, even > > trying to alloc them causes a crash. Does anyone have enough of a grasp of > > what's going on in the JIT and obj-C ABI to be able to give me some > > pointers here!? > > > > Thanks! > > > Obj-C classes are registered by the runtime at module load time. > When a module is loaded, the Obj-C runtime create classes and register them by parsing the module Obj-C data segments. > > My guess is that as you are using JIT, the runtime hook used to detect loading of new module is never called, and your classes are not registered. > You can try to load them manually by using the runtime functions (see https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html ) and if it's not enough, you may have to download the runtime source code (http://opensource.apple.com/source/objc4/objc4-493.11/) to see what it does when a new module is loaded. > > > -- Jean-Daniel > > > >