Property definitions

nitc $ SeparateRuntimeFunction :: defaultinit
# The C function associated to a methoddef separately compiled
class SeparateRuntimeFunction
	super AbstractRuntimeFunction

	# The call-side static receiver
	var called_recv: MType

	# The call-side static signature
	var called_signature: MSignature

	# The name on the compiled method
	redef var build_c_name: String

	redef fun to_s do return self.mmethoddef.to_s

	redef fun msignature
	do
		return called_signature
	end

	redef fun recv_mtype
	do
		return called_recv
	end

	redef fun return_mtype
	do
		return called_signature.return_mtype
	end

	# The C return type (something or `void`)
	var c_ret: String is lazy do
		var ret = called_signature.return_mtype
		if ret != null then
			return ret.ctype
		else
			return "void"
		end
	end

	# The C signature (only the parmeter part)
	var c_sig: String is lazy do
		var sig = new FlatBuffer
		sig.append("({called_recv.ctype} self")
		for i in [0..called_signature.arity[ do
			var mp = called_signature.mparameters[i]
			var mtype = mp.mtype
			if mp.is_vararg then
				mtype = mmethoddef.mclassdef.mmodule.array_type(mtype)
			end
			sig.append(", {mtype.ctype} p{i}")
		end
		sig.append(")")
		return sig.to_s
	end

	# The C type for the function pointer.
	var c_funptrtype: String is lazy do return "{c_ret}(*){c_sig}"

	redef fun declare_signature(v, sig)
	do
		v.compiler.provide_declaration(c_name, "{sig};")
	end

	redef fun body_to_c(v)
	do
		var rta = v.compiler.as(SeparateCompiler).runtime_type_analysis
		if rta != null and not rta.live_mmodules.has(mmethoddef.mclassdef.mmodule) then
			v.add_abort("FATAL: Dead method executed.")
		else
			super
		end
	end

	redef fun end_compile_to_c(v)
	do
		var compiler = v.compiler
		compiler.names[self.c_name] = "{mmethoddef.full_name} ({mmethoddef.location.file.filename}:{mmethoddef.location.line_start})"
	end

	redef fun build_frame(v, arguments)
	do
		var recv = mmethoddef.mclassdef.bound_mtype
		return new StaticFrame(v, mmethoddef, recv, arguments)
	end

	# Compile the trampolines used to implement late-binding.
	#
	# See `opt_trampoline_call`.
	fun compile_trampolines(compiler: SeparateCompiler)
	do
		var recv = self.mmethoddef.mclassdef.bound_mtype
		var selfvar = new RuntimeVariable("self", called_recv, recv)
		var ret = called_signature.return_mtype
		var arguments = ["self"]
		for i in [0..called_signature.arity[ do arguments.add "p{i}"

		if mmethoddef.is_intro and not recv.is_c_primitive then
			var m = mmethoddef.mproperty
			var n2 = "CALL_" + m.const_color
			compiler.provide_declaration(n2, "{c_ret} {n2}{c_sig};")
			var v2 = compiler.new_visitor
			v2.add "{c_ret} {n2}{c_sig} \{"
			v2.require_declaration(m.const_color)
			var call = "(({c_funptrtype})({v2.class_info(selfvar)}->vft[{m.const_color}]))({arguments.join(", ")});"
			if ret != null then
				v2.add "return {call}"
			else
				v2.add call
			end

			v2.add "\}"

		end
		if mmethoddef.has_supercall and not recv.is_c_primitive then
			var m = mmethoddef
			var n2 = "CALL_" + m.const_color
			compiler.provide_declaration(n2, "{c_ret} {n2}{c_sig};")
			var v2 = compiler.new_visitor
			v2.add "{c_ret} {n2}{c_sig} \{"
			v2.require_declaration(m.const_color)
			var call = "(({c_funptrtype})({v2.class_info(selfvar)}->vft[{m.const_color}]))({arguments.join(", ")});"
			if ret != null then
				v2.add "return {call}"
			else
				v2.add call
			end

			v2.add "\}"
		end
	end
end
src/compiler/separate_compiler.nit:2463,1--2594,3