Commit 8c4f0c5b authored by Dag Sverre Seljebotn's avatar Dag Sverre Seljebotn

Merge

parents 9f86b4fd df78cdc7
...@@ -30,8 +30,8 @@ class AnnotationCCodeWriter(CCodeWriter): ...@@ -30,8 +30,8 @@ class AnnotationCCodeWriter(CCodeWriter):
self.annotations = create_from.annotations self.annotations = create_from.annotations
self.code = create_from.code self.code = create_from.code
def create_new(self, create_from, buffer): def create_new(self, create_from, buffer, copy_formatting):
return AnnotationCCodeWriter(create_from, buffer) return AnnotationCCodeWriter(create_from, buffer, copy_formatting)
def write(self, s): def write(self, s):
CCodeWriter.write(self, s) CCodeWriter.write(self, s)
......
This diff is collapsed.
This diff is collapsed.
...@@ -1065,7 +1065,7 @@ class NameNode(AtomicExprNode): ...@@ -1065,7 +1065,7 @@ class NameNode(AtomicExprNode):
rhs.generate_post_assignment_code(code) rhs.generate_post_assignment_code(code)
def generate_acquire_buffer(self, rhs, code): def generate_acquire_buffer(self, rhs, code):
rhstmp = code.func.allocate_temp(self.entry.type) rhstmp = code.funcstate.allocate_temp(self.entry.type)
buffer_aux = self.entry.buffer_aux buffer_aux = self.entry.buffer_aux
bufstruct = buffer_aux.buffer_info_var.cname bufstruct = buffer_aux.buffer_info_var.cname
code.putln('%s = %s;' % (rhstmp, rhs.result_as(self.ctype()))) code.putln('%s = %s;' % (rhstmp, rhs.result_as(self.ctype())))
...@@ -1075,7 +1075,7 @@ class NameNode(AtomicExprNode): ...@@ -1075,7 +1075,7 @@ class NameNode(AtomicExprNode):
is_initialized=not self.skip_assignment_decref, is_initialized=not self.skip_assignment_decref,
pos=self.pos, code=code) pos=self.pos, code=code)
code.putln("%s = 0;" % rhstmp) code.putln("%s = 0;" % rhstmp)
code.func.release_temp(rhstmp) code.funcstate.release_temp(rhstmp)
def generate_deletion_code(self, code): def generate_deletion_code(self, code):
if self.entry is None: if self.entry is None:
...@@ -1520,7 +1520,7 @@ class IndexNode(ExprNode): ...@@ -1520,7 +1520,7 @@ class IndexNode(ExprNode):
def buffer_access_code(self, code): def buffer_access_code(self, code):
# Assign indices to temps # Assign indices to temps
index_temps = [code.func.allocate_temp(i.type) for i in self.indices] index_temps = [code.funcstate.allocate_temp(i.type) for i in self.indices]
for temp, index in zip(index_temps, self.indices): for temp, index in zip(index_temps, self.indices):
code.putln("%s = %s;" % (temp, index.result_code)) code.putln("%s = %s;" % (temp, index.result_code))
# Generate buffer access code using these temps # Generate buffer access code using these temps
......
...@@ -529,8 +529,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -529,8 +529,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
def generate_filename_table(self, code): def generate_filename_table(self, code):
code.putln("") code.putln("")
code.putln("static const char *%s[] = {" % Naming.filenames_cname) code.putln("static const char *%s[] = {" % Naming.filenames_cname)
if code.filename_list: if code.globalstate.filename_list:
for source_desc in code.filename_list: for source_desc in code.globalstate.filename_list:
filename = os.path.basename(source_desc.get_filenametable_entry()) filename = os.path.basename(source_desc.get_filenametable_entry())
escaped_filename = filename.replace("\\", "\\\\").replace('"', r'\"') escaped_filename = filename.replace("\\", "\\\\").replace('"', r'\"')
code.putln('"%s",' % code.putln('"%s",' %
...@@ -1610,7 +1610,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1610,7 +1610,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln('}') code.putln('}')
tempdecl_code.put_var_declarations(env.temp_entries) tempdecl_code.put_var_declarations(env.temp_entries)
tempdecl_code.put_temp_declarations(code.func) tempdecl_code.put_temp_declarations(code.funcstate)
code.exit_cfunc_scope() code.exit_cfunc_scope()
...@@ -1950,6 +1950,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1950,6 +1950,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
type.typeptr_cname, type.typeobj_cname)) type.typeptr_cname, type.typeobj_cname))
def generate_utility_functions(self, env, code, h_code): def generate_utility_functions(self, env, code, h_code):
for codetup, name in env.utility_code_list:
code.globalstate.use_utility_code(codetup, name)
code.globalstate.put_utility_code_protos(h_code)
code.putln("") code.putln("")
code.putln("/* Runtime support code */") code.putln("/* Runtime support code */")
code.putln("") code.putln("")
...@@ -1957,9 +1961,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1957,9 +1961,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln("%s = %s;" % code.putln("%s = %s;" %
(Naming.filetable_cname, Naming.filenames_cname)) (Naming.filetable_cname, Naming.filenames_cname))
code.putln("}") code.putln("}")
for utility_code in env.utility_code_used: code.globalstate.put_utility_code_defs(code)
h_code.put(utility_code[0])
code.put(utility_code[1])
code.put(PyrexTypes.type_conversion_functions) code.put(PyrexTypes.type_conversion_functions)
code.putln("") code.putln("")
......
...@@ -969,7 +969,7 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -969,7 +969,7 @@ class FuncDefNode(StatNode, BlockNode):
code.putln("}") code.putln("}")
# ----- Go back and insert temp variable declarations # ----- Go back and insert temp variable declarations
tempvardecl_code.put_var_declarations(lenv.temp_entries) tempvardecl_code.put_var_declarations(lenv.temp_entries)
tempvardecl_code.put_temp_declarations(code.func) tempvardecl_code.put_temp_declarations(code.funcstate)
# ----- Python version # ----- Python version
code.exit_cfunc_scope() code.exit_cfunc_scope()
if self.py_func: if self.py_func:
...@@ -2634,7 +2634,7 @@ class ContinueStatNode(StatNode): ...@@ -2634,7 +2634,7 @@ class ContinueStatNode(StatNode):
pass pass
def generate_execution_code(self, code): def generate_execution_code(self, code):
if code.in_try_finally: if code.funcstate.in_try_finally:
error(self.pos, "continue statement inside try of try...finally") error(self.pos, "continue statement inside try of try...finally")
elif not code.continue_label: elif not code.continue_label:
error(self.pos, "continue statement not inside loop") error(self.pos, "continue statement not inside loop")
...@@ -2797,7 +2797,7 @@ class ReraiseStatNode(StatNode): ...@@ -2797,7 +2797,7 @@ class ReraiseStatNode(StatNode):
gil_message = "Raising exception" gil_message = "Raising exception"
def generate_execution_code(self, code): def generate_execution_code(self, code):
vars = code.exc_vars vars = code.funcstate.exc_vars
if vars: if vars:
code.putln("__Pyx_Raise(%s, %s, %s);" % tuple(vars)) code.putln("__Pyx_Raise(%s, %s, %s);" % tuple(vars))
code.putln(code.error_goto(self.pos)) code.putln(code.error_goto(self.pos))
...@@ -3478,10 +3478,10 @@ class ExceptClauseNode(Node): ...@@ -3478,10 +3478,10 @@ class ExceptClauseNode(Node):
self.excinfo_tuple.generate_evaluation_code(code) self.excinfo_tuple.generate_evaluation_code(code)
self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code) self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
old_exc_vars = code.exc_vars old_exc_vars = code.funcstate.exc_vars
code.exc_vars = self.exc_vars code.funcstate.exc_vars = self.exc_vars
self.body.generate_execution_code(code) self.body.generate_execution_code(code)
code.exc_vars = old_exc_vars code.funcstate.exc_vars = old_exc_vars
for var in self.exc_vars: for var in self.exc_vars:
code.putln("Py_DECREF(%s); %s = 0;" % (var, var)) code.putln("Py_DECREF(%s); %s = 0;" % (var, var))
code.put_goto(end_label) code.put_goto(end_label)
...@@ -3556,11 +3556,11 @@ class TryFinallyStatNode(StatNode): ...@@ -3556,11 +3556,11 @@ class TryFinallyStatNode(StatNode):
code.putln( code.putln(
"/*try:*/ {") "/*try:*/ {")
if self.disallow_continue_in_try_finally: if self.disallow_continue_in_try_finally:
was_in_try_finally = code.in_try_finally was_in_try_finally = code.funcstate.in_try_finally
code.in_try_finally = 1 code.funcstate.in_try_finally = 1
self.body.generate_execution_code(code) self.body.generate_execution_code(code)
if self.disallow_continue_in_try_finally: if self.disallow_continue_in_try_finally:
code.in_try_finally = was_in_try_finally code.funcstate.in_try_finally = was_in_try_finally
code.putln( code.putln(
"}") "}")
code.putln( code.putln(
......
...@@ -23,11 +23,12 @@ nice_identifier = re.compile('^[a-zA-Z0-0_]+$').match ...@@ -23,11 +23,12 @@ nice_identifier = re.compile('^[a-zA-Z0-0_]+$').match
class BufferAux: class BufferAux:
writable_needed = False writable_needed = False
def __init__(self, buffer_info_var, stridevars, shapevars, tschecker): def __init__(self, buffer_info_var, stridevars, shapevars,
suboffsetvars):
self.buffer_info_var = buffer_info_var self.buffer_info_var = buffer_info_var
self.stridevars = stridevars self.stridevars = stridevars
self.shapevars = shapevars self.shapevars = shapevars
self.tschecker = tschecker self.suboffsetvars = suboffsetvars
def __repr__(self): def __repr__(self):
return "<BufferAux %r>" % self.__dict__ return "<BufferAux %r>" % self.__dict__
...@@ -620,9 +621,6 @@ class Scope: ...@@ -620,9 +621,6 @@ class Scope:
def use_utility_code(self, new_code, name=None): def use_utility_code(self, new_code, name=None):
self.global_scope().use_utility_code(new_code, name) self.global_scope().use_utility_code(new_code, name)
def has_utility_code(self, name):
return self.global_scope().has_utility_code(name)
def generate_library_function_declarations(self, code): def generate_library_function_declarations(self, code):
# Generate extern decls for C library funcs used. # Generate extern decls for C library funcs used.
...@@ -742,8 +740,7 @@ class ModuleScope(Scope): ...@@ -742,8 +740,7 @@ class ModuleScope(Scope):
# doc string Module doc string # doc string Module doc string
# doc_cname string C name of module doc string # doc_cname string C name of module doc string
# const_counter integer Counter for naming constants # const_counter integer Counter for naming constants
# utility_code_used [string] Utility code to be included # utility_code_list [((string, string), string)] Queuing utility codes for forwarding to Code.py
# utility_code_names set(string) (Optional) names for named (often generated) utility code
# default_entries [Entry] Function argument default entries # default_entries [Entry] Function argument default entries
# python_include_files [string] Standard Python headers to be included # python_include_files [string] Standard Python headers to be included
# include_files [string] Other C headers to be included # include_files [string] Other C headers to be included
...@@ -777,8 +774,7 @@ class ModuleScope(Scope): ...@@ -777,8 +774,7 @@ class ModuleScope(Scope):
self.doc = "" self.doc = ""
self.doc_cname = Naming.moddoc_cname self.doc_cname = Naming.moddoc_cname
self.const_counter = 1 self.const_counter = 1
self.utility_code_used = [] self.utility_code_list = []
self.utility_code_names = set()
self.default_entries = [] self.default_entries = []
self.module_entries = {} self.module_entries = {}
self.python_include_files = ["Python.h", "structmember.h"] self.python_include_files = ["Python.h", "structmember.h"]
...@@ -938,25 +934,8 @@ class ModuleScope(Scope): ...@@ -938,25 +934,8 @@ class ModuleScope(Scope):
return "%s%s%d" % (Naming.const_prefix, prefix, n) return "%s%s%d" % (Naming.const_prefix, prefix, n)
def use_utility_code(self, new_code, name=None): def use_utility_code(self, new_code, name=None):
# Add string to list of utility code to be included, self.utility_code_list.append((new_code, name))
# if not already there (tested using the provided name,
# or 'is' if name=None -- if the utility code is dynamically
# generated, use the name, otherwise it is not needed).
if name is not None:
if name in self.utility_code_names:
return
for old_code in self.utility_code_used:
if old_code is new_code:
return
self.utility_code_used.append(new_code)
self.utility_code_names.add(name)
def has_utility_code(self, name):
# Checks if utility code (that is registered by name) has
# previously been registered. This is useful if the utility code
# is dynamically generated to avoid re-generation.
return name in self.utility_code_names
def declare_c_class(self, name, pos, defining = 0, implementing = 0, def declare_c_class(self, name, pos, defining = 0, implementing = 0,
module_name = None, base_type = None, objstruct_cname = None, module_name = None, base_type = None, objstruct_cname = None,
typeobj_cname = None, visibility = 'private', typedef_flag = 0, api = 0): typeobj_cname = None, visibility = 'private', typedef_flag = 0, api = 0):
......
...@@ -7,8 +7,7 @@ class StringIOTree(object): ...@@ -7,8 +7,7 @@ class StringIOTree(object):
def __init__(self, stream=None): def __init__(self, stream=None):
self.prepended_children = [] self.prepended_children = []
if stream is None: stream = StringIO() self.stream = stream # if set to None, it will be constructed on first write
self.stream = stream
def getvalue(self): def getvalue(self):
return ("".join([x.getvalue() for x in self.prepended_children]) + return ("".join([x.getvalue() for x in self.prepended_children]) +
...@@ -19,20 +18,44 @@ class StringIOTree(object): ...@@ -19,20 +18,44 @@ class StringIOTree(object):
needs to happen.""" needs to happen."""
for child in self.prepended_children: for child in self.prepended_children:
child.copyto(target) child.copyto(target)
target.write(self.stream.getvalue()) if self.stream:
target.write(self.stream.getvalue())
def write(self, what): def write(self, what):
if not self.stream:
self.stream = StringIO()
self.stream.write(what) self.stream.write(what)
def commit(self):
# Save what we have written until now so that the buffer
# itself is empty -- this makes it ready for insertion
if self.stream:
self.prepended_children.append(StringIOTree(self.stream))
self.stream = None
def insert(self, iotree):
"""
Insert a StringIOTree (and all of its contents) at this location.
Further writing to self appears after what is inserted.
"""
self.commit()
self.prepended_children.append(iotree)
def insertion_point(self): def insertion_point(self):
"""
Returns a new StringIOTree, which is left behind at the current position
(it what is written to the result will appear right before whatever is
next written to self).
Calling getvalue() or copyto() on the result will only return the
contents written to it.
"""
# Save what we have written until now # Save what we have written until now
# (would it be more efficient to check with len(self.stream.getvalue())? # This is so that getvalue on the result doesn't include it.
# leaving it out for now) self.commit()
self.prepended_children.append(StringIOTree(self.stream))
# Construct the new forked object to return # Construct the new forked object to return
other = StringIOTree() other = StringIOTree()
self.prepended_children.append(other) self.prepended_children.append(other)
self.stream = StringIO()
return other return other
__doc__ = r""" __doc__ = r"""
...@@ -65,12 +88,16 @@ beta ...@@ -65,12 +88,16 @@ beta
gamma gamma
<BLANKLINE> <BLANKLINE>
>>> i = StringIOTree()
>>> d.insert(i)
>>> i.write('inserted\n')
>>> out = StringIO() >>> out = StringIO()
>>> a.copyto(out) >>> a.copyto(out)
>>> print out.getvalue() >>> print out.getvalue()
first first
second second
alpha alpha
inserted
beta beta
gamma gamma
third third
......
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