1.1 --- a/docs/structures.txt Sat Feb 07 22:04:24 2009 +0100
1.2 +++ b/docs/structures.txt Sun Feb 08 23:48:47 2009 +0100
1.3 @@ -198,9 +198,9 @@
1.4
1.5 If C has a __call__ attribute, the invocation "slot" of C instances would
1.6 refer to the same thing as C.__call__. This "slot" has to be prepared when
1.7 -creating instances, potentially using a template instance or by modifying the
1.8 -sequence of instructions used in, amongst other places, the instantiator
1.9 -function.
1.10 +creating instances, either by modifying the sequence of instructions used in,
1.11 +amongst other places, the instantiator function, or by generating a template
1.12 +instance whose details are copied when new instances are created.
1.13
1.14 For functions, the same general layout applies:
1.15
2.1 --- a/micropython/__init__.py Sat Feb 07 22:04:24 2009 +0100
2.2 +++ b/micropython/__init__.py Sun Feb 08 23:48:47 2009 +0100
2.3 @@ -208,8 +208,20 @@
2.4
2.5 # Other multi-location objects.
2.6
2.7 - elif isinstance(item, (micropython.data.Class, micropython.data.Const,
2.8 - micropython.data.Function, micropython.data.Module)):
2.9 + elif isinstance(item, (
2.10 + micropython.data.Class, micropython.data.Const,
2.11 + micropython.data.Function, micropython.data.Module
2.12 + )):
2.13 +
2.14 + if isinstance(item, micropython.data.Class):
2.15 +
2.16 + # Append a template of an instance for use when
2.17 + # instantiating classes.
2.18 +
2.19 + item.instance_template_location = pos
2.20 + pos += 1
2.21 +
2.22 + # Record the location of the object.
2.23
2.24 item.location = pos
2.25 pos += 1
2.26 @@ -253,6 +265,31 @@
2.27 # Using classcode, attrcode, codeaddr, codedetails, instance.
2.28
2.29 elif isinstance(item, micropython.data.Class):
2.30 + assert item.instance_template_location == len(self.raw_code)
2.31 +
2.32 + classcode = objtable.as_list().get_code(item.full_name())
2.33 + attrcode = objtable.get_index(item.full_name())
2.34 +
2.35 + # Append a template of an instance for use when
2.36 + # instantiating classes.
2.37 +
2.38 + call_method = item.get("__call__")
2.39 + call_method_code_location = call_method and call_method.value.code_location
2.40 +
2.41 + self.raw_code.append(
2.42 + DataObject(
2.43 + classcode,
2.44 + attrcode,
2.45 + call_method_code_location,
2.46 + (
2.47 + call_method and len(call_method.value.positional_names),
2.48 + call_method and len(call_method.value.defaults)
2.49 + ),
2.50 + 1,
2.51 + item.full_name()
2.52 + )
2.53 + )
2.54 +
2.55 assert item.location == len(self.raw_code)
2.56
2.57 # NOTE: The instantiator code is the first block of the class.
2.58 @@ -262,8 +299,8 @@
2.59 # NOTE: Need initialiser details!
2.60 self.raw_code.append(
2.61 DataObject(
2.62 - objtable.as_list().get_code(item.full_name()),
2.63 - objtable.get_index(item.full_name()),
2.64 + classcode,
2.65 + attrcode,
2.66 instantiator_code_location,
2.67 (
2.68 len(item.get_instantiator().positional_names),
3.1 --- a/micropython/ast.py Sat Feb 07 22:04:24 2009 +0100
3.2 +++ b/micropython/ast.py Sun Feb 08 23:48:47 2009 +0100
3.3 @@ -197,9 +197,10 @@
3.4 Request a new object with the given class 'cls' and with 'n' attributes.
3.5 """
3.6
3.7 + # Load the class in order to locate the instance template.
3.8 +
3.9 self.new_op(LoadConst(cls))
3.10
3.11 - # NOTE: Provide __call__ details, if any.
3.12 # NOTE: Object headers are one location.
3.13
3.14 self.new_op(MakeObject(n + 1))
4.1 --- a/micropython/data.py Sat Feb 07 22:04:24 2009 +0100
4.2 +++ b/micropython/data.py Sun Feb 08 23:48:47 2009 +0100
4.3 @@ -402,6 +402,7 @@
4.4 self.location = None
4.5 self.code_location = None
4.6 self.instantiator = None
4.7 + self.instance_template_location = None # for creating instances at run-time
4.8
4.9 # Program-related details.
4.10
4.11 @@ -450,6 +451,8 @@
4.12 self.finalise_instance_attributes()
4.13 self.finalised = 1
4.14
4.15 + # Convenience methods for accessing functions and methods.
4.16 +
4.17 def get_instantiator(self):
4.18
4.19 "Return a function which can be used to instantiate the class."
5.1 --- a/rsvp.py Sat Feb 07 22:04:24 2009 +0100
5.2 +++ b/rsvp.py Sun Feb 08 23:48:47 2009 +0100
5.3 @@ -117,7 +117,7 @@
5.4 # Native class constants.
5.5
5.6 cls = objlist.access("__builtins__", "int")
5.7 - self.int_class = cls and cls.value.location
5.8 + self.int_instance_location = cls and cls.value.instance_template_location
5.9
5.10 # Debugging methods.
5.11
5.12 @@ -329,18 +329,21 @@
5.13 def MakeObject(self):
5.14 size = self.operand
5.15 context, ref = self.value
5.16 - addr = self._MakeObject(size, ref)
5.17 - # Introduce null context for new object.
5.18 + # NOTE: Referencing the instance template.
5.19 + addr = self._MakeObject(size, ref - 1)
5.20 + # Introduce object as context for the new object.
5.21 self.value = None, addr
5.22
5.23 def LoadAttr(self):
5.24 context, ref = self.value
5.25 # Retrieved context should already be appropriate for the instance.
5.26 + # NOTE: Adding 1 to skip any header.
5.27 self.value = self.load(ref + self.operand + 1)
5.28
5.29 def StoreAttr(self):
5.30 context, ref = self.value
5.31 # Target should already be an instance.
5.32 + # NOTE: Adding 1 to skip any header.
5.33 self.save(ref + self.operand + 1, self.source)
5.34
5.35 def LoadAttrIndex(self):
5.36 @@ -392,10 +395,11 @@
5.37 self.frame_stack[frame + self.operand] = self.value
5.38
5.39 def StoreFrameIndex(self):
5.40 + context, ref = self.value
5.41 frame = self.invocation_sp_stack[-1] # different from the current frame after MakeFrame
5.42 data = self.load(ref)
5.43 element = self.objlist[data.classcode + self.operand]
5.44 - attr_index, offset = element
5.45 + attr_index, class_attr, replace_context, offset = element
5.46 if attr_index == self.operand:
5.47 self.frame_stack[frame + offset] = self.value
5.48 else:
5.49 @@ -434,8 +438,8 @@
5.50 operand -= 1
5.51
5.52 nargs, ndefaults = data.codedetails
5.53 - if not (nargs - ndefaults <= operand <= nargs):
5.54 - raise Exception, "CheckFrame %r" % (nargs - ndefaults, self.operand, nargs)
5.55 + if not ((nargs - ndefaults) <= operand <= nargs):
5.56 + raise Exception, "CheckFrame %r (%r <= %r <= %r)" % (self.operand, nargs - ndefaults, operand, nargs)
5.57
5.58 # NOTE: Support population of defaults.
5.59
5.60 @@ -535,7 +539,7 @@
5.61 data = self.load(ref)
5.62 addr = self.new(size)
5.63 # Set the header to resemble the class.
5.64 - self.save(addr, DataObject(data.classcode, data.attrcode, None, None, 1, data.name)) # NOTE: __call__ method not yet provided.
5.65 + self.save(addr, data)
5.66 return addr
5.67
5.68 # Native function implementations.
5.69 @@ -567,7 +571,7 @@
5.70
5.71 # Make a new object.
5.72
5.73 - addr = self._MakeObject(2, self.int_class)
5.74 + addr = self._MakeObject(2, self.int_instance_location)
5.75 self.save(addr + 1, self.load(left_data) + self.load(right_data))
5.76
5.77 # Return the new object (with a null context).