eckel@erik.ircam.fr (Gerhard Eckel) (05/04/90)
I try to write a 'send' function for a SMALL lisp interpreter that sends messages to Obj-C objects and receives the return values from the corresponding methods (this is similar to the 'send' function of the objc package in Common Lisp on the NeXT). I try to use objc_msgSend() which returns an id. I did some assembler hacking to get the other 4 bytes (asm("movel d1, something")). I found that Obj-C doesn't return structures correctly that are bigger than 8 bytes. C functions return such structures over the stack (it seems that the compiler uses the register a1 to pass the address - data smaller than 8 bytes is returned in the registers d0 and d1 as far as I could see). It seems that it is a bug since the methods try to copy the data using register a1. But where does it end up (I hate 'Bus error' and 'Segmentation fault')? Consider the following fragment: typedef struct { int a, b, c; } threeInts; @interface SomeClass : SomeSuperClass { threeInts someInts; } - (threeInts) someMethod; @end @implementation SomeClass - (threeInts) someMethod { return someInts; } @end id instance = [SomeClass new]; // the following line doesn't work // (i.e. the data is not copied into r) threeInts result = [instance someMethod]; // it works for twoInts (struct { int a, b; }) Any idea? Is this how it should be? Anything in the doc that I missed? Anybody else who tried to do a similar thing? Gerhard Eckel IRCAM, Paris eckel@ircam.fr
cox@stpstn.UUCP (Brad Cox) (05/07/90)
In article <1062@ircam.ircam.fr> eckel@ircam.UUCP (Gerhard Eckel) writes: > > I try to write a 'send' function for a SMALL lisp interpreter that >sends messages to Obj-C objects and receives the return values from the >corresponding methods (this is similar to the 'send' function of the objc >package in Common Lisp on the NeXT). I try to use objc_msgSend() which returns >an id. I did some assembler hacking to get the other 4 bytes (asm("movel d1, >something")). I found that Obj-C doesn't return structures correctly that are >bigger than 8 bytes. C functions return such structures over the stack (it >seems that the compiler uses the register a1 to pass the address - data >smaller than 8 bytes is returned in the registers d0 and d1 as far as I could >see). It seems that it is a bug since the methods try to copy the data using >register a1. But where does it end up (I hate 'Bus error' and 'Segmentation >fault')? Take a look at the C code generated by this message. Unless NeXT has broken something, you should find that Objective-C is generating a complicated-looking typecast that a C wizard would explain as typecasting the *name* _msg (*not* the value) to be pointer to function returning struct threeInts. In other words, messages return precisely what they've been declared to return, exactly as they should. The end effect is that your assembly language routine is going to have to be driven from a table of return-type declarations. I seriously doubt that the code C generates from all this will boil down to anything that can be sorted out from run-time register sniffing. -- Brad Cox; cox@stepstone.com; CI$ 71230,647; 203 426 1875 The Stepstone Corporation; 75 Glen Road; Sandy Hook CT 06482