Commit bb4d9c2d authored by Stefan Behnel's avatar Stefan Behnel

replace the incorrect and leaky global c-tuple type cache by a per-module one

parent b9c47cfc
......@@ -6539,9 +6539,7 @@ class TupleNode(SequenceNode):
if any(type.is_pyobject or type.is_unspecified or type.is_fused for type in arg_types):
return tuple_type
else:
type = PyrexTypes.c_tuple_type(arg_types)
env.declare_tuple_type(self.pos, type)
return type
return env.declare_tuple_type(self.pos, arg_types).type
def analyse_types(self, env, skip_children=False):
if len(self.args) == 0:
......@@ -6552,8 +6550,7 @@ class TupleNode(SequenceNode):
if not skip_children:
self.args = [arg.analyse_types(env) for arg in self.args]
if not self.mult_factor and not any(arg.type.is_pyobject or arg.type.is_fused for arg in self.args):
self.type = PyrexTypes.c_tuple_type(arg.type for arg in self.args)
env.declare_tuple_type(self.pos, self.type)
self.type = env.declare_tuple_type(self.pos, (arg.type for arg in self.args)).type
self.is_temp = 1
return self
else:
......
......@@ -1180,10 +1180,9 @@ class CTupleBaseTypeNode(CBaseTypeNode):
error(c.pos, "Tuple types can't (yet) contain Python objects.")
return error_type
component_types.append(type)
type = PyrexTypes.c_tuple_type(component_types)
entry = env.declare_tuple_type(self.pos, type)
entry = env.declare_tuple_type(self.pos, component_types)
entry.used = True
return type
return entry.type
class FusedTypeNode(CBaseTypeNode):
......
......@@ -3684,13 +3684,11 @@ class CTupleType(CType):
env.use_utility_code(self._convert_from_py_code)
return True
c_tuple_types = {}
def c_tuple_type(components):
components = tuple(components)
tuple_type = c_tuple_types.get(components)
if tuple_type is None:
cname = Naming.ctuple_type_prefix + type_list_identifier(components)
tuple_type = c_tuple_types[components] = CTupleType(cname, components)
cname = Naming.ctuple_type_prefix + type_list_identifier(components)
tuple_type = CTupleType(cname, components)
return tuple_type
......
......@@ -610,8 +610,8 @@ class Scope(object):
self.sue_entries.append(entry)
return entry
def declare_tuple_type(self, pos, type):
return self.outer_scope.declare_tuple_type(pos, type)
def declare_tuple_type(self, pos, components):
return self.outer_scope.declare_tuple_type(pos, components)
def declare_var(self, name, type, pos,
cname = None, visibility = 'private',
......@@ -1056,6 +1056,7 @@ class ModuleScope(Scope):
self.cached_builtins = []
self.undeclared_cached_builtins = []
self.namespace_cname = self.module_cname
self._cached_tuple_types = {}
for var_name in ['__builtins__', '__name__', '__file__', '__doc__', '__path__']:
self.declare_var(EncodedString(var_name), py_object_type, None)
......@@ -1075,18 +1076,24 @@ class ModuleScope(Scope):
return self.outer_scope.lookup(name, language_level=language_level)
def declare_tuple_type(self, pos, type):
cname = type.cname
def declare_tuple_type(self, pos, components):
components = tuple(components)
try:
ttype = self._cached_tuple_types[components]
except KeyError:
ttype = self._cached_tuple_types[components] = PyrexTypes.c_tuple_type(components)
cname = ttype.cname
entry = self.lookup_here(cname)
if not entry:
scope = StructOrUnionScope(cname)
for ix, component in enumerate(type.components):
for ix, component in enumerate(components):
scope.declare_var(name="f%s" % ix, type=component, pos=pos)
struct_entry = self.declare_struct_or_union(cname + '_struct', 'struct', scope, typedef_flag=True, pos=pos, cname=cname)
struct_entry = self.declare_struct_or_union(
cname + '_struct', 'struct', scope, typedef_flag=True, pos=pos, cname=cname)
self.type_entries.remove(struct_entry)
type.struct_entry = struct_entry
entry = self.declare_type(cname, type, pos, cname)
type.entry = entry
ttype.struct_entry = struct_entry
entry = self.declare_type(cname, ttype, pos, cname)
ttype.entry = entry
return entry
def declare_builtin(self, name, pos):
......
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