GCC/ObjC enhancements, comments requested

Ovidiu Predescu ovidiu@aracnet.com
Tue Feb 10 10:58:00 GMT 1998


On Mon, 9 Feb 1998 22:46:28, Bruno Haible wrote:

> > What I would like to see though is a compiler based approach as it
> > would be much more easier and straightforward than maintaining an
> > additional library.
>
> Do you mean the following: Adding enough builtins to gcc so that the
> thing can be performed with a single function largely written in C ?
> (Similar to __throw.)

Not quite builtin functions, in the sense they are expanded by compiler, but  
some functions that are present in libgcc that appear in a header file with  
their needed types so that programs can call them to perform dynamic  
invocations.

> I think it can be done. The only requirement is that gcc emits some
> RTTI-like information for each structure type, containing:
> - the structure size,
> - the structure alignment,
> - a few other bits of information, in order to fix the
> return-in-registers/return-in-memory problem alluded to in the BUGS
> section of the avcall manual page.

I don't like to base the functionality on the information emitted by  
compiler at compile time. The set of functions that can be called is not  
limited to the functions compiled by the compiler; what happens if I write a  
JIT compiler myself and want those functions use the native convention calls?  
I have to do the same thing the compiler does to compile that function.

> I want an API independent of ObjC because the issue arises again for Java.

Me too. I want some things written in plain C, not even C++.

> Before I start putting a lot of thought into it, let's start from the
> beginning.
>
> 1. What do you want to perform? If I understood it well, some ObjC method
> is present at runtime, and is represented by argtype+rettype information,
> plus a code address, plus maybe an object pointer. You want to call
> this method. Where do the arguments for this call come from, originally?

I want to be able to dynamically create invocations of ObjC methods and C  
functions, I explained how this works in another message posted on the group.  
This is definitely possible in ObjC, but only if you have the frame passed  
to __builtin_apply() already constructed; this is possible if you send a  
message to an object that doesn't implement that message. But you don't have  
any standard way to create that frame.

Here is the function that creates the frame when you send a message to an  
object that doesn't implement it:

static id
__objc_word_forward (id rcv, SEL op, ...)
{
  void *args, *res;

  args = __builtin_apply_args ();
  res = __objc_forward (rcv, op, args);
  if (res)
    __builtin_return (res);
  else
    return res;
}

The __objc_word_forward is returned by the runtime system as the method's  
implementation when an object does not implement a method. This function  
calls __objc_forward() that invokes a special method of the object which has  
as arguments the original name of the message and it's arguments in 'args'.  
In that special method one can call objc_msg_sendv() to send the same message  
with the same arguments to another method. Take a look on objc/sendmsg.c to  
see the whole picture.

> 2. How are the types encoded? Elementary types are easy, they are finite
> in number. How about structure types? Are they given as strings (worst)
> or can we pass some RTTI pointer?

Objective-C encodes the types in strings. You can encode both elementary  
types and compound types. For example:

char		c
short		s
int		i
long		l
float		f
double		d

The unsigned versions are with capital letters. Structs are encoded like this:

struct {
  int i;
  char c;
};

is encoded "{ic}". Unions are encoded like "(ic)", arrays between "[" and "]".

A method is encoded like this: first the type of the return value followed  
by the number of bytes occupied by all the arguments on the stack. Then each  
argument is encoded with its type followed by its relative position on the  
__builtin_apply() frame. If the argument is passed on the stack, a '+' sign  
is encoded before the type and the offset is relative to the registers buffer  
in the __builtin_apply() frame. The builtin_apply frame is a structure  
containing two buffers, one for the stack arguments and another one for the  
register arguments. The compiler puts all the arguments in the corresponding  
buffer so the user programs can simply access the arguments without having to  
worry about where the argument might be, if it's partially passed in  
registers and things like this. For

This encoding is quite convinient except for the fact that the compiler  
doesn't encode the size of the registers buffer and doesn't tell you how to  
access the return value in the buffer returned by __builtin_apply. The  
encoding is generated by the compiler when it compiles an ObjC method (see  
objc/objc-act.c/encode_method_prototype()).

What I'd like to have is a new encoding way which says how to access the  
return value, no matter it's passed as reference or by value, and the size of  
the registers buffer. Right now one is able to create a partial frame for  
__builtin_apply containing the stack arguments but he has no way to create  
the registers frame. Also it's though to access the return value.

The second thing would be a runtime function that takes an encoding string  
which has only the method/function types and returns a full encoding that  
gives all the information on how to build/access a __builtin_apply frame.

--
Ovidiu Predescu <ovidiu@net-community.com> (NeXTMail, MIME)
http://www.net-community.com/Users/~ovidiu



More information about the Gcc mailing list