Base class for all thunk-like function. A thunk is a function whose purpose

is to call another function. Like a class wrapper or decorator, a thunk is used to computer things (conversions, log, etc) before or after a function call. It's an intermediary between the caller and the callee.

The most basic use of a thunk is to unbox its argument before invoking the real callee. Virtual functions are a use case of thunk function:

redef class Object
      fun toto(x: Int): Int do return 1 + x
end
redef class Int
      redef fun toto(x) do return x + self
end

long Object__toto(val self, long x) { return 1 + x } long Inttoto(long self, long x) { return x + self } long THUNK_Inttoto(val self, long x) {

  long self2 = (long)(self)>>2    // Unboxing from Object to Int
  return Int_toto(self2, x)

}

A thunk has its OWN SIGNATURE and is considered like any other AbstractRuntimeFunction. Thus, one might need to be careful when overriding parent's method. Since most usage of thunks in Nit is to unbox and box things between a caller and a callee, the default implementation is doing just that. In other words, a thunk takes a signature and a method and tries to cast its signature to the underlying method's signature.

A virtual function has the same signature as its mmethoddef field, except for its receiver is of type Object. In the same vibe, a call reference has all of its argument boxed as Object.

Introduced properties

private var _polymorph_call_flag: Bool

nitc :: ThunkFunction :: _polymorph_call_flag

Determines if the callsite should be polymorphic or static.
fun polymorph_call_flag: Bool

nitc :: ThunkFunction :: polymorph_call_flag

Determines if the callsite should be polymorphic or static.
fun polymorph_call_flag=(polymorph_call_flag: Bool)

nitc :: ThunkFunction :: polymorph_call_flag=

Determines if the callsite should be polymorphic or static.
abstract fun target_recv: MType

nitc :: ThunkFunction :: target_recv

The type expected by the callee. Used to resolve mmethoddef's formal

Redefined properties

redef type SELF: ThunkFunction

nitc $ ThunkFunction :: SELF

Type of this instance, automatically specialized in every class
redef fun body_to_c(v: VISITOR)

nitc $ ThunkFunction :: body_to_c

Generate the code for the body without return statement at the end and

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 _mmethoddef: MMethodDef

nitc :: AbstractRuntimeFunction :: _mmethoddef

The associated Nit method
private var _polymorph_call_flag: Bool

nitc :: ThunkFunction :: _polymorph_call_flag

Determines if the callsite should be polymorphic or static.
protected fun body_to_c(v: VISITOR)

nitc :: AbstractRuntimeFunction :: body_to_c

Generate the code for the body without return statement at the end and
protected abstract fun build_c_name: String

nitc :: AbstractRuntimeFunction :: build_c_name

Non cached version of c_name
protected fun build_frame(v: VISITOR, arguments: Array[RuntimeVariable]): StaticFrame

nitc :: AbstractRuntimeFunction :: build_frame

Builds the static frame for current runtime method
fun c_name: String

nitc :: AbstractRuntimeFunction :: c_name

The mangled c name of the runtime_function
protected fun c_name_cache: nullable String

nitc :: AbstractRuntimeFunction :: c_name_cache

fun c_name_cache=(c_name_cache: nullable String)

nitc :: AbstractRuntimeFunction :: c_name_cache=

abstract fun call(v: VISITOR, arguments: Array[RuntimeVariable]): nullable RuntimeVariable

nitc :: AbstractRuntimeFunction :: call

Implements a call of the runtime_function
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 compile_to_c(compiler: COMPILER)

nitc :: AbstractRuntimeFunction :: compile_to_c

Generate the code
protected abstract fun declare_signature(v: VISITOR, signature: String)

nitc :: AbstractRuntimeFunction :: declare_signature

How the concrete compiler will declare the method, e.g inside a global header file,
protected fun end_compile_to_c(v: VISITOR)

nitc :: AbstractRuntimeFunction :: end_compile_to_c

Hook called at the end of compile_to_c function. This function
private fun fill_parameters(v: VISITOR)

nitc :: AbstractRuntimeFunction :: fill_parameters

Fills the argument array inside v.frame.arguments, calling resolve_ith_parameter
fun get_class: CLASS

core :: Object :: get_class

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

nitc :: AbstractRuntimeFunction :: has_return

Returns true if the associated mmethoddef's return type isn't null,
fun hash: Int

core :: Object :: hash

The hash code of the object.
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 mmethoddef: MMethodDef

nitc :: AbstractRuntimeFunction :: mmethoddef

The associated Nit method
protected fun mmethoddef=(mmethoddef: MMethodDef)

nitc :: AbstractRuntimeFunction :: mmethoddef=

The associated Nit method
fun msignature: MSignature

nitc :: AbstractRuntimeFunction :: msignature

The current msignature to use when compiling : signature_to_c and body_to_c.
private intern fun native_class_name: CString

core :: Object :: native_class_name

The class name of the object in CString format.
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 polymorph_call_flag: Bool

nitc :: ThunkFunction :: polymorph_call_flag

Determines if the callsite should be polymorphic or static.
fun polymorph_call_flag=(polymorph_call_flag: Bool)

nitc :: ThunkFunction :: polymorph_call_flag=

Determines if the callsite should be polymorphic or static.
protected fun recv_mtype: MType

nitc :: AbstractRuntimeFunction :: recv_mtype

The current receiver type to compile : signature_to_c and body_to_c.
protected fun resolve_ith_parameter(v: VISITOR, i: Int): RuntimeVariable

