+ #Build BOX
+ self.provide_declaration("BOX_{c_name}", "val* BOX_{c_name}({mtype.ctype_extern});")
+ v.add_decl("/* allocate {mtype} */")
+ v.add_decl("val* BOX_{mtype.c_name}({mtype.ctype_extern} value) \{")
+ v.add("struct instance_{c_name}*res = nit_alloc(sizeof(struct instance_{c_name}));")
+ v.require_declaration("class_{c_name}")
+ v.add("res->class = &class_{c_name};")
+ v.add("res->value = value;")
+ v.add("return (val*)res;")
+ v.add("\}")
+
+ if mtype.mclass.name != "Pointer" then return true
+
+ v = new_visitor
+ self.provide_declaration("NEW_{c_name}", "{mtype.ctype} NEW_{c_name}();")
+ v.add_decl("/* allocate {mtype} */")
+ v.add_decl("{mtype.ctype} NEW_{c_name}() \{")
+ if is_dead then
+ v.add_abort("{mclass} is DEAD")
+ else
+ var res = v.new_named_var(mtype, "self")
+ res.is_exact = true
+ v.add("{res} = nit_alloc(sizeof(struct instance_{mtype.c_name}));")
+ v.require_declaration("class_{c_name}")
+ v.add("{res}->class = &class_{c_name};")
+ v.add("((struct instance_{mtype.c_name}*){res})->value = NULL;")
+ v.add("return {res};")
+ end
+ v.add("\}")
+ return true
+ else if mclass.name == "NativeArray" then
+ #Build instance struct
+ self.header.add_decl("struct instance_{c_name} \{")
+ self.header.add_decl("const struct class *class;")
+ self.header.add_decl("int length;")
+ self.header.add_decl("val* values[];")
+ self.header.add_decl("\};")
+
+ #Build NEW
+ self.provide_declaration("NEW_{c_name}", "{mtype.ctype} NEW_{c_name}(int length);")
+ v.add_decl("/* allocate {mtype} */")
+ v.add_decl("{mtype.ctype} NEW_{c_name}(int length) \{")
+ var res = v.get_name("self")
+ v.add_decl("struct instance_{c_name} *{res};")
+ var mtype_elt = mtype.arguments.first
+ v.add("{res} = nit_alloc(sizeof(struct instance_{c_name}) + length*sizeof({mtype_elt.ctype}));")
+ v.require_declaration("class_{c_name}")
+ v.add("{res}->class = &class_{c_name};")
+ v.add("{res}->length = length;")
+ v.add("return (val*){res};")
+ v.add("\}")
+ return true
+ else if mclass.name == "RoutineRef" then
+ self.header.add_decl("struct instance_{c_name} \{")
+ self.header.add_decl("const struct class *class;")
+ self.header.add_decl("val* recv;")
+ self.header.add_decl("nitmethod_t method;")
+ self.header.add_decl("\};")
+
+ self.provide_declaration("NEW_{c_name}", "{mtype.ctype} NEW_{c_name}(val* recv, nitmethod_t method, const struct class* class);")
+ v.add_decl("/* allocate {mtype} */")
+ v.add_decl("{mtype.ctype} NEW_{c_name}(val* recv, nitmethod_t method, const struct class* class)\{")
+ var res = v.get_name("self")
+ v.add_decl("struct instance_{c_name} *{res};")
+ var alloc = v.nit_alloc("sizeof(struct instance_{c_name})", mclass.full_name)
+ v.add("{res} = {alloc};")
+ v.add("{res}->class = class;")
+ v.add("{res}->recv = recv;")
+ v.add("{res}->method = method;")
+ v.add("return (val*){res};")
+ v.add("\}")
+ return true
+ else if mtype.mclass.kind == extern_kind and mtype.mclass.name != "CString" then
+ var pointer_type = mainmodule.pointer_type
+
+ self.provide_declaration("NEW_{c_name}", "{mtype.ctype} NEW_{c_name}();")
+ v.add_decl("/* allocate {mtype} */")
+ v.add_decl("{mtype.ctype} NEW_{c_name}() \{")
+ if is_dead then
+ v.add_abort("{mclass} is DEAD")
+ else
+ var res = v.new_named_var(mtype, "self")
+ res.is_exact = true
+ v.add("{res} = nit_alloc(sizeof(struct instance_{pointer_type.c_name}));")
+ #v.add("{res}->type = type;")
+ v.require_declaration("class_{c_name}")
+ v.add("{res}->class = &class_{c_name};")
+ v.add("((struct instance_{pointer_type.c_name}*){res})->value = NULL;")
+ v.add("return {res};")
+ end
+ v.add("\}")
+ return true