# HG changeset patch # User Paul Boddie # Date 1234133327 -3600 # Node ID 0442304c5adacc0f04064dfc0708d62e529baaab # Parent 7d3226e3d4f7eaed91aba256dc040d8dd78eaeb1 Introduced instance templates to the generated raw image. Fixed StoreFrameIndex. diff -r 7d3226e3d4f7 -r 0442304c5ada docs/structures.txt --- a/docs/structures.txt Sat Feb 07 22:04:24 2009 +0100 +++ b/docs/structures.txt Sun Feb 08 23:48:47 2009 +0100 @@ -198,9 +198,9 @@ If C has a __call__ attribute, the invocation "slot" of C instances would refer to the same thing as C.__call__. This "slot" has to be prepared when -creating instances, potentially using a template instance or by modifying the -sequence of instructions used in, amongst other places, the instantiator -function. +creating instances, either by modifying the sequence of instructions used in, +amongst other places, the instantiator function, or by generating a template +instance whose details are copied when new instances are created. For functions, the same general layout applies: diff -r 7d3226e3d4f7 -r 0442304c5ada micropython/__init__.py --- a/micropython/__init__.py Sat Feb 07 22:04:24 2009 +0100 +++ b/micropython/__init__.py Sun Feb 08 23:48:47 2009 +0100 @@ -208,8 +208,20 @@ # Other multi-location objects. - elif isinstance(item, (micropython.data.Class, micropython.data.Const, - micropython.data.Function, micropython.data.Module)): + elif isinstance(item, ( + micropython.data.Class, micropython.data.Const, + micropython.data.Function, micropython.data.Module + )): + + if isinstance(item, micropython.data.Class): + + # Append a template of an instance for use when + # instantiating classes. + + item.instance_template_location = pos + pos += 1 + + # Record the location of the object. item.location = pos pos += 1 @@ -253,6 +265,31 @@ # Using classcode, attrcode, codeaddr, codedetails, instance. elif isinstance(item, micropython.data.Class): + assert item.instance_template_location == len(self.raw_code) + + classcode = objtable.as_list().get_code(item.full_name()) + attrcode = objtable.get_index(item.full_name()) + + # Append a template of an instance for use when + # instantiating classes. + + call_method = item.get("__call__") + call_method_code_location = call_method and call_method.value.code_location + + self.raw_code.append( + DataObject( + classcode, + attrcode, + call_method_code_location, + ( + call_method and len(call_method.value.positional_names), + call_method and len(call_method.value.defaults) + ), + 1, + item.full_name() + ) + ) + assert item.location == len(self.raw_code) # NOTE: The instantiator code is the first block of the class. @@ -262,8 +299,8 @@ # NOTE: Need initialiser details! self.raw_code.append( DataObject( - objtable.as_list().get_code(item.full_name()), - objtable.get_index(item.full_name()), + classcode, + attrcode, instantiator_code_location, ( len(item.get_instantiator().positional_names), diff -r 7d3226e3d4f7 -r 0442304c5ada micropython/ast.py --- a/micropython/ast.py Sat Feb 07 22:04:24 2009 +0100 +++ b/micropython/ast.py Sun Feb 08 23:48:47 2009 +0100 @@ -197,9 +197,10 @@ Request a new object with the given class 'cls' and with 'n' attributes. """ + # Load the class in order to locate the instance template. + self.new_op(LoadConst(cls)) - # NOTE: Provide __call__ details, if any. # NOTE: Object headers are one location. self.new_op(MakeObject(n + 1)) diff -r 7d3226e3d4f7 -r 0442304c5ada micropython/data.py --- a/micropython/data.py Sat Feb 07 22:04:24 2009 +0100 +++ b/micropython/data.py Sun Feb 08 23:48:47 2009 +0100 @@ -402,6 +402,7 @@ self.location = None self.code_location = None self.instantiator = None + self.instance_template_location = None # for creating instances at run-time # Program-related details. @@ -450,6 +451,8 @@ self.finalise_instance_attributes() self.finalised = 1 + # Convenience methods for accessing functions and methods. + def get_instantiator(self): "Return a function which can be used to instantiate the class." diff -r 7d3226e3d4f7 -r 0442304c5ada rsvp.py --- a/rsvp.py Sat Feb 07 22:04:24 2009 +0100 +++ b/rsvp.py Sun Feb 08 23:48:47 2009 +0100 @@ -117,7 +117,7 @@ # Native class constants. cls = objlist.access("__builtins__", "int") - self.int_class = cls and cls.value.location + self.int_instance_location = cls and cls.value.instance_template_location # Debugging methods. @@ -329,18 +329,21 @@ def MakeObject(self): size = self.operand context, ref = self.value - addr = self._MakeObject(size, ref) - # Introduce null context for new object. + # NOTE: Referencing the instance template. + addr = self._MakeObject(size, ref - 1) + # Introduce object as context for the new object. self.value = None, addr def LoadAttr(self): context, ref = self.value # Retrieved context should already be appropriate for the instance. + # NOTE: Adding 1 to skip any header. self.value = self.load(ref + self.operand + 1) def StoreAttr(self): context, ref = self.value # Target should already be an instance. + # NOTE: Adding 1 to skip any header. self.save(ref + self.operand + 1, self.source) def LoadAttrIndex(self): @@ -392,10 +395,11 @@ self.frame_stack[frame + self.operand] = self.value def StoreFrameIndex(self): + context, ref = self.value frame = self.invocation_sp_stack[-1] # different from the current frame after MakeFrame data = self.load(ref) element = self.objlist[data.classcode + self.operand] - attr_index, offset = element + attr_index, class_attr, replace_context, offset = element if attr_index == self.operand: self.frame_stack[frame + offset] = self.value else: @@ -434,8 +438,8 @@ operand -= 1 nargs, ndefaults = data.codedetails - if not (nargs - ndefaults <= operand <= nargs): - raise Exception, "CheckFrame %r" % (nargs - ndefaults, self.operand, nargs) + if not ((nargs - ndefaults) <= operand <= nargs): + raise Exception, "CheckFrame %r (%r <= %r <= %r)" % (self.operand, nargs - ndefaults, operand, nargs) # NOTE: Support population of defaults. @@ -535,7 +539,7 @@ data = self.load(ref) addr = self.new(size) # Set the header to resemble the class. - self.save(addr, DataObject(data.classcode, data.attrcode, None, None, 1, data.name)) # NOTE: __call__ method not yet provided. + self.save(addr, data) return addr # Native function implementations. @@ -567,7 +571,7 @@ # Make a new object. - addr = self._MakeObject(2, self.int_class) + addr = self._MakeObject(2, self.int_instance_location) self.save(addr + 1, self.load(left_data) + self.load(right_data)) # Return the new object (with a null context).