do
_program = p
_compdir = p.tc.compdir.as(not null)
- _build_file = "{compdir}/{program.main_module.name}._build.sh"
+ _build_file = "{compdir}/{program.main_module.cname}._build.sh"
end
# The Nit program compiled to C
if _module_include.has_key(m) then
return _module_include[m]
end
- var filename = "{m.name}.{get_file_ending}.h"
+ var filename = "{m.cname}.{get_file_ending}.h"
_module_include[m] = filename
return filename
end
end
f.write("#!/bin/sh\n")
- f.write("# This shell script is generated by NIT to compile the program {program.main_module.name}.\n")
+ f.write("# This shell script is generated by NIT to compile the program {program.main_module.full_name}.\n")
f.write("CLIBDIR=\"{tc.clibdir.as(not null)}\"\n")
f.write("{tc.bindir.as(not null)}/gccx {verbose} -d {compdir} -I $CLIBDIR {include_dirs.join(" ")}")
if tc.output_file != null then
do
return "ATTR_{intro.cname}"
end
+
+ # C symbol refering a virtual type class color
+ fun vt_class_color: String
+ do
+ return "VTCOLOR_{intro.cname}"
+ end
+
+ # C symbol refering a virtual type class id
+ fun vt_class_id: String
+ do
+ return "VTID_{intro.cname}"
+ end
end
redef class MMGlobalClass
+ # Cacher result of cname
+ var _cname_cache: nullable String
+
+ # The mangled name of the global class
+ fun cname: String
+ do
+ var cname = _cname_cache
+ if cname == null then
+ cname = intro.mmmodule.cname + "___" + cmangle(intro.name)
+ _cname_cache = cname
+ end
+ return cname
+ end
+
# C symbol refering the identifier of the class
fun id_id: String
do
- return "ID_{intro.name}"
+ return "ID_{cname}"
end
# C symbol refering the color of the class (for subtype tests)
fun color_id: String
do
- return "COLOR_{intro.name}"
+ return "COLOR_{cname}"
end
# C symbol refering the init table position of the class (for constructor linearization)
fun init_table_pos_id: String
do
- return "INIT_TABLE_POS_{intro.name}"
+ return "INIT_TABLE_POS_{cname}"
+ end
+end
+
+redef class MMModule
+ # Cacher result of cname
+ var _cname_cache: nullable String
+
+ # The mangled name of the module
+ fun cname: String
+ do
+ var cname = _cname_cache
+ if cname == null then
+ var l = new List[String]
+ var m: nullable MMModule = self
+ while m != null do
+ l.unshift(cmangle(m.name))
+ var d: nullable MMDirectory = m.directory
+ while d != null and d.owner == m do d = d.parent
+ if d == null then m = null else m = d.owner
+ end
+ cname = l.to_a.join("___")
+ _cname_cache = cname
+ end
+ return cname
end
end
+redef class MMLocalClass
+ # The mangled name of the global class
+ fun cname: String do return global.cname
+end
+
redef class MMLocalProperty
# Cacher result of cname
var _cname_cache: nullable String
do
var cname = _cname_cache
if cname == null then
- cname = cmangle(mmmodule.name, local_class.name, name)
+ cname = mmmodule.cname + "___" + cmangle(local_class.name, name)
_cname_cache = cname
end
return cname
var s = new Buffer.from("classtable_t TAG2VFT[4] = \{NULL")
for t in ["Int","Char","Bool"] do
if main_module.has_global_class_named(t.to_symbol) then
- s.append(", (const classtable_t)VFT_{t}")
+ var c = main_module.class_by_name(t.to_symbol)
+ s.append(", (const classtable_t)VFT_{c.cname}")
else
s.append(", NULL")
end
if v.program.main_method == null then
print("No main")
else
- v.add_instr("G_sys = NEW_Sys();")
+ var c = v.program.main_class
+ v.add_instr("G_sys = NEW_{c.cname}();")
v.add_instr("register_static_object(&G_sys);")
v.add_instr("{v.program.main_method.cname}(G_sys);")
end
# Compile sep files
fun compile_mod_to_c(v: CompilerVisitor)
do
- v.add_decl("extern const char *LOCATE_{name};")
+ v.add_decl("extern const char *LOCATE_{cname};")
if not v.program.tc.use_SFT_optimization then
- v.add_decl("extern const int SFT_{name}[];")
+ v.add_decl("extern const int SFT_{cname}[];")
end
var i = 0
for e in local_table do
if v.program.tc.use_SFT_optimization then
value = "{e.value(v.program)}"
else
- value = "SFT_{name}[{i}]"
+ value = "SFT_{cname}[{i}]"
i = i + 1
end
e.compile_macros(v, value)
# Compile module file for the current module
fun compile_local_table_to_c(v: CompilerVisitor)
do
- v.add_instr("const char *LOCATE_{name} = \"{location.file}\";")
+ v.add_instr("const char *LOCATE_{cname} = \"{location.file.filename}\";")
if v.program.tc.use_SFT_optimization or local_table.is_empty then
return
end
- v.add_instr("const int SFT_{name}[{local_table.length}] = \{")
+ v.add_instr("const int SFT_{cname}[{local_table.length}] = \{")
v.indent
for e in local_table do
v.add_instr(e.value(v.program) + ",")
end
end
+ redef class TableEltVTClassColor
+ redef fun compile_macros(v, value)
+ do
+ var pg = property.global
+ v.add_decl("#define {pg.vt_class_color}(recv) (VAL2VFT(recv)[{value}].i)")
+ end
+
+ redef fun compile_to_c(v, c)
+ do
+ var prog = v.program
+ var p = c[property.global]
+ var g = p.signature_for(c.get_type).return_type.local_class.global
+ var col = g.intro.as(MMConcreteClass).class_color_pos
+ return "{prog.table_information.color(col)} /* {prog.table_information.color(self)}: VT {c}::{p} : color of {g} */"
+ end
+ end
+
+ redef class TableEltVTClassId
+ redef fun compile_macros(v, value)
+ do
+ var pg = property.global
+ v.add_decl("#define {pg.vt_class_id}(recv) (VAL2VFT(recv)[{value}].i)")
+ end
+
+ redef fun compile_to_c(v, c)
+ do
+ var prog = v.program
+ var p = c[property.global]
+ var g = p.signature_for(c.get_type).return_type.local_class.global
+ return "{prog.compiled_classes[g].id} /* {prog.table_information.color(self)}: VT {c}::{p} : id of {g} */"
+ end
+ end
+
redef class TableEltAttr
redef fun compile_macros(v, value)
do
end
end
+
redef class AbsTableEltClass
# The C macro name refering the value
fun symbol: String is abstract
end
end
+redef class TableEltClassSelfName
+ redef fun compile_to_c(v, c)
+ do
+ var prog = v.program
+ return "\"{c.global.name}\" /* {prog.table_information.color(self)}: Class Name */"
+ end
+end
+
redef class TableEltClassObjectSize
redef fun compile_to_c(v, c)
do
do
v.add_decl("")
var pi = primitive_info
- v.add_decl("extern const classtable_elt_t VFT_{name}[];")
+ v.add_decl("extern const classtable_elt_t VFT_{cname}[];")
if pi != null and not pi.tagged then
var t = pi.cname
var tbox = "struct TBOX_{name}"
clen = v.program.table_information.max_class_table_length
end
- v.add_instr("const classtable_elt_t VFT_{name}[{clen}] = \{")
+ v.add_instr("const classtable_elt_t VFT_{cname}[{clen}] = \{")
v.indent
for e in ctab do
if e == null then
v.indent
v.add_instr("Nit_NativeArray array;")
v.add_instr("array = (Nit_NativeArray)alloc(sizeof(struct Nit_NativeArray) + ((length - 1) * size));")
- v.add_instr("array->vft = (classtable_elt_t*)VFT_{name};")
+ v.add_instr("array->vft = (classtable_elt_t*)VFT_{cname};")
v.add_instr("array->object_id = object_id_counter;")
v.add_instr("object_id_counter = object_id_counter + 1;")
v.add_instr("array->size = length;")
else if pi == null then
do
# Generate INIT_ATTRIBUTES routine
- var cname = "INIT_ATTRIBUTES__{name}"
+ var cname = "INIT_ATTRIBUTES__{cname}"
var args = init_var_iroutine.compile_signature_to_c(v, cname, "init var of {name}", null, null)
var decl_writer_old = v.decl_writer
v.decl_writer = v.writer.sub
end
do
# Generate NEW routine
- v.add_decl("val_t NEW_{name}(void);")
- v.add_instr("val_t NEW_{name}(void)")
+ v.add_decl("val_t NEW_{cname}(void);")
+ v.add_instr("val_t NEW_{cname}(void)")
v.add_instr("\{")
v.indent
v.add_instr("obj_t obj;")
v.add_instr("obj = alloc(sizeof(val_t) * {itab.length});")
- v.add_instr("obj->vft = (classtable_elt_t*)VFT_{name};")
+ v.add_instr("obj->vft = (classtable_elt_t*)VFT_{cname};")
v.add_instr("obj[1].object_id = object_id_counter;")
v.add_instr("object_id_counter = object_id_counter + 1;")
v.add_instr("return OBJ2VAL(obj);")
end
do
# Compile CHECKNAME
- var cname = "CHECKNEW_{name}"
+ var cname = "CHECKNEW_{cname}"
var args = checknew_iroutine.compile_signature_to_c(v, cname, "check new {name}", null, null)
var decl_writer_old = v.decl_writer
v.decl_writer = v.writer.sub
v.add_instr("val_t BOX_{name}({t} val) \{")
v.indent
v.add_instr("{tbox} *box = ({tbox}*)alloc(sizeof({tbox}));")
- v.add_instr("box->vft = VFT_{name};")
+ v.add_instr("box->vft = VFT_{cname};")
v.add_instr("box->val = val;")
v.add_instr("box->object_id = object_id_counter;")
v.add_instr("object_id_counter = object_id_counter + 1;")
if l != null then
visitor.add_indent(w)
w.add("/* ")
- w.add(l.file)
+ w.add(l.file.filename)
w.add(":")
w.add(l.line_start.to_s)
w.add(" */\n")
v.add_decl("struct \{struct stack_frame_t me;\} fra;")
end
v.add_instr("fra.me.prev = stack_frame_head; stack_frame_head = &fra.me;")
- v.add_instr("fra.me.file = LOCATE_{v.visitor.mmmodule.name};")
+ v.add_instr("fra.me.file = LOCATE_{v.visitor.mmmodule.cname};")
v.add_instr("fra.me.line = {ll};")
v.add_instr("fra.me.meth = LOCATE_{v.basecname};")
v.add_instr("fra.me.has_broke = 0;")
v.add_location(location)
var w = new_result(v)
w.add("NEW_")
- w.add(stype.local_class.name.to_s)
+ w.add(stype.local_class.cname)
w.add("()")
end
end
v.add_location(location)
var w = new_result(v)
w.add("CHECKNEW_")
- w.add(stype.local_class.name.to_s)
+ w.add(stype.local_class.cname)
w.add("(")
w.add(v.register(expr))
w.add(")")
v.add_location(location)
var w = v.new_instr
w.add("INIT_ATTRIBUTES__")
- w.add(stype.local_class.name.to_s)
+ w.add(stype.local_class.cname)
w.add("(")
w.add(v.register(expr))
w.add(");\n")
s = "NEW_NativeArray(UNTAG_Int({regs[1]}), sizeof(val_t))"
else if n == once "calloc_string".to_symbol then
s = "BOX_NativeString((char*)raw_alloc((UNTAG_Int({regs[1]}) * sizeof(char))))"
+ # Add output_class_name native implementation
+ else if n == once "output_class_name".to_symbol then
+ s = "printf(\"%s\\n\", VAL2VFT({regs[0]})[2].cname);"
+ # Add class_name implementation
+ else if n == once "native_class_name".to_symbol then
+ s = "BOX_NativeString(VAL2VFT({regs[0]})[2].cname);"
end
+
if s == null then
var ll = location
if ll != null then v.add_instr("fprintf(stderr, \"{ll.to_s}: \");")
w.add("\", NULL")
end
w.add(", LOCATE_")
- w.add(module_location.name.to_s)
+ w.add(module_location.cname)
var ll = location
if ll != null then
w.add(", ")
redef fun compile_to_c(v)
do
if not need_result then return
- # FIXME handle formaltypes
v.add_location(location)
- var g = stype.local_class.global
- var recv = v.register(expr)
+ var recv = v.register(expr2)
var w = new_result(v)
w.add("TAG_Bool(")
- if expr.stype.is_nullable then
+ if expr2.stype.is_nullable then
if stype.is_nullable then
w.add("(")
w.add(recv)
w.add("==NIT_NULL) || ")
- else if stype.as_nullable == expr.stype then
+ else if stype.as_nullable == expr2.stype then
w.add(recv)
w.add("!=NIT_NULL)")
return
w.add("!=NIT_NULL) && ")
end
end
- w.add("VAL_ISA(")
- w.add(recv)
- w.add(", ")
- w.add(g.color_id)
- w.add(", ")
- w.add(g.id_id)
- w.add(")) /*cast ")
- w.add(stype.to_s)
- w.add("*/")
+ # FIXME handle formaltypes
+ var t = stype
+ if t isa MMVirtualType then
+ var slf = v.register(expr1)
+ var g = t.property.global
+ w.add("VAL_ISA(")
+ w.add(recv)
+ w.add(", ")
+ w.add(g.vt_class_color)
+ w.add("(")
+ w.add(slf)
+ w.add(")")
+ w.add(", ")
+ w.add(g.vt_class_id)
+ w.add("(")
+ w.add(slf)
+ w.add(")")
+ w.add(")) /*cast ")
+ w.add(t.to_s)
+ w.add("*/")
+ else
+ var g = t.local_class.global
+ w.add("VAL_ISA(")
+ w.add(recv)
+ w.add(", ")
+ w.add(g.color_id)
+ w.add(", ")
+ w.add(g.id_id)
+ w.add(")) /*cast ")
+ w.add(t.to_s)
+ w.add("*/")
+ end
end
end
ilt.add(new TableEltAttr(p))
else if p isa MMMethod then
clt.add(new TableEltMeth(p))
+ else if p isa MMTypeProperty then
+ clt.add(new TableEltVTClassId(p))
+ clt.add(new TableEltVTClassColor(p))
end
end
if p isa MMMethod and p.need_super then
ctab.add(new TableEltClassSelfId)
ctab.add(new TableEltClassObjectSize)
+ ctab.add(new TableEltClassSelfName)
itab.add(new TableEltVftPointer)
itab.add(new TableEltObjectId)
super TableEltProp
end
+ # An element that represents a class color value for a virtual type
+ class TableEltVTClassColor
+ super TableEltProp
+ end
+
+ # An element that represents a class id value for a virtual type
+ class TableEltVTClassId
+ super TableEltProp
+ end
+
# An element that represents a function pointer to the super method of a local method
class TableEltSuper
super TableEltProp
redef fun is_related_to(c) do return true
end
+# The element that represent the class name
+class TableEltClassSelfName
+ super TableElt
+ redef fun is_related_to(c) do return true
+end
+
# The element that represent the Object Size
class TableEltClassObjectSize
super TableElt
init(m: MMMethod, e: nullable Sequence[IRegister])
do
- super(e)
+ # Checks that arguments contains at least one IRegister element
+ assert e.length == m.signature.arity + 1
+
+ super(e)
_method = m
end
end
# A type check
- # expr is the expression checked
+ # expr1 is the type reciever (self)
+ # expr2 is the expression checked
class ITypeCheck
- super ICode1
+ super ICode2
# The static type checkes to
readable var _stype: MMType
- init(e: IRegister, t: MMType)
+ init(e1, e2: IRegister, t: MMType)
do
- super(e)
+ super(e1, e2)
_stype = t
end