Compiler that use global compilation and perform hard optimisations like:

  • customization
  • switch dispatch
  • inlining

Introduced properties

private var _classids: HashMap[MClassType, String]

nitc :: GlobalCompiler :: _classids

Cache for classid
private var _live_primitive_types: Array[MClassType]

nitc :: GlobalCompiler :: _live_primitive_types

Subset of runtime_type_analysis.live_types that contains only primitive types
private var _runtime_type_analysis: RapidTypeAnalysis

nitc :: GlobalCompiler :: _runtime_type_analysis

The result of the RTA (used to know live types and methods)
private var _seen: HashSet[AbstractRuntimeFunction]

nitc :: GlobalCompiler :: _seen

runtime_functions already seen (todo or done)
private var _todos: List[AbstractRuntimeFunction]

nitc :: GlobalCompiler :: _todos

runtime_functions that need to be compiled
fun classid(mtype: MClassType): String

nitc :: GlobalCompiler :: classid

Return the C symbol associated to a live type runtime
protected fun classids: HashMap[MClassType, String]

nitc :: GlobalCompiler :: classids

Cache for classid
protected fun classids=(classids: HashMap[MClassType, String])

nitc :: GlobalCompiler :: classids=

Cache for classid
protected fun compile_class_names

nitc :: GlobalCompiler :: compile_class_names

Compile class names (for the class_name and output_class_name methods)
fun declare_runtimeclass(mtype: MClassType)

nitc :: GlobalCompiler :: declare_runtimeclass

Declare C structures and identifiers for a runtime class
init defaultinit(mainmodule: MModule, modelbuilder: ModelBuilder, runtime_type_analysis: RapidTypeAnalysis)

nitc :: GlobalCompiler :: defaultinit

fun generate_init_instance(mtype: MClassType)

nitc :: GlobalCompiler :: generate_init_instance

Generate the init-instance of a live type (allocate + init-instance)
fun live_primitive_types: Array[MClassType]

nitc :: GlobalCompiler :: live_primitive_types

Subset of runtime_type_analysis.live_types that contains only primitive types
protected fun live_primitive_types=(live_primitive_types: Array[MClassType])

nitc :: GlobalCompiler :: live_primitive_types=

Subset of runtime_type_analysis.live_types that contains only primitive types
fun runtime_type_analysis: RapidTypeAnalysis

nitc :: GlobalCompiler :: runtime_type_analysis

The result of the RTA (used to know live types and methods)
protected fun runtime_type_analysis=(runtime_type_analysis: RapidTypeAnalysis)

nitc :: GlobalCompiler :: runtime_type_analysis=

The result of the RTA (used to know live types and methods)
private fun seen: HashSet[AbstractRuntimeFunction]

nitc :: GlobalCompiler :: seen

runtime_functions already seen (todo or done)
private fun seen=(seen: HashSet[AbstractRuntimeFunction])

nitc :: GlobalCompiler :: seen=

runtime_functions already seen (todo or done)
fun todo(m: AbstractRuntimeFunction)

nitc :: GlobalCompiler :: todo

Add a new todo task
private fun todos: List[AbstractRuntimeFunction]

nitc :: GlobalCompiler :: todos

runtime_functions that need to be compiled
private fun todos=(todos: List[AbstractRuntimeFunction])

nitc :: GlobalCompiler :: todos=

runtime_functions that need to be compiled

Redefined properties

redef type SELF: GlobalCompiler

nitc $ GlobalCompiler :: SELF

Type of this instance, automatically specialized in every class
redef fun compile_header_structs

nitc $ GlobalCompiler :: compile_header_structs

Declaration of structures the live Nit types
redef fun compile_nitni_structs

nitc $ GlobalCompiler :: compile_nitni_structs

Declaration of structures for nitni undelying the FFI
redef fun do_compilation

nitc $ GlobalCompiler :: do_compilation

Do the full code generation of the program mainmodule
redef init init

nitc $ GlobalCompiler :: init

redef fun new_visitor: VISITOR

