[M3devel] layout of objects?

Jay K jay.krell at cornell.edu
Fri Mar 22 17:13:44 CET 2013


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 University305 N. University Street | West Lafayette | IN 47907 | USAMobile +1 765 427 5484
 		 	   		  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://m3lists.elegosoft.com/pipermail/m3devel/attachments/20130322/e39d2ceb/attachment-0002.html>


More information about the M3devel mailing list