summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Behnel <stefan_ml@behnel.de>2018-12-12 20:25:00 +0100
committerStefan Behnel <stefan_ml@behnel.de>2018-12-12 20:25:00 +0100
commitca688476359325dfcf1ec6239f51b500842f8293 (patch)
tree5a07a52ed44709fc9430141c8cfdf8e08a16b0a8
parent62b6ba0ff7f706a32c6ca1316369010318c1278c (diff)
parentcfa02c2765cfd8bcd2bf2b449fed2ef4ac87419a (diff)
downloadcython-ca688476359325dfcf1ec6239f51b500842f8293.tar.gz
Merge branch '0.29.x'
-rw-r--r--Cython/Compiler/Code.py12
-rw-r--r--Cython/Compiler/ExprNodes.py32
2 files changed, 28 insertions, 16 deletions
diff --git a/Cython/Compiler/Code.py b/Cython/Compiler/Code.py
index e7ccdc5ae..098988a3c 100644
--- a/Cython/Compiler/Code.py
+++ b/Cython/Compiler/Code.py
@@ -1133,6 +1133,7 @@ class GlobalState(object):
self.num_const_index = {}
self.py_constants = []
self.cached_cmethods = {}
+ self.initialised_constants = set()
writer.set_global_state(self)
self.rootwriter = writer
@@ -1242,7 +1243,12 @@ class GlobalState(object):
# constant handling at code generation time
- def get_cached_constants_writer(self):
+ def get_cached_constants_writer(self, target=None):
+ if target is not None:
+ if target in self.initialised_constants:
+ # Return None on second/later calls to prevent duplicate creation code.
+ return None
+ self.initialised_constants.add(target)
return self.parts['cached_constants']
def get_int_const(self, str_value, longness=False):
@@ -1816,8 +1822,8 @@ class CCodeWriter(object):
def intern_identifier(self, text):
return self.get_py_string_const(text, identifier=True)
- def get_cached_constants_writer(self):
- return self.globalstate.get_cached_constants_writer()
+ def get_cached_constants_writer(self, target=None):
+ return self.globalstate.get_cached_constants_writer(target)
# code generation
diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py
index 65d903019..71aa853fd 100644
--- a/Cython/Compiler/ExprNodes.py
+++ b/Cython/Compiler/ExprNodes.py
@@ -1621,15 +1621,17 @@ class UnicodeNode(ConstNode):
# decoded by the UTF-8 codec in Py3.3
self.result_code = code.get_py_const(py_object_type, 'ustring')
data_cname = code.get_pyunicode_ptr_const(self.value)
- code = code.get_cached_constants_writer()
- code.mark_pos(self.pos)
- code.putln(
+ const_code = code.get_cached_constants_writer(self.result_code)
+ if const_code is None:
+ return # already initialised
+ const_code.mark_pos(self.pos)
+ const_code.putln(
"%s = PyUnicode_FromUnicode(%s, (sizeof(%s) / sizeof(Py_UNICODE))-1); %s" % (
self.result_code,
data_cname,
data_cname,
code.error_goto_if_null(self.result_code, self.pos)))
- code.put_error_if_neg(
+ const_code.put_error_if_neg(
self.pos, "__Pyx_PyUnicode_READY(%s)" % self.result_code)
else:
self.result_code = code.get_py_string_const(self.value)
@@ -5253,7 +5255,9 @@ class SliceNode(ExprNode):
if self.is_literal:
dedup_key = make_dedup_key(self.type, (self,))
self.result_code = code.get_py_const(py_object_type, 'slice', cleanup_level=2, dedup_key=dedup_key)
- code = code.get_cached_constants_writer()
+ code = code.get_cached_constants_writer(self.result_code)
+ if code is None:
+ return # already initialised
code.mark_pos(self.pos)
code.putln(
@@ -7988,14 +7992,14 @@ class TupleNode(SequenceNode):
return
if self.is_literal or self.is_partly_literal:
- dedup_key = None
- if self.is_literal:
- dedup_key = make_dedup_key(self.type, self.args)
+ dedup_key = make_dedup_key(self.type, self.args) if self.is_literal else None
tuple_target = code.get_py_const(py_object_type, 'tuple', cleanup_level=2, dedup_key=dedup_key)
- const_code = code.get_cached_constants_writer()
- const_code.mark_pos(self.pos)
- self.generate_sequence_packing_code(const_code, tuple_target, plain=not self.is_literal)
- const_code.put_giveref(tuple_target)
+ const_code = code.get_cached_constants_writer(tuple_target)
+ if const_code is not None:
+ # constant is not yet initialised
+ const_code.mark_pos(self.pos)
+ self.generate_sequence_packing_code(const_code, tuple_target, plain=not self.is_literal)
+ const_code.put_giveref(tuple_target)
if self.is_literal:
self.result_code = tuple_target
else:
@@ -9511,7 +9515,9 @@ class CodeObjectNode(ExprNode):
if self.result_code is None:
self.result_code = code.get_py_const(py_object_type, 'codeobj', cleanup_level=2)
- code = code.get_cached_constants_writer()
+ code = code.get_cached_constants_writer(self.result_code)
+ if code is None:
+ return # already initialised
code.mark_pos(self.pos)
func = self.def_node
func_name = code.get_py_string_const(