nitc $ GlobalCompiler :: new_visitor

Initialize a visitor specific for a compiler engine

All properties

fun !=(other: nullable Object): Bool

core :: Object :: !=

Have self and other different values?
fun ==(other: nullable Object): Bool

core :: Object :: ==

Have self and other the same value?
type CLASS: Class[SELF]

core :: Object :: CLASS

The type of the class of self.
type SELF: Object

core :: Object :: SELF

Type of this instance, automatically specialized in every class
private var _classids: HashMap[MClassType, String]

nitc :: GlobalCompiler :: _classids

Cache for classid
private var _compiled_callref_thunk: HashSet[MMethodDef]

nitc :: AbstractCompiler :: _compiled_callref_thunk

All methods who already has a callref_thunk generated for
private var _compiled_null_types: Array[MNullableType]

nitc :: AbstractCompiler :: _compiled_null_types

Cache to avoid multiple compilation of NULL values
private var _extern_bodies: Array[ExternFile]

nitc :: AbstractCompiler :: _extern_bodies

List of additional files required to compile (FFI)
private var _files: Array[CodeFile]

nitc :: AbstractCompiler :: _files

The list of all associated files
private var _files_to_copy: Array[String]

nitc :: AbstractCompiler :: _files_to_copy

List of source files to copy over to the compile dir
private var _header: CodeWriter

nitc :: AbstractCompiler :: _header

Where global declaration are stored (the main .h)
private var _linker_script: Array[String]

nitc :: AbstractCompiler :: _linker_script

Additionnal linker script for ld.
private var _live_primitive_types: Array[MClassType]

nitc :: GlobalCompiler :: _live_primitive_types

Subset of runtime_type_analysis.live_types that contains only primitive types
private var _mainmodule: MModule

nitc :: AbstractCompiler :: _mainmodule

The main module of the program currently compiled
private var _modelbuilder: ModelBuilder

nitc :: AbstractCompiler :: _modelbuilder

The modelbuilder used to know the model and the AST
private var _names: HashMap[String, String]

nitc :: AbstractCompiler :: _names

Table corresponding c_names to nit names (methods)
private var _realmainmodule: MModule

nitc :: AbstractCompiler :: _realmainmodule

The real main module of the program
private var _runtime_type_analysis: RapidTypeAnalysis

nitc :: GlobalCompiler :: _runtime_type_analysis

The result of the RTA (used to know live types and methods)
private var _seen: HashSet[AbstractRuntimeFunction]

nitc :: GlobalCompiler :: _seen

runtime_functions already seen (todo or done)
private var _seen_extern: ArraySet[String]

nitc :: AbstractCompiler :: _seen_extern

This is used to avoid adding an extern file more than once
private var _target_platform: Platform

nitc :: AbstractCompiler :: _target_platform

The targeted specific platform
private var _todos: List[AbstractRuntimeFunction]

nitc :: GlobalCompiler :: _todos

runtime_functions that need to be compiled
private var _toolchain: Toolchain

nitc :: AbstractCompiler :: _toolchain

The associated toolchain
protected fun all_routine_types_name=(all_routine_types_name: Set[String])

nitc :: AbstractCompiler :: all_routine_types_name=

fun build_c_to_nit_bindings

nitc :: AbstractCompiler :: build_c_to_nit_bindings

Builds the .c and .h files to be used when generating a Stack Trace
protected fun class_factory(name: String): CLASS

core :: Object :: class_factory

Implementation used by get_class to create the specific class.
fun class_name: String

core :: Object :: class_name

The class name of the object.
fun classid(mtype: MClassType): String

nitc :: GlobalCompiler :: classid

Return the C symbol associated to a live type runtime
protected fun classids: HashMap[MClassType, String]

nitc :: GlobalCompiler :: classids

Cache for classid
protected fun classids=(classids: HashMap[MClassType, String])

nitc :: GlobalCompiler :: classids=

Cache for classid
fun compile_before_main(v: VISITOR)

nitc :: AbstractCompiler :: compile_before_main

