[M3devel] layout of objects?

Tony Hosking hosking at cs.purdue.edu
Fri Mar 22 19:11:59 CET 2013


Every opaque type in a linkage must have only one revelation.

Sent from my iPad

On Mar 22, 2013, at 12:13 PM, Jay K <jay.krell at cornell.edu> wrote:

> Are opaque types always revealed eventually? Or only sometimes?
> I'd like to generate structs and member references and not be adding offsets to pointers.
> For method calls and record field references.
> And, ugh, the GC data needs to be generated using "offsetof". But probably all we get is a bunch
> of integers and no indication where the frontend got them from.. :(
> 
> 
> Thanks,
>  - Jay
> 
> 
> From: hosking at cs.purdue.edu
> Date: Fri, 22 Mar 2013 03:08:04 -0500
> To: jay.krell at cornell.edu
> CC: m3devel at elegosoft.com
> Subject: Re: [M3devel] layout of objects?
> 
> x>=0 means a known constant method offset at compile time.
> Otherwise, offset must be loaded at run time.  This is needed for opaque types, where the offset cannot be computed at run time.  Given TYPE T <: U we can't know at compile time how many methods are defined between U and T so the offset cannot be a compile time constant.
> 
> On Mar 22, 2013, at 2:01 AM, Jay K <jay.krell at cornell.edu> wrote:
> 
> Do you understand hereabouts m3front/src/exprs/MethodExpr.m3?
> 
> 
> PROCEDURE Compile (p: P) =
>   VAR
>     x := ObjectType.MethodOffset (p.holder);
>     method: Method.Info;
>   BEGIN
>     Type.Compile (p.object);
>     Method.SplitX (p.method, method);
> 
>     Type.LoadInfo (p.object, M3RT.OTC_defaultMethods, addr := TRUE);
>     IF (x >= 0) THEN
>       INC (method.offset, x);
>     ELSE (* runtime offset to methods *)
>       Type.LoadInfo (p.holder, M3RT.OTC_methodOffset);
>       CG.Index_bytes (Target.Byte);
>     END;
>     CG.Boost_alignment (Target.Address.align);
>     CG.Load_indirect (CG.Type.Addr, method.offset, Target.Address.size);
>     CG.Boost_alignment (Target.Address.align);
>   END Compile;
> 
> 
> "runtime offset to methods"?
> 
> ObjectType.MethodOffset:
> 
> PROCEDURE MethodOffset (t: Type.T): INTEGER =
>   VAR p := Confirm (t);
>   BEGIN
>     IF (p = NIL) THEN RETURN Unknown_w_magic END;
>     GetOffsets (p, use_magic := TRUE);
>     RETURN p.methodOffset;
>   END MethodOffset;
> 
> 
> PROCEDURE Confirm (t: Type.T): P =
>   VAR info: Type.Info;
>   BEGIN
>     LOOP
>       t := Type.CheckInfo (t, info);
>       IF (info.class = Type.Class.Object) THEN
>         RETURN t;
>       ELSIF (info.class = Type.Class.Opaque) THEN
>         t := Revelation.LookUp (t);
>       ELSE
>         RETURN NIL;
>       END;
>     END;
>   END Confirm;
> 
> 
> ...
> 
> 
> 
>  - Jay
> 
> 
> 
> 
> 
> Subject: Re: [M3devel] layout of objects?
> From: hosking at cs.purdue.edu
> Date: Fri, 22 Mar 2013 01:44:37 -0500
> CC: jay.krell at cornell.edu; m3devel at elegosoft.com
> To: dragisha at m3w.org
> 
> Not quite.  I just checked RTAllocator.m3 and it is pointer to methods at offset 0, followed by fields.
> Heap header is at -ADRSIZE(Header).
> The type information in RT0 is used to initialize the object instances.
> 
> On Mar 22, 2013, at 1:34 AM, Dragiša Durić <dragisha at m3w.org> wrote:
> 
> It's not m3front, it's RT0.
> 
> First data field is at offset 0, and pointer to type information is at -BYTESIZE(POINTER). Type information records are specified in RT0.
> 
> On Mar 22, 2013, at 5:56 AM, Jay K wrote:
> 
> layout of objects?
> 
> 
> 
> How are Modula-3 objects layed out?
> i.e. "OBJECT"/"METHODS"/"OVERRIDES"
> I skimmed m3front and it wasn't obvious.
> 
> 
> 
> A common way for C++ "objects" to be layed out,
> in the face of no RTTI and only single inheritance,
> and virtual functions, is that a pointer to a record
> of function pointers is first in the record.
> 
> 
> Like this:
> 
> 
> class Type
> {
> virtual void F1();
> virtual void F2();
> int data1;
> int data2;
> };
> 
> 
> ends up lik more this:
> 
> 
> struct TypeFunctions
> {
>  void (*F1)(Type*);
>  void (*F2)(Type*);
> };
> 
> 
> struct Type
> {
> TypeFunctions* Functions; /* always first,
> or at least a fixed offset, and located independent
> of the size of the data; could also be at "-1" or such */.
> int data1;
> int data2;
> };
> 
> 
> Type* x;
> x->F1();
> 
> 
> =>
> x->Functions->F1(x);
> 
> 
> Functions added in more derived types go at the end.
> Ditto for data.
> In the absence of multiple-inheritance and RTTI, it is simple and predictable.
> (RTTI makes only small modifications.)
> 
> 
> Looking through m3front, it wasn't at all obvious if it works this way.
> 
> 
> I would like to declare something in C (or possibly C++, but not likely),
> such that I might actually recognize the various low level operations
> and "uncompile" it back to a typeful/typesafe form, like the above C++
> to C transform.
> 
> 
> 
> I can't likely uncompile to C++ with virtual functions,
> because the actual layout in C++ is not guaranteed.
> 
> 
> 
> Granted, I am being lazy.
> I should/could compile some small samples.
> But I might not get the entire story that way.
> 
> 
> 
> Thanks,
> - Jay
> 
> 
> 
> 
> 
> Antony Hosking | Associate Professor | Computer Science | Purdue University
> 305 N. University Street | West Lafayette | IN 47907 | USA
> Mobile +1 765 427 5484
> 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://m3lists.elegosoft.com/pipermail/m3devel/attachments/20130322/686bd4fe/attachment-0002.html>


More information about the M3devel mailing list