Commit cfa02c27 authored by Stefan Behnel's avatar Stefan Behnel

Prevent repeated initialisation of constants that overwrite the previously...

Prevent repeated initialisation of constants that overwrite the previously created objects without cleanup.
Closes #2750.
parent 498c05f1
......@@ -1139,6 +1139,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
......@@ -1248,7 +1249,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):
......@@ -1822,8 +1828,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
......
......@@ -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(
......@@ -7985,14 +7989,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:
......@@ -9508,7 +9512,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(
......
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