Hook to add specif piece of code before the the main C function.
fun compile_begin_main(v: VISITOR)

nitc :: AbstractCompiler :: compile_begin_main

Hook to add specif piece of code at the begin on the main C function.
protected fun compile_catch_stack

nitc :: AbstractCompiler :: compile_catch_stack

Stack stocking environment for longjumps
protected fun compile_class_names

nitc :: GlobalCompiler :: compile_class_names

Compile class names (for the class_name and output_class_name methods)
fun compile_header

nitc :: AbstractCompiler :: compile_header

Compile C headers
protected abstract fun compile_header_structs

nitc :: AbstractCompiler :: compile_header_structs

Declaration of structures for live Nit types
fun compile_main_function

nitc :: AbstractCompiler :: compile_main_function

Generate the main C function.
fun compile_nitni_global_ref_functions

nitc :: AbstractCompiler :: compile_nitni_global_ref_functions

Copile all C functions related to the [incr|decr]_ref features of the FFI
protected fun compile_nitni_structs

nitc :: AbstractCompiler :: compile_nitni_structs

Declaration of structures for nitni undelying the FFI
fun compiled_callref_thunk: HashSet[MMethodDef]

nitc :: AbstractCompiler :: compiled_callref_thunk

All methods who already has a callref_thunk generated for
protected fun compiled_callref_thunk=(compiled_callref_thunk: HashSet[MMethodDef])

nitc :: AbstractCompiler :: compiled_callref_thunk=

All methods who already has a callref_thunk generated for
private fun compiled_null_types: Array[MNullableType]

nitc :: AbstractCompiler :: compiled_null_types

Cache to avoid multiple compilation of NULL values
private fun compiled_null_types=(compiled_null_types: Array[MNullableType])

nitc :: AbstractCompiler :: compiled_null_types=

Cache to avoid multiple compilation of NULL values
protected fun count_type_test_resolved=(count_type_test_resolved: HashMap[String, Int])

nitc :: AbstractCompiler :: count_type_test_resolved=

protected fun count_type_test_skipped=(count_type_test_skipped: HashMap[String, Int])

nitc :: AbstractCompiler :: count_type_test_skipped=

protected fun count_type_test_tags=(count_type_test_tags: Array[String])

nitc :: AbstractCompiler :: count_type_test_tags=

protected fun count_type_test_unresolved=(count_type_test_unresolved: HashMap[String, Int])

nitc :: AbstractCompiler :: count_type_test_unresolved=

fun declare_runtimeclass(mtype: MClassType)

nitc :: GlobalCompiler :: declare_runtimeclass

Declare C structures and identifiers for a runtime class
init defaultinit(mainmodule: MModule, modelbuilder: ModelBuilder, runtime_type_analysis: RapidTypeAnalysis)

nitc :: GlobalCompiler :: defaultinit

init defaultinit(mainmodule: MModule, modelbuilder: ModelBuilder)

nitc :: AbstractCompiler :: defaultinit

fun display_stats

nitc :: AbstractCompiler :: display_stats

Display stats about compilation process
abstract fun do_compilation

nitc :: AbstractCompiler :: do_compilation

Do the full code generation of the program mainmodule
fun extern_bodies: Array[ExternFile]

nitc :: AbstractCompiler :: extern_bodies

List of additional files required to compile (FFI)
protected fun extern_bodies=(extern_bodies: Array[ExternFile])

nitc :: AbstractCompiler :: extern_bodies=

List of additional files required to compile (FFI)
fun files: Array[CodeFile]

nitc :: AbstractCompiler :: files

The list of all associated files
protected fun files=(files: Array[CodeFile])

nitc :: AbstractCompiler :: files=

The list of all associated files
fun files_to_copy: Array[String]

nitc :: AbstractCompiler :: files_to_copy

List of source files to copy over to the compile dir
protected fun files_to_copy=(files_to_copy: Array[String])

nitc :: AbstractCompiler :: files_to_copy=

List of source files to copy over to the compile dir
fun generate_check_attr(v: VISITOR, recv: RuntimeVariable, mtype: MClassType)

