+ redef fun unbox_extern(value, mtype)
+ do
+ if mtype isa MClassType and mtype.mclass.kind == extern_kind and
+ mtype.mclass.name != "NativeString" then
+ var pointer_type = compiler.mainmodule.pointer_type
+ var res = self.new_var_extern(mtype)
+ self.add "{res} = ((struct instance_{pointer_type.c_name}*){value})->value; /* unboxing {value.mtype} */"
+ return res
+ else
+ return value
+ end
+ end
+
+ redef fun box_extern(value, mtype)
+ do
+ if mtype isa MClassType and mtype.mclass.kind == extern_kind and
+ mtype.mclass.name != "NativeString" then
+ var valtype = compiler.mainmodule.pointer_type
+ var res = self.new_var(mtype)
+ compiler.undead_types.add(mtype)
+ self.require_declaration("BOX_{valtype.c_name}")
+ self.add("{res} = BOX_{valtype.c_name}({value}); /* boxing {value.mtype} */")
+ self.require_declaration("type_{mtype.c_name}")
+ self.add("{res}->type = &type_{mtype.c_name};")
+ self.require_declaration("class_{mtype.c_name}")
+ self.add("{res}->class = &class_{mtype.c_name};")
+ return res
+ else
+ return value
+ end
+ end
+
+ # Returns a C expression containing the tag of the value as a long.
+ #
+ # If the C expression is evaluated to 0, it means there is no tag.
+ # Thus the expression can be used as a condition.
+ fun extract_tag(value: RuntimeVariable): String
+ do
+ assert not value.mtype.is_c_primitive
+ return "((long){value}&3)" # Get the two low bits
+ end
+
+ # Returns a C expression of the runtime class structure of the value.
+ # The point of the method is to work also with primitive types.
+ fun class_info(value: RuntimeVariable): String
+ do
+ if not value.mtype.is_c_primitive then
+ if can_be_primitive(value) and not compiler.modelbuilder.toolcontext.opt_no_tag_primitives.value then
+ var tag = extract_tag(value)
+ return "({tag}?class_info[{tag}]:{value}->class)"
+ end
+ return "{value}->class"
+ else
+ compiler.undead_types.add(value.mtype)
+ self.require_declaration("class_{value.mtype.c_name}")
+ return "(&class_{value.mtype.c_name})"
+ end
+ end
+
+ # Returns a C expression of the runtime type structure of the value.
+ # The point of the method is to work also with primitive types.