Implements a call of the runtime_function

May inline the body or generate a C function call

Property definitions

nitc $ AbstractRuntimeFunction :: call
	# Implements a call of the runtime_function
	# May inline the body or generate a C function call
	fun call(v: VISITOR, arguments: Array[RuntimeVariable]): nullable RuntimeVariable is abstract
src/compiler/abstract_compiler.nit:2104,2--2106,94

nitc $ CustomizedRuntimeFunction :: call
	redef fun call(v: VISITOR, arguments: Array[RuntimeVariable]): nullable RuntimeVariable
	do
		var ret = self.mmethoddef.msignature.return_mtype
		if ret != null then
			ret = v.resolve_for(ret, arguments.first)
		end

                # TODO: remove this guard when gcc warning issue (#2781) is resolved
                # WARNING: the next two lines of code is used to prevent inlining.
                # Inlining of a callref seems to work all the time. However,
                # it will produce some deadcode in certain scenarios (when using nullable type).
                #
                # ~~~~nitish
                # class A[E]
                #       fun toto(x: E)
                #       do
                #               # ...do something with x...
                #       end
                # end
                # end
                # var a = new A[nullable Int]
                # var f = &a.toto
                # f.call(null)  # Will produce a proper C callsite, but it will
                #               # produce unreachable (dead code) for type checking
                #               # and covariance. Thus, creating warnings when
                #               # compiling in global. However, if you ignore
                #               # those warnings, the binary works perfectly fine.
                # ~~~~
                var intromclassdef = self.mmethoddef.mproperty.intro_mclassdef
                var is_callref = v.compiler.all_routine_types_name.has(intromclassdef.name)

                if self.mmethoddef.can_inline(v) and not is_callref then
			var frame = new StaticFrame(v, self.mmethoddef, self.recv, arguments)
			frame.returnlabel = v.get_name("RET_LABEL")
			if ret != null then
				frame.returnvar = v.new_var(ret)
			end
			var old_frame = v.frame
			v.frame = frame
			v.add("\{ /* Inline {self} ({arguments.join(",")}) */")
			self.mmethoddef.compile_inside_to_c(v, arguments)
			v.add("{frame.returnlabel.as(not null)}:(void)0;")
			v.add("\}")
			v.frame = old_frame
			return frame.returnvar
		end
		v.adapt_signature(self.mmethoddef, arguments)
		v.compiler.todo(self)
		if ret == null then
			v.add("{self.c_name}({arguments.join(",")});")
			return null
		else
			var res = v.new_var(ret)
			v.add("{res} = {self.c_name}({arguments.join(",")});")
			return res
		end
	end
src/compiler/global_compiler.nit:1104,2--1160,4