nitc :: AbstractCompiler :: generate_check_attr

Generate code that check if an attribute is correctly initialized
fun generate_init_attr(v: VISITOR, recv: RuntimeVariable, mtype: MClassType)

nitc :: AbstractCompiler :: generate_init_attr

Generate code that initialize the attributes on a new instance
fun generate_init_instance(mtype: MClassType)

nitc :: GlobalCompiler :: generate_init_instance

Generate the init-instance of a live type (allocate + init-instance)
fun get_class: CLASS

core :: Object :: get_class

The meta-object representing the dynamic type of self.
fun hardening: Bool

nitc :: AbstractCompiler :: hardening

Is hardening asked? (see --hardening)
fun hash: Int

core :: Object :: hash

The hash code of the object.
fun header: CodeWriter

nitc :: AbstractCompiler :: header

Where global declaration are stored (the main .h)
fun header=(header: CodeWriter)

nitc :: AbstractCompiler :: header=

Where global declaration are stored (the main .h)
init init

core :: Object :: init

fun inspect: String

core :: Object :: inspect

Developer readable representation of self.
protected fun inspect_head: String

core :: Object :: inspect_head

Return "CLASSNAME:#OBJECTID".
intern fun is_same_instance(other: nullable Object): Bool

core :: Object :: is_same_instance

Return true if self and other are the same instance (i.e. same identity).
fun is_same_serialized(other: nullable Object): Bool

core :: Object :: is_same_serialized

Is self the same as other in a serialization context?
intern fun is_same_type(other: Object): Bool

core :: Object :: is_same_type

Return true if self and other have the same dynamic type.
fun linker_script: Array[String]

nitc :: AbstractCompiler :: linker_script

Additionnal linker script for ld.
protected fun linker_script=(linker_script: Array[String])

nitc :: AbstractCompiler :: linker_script=

Additionnal linker script for ld.
fun live_primitive_types: Array[MClassType]

nitc :: GlobalCompiler :: live_primitive_types

Subset of runtime_type_analysis.live_types that contains only primitive types
protected fun live_primitive_types=(live_primitive_types: Array[MClassType])

nitc :: GlobalCompiler :: live_primitive_types=

Subset of runtime_type_analysis.live_types that contains only primitive types
fun mainmodule: MModule

nitc :: AbstractCompiler :: mainmodule

The main module of the program currently compiled
fun mainmodule=(mainmodule: MModule)

nitc :: AbstractCompiler :: mainmodule=

The main module of the program currently compiled
fun modelbuilder: ModelBuilder

nitc :: AbstractCompiler :: modelbuilder

The modelbuilder used to know the model and the AST
protected fun modelbuilder=(modelbuilder: ModelBuilder)

nitc :: AbstractCompiler :: modelbuilder=

The modelbuilder used to know the model and the AST
fun names: HashMap[String, String]

nitc :: AbstractCompiler :: names

Table corresponding c_names to nit names (methods)
protected fun names=(names: HashMap[String, String])

nitc :: AbstractCompiler :: names=

Table corresponding c_names to nit names (methods)
private intern fun native_class_name: CString

core :: Object :: native_class_name

The class name of the object in CString format.
fun new_file(name: String): CodeFile

nitc :: AbstractCompiler :: new_file

Force the creation of a new file
abstract fun new_visitor: VISITOR

nitc :: AbstractCompiler :: new_visitor

Initialize a visitor specific for a compiler engine
intern fun object_id: Int

core :: Object :: object_id

An internal hash code for the object based on its identity.
fun output

core :: Object :: output

Display self on stdout (debug only).
intern fun output_class_name

core :: Object :: output_class_name

Display class name on stdout (debug only).
fun provide_declaration(key: String, s: String)

nitc :: AbstractCompiler :: provide_declaration

Provide a declaration that can be requested (before or latter) by a visitor
fun realmainmodule: MModule

nitc :: AbstractCompiler :: realmainmodule

The real main module of the program
protected fun realmainmodule=(realmainmodule: MModule)

