[comp.sys.next] what Obj-C methods return

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