# the LHS of an assignment or argument of a del
# statement. Similar responsibilities to analyse_types.
#
- # allocate_temps
- # - Call allocate_temps for all sub-nodes.
- # - Call allocate_temp for this node.
- # - If a temporary was allocated, call release_temp on
- # all sub-expressions.
- #
- # allocate_target_temps
- # - Call allocate_temps on sub-nodes and allocate any other
- # temps used during assignment.
- # - Fill in result_code with a C lvalue if needed.
- # - If a rhs node is supplied, call release_temp on it.
- # - Call release_temp on sub-nodes and release any other
- # temps used during assignment.
- #
# target_code
# Called by the default implementation of allocate_target_temps.
# Should return a C lvalue for assigning to the node. The default
# checks whether it is a legal const expression,
# and determines its value.
self.analyse_types(env)
- self.allocate_temps(env)
self.check_const()
def analyse_expressions(self, env):
# Analysis and Temp Allocation phases for a whole
# expression.
self.analyse_types(env)
- self.allocate_temps(env)
def analyse_target_expression(self, env, rhs):
# Convenience routine performing both the Type
# Analysis and Temp Allocation phases for the LHS of
# an assignment.
self.analyse_target_types(env)
- self.allocate_target_temps(env, rhs)
def analyse_boolean_expression(self, env):
# Analyse expression and coerce to a boolean.
self.analyse_types(env)
bool = self.coerce_to_boolean(env)
- bool.allocate_temps(env)
return bool
def analyse_temp_boolean_expression(self, env):
self.analyse_types(env)
bool = self.coerce_to_boolean(env)
temp_bool = bool.coerce_to_temp(env)
- temp_bool.allocate_temps(env)
return temp_bool
# --------------- Type Analysis ------------------
# a subnode.
return self.is_temp
- def allocate_target_temps(self, env, rhs):
- self.allocate_subexpr_temps(env)
- self.is_target = True
- if rhs:
- rhs.release_temp(env)
- self.release_subexpr_temps(env)
-
- def allocate_temps(self, env, result = None):
- assert result is None, "deprecated, contact dagss if this triggers"
- self.allocate_subexpr_temps(env)
- if self.is_temp:
- self.release_subexpr_temps(env)
-
- def allocate_temps(self, env, result = None):
- # Allocate temporary variables for this node and
- # all its sub-expressions. If a result is specified,
- # this must be a temp node and the specified variable
- # is used as the result instead of allocating a new
- # one.
- assert result is None, "deprecated, contact dagss if this triggers"
- if debug_temp_alloc:
- print("%s Allocating temps" % self)
- self.allocate_subexpr_temps(env)
- self.allocate_temp(env, result)
- if self.is_temp:
- self.release_subexpr_temps(env)
-
- def allocate_subexpr_temps(self, env):
- # Allocate temporary variables for all sub-expressions
- # of this node.
- if debug_temp_alloc:
- print("%s Allocating temps for: %s" % (self, self.subexprs))
- for node in self.subexpr_nodes():
- if node:
- if debug_temp_alloc:
- print("%s Allocating temps for %s" % (self, node))
- node.allocate_temps(env)
-
- def allocate_temp(self, env, result = None):
- assert result is None
-
def target_code(self):
# Return code fragment for use as LHS of a C assignment.
return self.calculate_result_code()
# # Release temporaries used by LHS of an assignment.
# self.release_subexpr_temps(env)
-
- def release_temp(self, env):
- if self.is_temp:
- pass
- else:
- self.release_subexpr_temps(env)
-
- def release_subexpr_temps(self, env):
- # Release the results of all sub-expressions of
- # this node.
- for node in self.subexpr_nodes():
- if node:
- node.release_temp(env)
-
def allocate_temp_result(self, code):
if self.temp_code:
raise RuntimeError("Temp allocated multiple times")
self.type = py_object_type
env.use_utility_code(unpacking_utility_code)
- def allocate_target_temps(self, env, rhs):
- self.iterator.allocate_temps(env)
- for arg, node in zip(self.args, self.coerced_unpacked_items):
- node.allocate_temps(env)
- arg.allocate_target_temps(env, None)
- #arg.release_target_temp(env)
- #node.release_temp(env)
- if rhs:
- rhs.release_temp(env)
- self.iterator.release_temp(env)
- for node in self.coerced_unpacked_items:
- node.release_temp(env)
-
-# def release_target_temp(self, env):
-# #for arg in self.args:
-# # arg.release_target_temp(env)
-# #for node in self.coerced_unpacked_items:
-# # node.release_temp(env)
-# self.iterator.release_temp(env)
-
def generate_result_code(self, code):
self.generate_operation_code(code)
self.type = self.target.type
self.append.target = self # this is a CloneNode used in the PyList_Append in the inner loop
self.loop.analyse_declarations(env)
-
- def allocate_temps(self, env, result = None):
- if debug_temp_alloc:
- print("%s Allocating temps" % self)
- self.allocate_temp(env, result)
- # call loop.analyse_expressions() now to make sure temps get
- # allocated at the right time
self.loop.analyse_expressions(env)
def calculate_result_code(self):
gil_message = "Truth-testing Python object"
-## def allocate_temps(self, env, result_code = None):
-## # We don't need both operands at the same time, and
-## # one of the operands will also be our result. So we
-## # use an allocation strategy here which results in
-## # this node and both its operands sharing the same
-## # result variable. This allows us to avoid some
-## # assignments and increfs/decrefs that would otherwise
-## # be necessary.
-## self.allocate_temp(env, result_code)
-## self.operand1.allocate_temps(env, self.result())
-## self.operand2.allocate_temps(env, self.result())
-## # We haven't called release_temp on either operand,
-## # because although they are temp nodes, they don't own
-## # their result variable. And because they are temp
-## # nodes, any temps in their subnodes will have been
-## # released before their allocate_temps returned.
-## # Therefore, they contain no temp vars that need to
-## # be released.
-
def check_const(self):
self.operand1.check_const()
self.operand2.check_const()
if self.cascade:
self.cascade.coerce_chars_to_ints(env)
- def allocate_subexpr_temps(self, env):
- self.operand1.allocate_temps(env)
- self.operand2.allocate_temps(env)
- if self.cascade:
- self.cascade.allocate_subexpr_temps(env)
-
- def release_subexpr_temps(self, env):
- self.operand1.release_temp(env)
- self.operand2.release_temp(env)
- if self.cascade:
- self.cascade.release_subexpr_temps(env)
-
def check_const(self):
self.operand1.check_const()
self.operand2.check_const()
self.operand2 = self.operand2.coerce_to_simple(env)
self.cascade.coerce_cascaded_operands_to_temp(env)
- def allocate_subexpr_temps(self, env):
- self.operand2.allocate_temps(env)
- if self.cascade:
- self.cascade.allocate_subexpr_temps(env)
-
- def release_subexpr_temps(self, env):
- self.operand2.release_temp(env)
- if self.cascade:
- self.cascade.release_subexpr_temps(env)
-
def generate_evaluation_code(self, code, result, operand1):
if self.type.is_pyobject:
code.putln("if (__Pyx_PyObject_IsTrue(%s)) {" % result)
def generate_disposal_code(self, code):
pass
- def allocate_temps(self, env):
- pass
-
- def release_temp(self, env):
- pass
-
def free_temps(self, code):
pass
if arg.is_generic:
arg.default.analyse_types(env)
arg.default = arg.default.coerce_to(arg.type, genv)
- arg.default.allocate_temps(genv)
else:
error(arg.pos,
"This argument cannot have a default value")
cenv = self.scope
self.body.analyse_expressions(cenv)
self.target.analyse_target_expression(env, self.classobj)
- self.dict.release_temp(env)
- #self.classobj.release_temp(env)
- #self.target.release_target_temp(env)
def generate_function_definitions(self, env, code):
self.body.generate_function_definitions(self.scope, code)
def analyse_expressions(self, env):
self.expr.analyse_expressions(env)
- self.expr.release_temp(env)
def generate_execution_code(self, code):
self.expr.generate_evaluation_code(code)
def analyse_expressions(self, env):
self.analyse_types(env)
- self.allocate_rhs_temps(env)
- self.allocate_lhs_temps(env)
# def analyse_expressions(self, env):
# self.analyse_expressions_1(env)
if use_temp:
self.rhs = self.rhs.coerce_to_temp(env)
- def allocate_rhs_temps(self, env):
- self.rhs.allocate_temps(env)
-
- def allocate_lhs_temps(self, env):
- self.lhs.allocate_target_temps(env, self.rhs)
- #self.lhs.release_target_temp(env)
- #self.rhs.release_temp(env)
-
def generate_rhs_evaluation_code(self, code):
self.rhs.generate_evaluation_code(code)
rhs = rhs.coerce_to(lhs.type, env)
self.coerced_rhs_list.append(rhs)
- def allocate_rhs_temps(self, env):
- self.rhs.allocate_temps(env)
-
- def allocate_lhs_temps(self, env):
- for lhs, rhs in zip(self.lhs_list, self.coerced_rhs_list):
- rhs.allocate_temps(env)
- lhs.allocate_target_temps(env, rhs)
- #lhs.release_target_temp(env)
- #rhs.release_temp(env)
- self.rhs.release_temp(env)
-
def generate_rhs_evaluation_code(self, code):
self.rhs.generate_evaluation_code(code)
def analyse_expressions(self, env):
for stat in self.stats:
stat.analyse_types(env, use_temp = 1)
- stat.allocate_rhs_temps(env)
- for stat in self.stats:
- stat.allocate_lhs_temps(env)
# def analyse_expressions(self, env):
# for stat in self.stats:
self.lhs.analyse_target_types(env)
if Options.incref_local_binop and self.dup.type.is_pyobject:
self.dup = self.dup.coerce_to_temp(env)
-
- def allocate_rhs_temps(self, env):
import ExprNodes
if self.lhs.type.is_pyobject:
self.rhs = self.rhs.coerce_to_pyobject(env)
if self.lhs.type.is_pyobject:
self.result_value_temp = ExprNodes.PyTempNode(self.pos, env)
self.result_value = self.result_value_temp.coerce_to(self.lhs.type, env)
- self.result_value.allocate_temps(env)
-# if use_temp:
-# self.rhs = self.rhs.coerce_to_temp(env)
- self.rhs.allocate_temps(env)
- self.dup.allocate_subexpr_temps(env)
- self.dup.allocate_temp(env)
-
- def allocate_lhs_temps(self, env):
- self.lhs.allocate_target_temps(env, self.rhs)
-# self.lhs.release_target_temp(env)
- self.dup.release_temp(env)
- if self.dup.is_temp:
- self.dup.release_subexpr_temps(env)
-# self.rhs.release_temp(env)
- if self.lhs.type.is_pyobject:
- self.result_value.release_temp(env)
-
+
def generate_execution_code(self, code):
import ExprNodes
self.rhs.generate_evaluation_code(code)
def analyse_expressions(self, env):
self.arg_tuple.analyse_expressions(env)
self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
- self.arg_tuple.release_temp(env)
env.use_utility_code(printing_utility_code)
if len(self.arg_tuple.args) == 1 and self.append_newline:
env.use_utility_code(printing_one_utility_code)
for i, arg in enumerate(self.args):
arg.analyse_expressions(env)
arg = arg.coerce_to_pyobject(env)
- arg.release_temp(env)
self.args[i] = arg
self.temp_result = env.allocate_temp_pyobject()
env.release_temp(self.temp_result)
"Return with value in void function")
else:
self.value = self.value.coerce_to(env.return_type, env)
- self.value.allocate_temps(env)
- self.value.release_temp(env)
else:
if (not return_type.is_void
and not return_type.is_pyobject
if self.exc_type:
self.exc_type.analyse_types(env)
self.exc_type = self.exc_type.coerce_to_pyobject(env)
- self.exc_type.allocate_temps(env)
if self.exc_value:
self.exc_value.analyse_types(env)
self.exc_value = self.exc_value.coerce_to_pyobject(env)
- self.exc_value.allocate_temps(env)
if self.exc_tb:
self.exc_tb.analyse_types(env)
self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
- self.exc_tb.allocate_temps(env)
- if self.exc_type:
- self.exc_type.release_temp(env)
- if self.exc_value:
- self.exc_value.release_temp(env)
- if self.exc_tb:
- self.exc_tb.release_temp(env)
env.use_utility_code(raise_utility_code)
env.use_utility_code(restore_exception_utility_code)
if self.value:
self.value.analyse_types(env)
self.value = self.value.coerce_to_pyobject(env)
- self.value.allocate_temps(env)
- self.cond.release_temp(env)
- if self.value:
- self.value.release_temp(env)
- #env.recycle_pending_temps() # TEMPORARY
gil_check = StatNode._gil_check
gil_message = "Raising exception"
def analyse_expressions(self, env):
self.condition = \
self.condition.analyse_temp_boolean_expression(env)
- self.condition.release_temp(env)
self.body.analyse_expressions(env)
def generate_execution_code(self, code, end_label):
def analyse_expressions(self, env):
self.condition = \
self.condition.analyse_temp_boolean_expression(env)
- self.condition.release_temp(env)
- #env.recycle_pending_temps() # TEMPORARY
self.body.analyse_expressions(env)
if self.else_clause:
self.else_clause.analyse_expressions(env)
self.iterator.analyse_expressions(env)
self.item = ExprNodes.NextNode(self.iterator, env)
self.item = self.item.coerce_to(self.target.type, env)
- self.item.allocate_temps(env)
- self.target.allocate_target_temps(env, self.item)
- #self.item.release_temp(env)
- #self.target.release_target_temp(env)
self.body.analyse_expressions(env)
if self.else_clause:
self.else_clause.analyse_expressions(env)
- self.iterator.release_temp(env)
def generate_execution_code(self, code):
old_loop_labels = code.new_loop_labels()
else:
self.is_py_target = True
c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
- c_loopvar_node.allocate_temps(env)
self.loopvar_node = c_loopvar_node
self.py_loopvar_node = \
ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
- self.bound1.allocate_temps(env)
- self.bound2.allocate_temps(env)
- if self.step is not None:
- self.step.allocate_temps(env)
- if self.is_py_target:
- self.py_loopvar_node.allocate_temps(env)
- self.target.allocate_target_temps(env, self.py_loopvar_node)
- #self.target.release_target_temp(env)
- #self.py_loopvar_node.release_temp(env)
self.body.analyse_expressions(env)
- if self.is_py_target:
- c_loopvar_node.release_temp(env)
if self.else_clause:
self.else_clause.analyse_expressions(env)
- self.bound1.release_temp(env)
- self.bound2.release_temp(env)
- if self.step is not None:
- self.step.release_temp(env)
def generate_execution_code(self, code):
old_loop_labels = code.new_loop_labels()
if self.step is not None:
self.step.generate_disposal_code(code)
self.step.free_temps(code)
- if from_range:
- code.funcstate.release_temp(loopvar_name)
relation_table = {
# {relop : (initial offset, increment op)}
self.pattern.analyse_expressions(env)
self.pattern = self.pattern.coerce_to_pyobject(env)
self.match_flag = env.allocate_temp(PyrexTypes.c_int_type)
- self.pattern.release_temp(env)
env.release_temp(self.match_flag)
if self.target or self.excinfo_target:
if self.target:
self.exc_value = ExprNodes.ExcValueNode(self.pos, env, self.exc_vars[1])
- self.exc_value.allocate_temps(env)
self.target.analyse_target_expression(env, self.exc_value)
if self.excinfo_target is not None:
import ExprNodes
ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[2])
])
self.excinfo_tuple.analyse_expressions(env)
- self.excinfo_tuple.allocate_temps(env)
self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
self.body.analyse_expressions(env)
import ExprNodes
self.module.analyse_expressions(env)
self.item = ExprNodes.PyTempNode(self.pos, env)
- self.item.allocate_temp(env)
self.interned_items = []
for name, target in self.items:
if name == '*':
coerced_item = self.item.coerce_to(target.type, env)
self.interned_items.append(
(name, target, coerced_item))
- #target.release_target_temp(env) # was release_temp ?!?
- self.module.release_temp(env)
- self.item.release_temp(env)
def generate_execution_code(self, code):
self.module.generate_evaluation_code(code)