code.putln("/* Implementation of %s */" % env.qualified_name)
self.generate_const_definitions(env, code)
self.generate_interned_num_decls(env, code)
+ self.generate_interned_string_decls(env, code)
self.generate_py_string_decls(env, code)
self.generate_cached_builtins_decls(env, code)
self.body.generate_function_definitions(env, code, options.transforms)
entries = env.all_pystring_entries
if entries:
code.putln("")
- for entry in entries:
- if entry.is_interned:
- code.putln('static char %s[] = "%s";' % (
- entry.cname, entry.init))
- code.putln("")
code.putln(
"static __Pyx_StringTabEntry %s[] = {" %
Naming.stringtab_cname)
code.putln("/*--- Intern cleanup code ---*/")
for entry in env.pynum_entries:
code.put_var_decref_clear(entry)
- if env.intern_map:
- for name, cname in env.intern_map.items():
- code.put_decref_clear(cname, PyrexTypes.py_object_type)
+ if env.all_pystring_entries:
+ for entry in env.all_pystring_entries:
+ if entry.is_interned:
+ code.put_decref_clear(
+ entry.pystring_cname, PyrexTypes.py_object_type)
code.putln("Py_INCREF(Py_None); return Py_None;")
code.putln('}')
for entry in env.const_entries:
if not entry.is_interned:
code.put_var_declaration(entry, static = 1)
-
+
+ def generate_interned_string_decls(self, env, code):
+ entries = env.global_scope().new_interned_string_entries
+ if entries:
+ code.putln("")
+ for entry in entries:
+ code.put_var_declaration(entry, static = 1)
+ for entry in entries:
+ code.putln(
+ "static PyObject *%s;" % entry.pystring_cname)
+ del entries[:]
+
def generate_py_string_decls(self, env, code):
entries = env.pystring_entries
if entries:
for entry in entries:
code.putln(
"static PyObject *%s;" % entry.pystring_cname)
-
+
def generate_interned_num_decls(self, env, code):
# Flush accumulated interned nums from the global scope
# and generate declarations for them.
# if we supported them, which we probably won't.
# ----- Top-level constants used by this function
self.generate_interned_num_decls(lenv, code)
+ self.generate_interned_string_decls(lenv, code)
self.generate_py_string_decls(lenv, code)
self.generate_cached_builtins_decls(lenv, code)
#code.putln("")
# a string literal, and add it to the list of Python strings to
# be created at module init time. If the string resembles a
# Python identifier, it will be interned.
- if not entry.pystring_cname:
- value = entry.init
- if possible_identifier(value):
- entry.is_interned = 1
- entry.pystring_cname = entry.cname + "p"
- self.pystring_entries.append(entry)
- self.global_scope().all_pystring_entries.append(entry)
+ if entry.pystring_cname:
+ return
+ value = entry.init
+ entry.pystring_cname = entry.cname + "p"
+ self.pystring_entries.append(entry)
+ self.global_scope().all_pystring_entries.append(entry)
+ if possible_identifier(value):
+ entry.is_interned = 1
+ self.global_scope().new_interned_string_entries.append(entry)
def add_py_num(self, value):
# Add an entry for an int constant.
# type_names {string : 1} Set of type names (used during parsing)
# pxd_file_loaded boolean Corresponding .pxd file has been processed
# cimported_modules [ModuleScope] Modules imported with cimport
- # intern_map {string : string} Mapping from Python names to interned strs
+ # new_interned_string_entries [Entry] New interned strings waiting to be declared
# interned_nums [int/long] Interned numeric constants
# all_pystring_entries [Entry] Python string consts from all scopes
# types_imported {PyrexType : 1} Set of types for which import code generated
self.type_names = dict(outer_scope.type_names)
self.pxd_file_loaded = 0
self.cimported_modules = []
- self.intern_map = {}
+ self.new_interned_string_entries = []
self.interned_nums = []
self.interned_objs = []
self.all_pystring_entries = []
return entry
def intern(self, name):
- string_entry = self.add_string_const(name)
+ string_entry = self.get_string_const(name)
self.add_py_string(string_entry)
return string_entry.pystring_cname