nitc :: AbstractCompiler :: realmainmodule=

The real main module of the program
fun runtime_type_analysis: RapidTypeAnalysis

nitc :: GlobalCompiler :: runtime_type_analysis

The result of the RTA (used to know live types and methods)
protected fun runtime_type_analysis=(runtime_type_analysis: RapidTypeAnalysis)

nitc :: GlobalCompiler :: runtime_type_analysis=

The result of the RTA (used to know live types and methods)
private fun seen: HashSet[AbstractRuntimeFunction]

nitc :: GlobalCompiler :: seen

runtime_functions already seen (todo or done)
private fun seen=(seen: HashSet[AbstractRuntimeFunction])

nitc :: GlobalCompiler :: seen=

runtime_functions already seen (todo or done)
private fun seen_extern: ArraySet[String]

nitc :: AbstractCompiler :: seen_extern

This is used to avoid adding an extern file more than once
private fun seen_extern=(seen_extern: ArraySet[String])

nitc :: AbstractCompiler :: seen_extern=

This is used to avoid adding an extern file more than once
fun serialization_hash: Int

core :: Object :: serialization_hash

Hash value use for serialization
intern fun sys: Sys

core :: Object :: sys

Return the global sys object, the only instance of the Sys class.
fun target_platform: Platform

nitc :: AbstractCompiler :: target_platform

The targeted specific platform
protected fun target_platform=(target_platform: Platform)

nitc :: AbstractCompiler :: target_platform=

The targeted specific platform
abstract fun to_jvalue(env: JniEnv): JValue

core :: Object :: to_jvalue

fun to_s: String

core :: Object :: to_s

User readable representation of self.
fun todo(m: AbstractRuntimeFunction)

nitc :: GlobalCompiler :: todo

Add a new todo task
private fun todos: List[AbstractRuntimeFunction]

nitc :: GlobalCompiler :: todos

runtime_functions that need to be compiled
private fun todos=(todos: List[AbstractRuntimeFunction])

nitc :: GlobalCompiler :: todos=

runtime_functions that need to be compiled
fun toolchain: Toolchain

nitc :: AbstractCompiler :: toolchain

The associated toolchain
protected fun toolchain=(toolchain: Toolchain)

nitc :: AbstractCompiler :: toolchain=

The associated toolchain
package_diagram nitc::GlobalCompiler GlobalCompiler nitc::AbstractCompiler AbstractCompiler nitc::GlobalCompiler->nitc::AbstractCompiler core::Object Object nitc::AbstractCompiler->core::Object ...core::Object ... ...core::Object->core::Object

Ancestors

interface Object

core :: Object

The root of the class hierarchy.

Parents

abstract class AbstractCompiler

nitc :: AbstractCompiler

Singleton that store the knowledge about the compilation process

Class definitions

