1.1 --- a/micropython/trans.py Tue Nov 01 01:16:09 2011 +0100
1.2 +++ b/micropython/trans.py Thu Nov 17 01:49:57 2011 +0100
1.3 @@ -28,64 +28,6 @@
1.4
1.5 "Internal helper methods for AST visitors."
1.6
1.7 - # Allocation-related methods.
1.8 -
1.9 - def make_instance(self, cls, n):
1.10 -
1.11 - """
1.12 - Request a new instance using the given class 'cls' and with 'n'
1.13 - attributes.
1.14 - """
1.15 -
1.16 - # Load the class in order to locate the instance template.
1.17 -
1.18 - self.new_op(LoadConst(cls))
1.19 -
1.20 - # NOTE: Instance headers are one location.
1.21 -
1.22 - self.new_op(MakeInstance(n + 1))
1.23 -
1.24 - def make_exception(self, name):
1.25 -
1.26 - "Make an exception of the given 'name' using 'node'."
1.27 -
1.28 - # NOTE: Reserving an attribute.
1.29 -
1.30 - self.make_instance(self.get_builtin_class(name), 1)
1.31 -
1.32 - # Name-related methods.
1.33 -
1.34 - def get_scope(self, name):
1.35 -
1.36 - "Return the scope for the given 'name'."
1.37 -
1.38 - attr, scope, from_name = self.unit._get_with_scope(name)
1.39 - return scope
1.40 -
1.41 - def load_builtin(self, name, node):
1.42 -
1.43 - "Generate an instruction loading 'name' for the given 'node'."
1.44 -
1.45 - self.new_op(LoadAddress(self.get_builtin(name)))
1.46 -
1.47 - def get_builtin_class(self, name):
1.48 -
1.49 - "Return the built-in class with the given 'name'."
1.50 -
1.51 - return self.get_builtin(name).get_value()
1.52 -
1.53 - def get_builtin(self, name):
1.54 -
1.55 - "Return the built-in module definition for the given 'name'."
1.56 -
1.57 - if self.builtins is not None:
1.58 - try:
1.59 - return self.builtins[name]
1.60 - except KeyError:
1.61 - raise TranslateError("No __builtins__ definition is available for name %r." % name)
1.62 - else:
1.63 - raise TranslateError("No __builtins__ module is available for name %r." % name)
1.64 -
1.65 # Common methods.
1.66
1.67 def _generateGuards(self, node):
1.68 @@ -751,71 +693,37 @@
1.69 """
1.70 Generate code involved in a call to the given 'target' to test the
1.71 context provided by 'temp_context' against 'temp_first_argument', and to
1.72 - signal an exception (using 'node') if the context is incompatible with
1.73 - the first frame argument.
1.74 + signal an exception if the context is incompatible with the first frame
1.75 + argument.
1.76
1.77 In addition, the invocation frame will be shifted if 'temp_context'
1.78 indicates a function or a class.
1.79 -
1.80 - NOTE: This should probably be migrated to a native library.
1.81 """
1.82
1.83 - adjust_block = self.new_block()
1.84 - continue_block = self.new_block()
1.85 + # Need to store the explicit first argument in the working register for
1.86 + # the eventual test.
1.87 +
1.88 + if temp_first_argument is not None:
1.89 + self.new_op(temp_first_argument)
1.90 +
1.91 + # Put the context in the source register.
1.92 +
1.93 + if target is None or temp_first_argument is not None:
1.94 + if self.new_op(temp_context.copy()):
1.95 + self.last_op().target = "source"
1.96 + else:
1.97 + self.new_op(Transfer(source="working", target="source"))
1.98
1.99 # Add some preliminary tests where the target is not known.
1.100
1.101 if target is None:
1.102 -
1.103 - # Adjust the frame if a replaceable context is provided.
1.104 -
1.105 - self.new_op(temp_context)
1.106 - self.new_op(CheckContext(target="status"))
1.107 - self.new_op(JumpIfFalse(adjust_block, working="status"))
1.108 -
1.109 - # Skip adjustment and tests if the context is not a class.
1.110 - # Classes themselves employ a placeholder context so that
1.111 - # instantiators can be callable with a context which will be
1.112 - # overwritten in the frame.
1.113 -
1.114 - # Here, the working value should still refer to the context.
1.115 -
1.116 - self.new_op(CheckClass(target="status"))
1.117 - self.new_op(JumpIfFalse(continue_block, working="status"))
1.118 -
1.119 - # Test any explicit first argument against the context.
1.120 -
1.121 - if temp_first_argument is not None:
1.122 -
1.123 - # Check the current value (the argument) against the known context
1.124 - # (given as the source).
1.125 + if temp_first_argument is not None:
1.126 + self.new_op(JumpInFrameDirect(self.native.getCallFuncUnknownTargetTestableSelf()))
1.127 + else:
1.128 + self.new_op(JumpInFrameDirect(self.native.getCallFuncUnknownTarget()))
1.129
1.130 - if self.new_op(temp_context.copy()):
1.131 - self.last_op().target = "source"
1.132 - self.update_temp(temp_context, self.last_op())
1.133 -
1.134 - self.new_op(temp_first_argument)
1.135 - self.new_op(CheckInstance(source="source", target="status"))
1.136 -
1.137 - if target is None:
1.138 - self.new_op(JumpIfTrue(adjust_block, working="status"))
1.139 - else:
1.140 - self.new_op(JumpIfTrue(continue_block, working="status"))
1.141 -
1.142 - # Where the context is inappropriate, drop the incomplete frame and
1.143 - # raise an exception.
1.144 -
1.145 - self.new_op(DropFrame())
1.146 -
1.147 - self.make_exception("TypeError")
1.148 - self.set_target("exception")
1.149 - self.new_op(RaiseException())
1.150 -
1.151 - if target is None or temp_first_argument is not None:
1.152 - self.set_block(adjust_block)
1.153 - self.new_op(AdjustFrame(1))
1.154 -
1.155 - self.set_block(continue_block)
1.156 + elif temp_first_argument is not None:
1.157 + self.new_op(JumpInFrameDirect(self.native.getCallFuncKnownTargetTestableSelf()))
1.158
1.159 def _doCallFunc(self, temp_target, target=None):
1.160