Commit 5530fe1d authored by Stefan Behnel's avatar Stefan Behnel

almost complete refactoring of constant allocation to move it into the code generation phase

parent 86bb8a8f
This diff is collapsed.
This diff is collapsed.
...@@ -550,13 +550,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -550,13 +550,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln('static const char * %s= %s;' % (Naming.cfilenm_cname, Naming.file_c_macro)) code.putln('static const char * %s= %s;' % (Naming.cfilenm_cname, Naming.file_c_macro))
code.putln('static const char *%s;' % Naming.filename_cname) code.putln('static const char *%s;' % Naming.filename_cname)
code.putln('static const char **%s;' % Naming.filetable_cname) code.putln('static const char **%s;' % Naming.filetable_cname)
if env.doc:
docstr = env.doc
if not isinstance(docstr, str):
docstr = docstr.utf8encode()
code.putln('')
code.putln('static char %s[] = "%s";' % (
env.doc_cname, escape_byte_string(docstr)))
env.use_utility_code(streq_utility_code) env.use_utility_code(streq_utility_code)
...@@ -1491,12 +1484,16 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1491,12 +1484,16 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
"static struct PyGetSetDef %s[] = {" % "static struct PyGetSetDef %s[] = {" %
env.getset_table_cname) env.getset_table_cname)
for entry in env.property_entries: for entry in env.property_entries:
if entry.doc:
doc_code = "__Pyx_DOCSTR(%s)" % code.get_string_const(entry.doc)
else:
doc_code = "0"
code.putln( code.putln(
'{(char *)"%s", %s, %s, %s, 0},' % ( '{(char *)"%s", %s, %s, %s, 0},' % (
entry.name, entry.name,
entry.getter_cname or "0", entry.getter_cname or "0",
entry.setter_cname or "0", entry.setter_cname or "0",
entry.doc_cname or "0")) doc_code))
code.putln( code.putln(
"{0, 0, 0, 0, 0}") "{0, 0, 0, 0, 0}")
code.putln( code.putln(
...@@ -1719,7 +1716,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1719,7 +1716,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
def generate_pymoduledef_struct(self, env, code): def generate_pymoduledef_struct(self, env, code):
if env.doc: if env.doc:
doc = "__Pyx_DOCSTR(%s)" % env.doc_cname doc = "__Pyx_DOCSTR(%s)" % code.get_string_const(env.doc)
else: else:
doc = "0" doc = "0"
code.putln("") code.putln("")
...@@ -1741,7 +1738,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1741,7 +1738,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
# Generate code to create the module object and # Generate code to create the module object and
# install the builtins. # install the builtins.
if env.doc: if env.doc:
doc = env.doc_cname doc = "__Pyx_DOCSTR(%s)" % code.get_string_const(env.doc)
else: else:
doc = "0" doc = "0"
code.putln("#if PY_MAJOR_VERSION < 3") code.putln("#if PY_MAJOR_VERSION < 3")
......
...@@ -27,6 +27,7 @@ label_prefix = pyrex_prefix + "L" ...@@ -27,6 +27,7 @@ label_prefix = pyrex_prefix + "L"
pymethdef_prefix = pyrex_prefix + "mdef_" pymethdef_prefix = pyrex_prefix + "mdef_"
methtab_prefix = pyrex_prefix + "methods_" methtab_prefix = pyrex_prefix + "methods_"
memtab_prefix = pyrex_prefix + "members_" memtab_prefix = pyrex_prefix + "members_"
interned_str_prefix = pyrex_prefix + "n_"
interned_num_prefix = pyrex_prefix + "int_" interned_num_prefix = pyrex_prefix + "int_"
objstruct_prefix = pyrex_prefix + "obj_" objstruct_prefix = pyrex_prefix + "obj_"
typeptr_prefix = pyrex_prefix + "ptype_" typeptr_prefix = pyrex_prefix + "ptype_"
......
This diff is collapsed.
...@@ -248,9 +248,6 @@ class Scope(object): ...@@ -248,9 +248,6 @@ class Scope(object):
def __str__(self): def __str__(self):
return "<%s %s>" % (self.__class__.__name__, self.qualified_name) return "<%s %s>" % (self.__class__.__name__, self.qualified_name)
def intern_identifier(self, name):
return self.global_scope().intern_identifier(name)
def qualifying_scope(self): def qualifying_scope(self):
return self.parent_scope return self.parent_scope
...@@ -521,98 +518,6 @@ class Scope(object): ...@@ -521,98 +518,6 @@ class Scope(object):
if entry and entry.is_type: if entry and entry.is_type:
return entry.type return entry.type
def add_string_const(self, value, identifier = False):
# Add an entry for a string constant.
if identifier:
cname = self.new_string_const_cname(value)
else:
cname = self.new_const_cname()
if value.is_unicode:
c_type = PyrexTypes.c_utf8_char_array_type
value = value.utf8encode()
else:
c_type = PyrexTypes.c_char_array_type
value = value.byteencode()
entry = Entry("", cname, c_type, init = value)
entry.used = 1
self.const_entries.append(entry)
return entry
def get_string_const(self, value, identifier = False):
# Get entry for string constant. Returns an existing
# one if possible, otherwise creates a new one.
genv = self.global_scope()
if identifier:
string_map = genv.identifier_to_entry
else:
string_map = genv.string_to_entry
entry = string_map.get(value)
if not entry:
entry = self.add_string_const(value, identifier)
entry.is_identifier = identifier
string_map[value] = entry
return entry
def add_py_string(self, entry, identifier = None):
# If not already done, allocate a C name for a Python version of
# 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 entry.pystring_cname:
return
value = entry.init
entry.pystring_cname = Naming.py_const_prefix + entry.cname[len(Naming.const_prefix):]
self.pystring_entries.append(entry)
self.global_scope().all_pystring_entries.append(entry)
if identifier or (identifier is None and 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.
cname = "%s%s" % (Naming.interned_num_prefix, value)
cname = cname.replace('-', 'neg_').replace('.','_')
entry = Entry("", cname, py_object_type, init = value)
entry.used = 1
entry.is_interned = 1
self.const_entries.append(entry)
self.interned_nums.append(entry)
return entry
def get_py_num(self, value, longness):
# Get entry for int constant. Returns an existing
# one if possible, otherwise creates a new one.
if longness or Utils.long_literal(value):
value += "L"
genv = self.global_scope()
entry = genv.num_to_entry.get(value)
if not entry:
entry = genv.add_py_num(value)
genv.num_to_entry[value] = entry
genv.pynum_entries.append(entry)
return entry
def get_py_obj(self, obj, c_prefix=''):
# Get entry for a generic constant. Returns an existing
# one if possible, otherwise creates a new one.
genv = self.global_scope()
entry = genv.obj_to_entry.get(obj)
if not entry:
entry = genv.add_py_num(obj, c_prefix)
genv.obj_to_entry[obj] = entry
return entry
def new_string_const_cname(self, value):
# Create a new globally-unique nice name for a string constant.
if len(value) < 20 and nice_identifier(value):
return "%s%s" % (Naming.const_prefix, value)
else:
return self.global_scope().new_const_cname()
def new_const_cname(self):
# Create a new globally-unique name for a constant.
return self.global_scope().new_const_cname()
def allocate_temp(self, type): def allocate_temp(self, type):
# Allocate a temporary variable of the given type from the # Allocate a temporary variable of the given type from the
# free list if available, otherwise create a new one. # free list if available, otherwise create a new one.
...@@ -870,11 +775,6 @@ class ModuleScope(Scope): ...@@ -870,11 +775,6 @@ class ModuleScope(Scope):
entry.is_builtin = 1 entry.is_builtin = 1
return entry return entry
def intern_identifier(self, name):
string_entry = self.get_string_const(name, identifier = True)
self.add_py_string(string_entry, identifier = 1)
return string_entry.pystring_cname
def find_module(self, module_name, pos): def find_module(self, module_name, pos):
# Find a module in the import namespace, interpreting # Find a module in the import namespace, interpreting
# relative imports relative to this module's parent. # relative imports relative to this module's parent.
...@@ -1416,7 +1316,6 @@ class CClassScope(ClassScope): ...@@ -1416,7 +1316,6 @@ class CClassScope(ClassScope):
# I keep it in for now. is_member should be enough # I keep it in for now. is_member should be enough
# later on # later on
self.namespace_cname = "(PyObject *)%s" % self.parent_type.typeptr_cname self.namespace_cname = "(PyObject *)%s" % self.parent_type.typeptr_cname
entry.interned_cname = self.intern_identifier(name)
return entry return entry
......
...@@ -2,7 +2,12 @@ cdef int c1 = "t" # works ...@@ -2,7 +2,12 @@ cdef int c1 = "t" # works
cdef int c2 = "te" # fails cdef int c2 = "te" # fails
cdef int cx = "test" # fails cdef int cx = "test" # fails
cdef int x1 = "\xFF" # works
cdef int x2 = u"\xFF" # fails
_ERRORS = u""" _ERRORS = u"""
2:14: Only coerce single-character ascii strings can be used as ints. 2:14: Only single-character byte strings can be coerced into ints.
3:14: Only coerce single-character ascii strings can be used as ints. 3:14: Only single-character byte strings can be coerced into ints.
6:14: Unicode objects do not support coercion to C types.
""" """
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