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

Introduce pre-splitting of code-stream in Code.py

parent 4c78f464
...@@ -1150,7 +1150,7 @@ static int __Pyx_GetBufferAndValidate(Py_buffer* buf, PyObject* obj, __Pyx_TypeI ...@@ -1150,7 +1150,7 @@ static int __Pyx_GetBufferAndValidate(Py_buffer* buf, PyObject* obj, __Pyx_TypeI
__Pyx_BufFmt_Init(&ctx, stack, dtype); __Pyx_BufFmt_Init(&ctx, stack, dtype);
if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail; if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail;
} }
if (buf->itemsize != dtype->size) { if ((unsigned)buf->itemsize != dtype->size) {
PyErr_Format(PyExc_ValueError, PyErr_Format(PyExc_ValueError,
"Item size of buffer (%"PY_FORMAT_SIZE_T"d byte%s) does not match size of '%s' (%"PY_FORMAT_SIZE_T"d byte%s)", "Item size of buffer (%"PY_FORMAT_SIZE_T"d byte%s) does not match size of '%s' (%"PY_FORMAT_SIZE_T"d byte%s)",
buf->itemsize, (buf->itemsize > 1) ? "s" : "", buf->itemsize, (buf->itemsize > 1) ? "s" : "",
......
...@@ -213,6 +213,8 @@ class GlobalState(object): ...@@ -213,6 +213,8 @@ class GlobalState(object):
# In time, hopefully the literals etc. will be # In time, hopefully the literals etc. will be
# supplied directly instead. # supplied directly instead.
# parts {string:CCodeWriter}
# interned_strings # interned_strings
# consts # consts
...@@ -226,7 +228,21 @@ class GlobalState(object): ...@@ -226,7 +228,21 @@ class GlobalState(object):
directives = {} directives = {}
def __init__(self, rootwriter, emit_linenums=False): code_layout = [
'h_code',
'before_global_var',
'global_var',
'after_global_var',
'utility_proto',
'pystring_table',
'init_cached_builtins',
'init',
'utility_def',
]
def __init__(self, writer, emit_linenums=False):
self.filename_table = {} self.filename_table = {}
self.filename_list = [] self.filename_list = []
self.input_file_contents = {} self.input_file_contents = {}
...@@ -235,6 +251,14 @@ class GlobalState(object): ...@@ -235,6 +251,14 @@ class GlobalState(object):
self.pystring_table_needed = False self.pystring_table_needed = False
self.in_utility_code_generation = False self.in_utility_code_generation = False
self.emit_linenums = emit_linenums self.emit_linenums = emit_linenums
self.parts = {}
assert writer.globalstate is None
writer.globalstate = self
for part in self.code_layout:
self.parts[part] = writer.insertion_point()#new_writer()
self.initwriters(writer)
def initwriters(self, rootwriter): def initwriters(self, rootwriter):
self.utilprotowriter = rootwriter.new_writer() self.utilprotowriter = rootwriter.new_writer()
...@@ -261,12 +285,12 @@ class GlobalState(object): ...@@ -261,12 +285,12 @@ class GlobalState(object):
self.pystring_table.putln("static __Pyx_StringTabEntry %s[] = {" % self.pystring_table.putln("static __Pyx_StringTabEntry %s[] = {" %
Naming.stringtab_cname) Naming.stringtab_cname)
def __getitem__(self, key):
return self.parts[key]
# #
# Global constants, interned objects, etc. # Global constants, interned objects, etc.
# #
def insert_global_var_declarations_into(self, code):
code.insert(self.decls_writer)
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 (but can be called before or after insert_XXX).
...@@ -310,7 +334,7 @@ class GlobalState(object): ...@@ -310,7 +334,7 @@ class GlobalState(object):
code.insert(self.cleanupwriter) code.insert(self.cleanupwriter)
def put_pyobject_decl(self, entry): def put_pyobject_decl(self, entry):
self.decls_writer.putln("static PyObject *%s;" % entry.cname) self['global_var'].putln("static PyObject *%s;" % entry.cname)
# 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.
...@@ -329,16 +353,16 @@ class GlobalState(object): ...@@ -329,16 +353,16 @@ class GlobalState(object):
def add_const_definition(self, entry): def add_const_definition(self, entry):
if self.should_declare(entry.cname, entry): if self.should_declare(entry.cname, entry):
self.decls_writer.put_var_declaration(entry, static = 1) self['global_var'].put_var_declaration(entry, static = 1)
def add_interned_string_decl(self, entry): def add_interned_string_decl(self, entry):
if self.should_declare(entry.cname, entry): if self.should_declare(entry.cname, entry):
self.decls_writer.put_var_declaration(entry, static = 1) self['global_var'].put_var_declaration(entry, static = 1)
self.add_py_string_decl(entry) self.add_py_string_decl(entry)
def add_py_string_decl(self, entry): def add_py_string_decl(self, entry):
if self.should_declare(entry.pystring_cname, entry): if self.should_declare(entry.pystring_cname, entry):
self.decls_writer.putln("static PyObject *%s;" % entry.pystring_cname) self['global_var'].putln("static PyObject *%s;" % entry.pystring_cname)
self.pystring_table_needed = True self.pystring_table_needed = True
self.pystring_table.putln("{&%s, %s, sizeof(%s), %d, %d, %d}," % ( self.pystring_table.putln("{&%s, %s, sizeof(%s), %d, %d, %d}," % (
entry.pystring_cname, entry.pystring_cname,
...@@ -503,6 +527,8 @@ class CCodeWriter(object): ...@@ -503,6 +527,8 @@ class CCodeWriter(object):
# globalstate GlobalState contains state global for a C file (input file info, # globalstate GlobalState contains state global for a C file (input file info,
# utility code, declared constants etc.) # utility code, declared constants etc.)
# emit_linenums boolean whether or not to write #line pragmas # emit_linenums boolean whether or not to write #line pragmas
globalstate = None
def __init__(self, create_from=None, buffer=None, copy_formatting=False, emit_linenums=None): def __init__(self, create_from=None, buffer=None, copy_formatting=False, emit_linenums=None):
if buffer is None: buffer = StringIOTree() if buffer is None: buffer = StringIOTree()
...@@ -515,12 +541,8 @@ class CCodeWriter(object): ...@@ -515,12 +541,8 @@ class CCodeWriter(object):
self.level = 0 self.level = 0
self.call_level = 0 self.call_level = 0
self.bol = 1 self.bol = 1
if create_from is None:
# Root CCodeWriter if create_from is not None:
self.globalstate = GlobalState(self, emit_linenums=emit_linenums)
self.globalstate.initwriters(self)
# ^^^ need seperate step because this will reference self.globalstate
else:
# Use same global state # Use same global state
self.globalstate = create_from.globalstate self.globalstate = create_from.globalstate
# Clone formatting state # Clone formatting state
...@@ -528,7 +550,7 @@ class CCodeWriter(object): ...@@ -528,7 +550,7 @@ class CCodeWriter(object):
self.level = create_from.level self.level = create_from.level
self.bol = create_from.bol self.bol = create_from.bol
self.call_level = create_from.call_level self.call_level = create_from.call_level
if emit_linenums is None: if emit_linenums is None and self.globalstate:
self.emit_linenums = self.globalstate.emit_linenums self.emit_linenums = self.globalstate.emit_linenums
else: else:
self.emit_linenums = emit_linenums self.emit_linenums = emit_linenums
...@@ -536,7 +558,8 @@ class CCodeWriter(object): ...@@ -536,7 +558,8 @@ class CCodeWriter(object):
def create_new(self, create_from, buffer, copy_formatting): def create_new(self, create_from, buffer, copy_formatting):
# polymorphic constructor -- very slightly more versatile # polymorphic constructor -- very slightly more versatile
# than using __class__ # than using __class__
return CCodeWriter(create_from, buffer, copy_formatting) result = CCodeWriter(create_from, buffer, copy_formatting)
return result
def copyto(self, f): def copyto(self, f):
self.buffer.copyto(f) self.buffer.copyto(f)
......
...@@ -106,6 +106,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -106,6 +106,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
if h_types or h_vars or h_funcs or h_extension_types: if h_types or h_vars or h_funcs or h_extension_types:
result.h_file = replace_suffix(result.c_file, ".h") result.h_file = replace_suffix(result.c_file, ".h")
h_code = Code.CCodeWriter() h_code = Code.CCodeWriter()
Code.GlobalState(h_code)
if options.generate_pxi: if options.generate_pxi:
result.i_file = replace_suffix(result.c_file, ".pxi") result.i_file = replace_suffix(result.c_file, ".pxi")
i_code = Code.PyrexCodeWriter(result.i_file) i_code = Code.PyrexCodeWriter(result.i_file)
...@@ -167,6 +168,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -167,6 +168,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
if api_funcs or has_api_extension_types: if api_funcs or has_api_extension_types:
result.api_file = replace_suffix(result.c_file, "_api.h") result.api_file = replace_suffix(result.c_file, "_api.h")
h_code = Code.CCodeWriter() h_code = Code.CCodeWriter()
Code.GlobalState(h_code)
name = self.api_name(env) name = self.api_name(env)
guard = Naming.api_guard_prefix + name guard = Naming.api_guard_prefix + name
h_code.put_h_guard(guard) h_code.put_h_guard(guard)
...@@ -243,18 +245,24 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -243,18 +245,24 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
def generate_c_code(self, env, options, result): def generate_c_code(self, env, options, result):
modules = self.referenced_modules modules = self.referenced_modules
if Options.annotate or options.annotate: if Options.annotate or options.annotate:
code = Annotate.AnnotationCCodeWriter() emit_linenums = False
rootwriter = Annotate.AnnotationCCodeWriter()
else: else:
code = Code.CCodeWriter(emit_linenums=options.emit_linenums) emit_linenums = options.emit_linenums
h_code = code.insertion_point() rootwriter = Code.CCodeWriter(emit_linenums=emit_linenums)
globalstate = Code.GlobalState(rootwriter, emit_linenums)
h_code = globalstate['h_code']
self.generate_module_preamble(env, modules, h_code) self.generate_module_preamble(env, modules, h_code)
code.globalstate.module_pos = self.pos globalstate.module_pos = self.pos
code.globalstate.directives = self.directives globalstate.directives = self.directives
code.globalstate.use_utility_code(refcount_utility_code) globalstate.use_utility_code(refcount_utility_code)
code = globalstate['before_global_var']
code.putln('#define __Pyx_MODULE_NAME "%s"' % self.full_module_name) code.putln('#define __Pyx_MODULE_NAME "%s"' % self.full_module_name)
code.putln("") code.putln("")
code.putln("/* Implementation of %s */" % env.qualified_name) code.putln("/* Implementation of %s */" % env.qualified_name)
...@@ -263,8 +271,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -263,8 +271,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
self.generate_interned_string_decls(env, code) self.generate_interned_string_decls(env, code)
self.generate_py_string_decls(env, code) self.generate_py_string_decls(env, code)
code.globalstate.insert_global_var_declarations_into(code) code = globalstate['after_global_var']
self.generate_cached_builtins_decls(env, code) self.generate_cached_builtins_decls(env, code)
self.body.generate_function_definitions(env, code) self.body.generate_function_definitions(env, code)
code.mark_pos(None) code.mark_pos(None)
...@@ -285,15 +293,15 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -285,15 +293,15 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
self.generate_declarations_for_modules(env, modules, h_code) self.generate_declarations_for_modules(env, modules, h_code)
h_code.write('\n') h_code.write('\n')
code.globalstate.close_global_decls() globalstate.close_global_decls()
f = open_new_file(result.c_file) f = open_new_file(result.c_file)
code.copyto(f) rootwriter.copyto(f)
f.close() f.close()
result.c_file_generated = 1 result.c_file_generated = 1
if Options.annotate or options.annotate: if Options.annotate or options.annotate:
self.annotate(code) self.annotate(rootwriter)
code.save_annotation(result.main_source_file, result.c_file) rootwriter.save_annotation(result.main_source_file, result.c_file)
def find_referenced_modules(self, env, module_list, modules_seen): def find_referenced_modules(self, env, module_list, modules_seen):
if env not in modules_seen: if env not in modules_seen:
......
...@@ -1061,6 +1061,7 @@ class CStructOrUnionType(CType): ...@@ -1061,6 +1061,7 @@ class CStructOrUnionType(CType):
if self._convert_code is None: if self._convert_code is None:
import Code import Code
code = Code.CCodeWriter() code = Code.CCodeWriter()
Code.GlobalState(code)
header = "static PyObject* %s(%s)" % (self.to_py_function, self.declaration_code('s')) header = "static PyObject* %s(%s)" % (self.to_py_function, self.declaration_code('s'))
code.putln("%s {" % header) code.putln("%s {" % header)
code.putln("PyObject* res;") code.putln("PyObject* res;")
......
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