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):
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.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)
......@@ -1491,12 +1484,16 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
"static struct PyGetSetDef %s[] = {" %
env.getset_table_cname)
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(
'{(char *)"%s", %s, %s, %s, 0},' % (
entry.name,
entry.getter_cname or "0",
entry.setter_cname or "0",
entry.doc_cname or "0"))
doc_code))
code.putln(
"{0, 0, 0, 0, 0}")
code.putln(
......@@ -1719,7 +1716,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
def generate_pymoduledef_struct(self, env, code):
if env.doc:
doc = "__Pyx_DOCSTR(%s)" % env.doc_cname
doc = "__Pyx_DOCSTR(%s)" % code.get_string_const(env.doc)
else:
doc = "0"
code.putln("")
......@@ -1741,7 +1738,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
# Generate code to create the module object and
# install the builtins.
if env.doc:
doc = env.doc_cname
doc = "__Pyx_DOCSTR(%s)" % code.get_string_const(env.doc)
else:
doc = "0"
code.putln("#if PY_MAJOR_VERSION < 3")
......
......@@ -27,6 +27,7 @@ label_prefix = pyrex_prefix + "L"
pymethdef_prefix = pyrex_prefix + "mdef_"
methtab_prefix = pyrex_prefix + "methods_"
memtab_prefix = pyrex_prefix + "members_"
interned_str_prefix = pyrex_prefix + "n_"
interned_num_prefix = pyrex_prefix + "int_"
objstruct_prefix = pyrex_prefix + "obj_"
typeptr_prefix = pyrex_prefix + "ptype_"
......
This diff is collapsed.
......@@ -248,9 +248,6 @@ class Scope(object):
def __str__(self):
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):
return self.parent_scope
......@@ -521,98 +518,6 @@ class Scope(object):
if entry and entry.is_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):
# Allocate a temporary variable of the given type from the
# free list if available, otherwise create a new one.
......@@ -870,11 +775,6 @@ class ModuleScope(Scope):
entry.is_builtin = 1
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):
# Find a module in the import namespace, interpreting
# relative imports relative to this module's parent.
......@@ -1416,7 +1316,6 @@ class CClassScope(ClassScope):
# I keep it in for now. is_member should be enough
# later on
self.namespace_cname = "(PyObject *)%s" % self.parent_type.typeptr_cname
entry.interned_cname = self.intern_identifier(name)
return entry
......
......@@ -2,7 +2,12 @@ cdef int c1 = "t" # works
cdef int c2 = "te" # fails
cdef int cx = "test" # fails
cdef int x1 = "\xFF" # works
cdef int x2 = u"\xFF" # fails
_ERRORS = u"""
2:14: Only coerce single-character ascii strings can be used as ints.
3: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 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