init(c: MMLocalClass) do _local_class = c
end
-redef class MMGlobalProperty
- # The position of the property in the local class table part
- # FIXME: It's ugly. store this somewhere else please
- readable writable attr _pos_of: Int
-end
-
redef class MMSrcLocalClass
# The table element of the subtype check
- readable attr _class_color_pos: TableEltClassColorPos
+ readable attr _class_color_pos: TableEltClassColor
# The proper local class table part (nor superclasses nor refinments)
- readable attr _class_layout: Array[LocalTableElt]
+ readable attr _class_layout: Array[TableElt]
# The proper local instance table part (nor superclasses nor refinments)
- readable attr _instance_layout: Array[LocalTableElt]
+ readable attr _instance_layout: Array[TableElt]
# Build the local layout of the class and feed the module table
- meth build_layout_in(tc: ToolContext, module_table: Array[LocalTableElt])
+ meth build_layout_in(tc: ToolContext, module_table: Array[ModuleTableElt])
do
- var intro_methods = new Array[MMGlobalProperty] # FIXME: Remove this
- var intro_attributes = new Array[MMGlobalProperty] # FIXME: Remove this
- var clt = new Array[LocalTableElt]
+ var clt = new Array[TableElt]
_class_layout = clt
- var ilt = new Array[LocalTableElt]
+ var ilt = new Array[TableElt]
_instance_layout = ilt
if global.intro == self then
- module_table.add(new TableEltClassIdPos(self))
- _class_color_pos = new TableEltClassColorPos(self)
+ module_table.add(new TableEltClassId(self))
+ _class_color_pos = new TableEltClassColor(self)
module_table.add(_class_color_pos)
- #clt.add(_class_color_pos)
- clt.add(new TableEltClassInitTablePos(self))
+ clt.add(new TableEltClassInitTable(self))
end
for p in src_local_properties do
var pg = p.global
if pg.intro == p then
if p isa MMSrcAttribute then
- pg.pos_of = intro_attributes.length
- intro_attributes.add(pg)
- ilt.add(new TableEltAttrPos(p))
+ ilt.add(new TableEltAttr(p))
else if p isa MMSrcMethod then
- pg.pos_of = intro_methods.length
- intro_methods.add(pg)
- clt.add(new TableEltMethPos(p))
+ clt.add(new TableEltMeth(p))
end
end
if p isa MMSrcMethod and p.need_super then
- clt.add(new TableEltSuperPos(p))
+ clt.add(new TableEltSuper(p))
end
end
- module_table.append(ilt)
- module_table.append(clt)
+
+ if not ilt.is_empty then
+ var teg = new ModuleTableEltGroup
+ teg.elements.append(ilt)
+ module_table.add(teg)
+ end
+
+ if not clt.is_empty then
+ var teg = new ModuleTableEltGroup
+ teg.elements.append(clt)
+ module_table.add(teg)
+ end
end
end
redef class MMSrcModule
# The local table of the module (refers things introduced in the module)
- attr _local_table: Array[LocalTableElt]
+ attr _local_table: Array[ModuleTableElt]
# Builds the local tables and local classes layouts
meth local_analysis(tc: ToolContext)
do
- var lt = new Array[LocalTableElt]
+ var lt = new Array[ModuleTableElt]
_local_table = lt
for c in src_local_classes do
c.build_layout_in(tc, lt)
for c in local_classes do
c.compile_tables_to_c(v)
end
- var s = "classtable_t TAG2VFT[4] = \{NULL"
+ var s = new Buffer.from("classtable_t TAG2VFT[4] = \{NULL")
for t in ["Int","Char","Bool"] do
if has_global_class_named(t.to_symbol) then
s.append(", (const classtable_t)VFT_{t}")
end
end
s.append("};")
- v.add_instr(s)
+ v.add_instr(s.to_s)
end
# Declare class table (for _sep.h)
end
var i = 0
for e in _local_table do
+ var value: String
if v.tc.global then
- v.add_decl("#define {e.symbol} {e.value(v.global_analysis)}")
+ value = "{e.value(v.global_analysis)}"
else
- v.add_decl("#define {e.symbol} SFT_{name}[{i}]")
+ value = "SFT_{name}[{i}]"
i = i + 1
end
+ e.compile_macros(v, value)
end
for c in src_local_classes do
for pg in c.global_properties do
var p = c[pg]
if p.local_class == c then
- if pg.intro == p then
- if p isa MMAttribute then
- v.add_decl("#define {pg.attr_access}(recv) ATTR(recv, {pg.color_id})")
- else if p isa MMMethod then
- v.add_decl("#define {pg.meth_call}(recv) (({p.cname}_t)CALL((recv), {pg.color_id}))")
- end
- end
- if p isa MMSrcMethod and p.need_super then
- v.add_decl("#define {p.super_meth_call}(recv) (({p.cname}_t)CALL((recv), {p.color_id_for_super}))")
- end
p.compile_property_to_c(v)
end
if pg.is_init_for(c) then
end
end
-class TableElt
+###############################################################################
+
+# An element of a class, an instance or a module table
+abstract class AbsTableElt
+ # Compile the macro needed to use the element and other related elements
+ meth compile_macros(v: CompilerVisitor, value: String) is abstract
+end
+
+# An element of a class or an instance table
+# Such an elements represent method function pointers, attribute values, etc.
+abstract class TableElt
+special AbsTableElt
+ # Is the element conflict to class `c' (used for coloring)
meth is_related_to(c: MMLocalClass): Bool is abstract
+
+ # Number of sub-elements. 1 if none
meth length: Int do return 1
+
+ # Access the ith subelement.
meth item(i: Int): TableElt do return self
+
+ # Return the value of the element for a given class
meth compile_to_c(v: CompilerVisitor, c: MMLocalClass): String is abstract
end
-class LocalTableElt
-special TableElt
- meth symbol: String is abstract
+# An element of a module table
+# Such an elements represent colors or identifiers
+abstract class ModuleTableElt
+special AbsTableElt
+ # Return the value of the element once the global analisys is performed
meth value(ga: GlobalAnalysis): String is abstract
end
-class TableEltPropPos
-special LocalTableElt
+# An element of a module table that represents a group of TableElt defined in the same local class
+class ModuleTableEltGroup
+special ModuleTableElt
+ readable attr _elements: Array[TableElt] = new Array[TableElt]
+
+ redef meth value(ga) do return "{ga.color(_elements.first)} /* Group of ? */"
+ redef meth compile_macros(v, value)
+ do
+ var i = 0
+ for e in _elements do
+ e.compile_macros(v, "{value} + {i}")
+ i += 1
+ end
+ end
+end
+
+# An element that represents a class property
+abstract class TableEltProp
+special TableElt
attr _property: MMLocalProperty
- redef meth symbol do return _property.global.color_id
- redef meth value(ga) do return "{ga.color(self)} /* Property {_property} */"
init(p: MMLocalProperty)
do
end
end
-class TableEltMethPos
-special TableEltPropPos
+# An element that represents a function pointer to a global method
+class TableEltMeth
+special TableEltProp
+ redef meth compile_macros(v, value)
+ do
+ var pg = _property.global
+ v.add_decl("#define {pg.meth_call}(recv) (({pg.intro.cname}_t)CALL((recv), ({value})))")
+ end
+
redef meth compile_to_c(v, c)
do
var p = c[_property.global]
return p.cname
end
- init(p) do super
end
-class TableEltSuperPos
-special TableEltPropPos
- redef meth symbol do return _property.color_id_for_super
+# An element that represents a function pointer to the super method of a local method
+class TableEltSuper
+special TableEltProp
+ redef meth compile_macros(v, value)
+ do
+ var p = _property
+ v.add_decl("#define {p.super_meth_call}(recv) (({p.cname}_t)CALL((recv), ({value})))")
+ end
+
redef meth compile_to_c(v, c)
do
var pc = _property.local_class
assert false
return null
end
-
- init(p) do super
end
-class TableEltAttrPos
-special TableEltPropPos
+# An element that represents the value stored for a global attribute
+class TableEltAttr
+special TableEltProp
+ redef meth compile_macros(v, value)
+ do
+ var pg = _property.global
+ v.add_decl("#define {pg.attr_access}(recv) ATTR(recv, ({value}))")
+ end
+
redef meth compile_to_c(v, c)
do
var ga = v.global_analysis
var p = c[_property.global]
return "/* {ga.color(self)}: Attribute {c}::{p} */"
end
-
- init(p) do super
end
-class TableEltClassPos
-special LocalTableElt
+# An element representing a class information
+class AbsTableEltClass
+special AbsTableElt
+ # The local class where the information comes from
attr _local_class: MMLocalClass
- redef meth is_related_to(c)
- do
- var bc = c.module[_local_class.global]
- return c.cshe <= bc
- end
init(c: MMLocalClass)
do
_local_class = c
end
+
+ # The C macro name refering the value
+ meth symbol: String is abstract
+
+ redef meth compile_macros(v, value)
+ do
+ v.add_decl("#define {symbol} ({value})")
+ end
end
-class TableEltClassIdPos
-special TableEltClassPos
+# An element of a class table representing a class information
+class TableEltClass
+special TableElt
+special AbsTableEltClass
+ redef meth is_related_to(c)
+ do
+ var bc = c.module[_local_class.global]
+ return c.cshe <= bc
+ end
+end
+
+# An element representing the id of a class in a module table
+class TableEltClassId
+special ModuleTableElt
+special AbsTableEltClass
redef meth symbol do return _local_class.global.id_id
+
redef meth value(ga)
do
return "{ga.compiled_classes[_local_class.global].id} /* Id of {_local_class} */"
end
-
- init(c) do super
end
-class TableEltClassInitTablePos
-special TableEltClassPos
+# An element representing the constructor marker position in a class table
+class TableEltClassInitTable
+special TableEltClass
redef meth symbol do return _local_class.global.init_table_pos_id
- redef meth value(ga)
- do
- return "{ga.color(self)} /* Color of {_local_class} */"
- end
+
redef meth compile_to_c(v, c)
do
var ga = v.global_analysis
end
return "{i} /* {ga.color(self)}: {c} < {cc.local_class}: superclass init_table position */"
end
-
- init(c) do super
end
-class TableEltClassColorPos
-special TableEltClassPos
+# An element used for a cast
+# Note: this element is both a TableElt and a ModuleTableElt.
+# At the TableElt offset, there is the id of the super-class
+# At the ModuleTableElt offset, there is the TableElt offset (ie. the color of the super-class).
+class TableEltClassColor
+special TableEltClass
+special ModuleTableElt
redef meth symbol do return _local_class.global.color_id
+
redef meth value(ga)
do
return "{ga.color(self)} /* Color of {_local_class} */"
end
+
redef meth compile_to_c(v, c)
do
var ga = v.global_analysis
var cc = ga.compiled_classes[_local_class.global]
return "{cc.id} /* {ga.color(self)}: {c} < {cc.local_class}: superclass typecheck marker */"
end
-
- init(c) do super
end
+# A Group of elements introduced in the same global-class that are colored together
class TableEltComposite
special TableElt
- attr _table: Array[LocalTableElt]
+ attr _table: Array[TableElt]
attr _cc: CompiledClass
attr _offsets: HashMap[MMLocalClass, Int]
redef meth length do return _table.length
redef meth is_related_to(c) do return c.cshe <= _cc.local_class
- meth add(c: MMLocalClass, tab: Array[LocalTableElt])
+ meth add(c: MMLocalClass, tab: Array[TableElt])
do
_offsets[c] = _table.length
_table.append(tab)
init(cc: CompiledClass)
do
_cc = cc
- _table = new Array[LocalTableElt]
+ _table = new Array[TableElt]
_offsets = new HashMap[MMLocalClass, Int]
end
end
+# The element that represent the class id
class TableEltClassSelfId
special TableElt
redef meth is_related_to(c) do return true
var ga = v.global_analysis
return "{v.global_analysis.compiled_classes[c.global].id} /* {ga.color(self)}: Identity */"
end
-
- init do end
end
+# The element that
class TableEltVftPointer
special TableElt
redef meth is_related_to(c) do return true
var ga = v.global_analysis
return "/* {ga.color(self)}: Pointer to the classtable */"
end
-
- init do end
end
+###############################################################################
+
# Used to sort local class in a deterministic total order
# The total order superset the class refinement and the class specialisation relations
class ClassSorter