1.1 --- a/bytecode.py Thu Nov 11 16:48:41 2004 +0100
1.2 +++ b/bytecode.py Thu Nov 11 16:49:35 2004 +0100
1.3 @@ -399,6 +399,10 @@
1.4 self.output.append(opmap["UNARY_NEGATIVE"])
1.5 self.position += 1
1.6
1.7 + def slice_1(self):
1.8 + self.output.append(opmap["SLICE+1"])
1.9 + self.position += 1
1.10 +
1.11 def compare_op(self, op):
1.12 self.output.append(opmap["COMPARE_OP"])
1.13 self.position += 1
1.14 @@ -1266,48 +1270,75 @@
1.15 # Get the number of parameters from the descriptor.
1.16 count = len(target.get_descriptor()[0])
1.17
1.18 - # Check for the method name and invoke superclasses where appropriate.
1.19 - # NOTE: This may not be a sufficient test.
1.20 - if str(self.method.get_python_name()) == str(target_name):
1.21 - program.build_tuple(count + 1) # Stack: tuple
1.22 - # Must use the actual class.
1.23 - # NOTE: Verify this.
1.24 - program.load_global(str(self.class_file.this_class.get_python_name()))
1.25 - # Stack: tuple, classref
1.26 - program.load_attr("__bases__") # Stack: tuple, bases
1.27 - program.dup_top() # Stack: tuple, bases, bases
1.28 - program.load_global("len") # Stack: tuple, bases, bases, len
1.29 - program.rot_two() # Stack: tuple, bases, len, bases
1.30 - program.call_function(1) # Stack: tuple, bases, #bases
1.31 - program.load_const(0) # Stack: tuple, bases, #bases, 0
1.32 - program.compare_op("==") # Stack: tuple, bases, result
1.33 - program.jump_to_label(1, "next")
1.34 - program.pop_top() # Stack: tuple, bases
1.35 - program.load_const(0) # Stack: tuple, bases, 0
1.36 - program.binary_subscr() # Stack: tuple, bases[0]
1.37 + # The stack may contain one of the following patterns:
1.38 + # Stack: classref, arg1, arg2, ...
1.39 + # Stack: objectref, arg1, arg2, ...
1.40 + # method == __init__, classref -> classref(arg1, arg2, ...)
1.41 + # method == __init__, objectref == self -> cls.bases[0].__init__(objectref, arg1, arg2, ...)
1.42 + # method == __init__, objectref != self -> should not occur
1.43 + # method != __init__, classref -> classref.method(classref, arg1, arg2, ...)
1.44 + # method != __init__, objectref == self -> cls.bases[0].method(objectref, arg1, arg2, ...)
1.45 + # method != __init__, objectref != self -> should not occur
1.46 +
1.47 + # First, we build a tuple of the reference and arguments.
1.48 + program.build_tuple(count + 1) # Stack: tuple
1.49 +
1.50 + # Then, we test the nature of the reference.
1.51 + program.dup_top() # Stack: tuple, tuple
1.52 + program.load_const(0) # Stack: tuple, tuple, 0
1.53 + program.binary_subscr() # Stack: tuple, reference
1.54 + program.dup_top() # Stack: tuple, reference, reference
1.55 +
1.56 + # Is it self?
1.57 + program.load_fast(0) # Stack: tuple, reference, reference, self
1.58 + program.compare_op("is") # Stack: tuple, reference, result
1.59 + program.jump_to_label(1, "is-self")
1.60 + program.pop_top() # Stack: tuple, reference
1.61 +
1.62 + # Is another class or reference.
1.63 + # NOTE: Reference case not covered!
1.64 + if str(target_name) == "__init__":
1.65 + program.rot_two() # Stack: reference, tuple
1.66 + program.load_const(1) # Stack: reference, tuple, 1
1.67 + program.slice_1() # Stack: reference, tuple[1:]
1.68 + program.load_global("apply") # Stack: reference, tuple, apply
1.69 + program.rot_three() # Stack: apply, reference, tuple
1.70 + program.call_function(2)
1.71 + # NOTE: Combinations of new, dup tend to produce interfering extra
1.72 + # NOTE: class references.
1.73 + program.rot_two() # Stack: objectref, classref
1.74 + program.pop_top()
1.75 + program.jump_to_label(None, "done")
1.76 + else:
1.77 self._invoke(target_name, program)
1.78 - program.jump_to_label(None, "next2")
1.79 - program.start_label("next")
1.80 - program.pop_top() # Stack: tuple, bases
1.81 - program.pop_top() # Stack: tuple
1.82 - program.pop_top() # Stack:
1.83 - program.start_label("next2")
1.84 + program.jump_to_label(None, "done")
1.85
1.86 - # Initialisation outside an initialisation method.
1.87 - elif str(target_name) == "__init__":
1.88 - # NOTE: Due to changes with the new instruction's implementation, the
1.89 - # NOTE: stack differs from that stated: objectref, arg1, arg2, ...
1.90 - # Stack: classref, arg1, arg2, ...
1.91 - program.build_tuple(count) # Stack: classref, tuple
1.92 - # NOTE: Stack: objectref, tuple
1.93 - program.load_global("apply") # Stack: classref, tuple, apply
1.94 - program.rot_three() # Stack: apply, classref, tuple
1.95 - program.call_function(2)
1.96 + # Is self.
1.97 + program.start_label("is-self")
1.98 + program.pop_top() # Stack: tuple, reference
1.99 + program.pop_top() # Stack: tuple
1.100 + program.load_global(str(self.class_file.this_class.get_python_name()))
1.101 + # Stack: tuple, classref
1.102 + program.load_attr("__bases__") # Stack: tuple, bases
1.103 + program.dup_top() # Stack: tuple, bases, bases
1.104 + program.load_global("len") # Stack: tuple, bases, bases, len
1.105 + program.rot_two() # Stack: tuple, bases, len, bases
1.106 + program.call_function(1) # Stack: tuple, bases, #bases
1.107 + program.load_const(0) # Stack: tuple, bases, #bases, 0
1.108 + program.compare_op("==") # Stack: tuple, bases, result
1.109 + program.jump_to_label(1, "no-bases")
1.110 + program.pop_top() # Stack: tuple, bases
1.111 + program.load_const(0) # Stack: tuple, bases, 0
1.112 + program.binary_subscr() # Stack: tuple, bases[0]
1.113 + self._invoke(target_name, program)
1.114 + program.jump_to_label(None, "done")
1.115
1.116 - else:
1.117 - program.build_tuple(count) # Stack: objectref, tuple
1.118 - program.rot_two() # Stack: tuple, objectref
1.119 - self._invoke(target_name, program)
1.120 + # No bases found, do no invocation.
1.121 + program.start_label("no-bases")
1.122 + program.pop_top() # Stack: tuple, bases
1.123 + program.pop_top() # Stack: tuple
1.124 + program.pop_top() # Stack:
1.125 + program.start_label("done")
1.126
1.127 """
1.128 def invokespecial(self, arguments, program):