1.1 --- a/rsvplib.py Sat Apr 30 23:36:09 2011 +0200
1.2 +++ b/rsvplib.py Sun May 01 00:37:51 2011 +0200
1.3 @@ -44,29 +44,28 @@
1.4
1.5 # Native class constants.
1.6
1.7 - cls = self.machine._get_class("__builtins__", "int")
1.8 - self.int_class = cls.location
1.9 - self.int_instance = cls.instance_template_location
1.10 - cls = self.machine._get_class("__builtins__", "list")
1.11 - if cls is not None:
1.12 - self.list_class = cls.location
1.13 - self.list_instance = cls.instance_template_location
1.14 - cls = self.machine._get_class("__builtins__", "IndexError")
1.15 - if cls is not None:
1.16 - self.index_error = cls.location
1.17 - self.index_error_instance = cls.instance_template_location
1.18 - cls = self.machine._get_class("__builtins__", "basestring")
1.19 - if cls is not None:
1.20 - self.str_class = cls.location
1.21 - self.str_instance = cls.instance_template_location
1.22 + self.int_class, self.int_instance = self._get_builtin_class_and_template("int")
1.23 + self.list_class, self.list_instance = self._get_builtin_class_and_template("list")
1.24 + self.index_error, self.index_error_instance = self._get_builtin_class_and_template("IndexError")
1.25 + self.str_class, self.str_instance = self._get_builtin_class_and_template("basestring")
1.26 + self.accessor_class, self.accessor_instance = self._get_builtin_class_and_template("_accessor")
1.27
1.28 self.tuple_class = self.machine.tuple_class
1.29 self.tuple_instance = self.machine.tuple_instance
1.30 +
1.31 + self.attr_error_instance = self.machine.attr_error_instance
1.32 self.type_error_instance = self.machine.type_error_instance
1.33
1.34 self.frame_stack = self.machine.frame_stack
1.35 self.local_sp_stack = self.machine.local_sp_stack
1.36
1.37 + def _get_builtin_class_and_template(self, name):
1.38 + cls = self.machine._get_class("__builtins__", name)
1.39 + if cls is not None:
1.40 + return cls.location, cls.instance_template_location
1.41 + else:
1.42 + return None, None
1.43 +
1.44 def _check_index(self, pos, nelements):
1.45 return pos >= 0 and pos < nelements
1.46
1.47 @@ -468,6 +467,39 @@
1.48 def builtins_object_init(self):
1.49 pass
1.50
1.51 + def builtins_getattr(self):
1.52 + frame = self.local_sp_stack[-1]
1.53 +
1.54 + # Get the object, attribute name.
1.55 +
1.56 + obj_value = self.frame_stack[frame]
1.57 + name_value = self.frame_stack[frame + 1]
1.58 +
1.59 + if not self.machine._CheckInstance(name_value.ref, self.accessor_class):
1.60 + self.machine.exception = self.machine._MakeObject(self.instance_size, self.attr_error_instance)
1.61 + return self.machine.RaiseException()
1.62 +
1.63 + # Get the object table index from the name. It is a bare integer, not a reference.
1.64 +
1.65 + index = self.machine.load(name_value.ref + self.instance_data_offset + 1)
1.66 +
1.67 + # NOTE: This is very much like LoadAttrIndex.
1.68 +
1.69 + data = self.machine.load(obj_value.ref)
1.70 + element = self.machine.objlist[data.classcode + index]
1.71 +
1.72 + if element is not None:
1.73 + attr_index, static_attr, offset = element
1.74 + if attr_index == index:
1.75 + if static_attr:
1.76 + self.machine.result = self.machine.load(offset) # offset is address of class/module attribute
1.77 + else:
1.78 + self.machine.result = self.machine.load(obj_value.ref + offset)
1.79 + return
1.80 +
1.81 + self.machine.exception = self.machine._MakeObject(self.instance_size, self.attr_error_instance)
1.82 + return self.machine.RaiseException()
1.83 +
1.84 def builtins_isinstance(self):
1.85 frame = self.local_sp_stack[-1]
1.86
1.87 @@ -528,6 +560,10 @@
1.88 "__builtins__.object.__init__" : builtins_object_init, # NOTE: A no-operation.
1.89 "__builtins__.BaseException.__init__" : builtins_object_init, # NOTE: To be made distinct, potentially in the builtins module.
1.90
1.91 + # Native functions:
1.92 +
1.93 + "__builtins__._getattr" : builtins_getattr,
1.94 +
1.95 # Native instantiator helpers:
1.96
1.97 "__builtins__.list.__new__" : builtins_list_new,