[M3devel] layout of objects?
Jay
jay.krell at cornell.edu
Fri Mar 22 19:18:21 CET 2013
Can it have zero revelations?
Can you assist lazy me and suggest an accurate way to describe opaque types in a typeful way in C?
Ultimate goal would be to get m3front & m3back optionally out of the business of computing offsets, instead using C structs and members and pointers and leave layout to the C compiler.
Ultimately generating one architecture-independent, pointer-size-independent C.
I understand there are multiple challenges here and eventually m3cg and m3front will need changes, to pass down more higher level information.
- Jay
On Mar 22, 2013, at 11:11 AM, Tony Hosking <hosking at cs.purdue.edu> wrote:
> 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/7d7dce99/attachment-0002.html>
More information about the M3devel
mailing list