+ # Compile structures used to map tagged primitive values to their classes and types.
+ # This method also determines which class will be tagged.
+ fun compile_class_infos
+ do
+ if modelbuilder.toolcontext.opt_no_tag_primitives.value then return
+
+ # Note: if you change the tagging scheme, do not forget to update
+ # `autobox` and `extract_tag`
+ var class_info = new Array[nullable MClass].filled_with(null, 4)
+ for t in box_kinds.keys do
+ # Note: a same class can be associated to multiple slots if one want to
+ # use some Huffman coding.
+ if t.name == "Int" then
+ class_info[1] = t
+ else if t.name == "Char" then
+ class_info[2] = t
+ else if t.name == "Bool" then
+ class_info[3] = t
+ else
+ continue
+ end
+ t.mclass_type.is_tagged = true
+ end
+
+ # Compile the table for classes. The tag is used as an index
+ var v = self.new_visitor
+ v.add_decl "const struct class *class_info[4] = \{"
+ for t in class_info do
+ if t == null then
+ v.add_decl("NULL,")
+ else
+ var s = "class_{t.c_name}"
+ v.require_declaration(s)
+ v.add_decl("&{s},")
+ end
+ end
+ v.add_decl("\};")
+
+ # Compile the table for types. The tag is used as an index
+ v.add_decl "const struct type *type_info[4] = \{"
+ for t in class_info do
+ if t == null then
+ v.add_decl("NULL,")
+ else
+ var s = "type_{t.c_name}"
+ undead_types.add(t.mclass_type)
+ v.require_declaration(s)
+ v.add_decl("&{s},")
+ end
+ end
+ v.add_decl("\};")
+ end
+