self.toolcontext.info("*** COMPILING TO C ***", 1)
var compiler = new SeparateCompiler(mainmodule, runtime_type_analysis, self)
- var v = compiler.new_visitor
- compiler.header = v
+ var v = compiler.header
v.add_decl("#include <stdlib.h>")
v.add_decl("#include <stdio.h>")
v.add_decl("#include <string.h>")
end
# compile live & cast type structures
- var mtypes = compiler.do_global_type_coloring
+ var mtypes = compiler.do_type_coloring
for t in mtypes do
compiler.compile_type_to_c(t)
end
private var ft_tables: Map[MClass, Array[nullable MParameterType]]
init(mainmodule: MModule, runtime_type_analysis: RapidTypeAnalysis, mmbuilder: ModelBuilder) do
+ self.header = self.new_visitor
# classes coloration
var class_coloring = new ClassColoring(mainmodule)
self.class_colors = class_coloring.colorize(mmbuilder.model.mclasses)
end
# colorize live types of the program
- private fun do_global_type_coloring: Set[MType] do
+ private fun do_type_coloring: Set[MType] do
var mtypes = new HashSet[MType]
mtypes.add_all(self.runtime_type_analysis.live_types)
mtypes.add_all(self.runtime_type_analysis.live_cast_types)
print "No bound found for virtual type {vt} ?"
abort
else
- var ntype = bound
- if ntype isa MNullableType then ntype = ntype.mtype
- if ntype isa MVirtualType then
- bound = ntype.anchor_to(self.mainmodule, mclass_type)
- else if ntype isa MParameterType then
- bound = ntype.anchor_to(self.mainmodule, mclass_type)
- else if ntype isa MGenericType and bound.need_anchor then
- bound = ntype.anchor_to(self.mainmodule, mclass_type)
- else if ntype isa MClassType then
+ var is_nullable = ""
+ if bound isa MNullableType then
+ bound = bound.mtype
+ is_nullable = "nullable_"
+ end
+ if bound isa MVirtualType then
+ bound = bound.anchor_to(self.mainmodule, mclass_type)
+ else if bound isa MParameterType then
+ bound = bound.anchor_to(self.mainmodule, mclass_type)
+ else if bound isa MGenericType and bound.need_anchor then
+ bound = bound.anchor_to(self.mainmodule, mclass_type)
+ else if bound isa MClassType then
else
- print "NOT YET IMPLEMENTED: mtype_to_livetype with type: {ntype}"
+ print "NOT YET IMPLEMENTED: mtype_to_livetype with type: {bound}"
abort
end
if self.typeids.has_key(bound) then
- v.add_decl("(struct type*)&type_{bound.c_name}, /* {ntype} */")
+ v.add_decl("(struct type*)&type_{is_nullable}{bound.c_name}, /* {bound} */")
else
- v.add_decl("NULL, /* dead type {ntype} */")
+ v.add_decl("NULL, /* dead type {bound} */")
end
end
end
v.add("{res}->type = type;")
v.add("{res}->class = (struct class*) &class_{c_name};")
- for cd in mtype.collect_mclassdefs(self.mainmodule)
- do
- var n = self.modelbuilder.mclassdef2nclassdef[cd]
- for npropdef in n.n_propdefs do
- if npropdef isa AAttrPropdef then
- npropdef.init_expr(v, res)
- end
- end
- end
+ self.generate_init_attr(v, res, mtype)
v.add("return {res};")
v.add("\}")
+
+ generate_check_init_instance(mtype)
+ end
+
+ redef fun generate_check_init_instance(mtype)
+ do
+ if self.modelbuilder.toolcontext.opt_no_check_initialization.value then return
+
+ var v = self.new_visitor
+ var c_name = mtype.mclass.c_name
+ var res = new RuntimeVariable("self", mtype, mtype)
+ self.header.add_decl("void CHECK_NEW_{c_name}({mtype.ctype});")
+ v.add_decl("/* allocate {mtype} */")
+ v.add_decl("void CHECK_NEW_{c_name}({mtype.ctype} {res}) \{")
+ self.generate_check_attr(v, res, mtype)
+ v.add("\}")
end
redef fun new_visitor do return new SeparateCompilerVisitor(self)
return self.new_expr("NEW_{mtype.mclass.c_name}((struct type *) &type_{mtype.c_name})", mtype)
end
+ redef fun check_init_instance(value, mtype)
+ do
+ if self.compiler.modelbuilder.toolcontext.opt_no_check_initialization.value then return
+ self.add("CHECK_NEW_{mtype.mclass.c_name}({value});")
+ end
+
+
redef fun type_test(value, mtype)
do
var compiler = self.compiler.as(SeparateCompiler)
end
var length = self.int_instance(array.length)
self.send(self.get_property("with_native", arraytype), [res, nat, length])
- self.check_init_instance(res)
+ self.check_init_instance(res, arraytype)
self.add("\}")
return res
end
end
private var c_name_cache: nullable String
end
+redef class MParameterType
+ redef fun c_name
+ do
+ var res = self.c_name_cache
+ if res != null then return res
+ res = "{self.mclass.c_name}_FT{self.rank}"
+ self.c_name_cache = res
+ return res
+ end
+end
+
+redef class MNullableType
+ redef fun c_name
+ do
+ var res = self.c_name_cache
+ if res != null then return res
+ res = "nullable_{self.mtype.c_name}"
+ self.c_name_cache = res
+ return res
+ end
+end