Commit b7ffe116 authored by Dag Sverre Seljebotn's avatar Dag Sverre Seljebotn

Moved string and int init code generation to Code.py

parent 6b0b0fa6
......@@ -161,11 +161,23 @@ class GlobalState(object):
self.input_file_contents = {}
self.used_utility_code = set()
self.declared_cnames = {}
self.pystring_table_needed = False
def initwriters(self, rootwriter):
self.utilprotowriter = rootwriter.new_writer()
self.utildefwriter = rootwriter.new_writer()
self.decls_writer = rootwriter.new_writer()
self.pystring_table = rootwriter.new_writer()
self.initwriter = rootwriter.new_writer()
self.initwriter.enter_cfunc_scope()
self.initwriter.putln("").putln("static int __Pyx_InitGlobals(void) {")
(self.pystring_table
.putln("")
.putln("static __Pyx_StringTabEntry %s[] = {" %
Naming.stringtab_cname)
)
#
# Global constants, interned objects, etc.
......@@ -173,10 +185,41 @@ class GlobalState(object):
def insert_global_var_declarations_into(self, code):
code.insert(self.decls_writer)
def close_global_decls(self):
# This is called when it is known that no more global declarations will
# declared (but can be called before or after insert_XXX).
if self.pystring_table_needed:
self.pystring_table.putln("{0, 0, 0, 0, 0}").putln("};")
import Nodes
self.use_utility_code(Nodes.init_string_tab_utility_code)
self.initwriter.putln(
"if (__Pyx_InitStrings(%s) < 0) %s;" % (
Naming.stringtab_cname,
self.initwriter.error_goto(self.module_pos)))
(self.initwriter
.putln("return 0;")
.put_label(self.initwriter.error_label)
.putln("return -1;")
.putln("}")
)
self.initwriter.exit_cfunc_scope()
def insert_py_string_table_into(self, code):
if self.pystring_table_needed:
code.insert(self.pystring_table)
def insert_initglobals_into(self, code):
code.insert(self.initwriter)
def put_pyobject_decl(self, entry):
self.decls_writer.putln("static PyObject *%s;" % entry.cname)
# The functions below are there in a transition phase only
# and will be deprecated. They are called from Nodes.BlockNode.
# The copy&paste duplication is intentional in order to be able
# to see quickly how BlockNode worked, until this is replaced.
# to see quickly how BlockNode worked, until this is replaced.
def should_declare(self, cname, entry):
if cname in self.declared_cnames:
other = self.declared_cnames[cname]
......@@ -194,20 +237,33 @@ class GlobalState(object):
def add_interned_string_decl(self, entry):
if self.should_declare(entry.cname, entry):
self.decls_writer.put_var_declaration(entry, static = 1)
if self.should_declare(entry.pystring_cname, entry):
self.decls_writer.putln("static PyObject *%s;" % entry.pystring_cname)
self.add_py_string_decl(entry)
def add_py_string_decl(self, entry):
if self.should_declare(entry.pystring_cname, entry):
self.decls_writer.putln("static PyObject *%s;" % entry.pystring_cname)
self.pystring_table_needed = True
self.pystring_table.putln("{&%s, %s, sizeof(%s), %d, %d, %d}," % (
entry.pystring_cname,
entry.cname,
entry.cname,
entry.type.is_unicode,
entry.is_interned,
entry.is_identifier
))
def add_interned_num_decl(self, entry):
if self.should_declare(entry.cname, entry):
self.decls_writer.putln("static PyObject *%s;" % entry.cname)
self.initwriter.putln("%s = PyInt_FromLong(%s); %s;" % (
entry.cname,
entry.init,
self.initwriter.error_goto_if_null(entry.cname, self.module_pos))) # todo: fix pos
self.put_pyobject_decl(entry)
def add_cached_builtin_decl(self, entry):
if self.should_declare(entry.cname, entry):
self.decls_writer.putln("static PyObject *%s;" % entry.cname)
self.put_pyobject_decl(entry)
#
# File name state
......@@ -418,6 +474,7 @@ class CCodeWriter(object):
self.put(code)
self.write("\n");
self.bol = 1
return self
def emit_marker(self):
self.write("\n");
......@@ -425,6 +482,7 @@ class CCodeWriter(object):
self.write("/* %s */\n" % self.marker[1])
self.last_marker_line = self.marker[0]
self.marker = None
return self
def put(self, code):
dl = code.count("{") - code.count("}")
......@@ -440,20 +498,25 @@ class CCodeWriter(object):
self.level += dl
elif dl == 0 and code.startswith('}'):
self.level += 1
return self
def increase_indent(self):
self.level = self.level + 1
return self
def decrease_indent(self):
self.level = self.level - 1
return self
def begin_block(self):
self.putln("{")
self.increase_indent()
return self
def end_block(self):
self.decrease_indent()
self.putln("}")
return self
def indent(self):
self.write(" " * self.level)
......@@ -481,10 +544,12 @@ class CCodeWriter(object):
def put_label(self, lbl):
if lbl in self.funcstate.labels_used:
self.putln("%s:;" % lbl)
return self
def put_goto(self, lbl):
self.funcstate.use_label(lbl)
self.putln("goto %s;" % lbl)
return self
def put_var_declarations(self, entries, static = 0, dll_linkage = None,
definition = True):
......
......@@ -242,6 +242,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
h_code = code.insertion_point()
self.generate_module_preamble(env, modules, h_code)
code.globalstate.module_pos = self.pos
code.putln("")
code.putln("/* Implementation of %s */" % env.qualified_name)
self.generate_const_definitions(env, code)
......@@ -270,6 +272,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
self.generate_declarations_for_modules(env, modules, h_code)
h_code.write('\n')
code.globalstate.close_global_decls()
f = open_new_file(result.c_file)
code.copyto(f)
f.close()
......@@ -1450,27 +1454,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
"};")
def generate_py_string_table(self, env, code):
# raise Exception()
entries = env.all_pystring_entries
if entries:
code.putln("")
code.putln(
"static __Pyx_StringTabEntry %s[] = {" %
Naming.stringtab_cname)
for entry in entries:
code.putln(
"{&%s, %s, sizeof(%s), %d, %d, %d}," % (
entry.pystring_cname,
entry.cname,
entry.cname,
entry.type.is_unicode,
entry.is_interned,
entry.is_identifier
))
code.putln(
"{0, 0, 0, 0, 0}")
code.putln(
"};")
code.globalstate.insert_py_string_table_into(code)
def generate_filename_init_prototype(self, code):
code.putln("");
......@@ -1539,6 +1523,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.exit_cfunc_scope() # done with labels
def generate_module_init_func(self, imported_modules, env, code):
# Insert code stream of __Pyx_InitGlobals
code.globalstate.insert_initglobals_into(code)
code.enter_cfunc_scope()
code.putln("")
header2 = "PyMODINIT_FUNC init%s(void)" % env.module_name
......@@ -1558,15 +1545,12 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
env.generate_library_function_declarations(code)
self.generate_filename_init_call(code)
code.putln("/*--- Initialize various global constants etc. ---*/")
code.putln(code.error_goto_if_neg("__Pyx_InitGlobals()", self.pos))
code.putln("/*--- Module creation code ---*/")
self.generate_module_creation_code(env, code)
code.putln("/*--- Intern code ---*/")
self.generate_intern_code(env, code)
code.putln("/*--- String init code ---*/")
self.generate_string_init_code(env, code)
if Options.cache_builtins:
code.putln("/*--- Builtin init code ---*/")
self.generate_builtin_init_code(env, code)
......@@ -1726,21 +1710,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
"if (!%s) %s;" % (
Naming.preimport_cname,
code.error_goto(self.pos)));
def generate_intern_code(self, env, code):
for entry in env.pynum_entries:
code.putln("%s = PyInt_FromLong(%s); %s;" % (
entry.cname,
entry.init,
code.error_goto_if_null(entry.cname, self.pos)))
def generate_string_init_code(self, env, code):
if env.all_pystring_entries:
env.use_utility_code(Nodes.init_string_tab_utility_code)
code.putln(
"if (__Pyx_InitStrings(%s) < 0) %s;" % (
Naming.stringtab_cname,
code.error_goto(self.pos)))
def generate_builtin_init_code(self, env, code):
# Lookup and cache builtin objects.
......
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