nitc $ GlobalCompiler
# Compiler that use global compilation and perform hard optimisations like:
#   * customization
#   * switch dispatch
#   * inlining
class GlobalCompiler
	super AbstractCompiler

	redef type VISITOR: GlobalCompilerVisitor

	# The result of the RTA (used to know live types and methods)
	var runtime_type_analysis: RapidTypeAnalysis

	init
	do
		var file = new_file("{mainmodule.c_name}.nitgg")
		self.header = new CodeWriter(file)
		self.live_primitive_types = new Array[MClassType]
		for t in runtime_type_analysis.live_types do
			if t.is_c_primitive or t.mclass.name == "Pointer" then
				self.live_primitive_types.add(t)
			end
		end
	end

	redef fun do_compilation
	do
		var compiler = self

		compiler.compile_header

		if mainmodule.model.get_mclasses_by_name("Pointer") != null then
			runtime_type_analysis.live_types.add(mainmodule.pointer_type)
		end
		for t in runtime_type_analysis.live_types do
			compiler.declare_runtimeclass(t)
		end

		compiler.compile_class_names

		# Init instance code (allocate and init-arguments)
		for t in runtime_type_analysis.live_types do
			if not t.is_c_primitive then
				compiler.generate_init_instance(t)
				if t.mclass.kind == extern_kind then
					compiler.generate_box_instance(t)
				end
			else
				compiler.generate_box_instance(t)
			end
		end

		# The main function of the C
		compiler.compile_nitni_global_ref_functions
		compiler.compile_main_function

		# Compile until all runtime_functions are visited
		while not compiler.todos.is_empty do
			var m = compiler.todos.shift
			modelbuilder.toolcontext.info("Compile {m} ({compiler.seen.length-compiler.todos.length}/{compiler.seen.length})", 3)
			m.compile_to_c(compiler)
		end
		modelbuilder.toolcontext.info("Total methods to compile to C: {compiler.seen.length}", 2)

	end

	# Compile class names (for the class_name and output_class_name methods)
	protected fun compile_class_names do
		var v = new_visitor
		self.header.add_decl("extern const char *class_names[];")
		v.add("const char *class_names[] = \{")
		for t in self.runtime_type_analysis.live_types do
			v.add("\"{t}\", /* {self.classid(t)} */")
		end
		v.add("\};")
	end

	# Return the C symbol associated to a live type runtime
	# REQUIRE: self.runtime_type_analysis.live_types.has(mtype)
	fun classid(mtype: MClassType): String
	do
		if self.classids.has_key(mtype) then
			return self.classids[mtype]
		end
		print_error "No classid for {mtype}"
		abort
	end

	# Cache for classid
	protected var classids: HashMap[MClassType, String] = new HashMap[MClassType, String]

	# Declaration of structures the live Nit types
	# Each live type is generated as an independent C `struct` type.
	# They only share a common first field `classid` used to implement the polymorphism.
	# Usualy, all C variables that refers to a Nit object are typed on the abstract struct `val` that contains only the `classid` field.
	redef fun compile_header_structs do
		self.header.add_decl("typedef struct \{int classid;\} val; /* general C type representing a Nit instance. */")
	end

	# Subset of runtime_type_analysis.live_types that contains only primitive types
	# Used to implement the equal test
	var live_primitive_types: Array[MClassType] is noinit

	# Add a new todo task
	fun todo(m: AbstractRuntimeFunction)
	do
		if seen.has(m) then return
		todos.add(m)
		seen.add(m)
	end

	# runtime_functions that need to be compiled
	private var todos: List[AbstractRuntimeFunction] = new List[AbstractRuntimeFunction]

	# runtime_functions already seen (todo or done)
	private var seen: HashSet[AbstractRuntimeFunction] = new HashSet[AbstractRuntimeFunction]

	# Declare C structures and identifiers for a runtime class
	fun declare_runtimeclass(mtype: MClassType)
	do
		var v = self.header
		assert self.runtime_type_analysis.live_types.has(mtype)
		v.add_decl("/* runtime class {mtype} */")
		var idnum = classids.length
		var idname = "ID_" + mtype.c_name
		self.classids[mtype] = idname
		v.add_decl("#define {idname} {idnum} /* {mtype} */")

		v.add_decl("struct {mtype.c_name} \{")
		v.add_decl("int classid; /* must be {idname} */")

		if mtype.mclass.name == "NativeArray" then
			# NativeArrays are just a instance header followed by an array of values
			v.add_decl("int length;")
			v.add_decl("{mtype.arguments.first.ctype} values[1];")
		end

                if all_routine_types_name.has(mtype.mclass.name) then
                        v.add_decl("val* recv;")
                        var c_args = ["val* self"]
                        var c_ret = "void"
                        var k = mtype.arguments.length
                        if mtype.mclass.name.has("Fun") then
                                c_ret = mtype.arguments.last.ctype
                                k -= 1
                        end
                        for i in [0..k[ do
                                var t = mtype.arguments[i]
                                c_args.push("{t.ctype} p{i}")
                        end
                        var c_sig = c_args.join(", ")
                        v.add_decl("{c_ret} (*method)({c_sig});")
                end

		if mtype.ctype_extern != "val*" then
			# Is the Nit type is native then the struct is a box with two fields:
			# * the `classid` to be polymorph
			# * the `value` that contains the native value.
			v.add_decl("{mtype.ctype_extern} value;")
		end

		# Collect all attributes and associate them a field in the structure.
		# Note: we do not try to optimize the order and helps CC to optimize the client code.
		for cd in mtype.collect_mclassdefs(self.mainmodule) do
			for p in cd.intro_mproperties do
				if not p isa MAttribute then continue
				var t = p.intro.static_mtype.as(not null)
				t = t.anchor_to(self.mainmodule, mtype)
				v.add_decl("{t.ctype} {p.intro.c_name}; /* {p}: {t} */")
			end
		end
		v.add_decl("\};")
	end

	# Generate the init-instance of a live type (allocate + init-instance)
	fun generate_init_instance(mtype: MClassType)
	do
		assert self.runtime_type_analysis.live_types.has(mtype)
		assert not mtype.is_c_primitive
		var v = self.new_visitor

		var is_native_array = mtype.mclass.name == "NativeArray"
                var is_routine_ref = all_routine_types_name.has(mtype.mclass.name)
		var sig
		if is_native_array then
			sig = "int length"
		else
			sig = "void"
		end
                if is_routine_ref then
                        var c_args = ["val* self"]
                        var c_ret = "void"
                        var k = mtype.arguments.length
                        if mtype.mclass.name.has("Fun") then
                                c_ret = mtype.arguments.last.ctype
                                k -= 1
                        end
                        for i in [0..k[ do
                                var t = mtype.arguments[i]
                                c_args.push("{t.ctype} p{i}")
                        end
                        # The underlying method signature
                        var method_sig = "{c_ret} (*method)({c_args.join(", ")})"
                        sig = "val* recv, {method_sig}"
                end

		self.header.add_decl("{mtype.ctype} NEW_{mtype.c_name}({sig});")
		v.add_decl("/* allocate {mtype} */")
		v.add_decl("{mtype.ctype} NEW_{mtype.c_name}({sig}) \{")
		var res = v.new_var(mtype)
		res.is_exact = true
		if is_native_array then
			v.add("{res} = nit_alloc(sizeof(struct {mtype.c_name}) + length*sizeof(val*));")
			v.add("((struct {mtype.c_name}*){res})->length = length;")
		else
			v.add("{res} = nit_alloc(sizeof(struct {mtype.c_name}));")
		end
                if is_routine_ref then
			v.add("((struct {mtype.c_name}*){res})->recv = recv;")
                        v.add("((struct {mtype.c_name}*){res})->method = method;")
                end
		v.add("{res}->classid = {self.classid(mtype)};")

		self.generate_init_attr(v, res, mtype)
		v.set_finalizer res
		v.add("return {res};")
		v.add("\}")
	end

	fun generate_box_instance(mtype: MClassType)
	do
		assert self.runtime_type_analysis.live_types.has(mtype)
		var v = self.new_visitor

		self.header.add_decl("val* BOX_{mtype.c_name}({mtype.ctype});")
		v.add_decl("/* allocate {mtype} */")
		v.add_decl("val* BOX_{mtype.c_name}({mtype.ctype} value) \{")
		v.add("struct {mtype.c_name}*res = nit_alloc(sizeof(struct {mtype.c_name}));")
		v.add("res->classid = {self.classid(mtype)};")
		v.add("res->value = value;")
		v.add("return (val*)res;")
		v.add("\}")
	end

	redef fun new_visitor do return new GlobalCompilerVisitor(self)

	private var collect_types_cache: HashMap[MType, Array[MClassType]] = new HashMap[MType, Array[MClassType]]

	redef fun compile_nitni_structs
	do
		self.header.add_decl """
struct nitni_instance \{
	struct nitni_instance *next,
		*prev; /* adjacent global references in global list */
	int count; /* number of time this global reference has been marked */
	val *value;
\};"""
		super
	end
end
src/compiler/global_compiler.nit:71,1--329,3