Commit 514a3cd2 authored by Stefan Behnel's avatar Stefan Behnel

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

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