- if not self.runtime_type_analysis.live_types.has(mtype) then return
-
- self.header.add_decl("val* BOX_{c_name}({mtype.ctype});")
- v.add_decl("/* allocate {mtype} */")
- v.add_decl("val* BOX_{mtype.c_name}({mtype.ctype} value) \{")
- v.add("struct instance_{c_name}*res = GC_MALLOC(sizeof(struct instance_{c_name}));")
- v.add("res->type = (struct type*) &type_{c_name};")
- v.add("res->class = (struct class*) &class_{c_name};")
- v.add("res->value = value;")
- v.add("return (val*)res;")
- v.add("\}")
- return
- end
-
- var is_native_array = mclass.name == "NativeArray"
-
- var sig
- if is_native_array then
- sig = "int length, struct type* type"
- else
- sig = "struct type* type"
- end
-
- #Build instance struct
- #extern const struct instance_array__NativeArray instance_array__NativeArray;
- self.header.add_decl("struct instance_{c_name} \{")
- self.header.add_decl("const struct type *type;")
- self.header.add_decl("const struct class *class;")
- self.header.add_decl("nitattribute_t attrs[{attrs.length}];")
- if is_native_array then
- # NativeArrays are just a instance header followed by an array of values
- self.header.add_decl("val* values[0];")
- end
- self.header.add_decl("\};")
-
-
- self.header.add_decl("{mtype.ctype} NEW_{c_name}({sig});")
- v.add_decl("/* allocate {mtype} */")
- v.add_decl("{mtype.ctype} NEW_{c_name}({sig}) \{")
- var res = v.new_named_var(mtype, "self")
- res.is_exact = true
- if is_native_array then
- var mtype_elt = mtype.arguments.first
- v.add("{res} = GC_MALLOC(sizeof(struct instance_{c_name}) + length*sizeof({mtype_elt.ctype}));")
- else
- v.add("{res} = GC_MALLOC(sizeof(struct instance_{c_name}));")
- end
- v.add("{res}->type = type;")
- if v.compiler.modelbuilder.toolcontext.opt_hardening.value then
- v.add("if(type == NULL) \{")
- v.add_abort("type null")
- v.add("\}")
- if not v.compiler.modelbuilder.toolcontext.opt_generic_tree.value then
- v.add("if(type->unanchored_table == NULL) \{")
- v.add("fprintf(stderr, \"Insantiation of a dead type: %s\\n\", type->name);")
- v.add_abort("type dead")
- v.add("\}")
- end
- end
- v.add("{res}->class = (struct class*) &class_{c_name};")
-
- 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)
-end
-
-# The C function associated to a methoddef separately compiled
-class SeparateRuntimeFunction
- super AbstractRuntimeFunction
-
- redef fun build_c_name: String
- do
- return "{mmethoddef.c_name}"
- end
-
- redef fun to_s do return self.mmethoddef.to_s
-
- redef fun compile_to_c(compiler)
- do
- var mmethoddef = self.mmethoddef
-
- var recv = self.mmethoddef.mclassdef.bound_mtype
- var v = compiler.new_visitor
- var selfvar = new RuntimeVariable("self", recv, recv)
- var arguments = new Array[RuntimeVariable]
- var frame = new Frame(v, mmethoddef, recv, arguments)
- v.frame = frame
-
- var msignature = mmethoddef.msignature.resolve_for(mmethoddef.mclassdef.bound_mtype, mmethoddef.mclassdef.bound_mtype, mmethoddef.mclassdef.mmodule, true)
-
- var sig = new Buffer
- var comment = new Buffer
- var ret = msignature.return_mtype
- if ret != null then
- sig.append("{ret.ctype} ")
- else if mmethoddef.mproperty.is_new then
- ret = recv
- sig.append("{ret.ctype} ")
- else
- sig.append("void ")
- end
- sig.append(self.c_name)
- sig.append("({selfvar.mtype.ctype} {selfvar}")
- comment.append("(self: {selfvar}")
- arguments.add(selfvar)
- for i in [0..msignature.arity[ do
- var mtype = msignature.mparameters[i].mtype
- if i == msignature.vararg_rank then
- mtype = v.get_class("Array").get_mtype([mtype])
- end
- comment.append(", {mtype}")
- sig.append(", {mtype.ctype} p{i}")
- var argvar = new RuntimeVariable("p{i}", mtype, mtype)
- arguments.add(argvar)
- end
- sig.append(")")
- comment.append(")")
- if ret != null then
- comment.append(": {ret}")
- end
- compiler.header.add_decl("{sig};")
-
- v.add_decl("/* method {self} for {comment} */")
- v.add_decl("{sig} \{")
- if ret != null then
- frame.returnvar = v.new_var(ret)
- end
- frame.returnlabel = v.get_name("RET_LABEL")
-
- if recv != arguments.first.mtype then
- #print "{self} {recv} {arguments.first}"
- end
- mmethoddef.compile_inside_to_c(v, arguments)
-
- v.add("{frame.returnlabel.as(not null)}:;")
- if ret != null then
- v.add("return {frame.returnvar.as(not null)};")
- end
- v.add("\}")
- end
-end
-
-# The C function associated to a methoddef on a primitive type, stored into a VFT of a class
-# The first parameter (the reciever) is always typed by val* in order to accept an object value
-class VirtualRuntimeFunction
- super AbstractRuntimeFunction
-
- redef fun build_c_name: String
- do
- return "VIRTUAL_{mmethoddef.c_name}"
- end
-
- redef fun to_s do return self.mmethoddef.to_s
-
- redef fun compile_to_c(compiler)
- do
- var mmethoddef = self.mmethoddef
-
- var recv = self.mmethoddef.mclassdef.bound_mtype
- var v = compiler.new_visitor
- var selfvar = new RuntimeVariable("self", v.object_type, recv)
- var arguments = new Array[RuntimeVariable]
- var frame = new Frame(v, mmethoddef, recv, arguments)
- v.frame = frame
-
- var sig = new Buffer
- var comment = new Buffer
-
- # Because the function is virtual, the signature must match the one of the original class
- var intromclassdef = self.mmethoddef.mproperty.intro.mclassdef
- var msignature = mmethoddef.mproperty.intro.msignature.resolve_for(intromclassdef.bound_mtype, intromclassdef.bound_mtype, intromclassdef.mmodule, true)
- var ret = msignature.return_mtype
- if ret != null then
- sig.append("{ret.ctype} ")
- else if mmethoddef.mproperty.is_new then
- ret = recv
- sig.append("{ret.ctype} ")
- else
- sig.append("void ")
- end
- sig.append(self.c_name)
- sig.append("({selfvar.mtype.ctype} {selfvar}")
- comment.append("(self: {selfvar}")
- arguments.add(selfvar)
- for i in [0..msignature.arity[ do
- var mtype = msignature.mparameters[i].mtype
- if i == msignature.vararg_rank then
- mtype = v.get_class("Array").get_mtype([mtype])
- end
- comment.append(", {mtype}")
- sig.append(", {mtype.ctype} p{i}")
- var argvar = new RuntimeVariable("p{i}", mtype, mtype)
- arguments.add(argvar)
- end
- sig.append(")")
- comment.append(")")
- if ret != null then
- comment.append(": {ret}")
- end
- compiler.header.add_decl("{sig};")