+
+ # 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
+
+redef class MType
+ # Are values of `self` tagged?
+ # If false, it means that the type is not primitive, or is boxed.
+ var is_tagged = false
+
+ # The tag value of the type
+ #
+ # ENSURE `is_tagged == (tag_value > 0)`
+ # ENSURE `not is_tagged == (tag_value == 0)`
+ var tag_value = 0