Commit fc613954 authored by Stefan Behnel's avatar Stefan Behnel

merge

parents d1de0001 345ce9b8
...@@ -510,6 +510,7 @@ class CCodeWriter(object): ...@@ -510,6 +510,7 @@ class CCodeWriter(object):
self.funcstate = None self.funcstate = None
self.level = 0 self.level = 0
self.call_level = 0
self.bol = 1 self.bol = 1
if create_from is None: if create_from is None:
# Root CCodeWriter # Root CCodeWriter
...@@ -523,6 +524,7 @@ class CCodeWriter(object): ...@@ -523,6 +524,7 @@ class CCodeWriter(object):
if copy_formatting: if copy_formatting:
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
if emit_linenums is None: if emit_linenums is None:
self.emit_linenums = self.globalstate.emit_linenums self.emit_linenums = self.globalstate.emit_linenums
else: else:
......
...@@ -69,11 +69,55 @@ def embed_position(pos, docstring): ...@@ -69,11 +69,55 @@ def embed_position(pos, docstring):
doc.encoding = encoding doc.encoding = encoding
return doc return doc
from Code import CCodeWriter
from types import FunctionType
def write_func_call(func):
def f(*args, **kwds):
if len(args) > 1 and isinstance(args[1], CCodeWriter):
# here we annotate the code with this function call
# but only if new code is generated
node, code = args[:2]
marker = ' /* %s -> %s.%s %s */' % (
' ' * code.call_level,
node.__class__.__name__,
func.__name__,
node.pos[1:])
pristine = code.buffer.stream.tell()
code.putln(marker)
start = code.buffer.stream.tell()
code.call_level += 4
res = func(*args, **kwds)
code.call_level -= 4
if start == code.buffer.stream.tell():
code.buffer.stream.seek(pristine)
else:
marker = marker.replace('->', '<-')
code.putln(marker)
return res
else:
return func(*args, **kwds)
return f
class VerboseCodeWriter(type):
# Set this as a metaclass to trace function calls in code.
# This slows down code generation and makes much larger files.
def __new__(cls, name, bases, attrs):
attrs = dict(attrs)
for mname, m in attrs.items():
if isinstance(m, FunctionType):
attrs[mname] = write_func_call(m)
return super(VerboseCodeWriter, cls).__new__(cls, name, bases, attrs)
class Node(object): class Node(object):
# pos (string, int, int) Source file position # pos (string, int, int) Source file position
# is_name boolean Is a NameNode # is_name boolean Is a NameNode
# is_literal boolean Is a ConstNode # is_literal boolean Is a ConstNode
__metaclass__ = VerboseCodeWriter
is_name = 0 is_name = 0
is_literal = 0 is_literal = 0
temps = None temps = None
......
__doc__ = """
>>> A().test(3)
9
"""
cdef class A:
cdef int (*func_ptr)(int)
def __init__(self):
self.func_ptr = &func
cdef int do_it(self, int s):
cdef int r = first_call(self).func_ptr(s) # the temp for first_call(self) not properly freed
return r
def test(self, s):
return self.do_it(s)
cdef A first_call(A x):
return x
cdef int func(int s):
return s*s
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