Commit 3cae35ea authored by Vitja Makarov's avatar Vitja Makarov

Merge remote branch 'upstream/master'

parents 86d1bd4a 14f62011
...@@ -368,6 +368,11 @@ class ExprNode(Node): ...@@ -368,6 +368,11 @@ class ExprNode(Node):
else: else:
self.not_implemented("infer_type") self.not_implemented("infer_type")
def nonlocally_immutable(self):
# Returns whether this variable is a safe reference, i.e.
# can't be modified as part of globals or closures.
return self.is_temp
# --------------- Type Analysis ------------------ # --------------- Type Analysis ------------------
def analyse_as_module(self, env): def analyse_as_module(self, env):
...@@ -757,6 +762,9 @@ class ConstNode(AtomicExprNode): ...@@ -757,6 +762,9 @@ class ConstNode(AtomicExprNode):
def is_simple(self): def is_simple(self):
return 1 return 1
def nonlocally_immutable(self):
return 1
def may_be_none(self): def may_be_none(self):
return False return False
...@@ -1474,6 +1482,10 @@ class NameNode(AtomicExprNode): ...@@ -1474,6 +1482,10 @@ class NameNode(AtomicExprNode):
# If it's not a C variable, it'll be in a temp. # If it's not a C variable, it'll be in a temp.
return 1 return 1
def nonlocally_immutable(self):
entry = self.entry
return entry and (entry.is_local or entry.is_arg) and not entry.in_closure
def calculate_target_results(self, env): def calculate_target_results(self, env):
pass pass
...@@ -2997,7 +3009,7 @@ class SimpleCallNode(CallNode): ...@@ -2997,7 +3009,7 @@ class SimpleCallNode(CallNode):
if i == 0 and self.self is not None: if i == 0 and self.self is not None:
# a method's cloned "self" argument is ok # a method's cloned "self" argument is ok
pass pass
elif arg.is_name and arg.entry and arg.entry.is_local and not arg.entry.in_closure: elif arg.nonlocally_immutable():
# plain local variables are ok # plain local variables are ok
pass pass
else: else:
...@@ -4049,6 +4061,10 @@ class TupleNode(SequenceNode): ...@@ -4049,6 +4061,10 @@ class TupleNode(SequenceNode):
# either temp or constant => always simple # either temp or constant => always simple
return True return True
def nonlocally_immutable(self):
# either temp or constant => always safe
return True
def calculate_result_code(self): def calculate_result_code(self):
if len(self.args) > 0: if len(self.args) > 0:
return self.result_code return self.result_code
...@@ -5487,6 +5503,9 @@ class TypecastNode(ExprNode): ...@@ -5487,6 +5503,9 @@ class TypecastNode(ExprNode):
# either temp or a C cast => no side effects # either temp or a C cast => no side effects
return True return True
def nonlocally_immutable(self):
return self.operand.nonlocally_immutable()
def nogil_check(self, env): def nogil_check(self, env):
if self.type and self.type.is_pyobject and self.is_temp: if self.type and self.type.is_pyobject and self.is_temp:
self.gil_error() self.gil_error()
......
...@@ -1540,7 +1540,6 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -1540,7 +1540,6 @@ class FuncDefNode(StatNode, BlockNode):
def generate_arg_none_check(self, arg, code): def generate_arg_none_check(self, arg, code):
# Generate None check for one argument. # Generate None check for one argument.
code.globalstate.use_utility_code(arg_type_test_utility_code)
code.putln('if (unlikely(((PyObject *)%s) == Py_None)) {' % arg.entry.cname) code.putln('if (unlikely(((PyObject *)%s) == Py_None)) {' % arg.entry.cname)
code.putln('''PyErr_Format(PyExc_TypeError, "Argument '%s' must not be None"); %s''' % ( code.putln('''PyErr_Format(PyExc_TypeError, "Argument '%s' must not be None"); %s''' % (
arg.name, arg.name,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment