+
+ # Order superclasses of self
+ # Return the order of superclasses in runtime structures of this class
+ private fun superclasses_ordering(v: VirtualMachine): Array[MClass]
+ do
+ var superclasses = new Array[MClass]
+
+ # Add all superclasses of `self`
+ superclasses.add_all(self.in_hierarchy(v.mainmodule).greaters)
+
+ var res = new Array[MClass]
+ if superclasses.length > 1 then
+ # Starting at self
+ var ordering = self.dfs(v, res)
+
+ return ordering
+ else
+ # There is no super-class, self is Object
+ return superclasses
+ end
+ end
+
+ # A kind of Depth-First-Search for superclasses ordering
+ # *`v` : the current executed instance of VirtualMachine
+ # * `res` : Result Array, ie current superclasses ordering
+ private fun dfs(v: VirtualMachine, res: Array[MClass]): Array[MClass]
+ do
+ # Add this class at the beginning
+ res.insert(self, 0)
+
+ var direct_parents = self.in_hierarchy(v.mainmodule).direct_greaters.to_a
+
+ if direct_parents.length > 1 then
+ # Prefix represents the class which has the most properties
+ # we try to choose it in first to reduce the number of potential recompilations
+ var prefix = null
+ var max = -1
+ for cl in direct_parents do
+ # If we never have visited this class
+ if not res.has(cl) then
+ var properties_length = cl.mmethods.length + cl.mattributes.length
+ if properties_length > max then
+ max = properties_length
+ prefix = cl
+ end
+ end
+ end
+
+ if prefix != null then
+ # Add the prefix class ordering at the beginning of our sequence
+ var prefix_res = new Array[MClass]
+ prefix_res = prefix.dfs(v, prefix_res)
+
+ # Then we recurse on other classes
+ for cl in direct_parents do
+ if cl != prefix then
+ res = new Array[MClass]
+ res = cl.dfs(v, res)
+
+ for cl_res in res do
+ if not prefix_res.has(cl_res) then prefix_res.push(cl_res)
+ end
+ end
+ end
+ res = prefix_res
+ end
+
+ res.push(self)
+ else
+ if direct_parents.length > 0 then
+ res = direct_parents.first.dfs(v, res)
+ end
+ end
+
+ if not res.has(self) then res.push(self)
+
+ return res
+ end
+
+ # Update positions of the class `cl`
+ # * `attributes_offset`: absolute offset of introduced attributes
+ # * `methods_offset`: absolute offset of introduced methods
+ private fun update_positions(attributes_offsets: Int, methods_offset:Int, cl: MClass)
+ do
+ positions_attributes[cl] = attributes_offsets
+ positions_methods[cl] = methods_offset
+ end