class _ClassWithLayout(_Class): _immutable_fields_ = ["_layout_for_instances?"] def __init__(self, universe, number_of_fields=Object.NUMBER_OF_OBJECT_FIELDS, obj_class=None): _Class.__init__(self, universe, number_of_fields, obj_class) if number_of_fields >= 0: self._layout_for_instances = ObjectLayout(number_of_fields, self) else: self._layout_for_instances = None def set_instance_fields(self, value): assert isinstance(value, Array) self._instance_fields = value if (self._layout_for_instances is None or value.get_number_of_indexable_fields() != self._layout_for_instances.get_number_of_fields()): self._layout_for_instances = ObjectLayout( value.get_number_of_indexable_fields(), self) def get_layout_for_instances(self): return self._layout_for_instances def update_instance_layout_with_initialized_field(self, field_idx, spec_type): updated = self._layout_for_instances.with_initialized_field( field_idx, spec_type) if updated is not self._layout_for_instances: self._layout_for_instances = updated return self._layout_for_instances def update_instance_layout_with_generalized_field(self, field_idx): updated = self._layout_for_instances.with_generalized_field(field_idx) if updated is not self._layout_for_instances: self._layout_for_instances = updated return self._layout_for_instances
class Class(Object): _immutable_fields_ = ["_super_class" "_name", "_instance_fields" "_instance_invokables", "_invokables_table", "_universe", "_layout_for_instances?"] def __init__(self, universe, number_of_fields = -1, obj_class = None): Object.__init__(self, obj_class, number_of_fields) self._super_class = nilObject self._name = None self._instance_fields = None self._instance_invokables = None self._invokables_table = {} self._universe = universe if number_of_fields >= 0: self._layout_for_instances = ObjectLayout(number_of_fields, self) else: self._layout_for_instances = None def get_super_class(self): return self._super_class def set_super_class(self, value): self._super_class = value def has_super_class(self): return self._super_class is not nilObject def get_name(self): return self._name def set_name(self, value): self._name = value def get_instance_fields(self): return self._instance_fields def set_instance_fields(self, value): assert isinstance(value, Array) self._instance_fields = value if (self._layout_for_instances is None or value.get_number_of_indexable_fields() != self._layout_for_instances.get_number_of_fields()): self._layout_for_instances = ObjectLayout( value.get_number_of_indexable_fields(), self) def get_instance_invokables(self): return self._instance_invokables def set_instance_invokables(self, value): self._instance_invokables = value # Make sure this class is the holder of all invokables in the array for i in range(0, self.get_number_of_instance_invokables()): invokable = self.get_instance_invokable(i) assert invokable is not None invokable.set_holder(self) def get_number_of_instance_invokables(self): """ Return the number of instance invokables in this class """ return self.get_instance_invokables().get_number_of_indexable_fields() def get_instance_invokable(self, index): """ Get the instance invokable with the given index """ return self.get_instance_invokables().get_indexable_field(index) def set_instance_invokable(self, index, value): # Set this class as the holder of the given invokable value.set_holder(self) self.get_instance_invokables().set_indexable_field(index, value) @jit.elidable_promote("all") def lookup_invokable(self, signature): # Lookup invokable and return if found invokable = self._invokables_table.get(signature, None) if invokable: return invokable # Lookup invokable with given signature in array of instance invokables for i in range(0, self.get_number_of_instance_invokables()): invokable = self.get_instance_invokable(i) # Return the invokable if the signature matches if invokable.get_signature() == signature: self._invokables_table[signature] = invokable return invokable # Traverse the super class chain by calling lookup on the super class if self.has_super_class(): invokable = self.get_super_class().lookup_invokable(signature) if invokable: self._invokables_table[signature] = invokable return invokable # Invokable not found return None def lookup_field_index(self, field_name): # Lookup field with given name in array of instance fields i = self.get_number_of_instance_fields() - 1 while i >= 0: # Return the current index if the name matches if field_name == self.get_instance_field_name(i): return i i -= 1 # Field not found return -1 def add_instance_invokable(self, value): # Add the given invokable to the array of instance invokables for i in range(0, self.get_number_of_instance_invokables()): # Get the next invokable in the instance invokable array invokable = self.get_instance_invokable(i) # Replace the invokable with the given one if the signature matches if invokable.get_signature() == value.get_signature(): self.set_instance_invokable(i, value) return False # Append the given method to the array of instance methods self.set_instance_invokables(self.get_instance_invokables().copy_and_extend_with(value)) return True def add_instance_primitive(self, value, display_warning): if self.add_instance_invokable(value) and display_warning: from som.vm.universe import std_print, std_println std_print("Warning: Primitive " + value.get_signature().get_string()) std_println(" is not in class definition for class " + self.get_name().get_string()) def get_instance_field_name(self, index): return self.get_instance_fields().get_indexable_field(index) def get_number_of_instance_fields(self): # Get the total number of instance fields in this class return self.get_instance_fields().get_number_of_indexable_fields() @staticmethod def _includes_primitives(clazz): for i in range(0, clazz.get_number_of_instance_invokables()): # Get the next invokable in the instance invokable array if clazz.get_instance_invokable(i).is_primitive(): return True return False def has_primitives(self): return (self._includes_primitives(self) or self._includes_primitives(self._class)) def load_primitives(self, display_warning): from som.primitives.known import (primitives_for_class, PrimitivesNotFound) try: prim_class = primitives_for_class(self) prim_class(self._universe, display_warning).install_primitives_in(self) except PrimitivesNotFound: if display_warning: from som.vm.universe import error_println error_println("Loading of primitives failed for %s. Currently, " "we support primitives only for known classes" % self.get_name()) def __str__(self): return "Class(" + self.get_name().get_string() + ")" def get_layout_for_instances(self): return self._layout_for_instances def update_instance_layout_with_initialized_field(self, field_idx, spec_type): updated = self._layout_for_instances.with_initialized_field(field_idx, spec_type) if updated is not self._layout_for_instances: self._layout_for_instances = updated return self._layout_for_instances def update_instance_layout_with_generalized_field(self, field_idx): updated = self._layout_for_instances.with_generalized_field(field_idx) if updated is not self._layout_for_instances: self._layout_for_instances = updated return self._layout_for_instances
class Class(Object): _immutable_fields_ = [ "_super_class" "_name", "_instance_fields" "_instance_invokables", "_invokables_table", "_universe", "_layout_for_instances?" ] def __init__(self, universe, number_of_fields=-1, obj_class=None): Object.__init__(self, obj_class, number_of_fields) self._super_class = nilObject self._name = None self._instance_fields = None self._instance_invokables = None self._invokables_table = {} self._universe = universe if number_of_fields >= 0: self._layout_for_instances = ObjectLayout(number_of_fields, self) else: self._layout_for_instances = None def get_super_class(self): return self._super_class def set_super_class(self, value): self._super_class = value def has_super_class(self): return self._super_class is not nilObject def get_name(self): return self._name def set_name(self, value): self._name = value def get_instance_fields(self): return self._instance_fields def set_instance_fields(self, value): assert isinstance(value, Array) self._instance_fields = value if (self._layout_for_instances is None or value.get_number_of_indexable_fields() != self._layout_for_instances.get_number_of_fields()): self._layout_for_instances = ObjectLayout( value.get_number_of_indexable_fields(), self) def get_instance_invokables(self): return self._instance_invokables def set_instance_invokables(self, value): self._instance_invokables = value # Make sure this class is the holder of all invokables in the array for i in range(0, self.get_number_of_instance_invokables()): invokable = self.get_instance_invokable(i) assert invokable is not None invokable.set_holder(self) def get_number_of_instance_invokables(self): """ Return the number of instance invokables in this class """ return self.get_instance_invokables().get_number_of_indexable_fields() def get_instance_invokable(self, index): """ Get the instance invokable with the given index """ return self.get_instance_invokables().get_indexable_field(index) def set_instance_invokable(self, index, value): # Set this class as the holder of the given invokable value.set_holder(self) self.get_instance_invokables().set_indexable_field(index, value) @jit.elidable_promote("all") def lookup_invokable(self, signature): # Lookup invokable and return if found invokable = self._invokables_table.get(signature, None) if invokable: return invokable # Lookup invokable with given signature in array of instance invokables for i in range(0, self.get_number_of_instance_invokables()): invokable = self.get_instance_invokable(i) # Return the invokable if the signature matches if invokable.get_signature() == signature: self._invokables_table[signature] = invokable return invokable # Traverse the super class chain by calling lookup on the super class if self.has_super_class(): invokable = self.get_super_class().lookup_invokable(signature) if invokable: self._invokables_table[signature] = invokable return invokable # Invokable not found return None def lookup_field_index(self, field_name): # Lookup field with given name in array of instance fields i = self.get_number_of_instance_fields() - 1 while i >= 0: # Return the current index if the name matches if field_name == self.get_instance_field_name(i): return i i -= 1 # Field not found return -1 def add_instance_invokable(self, value): # Add the given invokable to the array of instance invokables for i in range(0, self.get_number_of_instance_invokables()): # Get the next invokable in the instance invokable array invokable = self.get_instance_invokable(i) # Replace the invokable with the given one if the signature matches if invokable.get_signature() == value.get_signature(): self.set_instance_invokable(i, value) return False # Append the given method to the array of instance methods self.set_instance_invokables( self.get_instance_invokables().copy_and_extend_with(value)) return True def add_instance_primitive(self, value, display_warning): if self.add_instance_invokable(value) and display_warning: from som.vm.universe import std_print, std_println std_print("Warning: Primitive " + value.get_signature().get_string()) std_println(" is not in class definition for class " + self.get_name().get_string()) def get_instance_field_name(self, index): return self.get_instance_fields().get_indexable_field(index) def get_number_of_instance_fields(self): # Get the total number of instance fields in this class return self.get_instance_fields().get_number_of_indexable_fields() @staticmethod def _includes_primitives(clazz): for i in range(0, clazz.get_number_of_instance_invokables()): # Get the next invokable in the instance invokable array if clazz.get_instance_invokable(i).is_primitive(): return True return False def has_primitives(self): return (self._includes_primitives(self) or self._includes_primitives(self._class)) def load_primitives(self, display_warning): from som.primitives.known import (primitives_for_class, PrimitivesNotFound) try: prim_class = primitives_for_class(self) prim_class(self._universe, display_warning).install_primitives_in(self) except PrimitivesNotFound: if display_warning: from som.vm.universe import error_println error_println( "Loading of primitives failed for %s. Currently, " "we support primitives only for known classes" % self.get_name()) def __str__(self): return "Class(" + self.get_name().get_string() + ")" def get_layout_for_instances(self): return self._layout_for_instances def update_instance_layout_with_initialized_field(self, field_idx, spec_type): updated = self._layout_for_instances.with_initialized_field( field_idx, spec_type) if updated is not self._layout_for_instances: self._layout_for_instances = updated return self._layout_for_instances def update_instance_layout_with_generalized_field(self, field_idx): updated = self._layout_for_instances.with_generalized_field(field_idx) if updated is not self._layout_for_instances: self._layout_for_instances = updated return self._layout_for_instances