nitc :: AbstractRuntimeFunction :: resolve_ith_parameter

Step 4 : Creates RuntimeVariable for each method argument.
protected fun resolve_receiver(v: VISITOR): RuntimeVariable

nitc :: AbstractRuntimeFunction :: resolve_receiver

Prepare the self runtime variable to be used by the rest of
protected fun resolve_return_mtype(v: VISITOR)

nitc :: AbstractRuntimeFunction :: resolve_return_mtype

Step 3 : Returns the return type used by the runtime function.
protected fun return_mtype: nullable MType

nitc :: AbstractRuntimeFunction :: return_mtype

protected fun return_mtype=(return_mtype: nullable MType)

nitc :: AbstractRuntimeFunction :: return_mtype=

fun serialization_hash: Int

core :: Object :: serialization_hash

Hash value use for serialization
protected fun signature_to_c(v: VISITOR): String

nitc :: AbstractRuntimeFunction :: signature_to_c

Generate the code for the signature with an open curly brace
intern fun sys: Sys

core :: Object :: sys

Return the global sys object, the only instance of the Sys class.
abstract fun target_recv: MType

nitc :: ThunkFunction :: target_recv

The type expected by the callee. Used to resolve mmethoddef's formal
abstract fun to_jvalue(env: JniEnv): JValue

core :: Object :: to_jvalue

fun to_s: String

core :: Object :: to_s

User readable representation of self.
package_diagram nitc::ThunkFunction ThunkFunction nitc::AbstractRuntimeFunction AbstractRuntimeFunction nitc::ThunkFunction->nitc::AbstractRuntimeFunction core::Object Object nitc::AbstractRuntimeFunction->core::Object ...core::Object ... ...core::Object->core::Object nitc::SeparateThunkFunction SeparateThunkFunction nitc::SeparateThunkFunction->nitc::ThunkFunction nitc::CustomizedThunkFunction CustomizedThunkFunction nitc::CustomizedThunkFunction->nitc::ThunkFunction

Ancestors

interface Object

core :: Object

The root of the class hierarchy.

Parents

abstract class AbstractRuntimeFunction

nitc :: AbstractRuntimeFunction

A C function associated to a Nit method

Children

class CustomizedThunkFunction

nitc :: CustomizedThunkFunction

Thunk implementation for global compiler.

Class definitions

nitc $ ThunkFunction
# Base class for all thunk-like function. A thunk is a function whose purpose
# is to call another function. Like a class wrapper or decorator, a thunk is used
# to computer things (conversions, log, etc) before or after a function call. It's
# an intermediary between the caller and the callee.
#
# The most basic use of a thunk is to unbox its argument before invoking the real callee.
# Virtual functions are a use case of thunk function:
#
# ~~~~nitish
# redef class Object
#       fun toto(x: Int): Int do return 1 + x
# end
# redef class Int
#       redef fun toto(x) do return x + self
# end
#
# ```generated C code
# long Object__toto(val* self, long x) { return 1 + x }
# long Int__toto(long self, long x) { return x + self }
# long THUNK_Int__toto(val* self, long x) {
#       long self2 = (long)(self)>>2    // Unboxing from Object to Int
#       return Int_toto(self2, x)
# }
#
# ```
# ~~~~
#
# A thunk has its OWN SIGNATURE and is considered like any other `AbstractRuntimeFunction`.
# Thus, one might need to be careful when overriding parent's method. Since most usage of
# thunks in Nit is to unbox and box things between a caller and a callee, the default
# implementation is doing just that. In other words, a thunk takes a signature and a method
# and tries to cast its signature to the underlying method's signature.
#
# A virtual function has the same signature as its `mmethoddef` field, except for
# its receiver is of type `Object`.
# In the same vibe, a call reference has all of its argument boxed as `Object`.
abstract class ThunkFunction
	super AbstractRuntimeFunction

	# Determines if the callsite should be polymorphic or static.
	var polymorph_call_flag = false is writable

	# The type expected by the callee. Used to resolve `mmethoddef`'s formal
	# parameters and virtual type. This type must NOT need anchor.
	fun target_recv: MType is abstract

	redef fun body_to_c(v)
	do
		assert not target_recv.need_anchor
		var frame = v.frame
		assert frame != null
		var selfvar = frame.selfvar
		var arguments = frame.arguments
		var arguments2 = new Array[RuntimeVariable]
		arguments2.push(v.autobox(selfvar, target_recv))
		var resolved_sig = msignature.resolve_for(target_recv, target_recv.as(MClassType), v.mmodule, true)
		for i in [0..resolved_sig.arity[ do
		var param = resolved_sig.mparameters[i]
			var mtype = param.mtype
			if param.is_vararg then
				mtype = v.mmodule.array_type(mtype)
			end
			var temp = v.autobox(arguments[i+1], mtype)
			arguments2.push(temp)
		end
		v.add("/* {mmethoddef}, {recv_mtype.ctype} */")
		var subret: nullable RuntimeVariable = null
		if polymorph_call_flag then
			subret = v.send(mmethoddef.mproperty, arguments2)
		else
			subret = v.call(mmethoddef, arguments2[0].mcasttype.as(MClassType), arguments2)
		end
		if has_return then
			assert subret != null
			var subret2 = v.autobox(subret, return_mtype.as(not null))
			v.assign(frame.returnvar.as(not null), subret2)
		end

	end

end
src/compiler/abstract_compiler.nit:2267,1--2347,3