Commit 0b29a562 authored by Dag Sverre Seljebotn's avatar Dag Sverre Seljebotn

Further code streams/code.globalstate/ModuleNode refactoring

parent 81f9a985
...@@ -34,22 +34,6 @@ class UtilityCode(object): ...@@ -34,22 +34,6 @@ class UtilityCode(object):
self._cache = {} self._cache = {}
self.specialize_list = [] self.specialize_list = []
def write_init_code(self, writer, pos):
if not self.init:
return
if isinstance(self.init, basestring):
writer.put(self.init)
else:
self.init(writer, pos)
def write_cleanup_code(self, writer, pos):
if not self.cleanup:
return
if isinstance(self.cleanup, basestring):
writer.put(self.cleanup)
else:
self.cleanup(writer, pos)
def specialize(self, pyrex_type=None, **data): def specialize(self, pyrex_type=None, **data):
# Dicts aren't hashable... # Dicts aren't hashable...
if pyrex_type is not None: if pyrex_type is not None:
...@@ -80,8 +64,19 @@ class UtilityCode(object): ...@@ -80,8 +64,19 @@ class UtilityCode(object):
output['utility_code_proto'].put(self.proto) output['utility_code_proto'].put(self.proto)
if self.impl: if self.impl:
output['utility_code_def'].put(self.impl) output['utility_code_def'].put(self.impl)
self.write_init_code(output.initwriter, output.module_pos) if self.init:
self.write_cleanup_code(output.cleanupwriter, output.module_pos) writer = output['init_globals']
if isinstance(self.init, basestring):
writer.put(self.init)
else:
self.init(writer, output.module_pos)
if self.cleanup and Options.generate_cleanup_code:
writer = output['cleanup_globals']
if isinstance(self.cleanup, basestring):
writer.put(self.cleanup)
else:
self.cleanup(writer, output.module_pos)
class FunctionState(object): class FunctionState(object):
...@@ -375,9 +370,7 @@ class GlobalState(object): ...@@ -375,9 +370,7 @@ class GlobalState(object):
# interned_strings # interned_strings
# consts # consts
# py_string_decls
# interned_nums # interned_nums
# cached_builtins
# directives set Temporary variable used to track # directives set Temporary variable used to track
# the current set of directives in the code generation # the current set of directives in the code generation
...@@ -395,6 +388,14 @@ class GlobalState(object): ...@@ -395,6 +388,14 @@ class GlobalState(object):
'global_var', 'global_var',
'decls', 'decls',
'all_the_rest', 'all_the_rest',
'pystring_table',
'cached_builtins',
'init_globals',
'init_module',
'cleanup_globals',
'cleanup_module',
'main_method',
'filename_table',
'utility_code_def', 'utility_code_def',
'end' 'end'
] ]
...@@ -424,22 +425,26 @@ class GlobalState(object): ...@@ -424,22 +425,26 @@ class GlobalState(object):
for part in self.code_layout: for part in self.code_layout:
self.parts[part] = rootwriter.insertion_point() self.parts[part] = rootwriter.insertion_point()
self.pystring_table = rootwriter.new_writer() if not Options.cache_builtins:
self.init_cached_builtins_writer = rootwriter.new_writer() del self.parts['cached_builtins']
self.initwriter = rootwriter.new_writer() else:
self.cleanupwriter = rootwriter.new_writer() w = self.parts['cached_builtins']
w.enter_cfunc_scope()
w.putln("static int __Pyx_InitCachedBuiltins(void) {")
if Options.cache_builtins:
self.init_cached_builtins_writer.enter_cfunc_scope()
self.init_cached_builtins_writer.putln("static int __Pyx_InitCachedBuiltins(void) {")
self.initwriter.enter_cfunc_scope() w = self.parts['init_globals']
self.initwriter.putln("") w.enter_cfunc_scope()
self.initwriter.putln("static int __Pyx_InitGlobals(void) {") w.putln("")
w.putln("static int __Pyx_InitGlobals(void) {")
self.cleanupwriter.enter_cfunc_scope() if not Options.generate_cleanup_code:
self.cleanupwriter.putln("") del self.parts['cleanup_globals']
self.cleanupwriter.putln("static void __Pyx_CleanupGlobals(void) {") else:
w = self.parts['cleanup_globals']
w.enter_cfunc_scope()
w.putln("")
w.putln("static void __Pyx_CleanupGlobals(void) {")
# #
# utility_code_def # utility_code_def
...@@ -474,36 +479,28 @@ class GlobalState(object): ...@@ -474,36 +479,28 @@ class GlobalState(object):
# #
def close_global_decls(self): def close_global_decls(self):
# This is called when it is known that no more global declarations will # This is called when it is known that no more global declarations will
# declared (but can be called before or after insert_XXX). # declared.
self.generate_const_declarations() self.generate_const_declarations()
if Options.cache_builtins: if Options.cache_builtins:
w = self.init_cached_builtins_writer w = self.parts['cached_builtins']
w.putln("return 0;") w.putln("return 0;")
w.put_label(w.error_label) w.put_label(w.error_label)
w.putln("return -1;") w.putln("return -1;")
w.putln("}") w.putln("}")
w.exit_cfunc_scope() w.exit_cfunc_scope()
w = self.initwriter w = self.parts['init_globals']
w.putln("return 0;") w.putln("return 0;")
w.put_label(w.error_label) w.put_label(w.error_label)
w.putln("return -1;") w.putln("return -1;")
w.putln("}") w.putln("}")
w.exit_cfunc_scope() w.exit_cfunc_scope()
w = self.cleanupwriter if Options.generate_cleanup_code:
w = self.parts['cleanup_module']
w.putln("}") w.putln("}")
w.exit_cfunc_scope() w.exit_cfunc_scope()
def insert_initcode_into(self, code):
code.insert(self.pystring_table)
if Options.cache_builtins:
code.insert(self.init_cached_builtins_writer)
code.insert(self.initwriter)
def insert_cleanupcode_into(self, code):
code.insert(self.cleanupwriter)
def put_pyobject_decl(self, entry): def put_pyobject_decl(self, entry):
self['global_var'].putln("static PyObject *%s;" % entry.cname) self['global_var'].putln("static PyObject *%s;" % entry.cname)
...@@ -581,12 +578,13 @@ class GlobalState(object): ...@@ -581,12 +578,13 @@ class GlobalState(object):
if self.should_declare(entry.cname, entry): if self.should_declare(entry.cname, entry):
interned_cname = self.get_py_string_const(entry.name, True).cname interned_cname = self.get_py_string_const(entry.name, True).cname
self.put_pyobject_decl(entry) self.put_pyobject_decl(entry)
self.init_cached_builtins_writer.putln('%s = __Pyx_GetName(%s, %s); if (!%s) %s' % ( w = self.parts['cached_builtins']
w.putln('%s = __Pyx_GetName(%s, %s); if (!%s) %s' % (
entry.cname, entry.cname,
Naming.builtins_cname, Naming.builtins_cname,
interned_cname, interned_cname,
entry.cname, entry.cname,
self.init_cached_builtins_writer.error_goto(entry.pos))) w.error_goto(entry.pos)))
def generate_const_declarations(self): def generate_const_declarations(self):
self.generate_string_constants() self.generate_string_constants()
...@@ -621,13 +619,14 @@ class GlobalState(object): ...@@ -621,13 +619,14 @@ class GlobalState(object):
self.use_utility_code(Nodes.init_string_tab_utility_code) self.use_utility_code(Nodes.init_string_tab_utility_code)
py_strings.sort() py_strings.sort()
self.pystring_table.putln("") w = self.parts['pystring_table']
self.pystring_table.putln("static __Pyx_StringTabEntry %s[] = {" % w.putln("")
w.putln("static __Pyx_StringTabEntry %s[] = {" %
Naming.stringtab_cname) Naming.stringtab_cname)
for c_cname, _, py_string in py_strings: for c_cname, _, py_string in py_strings:
decls_writer.putln( decls_writer.putln(
"static PyObject *%s;" % py_string.cname) "static PyObject *%s;" % py_string.cname)
self.pystring_table.putln( w.putln(
"{&%s, %s, sizeof(%s), %d, %d, %d}," % ( "{&%s, %s, sizeof(%s), %d, %d, %d}," % (
py_string.cname, py_string.cname,
c_cname, c_cname,
...@@ -636,13 +635,14 @@ class GlobalState(object): ...@@ -636,13 +635,14 @@ class GlobalState(object):
py_string.intern, py_string.intern,
py_string.identifier py_string.identifier
)) ))
self.pystring_table.putln("{0, 0, 0, 0, 0, 0}") w.putln("{0, 0, 0, 0, 0, 0}")
self.pystring_table.putln("};") w.putln("};")
self.initwriter.putln( init_globals = self.parts['init_globals']
init_globals.putln(
"if (__Pyx_InitStrings(%s) < 0) %s;" % ( "if (__Pyx_InitStrings(%s) < 0) %s;" % (
Naming.stringtab_cname, Naming.stringtab_cname,
self.initwriter.error_goto(self.module_pos))) init_globals.error_goto(self.module_pos)))
def generate_int_constants(self): def generate_int_constants(self):
consts = [ (len(c.value), c.value, c.is_long, c) consts = [ (len(c.value), c.value, c.is_long, c)
...@@ -656,10 +656,11 @@ class GlobalState(object): ...@@ -656,10 +656,11 @@ class GlobalState(object):
function = '%s = PyLong_FromString((char *)"%s", 0, 0); %s;' function = '%s = PyLong_FromString((char *)"%s", 0, 0); %s;'
else: else:
function = "%s = PyInt_FromLong(%s); %s;" function = "%s = PyInt_FromLong(%s); %s;"
self.initwriter.putln(function % ( init_globals = self.parts['init_globals']
init_globals.putln(function % (
cname, cname,
value, value,
self.initwriter.error_goto_if_null(cname, self.module_pos))) init_globals.error_goto_if_null(cname, self.module_pos)))
# The functions below are there in a transition phase only # The functions below are there in a transition phase only
# and will be deprecated. They are called from Nodes.BlockNode. # and will be deprecated. They are called from Nodes.BlockNode.
......
...@@ -275,12 +275,13 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -275,12 +275,13 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
if env.has_import_star: if env.has_import_star:
self.generate_import_star(env, code) self.generate_import_star(env, code)
self.generate_pymoduledef_struct(env, code) self.generate_pymoduledef_struct(env, code)
self.generate_module_init_func(modules[:-1], env, code)
code.mark_pos(None) # init_globals is inserted before this
self.generate_module_cleanup_func(env, code) self.generate_module_init_func(modules[:-1], env, globalstate['init_module'])
self.generate_module_cleanup_func(env, globalstate['cleanup_module'])
if Options.embed: if Options.embed:
self.generate_main_method(env, code) self.generate_main_method(env, globalstate['main_method'])
self.generate_filename_table(code) self.generate_filename_table(globalstate['filename_table'])
self.generate_declarations_for_modules(env, modules, globalstate) self.generate_declarations_for_modules(env, modules, globalstate)
h_code.write('\n') h_code.write('\n')
...@@ -1609,9 +1610,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1609,9 +1610,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.exit_cfunc_scope() # done with labels code.exit_cfunc_scope() # done with labels
def generate_module_init_func(self, imported_modules, env, code): def generate_module_init_func(self, imported_modules, env, code):
# Insert code stream of __Pyx_InitGlobals()
code.globalstate.insert_initcode_into(code)
code.enter_cfunc_scope() code.enter_cfunc_scope()
code.putln("") code.putln("")
header2 = "PyMODINIT_FUNC init%s(void)" % env.module_name header2 = "PyMODINIT_FUNC init%s(void)" % env.module_name
...@@ -1716,10 +1714,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1716,10 +1714,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
def generate_module_cleanup_func(self, env, code): def generate_module_cleanup_func(self, env, code):
if not Options.generate_cleanup_code: if not Options.generate_cleanup_code:
return return
env.use_utility_code(register_cleanup_utility_code) code.globalstate.use_utility_code(register_cleanup_utility_code)
# Insert code stream of __Pyx_CleanupGlobals()
code.globalstate.insert_cleanupcode_into(code)
code.putln()
code.putln('static PyObject* %s(PyObject *self, PyObject *unused) {' % Naming.cleanup_cname) code.putln('static PyObject* %s(PyObject *self, PyObject *unused) {' % Naming.cleanup_cname)
if Options.generate_cleanup_code >= 2: if Options.generate_cleanup_code >= 2:
code.putln("/*--- Global cleanup code ---*/") code.putln("/*--- Global cleanup code ---*/")
......
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