[M3devel] layout of objects?
Jay K
jay.krell at cornell.edu
Fri Mar 22 08:01:12 CET 2013
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/854c30e4/attachment-0002.html>
More information about the M3devel
mailing list