Remove unused patches
This commit is contained in:
parent
36afc7f791
commit
5f5775aa52
@ -1,15 +0,0 @@
|
|||||||
diff --git a/pypy/translator/platform/posix.py b/pypy/translator/platform/posix.py
|
|
||||||
--- a/pypy/translator/platform/posix.py
|
|
||||||
+++ b/pypy/translator/platform/posix.py
|
|
||||||
@@ -48,8 +48,10 @@
|
|
||||||
response_file = self._make_response_file("dynamic-symbols-")
|
|
||||||
f = response_file.open("w")
|
|
||||||
f.write("{\n")
|
|
||||||
+ f.write(" global:\n")
|
|
||||||
for sym in eci.export_symbols:
|
|
||||||
- f.write("%s;\n" % (sym,))
|
|
||||||
+ f.write(" %s;\n" % (sym,))
|
|
||||||
+ f.write(" local:*;\n")
|
|
||||||
f.write("};")
|
|
||||||
f.close()
|
|
||||||
|
|
37
config.patch
37
config.patch
@ -1,37 +0,0 @@
|
|||||||
diff -rup pypy-pypy-f66246c46ca3/rpython/translator/platform/linux.py pypy-pypy-f66246c46ca3/rpython/translator/platform/linux.py
|
|
||||||
--- pypy-pypy-f66246c46ca3/rpython/translator/platform/linux.py 2013-05-27 10:35:37.679237332 +0200
|
|
||||||
+++ pypy-pypy-f66246c46ca3/rpython/translator/platform/linux.py 2013-05-27 10:47:41.506354482 +0200
|
|
||||||
@@ -32,19 +32,20 @@ class BaseLinux(BasePosix):
|
|
||||||
return self._pkg_config("libffi", "--libs-only-L",
|
|
||||||
['/usr/lib/libffi'])
|
|
||||||
|
|
||||||
- def library_dirs_for_libffi_a(self):
|
|
||||||
- # places where we need to look for libffi.a
|
|
||||||
- # XXX obscuuure! only look for libffi.a if run with translate.py
|
|
||||||
- if 'translate' in sys.modules:
|
|
||||||
- if sys.maxint > 2**32:
|
|
||||||
- host = 'x86_64'
|
|
||||||
- else:
|
|
||||||
- host = 'x86'
|
|
||||||
- return self.library_dirs_for_libffi() + [
|
|
||||||
- '/usr/lib',
|
|
||||||
- '/usr/lib/%s-linux-gnu/' % host]
|
|
||||||
- else:
|
|
||||||
- return []
|
|
||||||
+ #Fedora, at least, has the shared version but not the static:
|
|
||||||
+ #def library_dirs_for_libffi_a(self):
|
|
||||||
+ # # places where we need to look for libffi.a
|
|
||||||
+ # # XXX obscuuure! only look for libffi.a if run with translate.py
|
|
||||||
+ # if 'translate' in sys.modules:
|
|
||||||
+ # if sys.maxint > 2**32:
|
|
||||||
+ # host = 'x86_64'
|
|
||||||
+ # else:
|
|
||||||
+ # host = 'x86'
|
|
||||||
+ # return self.library_dirs_for_libffi() + [
|
|
||||||
+ # '/usr/lib',
|
|
||||||
+ # '/usr/lib/%s-linux-gnu/' % host]
|
|
||||||
+ # else:
|
|
||||||
+ # return []
|
|
||||||
|
|
||||||
|
|
||||||
class Linux(BaseLinux):
|
|
@ -1,693 +0,0 @@
|
|||||||
diff -up pypy-pypy-release-1.7/pypy/interpreter/pycode.py.more-readable-c-code pypy-pypy-release-1.7/pypy/interpreter/pycode.py
|
|
||||||
--- pypy-pypy-release-1.7/pypy/interpreter/pycode.py.more-readable-c-code 2011-11-19 02:44:54.000000000 -0500
|
|
||||||
+++ pypy-pypy-release-1.7/pypy/interpreter/pycode.py 2011-11-21 16:16:15.673463780 -0500
|
|
||||||
@@ -13,6 +13,7 @@ from pypy.interpreter.gateway import Non
|
|
||||||
from pypy.interpreter.astcompiler.consts import (
|
|
||||||
CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS, CO_NESTED,
|
|
||||||
CO_GENERATOR, CO_CONTAINSGLOBALS)
|
|
||||||
+from pypy.interpreter.pytraceback import offset2lineno
|
|
||||||
from pypy.rlib.rarithmetic import intmask
|
|
||||||
from pypy.rlib.debug import make_sure_not_resized
|
|
||||||
from pypy.rlib import jit
|
|
||||||
@@ -81,6 +82,7 @@ class PyCode(eval.Code):
|
|
||||||
self.hidden_applevel = hidden_applevel
|
|
||||||
self.magic = magic
|
|
||||||
self._signature = cpython_code_signature(self)
|
|
||||||
+ self._cached_source = None
|
|
||||||
self._initialize()
|
|
||||||
|
|
||||||
def _initialize(self):
|
|
||||||
@@ -397,3 +399,23 @@ class PyCode(eval.Code):
|
|
||||||
|
|
||||||
def repr(self, space):
|
|
||||||
return space.wrap(self.get_repr())
|
|
||||||
+
|
|
||||||
+ def get_linenum_for_offset(self, offset):
|
|
||||||
+ # Given a bytecode offset, return a 1-based index into the lines of the
|
|
||||||
+ # source code
|
|
||||||
+ return offset2lineno(self, offset)
|
|
||||||
+
|
|
||||||
+ def _ensure_source(self):
|
|
||||||
+ # Lazily grab the source lines into self._cached_source (or raise
|
|
||||||
+ # an IOError)
|
|
||||||
+ if not self._cached_source:
|
|
||||||
+ f = open(self.co_filename, 'r')
|
|
||||||
+ source = [line.rstrip() for line in f.readlines()]
|
|
||||||
+ f.close()
|
|
||||||
+ self._cached_source = source
|
|
||||||
+
|
|
||||||
+ def get_source_text(self, linenum):
|
|
||||||
+ # Given a 1-based index, get the corresponding line of source code (or
|
|
||||||
+ # raise an IOError)
|
|
||||||
+ self._ensure_source()
|
|
||||||
+ return self._cached_source[linenum - 1]
|
|
||||||
diff -up pypy-pypy-release-1.7/pypy/objspace/flow/model.py.more-readable-c-code pypy-pypy-release-1.7/pypy/objspace/flow/model.py
|
|
||||||
--- pypy-pypy-release-1.7/pypy/objspace/flow/model.py.more-readable-c-code 2011-11-19 02:44:54.000000000 -0500
|
|
||||||
+++ pypy-pypy-release-1.7/pypy/objspace/flow/model.py 2011-11-21 16:15:36.599466455 -0500
|
|
||||||
@@ -31,6 +31,120 @@ from pypy.tool.identity_dict import iden
|
|
||||||
|
|
||||||
__metaclass__ = type
|
|
||||||
|
|
||||||
+class SourceLoc(object):
|
|
||||||
+ # A srcloc is a specific location within the RPython source code,
|
|
||||||
+ # intended for human display
|
|
||||||
+ __slots__ = ('code', # code object
|
|
||||||
+ 'linenum' # 1-based index, as displayed to a user
|
|
||||||
+ )
|
|
||||||
+ def __init__(self, code, linenum):
|
|
||||||
+ self.code = code
|
|
||||||
+ self.linenum = linenum
|
|
||||||
+
|
|
||||||
+ def get_text(self):
|
|
||||||
+ # Get the actual source text of this line
|
|
||||||
+ return self.code.get_source_text(self.linenum)
|
|
||||||
+
|
|
||||||
+ def __eq__(self, other):
|
|
||||||
+ return self.code == other.code and self.linenum == other.linenum
|
|
||||||
+
|
|
||||||
+ def __ne__(self, other):
|
|
||||||
+ if other:
|
|
||||||
+ return self.code != other.code or self.linenum != other.linenum
|
|
||||||
+ else:
|
|
||||||
+ return True
|
|
||||||
+
|
|
||||||
+class CodeLoc(object):
|
|
||||||
+ # A codeloc is a specific location within the RPython bytecode
|
|
||||||
+ __slots__ = ('code', # code object
|
|
||||||
+ 'offset' # int index into bytecode, or -1
|
|
||||||
+ )
|
|
||||||
+
|
|
||||||
+ def __init__(self, code, offset):
|
|
||||||
+ self.code = code
|
|
||||||
+ self.offset = offset
|
|
||||||
+
|
|
||||||
+ def __str__(self):
|
|
||||||
+ if self.offset >= 0:
|
|
||||||
+ return "%s@%d" % (self.code.co_name, self.offset)
|
|
||||||
+ else:
|
|
||||||
+ return ""
|
|
||||||
+
|
|
||||||
+ def __ne__(self, other):
|
|
||||||
+ if other:
|
|
||||||
+ return self.code != other.code or self.offset != other.offset
|
|
||||||
+ else:
|
|
||||||
+ return True
|
|
||||||
+
|
|
||||||
+ def __cmp__(self, other):
|
|
||||||
+ # Partial ordering, for those locations that have an offset:
|
|
||||||
+ if other:
|
|
||||||
+ if self.offset >= 0 and other.offset >= 0:
|
|
||||||
+ return self.offset - other.offset
|
|
||||||
+ return 0
|
|
||||||
+
|
|
||||||
+ def get_source_loc(self):
|
|
||||||
+ # Convert to a SourceLoc:
|
|
||||||
+ return SourceLoc(self.code, self.code.get_linenum_for_offset(self.offset))
|
|
||||||
+
|
|
||||||
+class OperationLoc(object):
|
|
||||||
+ # An oploc is the location within the RPython source code of a given
|
|
||||||
+ # operation
|
|
||||||
+ #
|
|
||||||
+ # This is a list consisting of CodeLoc instances, some of which may be None
|
|
||||||
+ #
|
|
||||||
+ # For the simple case, this is list of length 1 with a single CodeLoc
|
|
||||||
+ #
|
|
||||||
+ # For an operation inside an inlined callsite, we have a list of length 2:
|
|
||||||
+ # [codeloc of callsite,
|
|
||||||
+ # codeloc of operation within inlined body]
|
|
||||||
+ #
|
|
||||||
+ # For more interesting inlined cases, we have a chain of source locations:
|
|
||||||
+ # [codeloc of callsite,
|
|
||||||
+ # codeloc of inner callsite,
|
|
||||||
+ # ... ,
|
|
||||||
+ # codeloc of innermost inlined callsite,
|
|
||||||
+ # codeloc of operation within inlined body]
|
|
||||||
+ #
|
|
||||||
+
|
|
||||||
+ __slots__ = ('codelocs', )
|
|
||||||
+
|
|
||||||
+ def __init__(self, codelocs):
|
|
||||||
+ self.codelocs = codelocs
|
|
||||||
+
|
|
||||||
+ def __str__(self):
|
|
||||||
+ return '[' + ' > '.join(str(codeloc) for codeloc in self.codelocs) + ']'
|
|
||||||
+
|
|
||||||
+ def __cmp__(self, other):
|
|
||||||
+ return cmp(self.codelocs, other.codelocs)
|
|
||||||
+
|
|
||||||
+def block_comparator(blk0, blk1):
|
|
||||||
+ '''
|
|
||||||
+ Sort function for blocks, putting them in an ordering that attempts to
|
|
||||||
+ maximize readability of the generated C code
|
|
||||||
+ '''
|
|
||||||
+ # print 'comparing %r and %r' % (blk0, blk1)
|
|
||||||
+ # Put the start/end block at the top/bottom:
|
|
||||||
+ if blk0.isstartblock:
|
|
||||||
+ return -1
|
|
||||||
+
|
|
||||||
+ if blk1.isstartblock:
|
|
||||||
+ return 1
|
|
||||||
+
|
|
||||||
+ # Order blocks by the offset, where present:
|
|
||||||
+ if blk0.operations:
|
|
||||||
+ if blk1.operations:
|
|
||||||
+ return cmp(blk0.operations[0].oploc, blk1.operations[0].oploc)
|
|
||||||
+ else:
|
|
||||||
+ return -1
|
|
||||||
+ else:
|
|
||||||
+ if blk1.operations:
|
|
||||||
+ return 1
|
|
||||||
+ else:
|
|
||||||
+ return 0
|
|
||||||
+
|
|
||||||
+def edge_comparator(edge0, edge1):
|
|
||||||
+ return block_comparator(edge0.target, edge1.target)
|
|
||||||
|
|
||||||
class FunctionGraph(object):
|
|
||||||
__slots__ = ['startblock', 'returnblock', 'exceptblock', '__dict__']
|
|
||||||
@@ -94,6 +208,21 @@ class FunctionGraph(object):
|
|
||||||
seen[block] = True
|
|
||||||
stack += block.exits[::-1]
|
|
||||||
|
|
||||||
+ def iterblocks_by_source(self):
|
|
||||||
+ # Try to preserve logical source ordering in the blocks
|
|
||||||
+ block = self.startblock
|
|
||||||
+ yield block
|
|
||||||
+ seen = {block: True}
|
|
||||||
+ stack = list(block.exits[::-1])
|
|
||||||
+ stack.sort(edge_comparator)
|
|
||||||
+ while stack:
|
|
||||||
+ block = stack.pop().target
|
|
||||||
+ if block not in seen:
|
|
||||||
+ yield block
|
|
||||||
+ seen[block] = True
|
|
||||||
+ stack += block.exits[::-1]
|
|
||||||
+ stack.sort(edge_comparator)
|
|
||||||
+
|
|
||||||
def iterlinks(self):
|
|
||||||
block = self.startblock
|
|
||||||
seen = {block: True}
|
|
||||||
@@ -183,14 +312,14 @@ class Block(object):
|
|
||||||
self.exits = [] # list of Link(s)
|
|
||||||
|
|
||||||
def at(self):
|
|
||||||
- if self.operations and self.operations[0].offset >= 0:
|
|
||||||
- return "@%d" % self.operations[0].offset
|
|
||||||
+ if self.operations:
|
|
||||||
+ return str(self.operations[0].oploc)
|
|
||||||
else:
|
|
||||||
return ""
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
if self.operations:
|
|
||||||
- txt = "block@%d" % self.operations[0].offset
|
|
||||||
+ txt = "block%s" % self.operations[0].oploc
|
|
||||||
else:
|
|
||||||
if (not self.exits) and len(self.inputargs) == 1:
|
|
||||||
txt = "return block"
|
|
||||||
@@ -245,6 +374,21 @@ class Block(object):
|
|
||||||
from pypy.translator.tool.graphpage import try_show
|
|
||||||
try_show(self)
|
|
||||||
|
|
||||||
+ def isreturnblock(self):
|
|
||||||
+ return (not self.operations) and (not self.exits) and len(self.inputargs) == 1
|
|
||||||
+
|
|
||||||
+ def get_base_label(self, blocknum):
|
|
||||||
+ # Generate a more friendly C label for this block
|
|
||||||
+ if self.operations:
|
|
||||||
+ txt = "block"
|
|
||||||
+ elif (not self.exits) and len(self.inputargs) == 1:
|
|
||||||
+ txt = "return_block"
|
|
||||||
+ elif (not self.exits) and len(self.inputargs) == 2:
|
|
||||||
+ txt = "raise_block"
|
|
||||||
+ else:
|
|
||||||
+ txt = "codeless_block"
|
|
||||||
+ return '%s%d' % (txt, blocknum)
|
|
||||||
+
|
|
||||||
|
|
||||||
class Variable(object):
|
|
||||||
__slots__ = ["_name", "_nr", "concretetype"]
|
|
||||||
@@ -331,13 +475,15 @@ class WrapException(Exception):
|
|
||||||
|
|
||||||
|
|
||||||
class SpaceOperation(object):
|
|
||||||
- __slots__ = "opname args result offset".split()
|
|
||||||
+ __slots__ = "opname args result oploc".split()
|
|
||||||
|
|
||||||
- def __init__(self, opname, args, result, offset=-1):
|
|
||||||
+ def __init__(self, opname, args, result, oploc=None):
|
|
||||||
self.opname = intern(opname) # operation name
|
|
||||||
self.args = list(args) # mixed list of var/const
|
|
||||||
self.result = result # either Variable or Constant instance
|
|
||||||
- self.offset = offset # offset in code string
|
|
||||||
+ if oploc is None:
|
|
||||||
+ oploc = OperationLoc([None])
|
|
||||||
+ self.oploc = oploc
|
|
||||||
|
|
||||||
def __eq__(self, other):
|
|
||||||
return (self.__class__ is other.__class__ and
|
|
||||||
@@ -352,8 +498,9 @@ class SpaceOperation(object):
|
|
||||||
return hash((self.opname,tuple(self.args),self.result))
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
- return "%r = %s(%s)" % (self.result, self.opname,
|
|
||||||
- ", ".join(map(repr, self.args)))
|
|
||||||
+ return "%r = %s(%s) (%s)" % (self.result, self.opname,
|
|
||||||
+ ", ".join(map(repr, self.args)),
|
|
||||||
+ self.oploc)
|
|
||||||
|
|
||||||
class Atom(object):
|
|
||||||
def __init__(self, name):
|
|
||||||
@@ -427,8 +574,7 @@ def copygraph(graph, shallow=False, varm
|
|
||||||
for op in oplist:
|
|
||||||
copyop = SpaceOperation(op.opname,
|
|
||||||
[copyvar(v) for v in op.args],
|
|
||||||
- copyvar(op.result), op.offset)
|
|
||||||
- #copyop.offset = op.offset
|
|
||||||
+ copyvar(op.result), op.oploc)
|
|
||||||
result.append(copyop)
|
|
||||||
return result
|
|
||||||
newblock.operations = copyoplist(block.operations)
|
|
||||||
diff -up pypy-pypy-release-1.7/pypy/objspace/flow/objspace.py.more-readable-c-code pypy-pypy-release-1.7/pypy/objspace/flow/objspace.py
|
|
||||||
--- pypy-pypy-release-1.7/pypy/objspace/flow/objspace.py.more-readable-c-code 2011-11-19 02:44:54.000000000 -0500
|
|
||||||
+++ pypy-pypy-release-1.7/pypy/objspace/flow/objspace.py 2011-11-21 16:15:36.600466455 -0500
|
|
||||||
@@ -315,7 +315,9 @@ class FlowObjSpace(ObjSpace):
|
|
||||||
def do_operation(self, name, *args_w):
|
|
||||||
spaceop = SpaceOperation(name, args_w, Variable())
|
|
||||||
if hasattr(self, 'executioncontext'): # not here during bootstrapping
|
|
||||||
- spaceop.offset = self.executioncontext.crnt_offset
|
|
||||||
+ codeloc = CodeLoc(self.executioncontext.code,
|
|
||||||
+ self.executioncontext.crnt_offset)
|
|
||||||
+ spaceop.oploc = OperationLoc([codeloc])
|
|
||||||
self.executioncontext.recorder.append(spaceop)
|
|
||||||
return spaceop.result
|
|
||||||
|
|
||||||
diff -up pypy-pypy-release-1.7/pypy/objspace/flow/test/test_model.py.more-readable-c-code pypy-pypy-release-1.7/pypy/objspace/flow/test/test_model.py
|
|
||||||
--- pypy-pypy-release-1.7/pypy/objspace/flow/test/test_model.py.more-readable-c-code 2011-11-19 02:44:54.000000000 -0500
|
|
||||||
+++ pypy-pypy-release-1.7/pypy/objspace/flow/test/test_model.py 2011-11-21 16:15:36.600466455 -0500
|
|
||||||
@@ -119,3 +119,25 @@ def test_variable():
|
|
||||||
assert v2.renamed
|
|
||||||
assert v2.name.startswith("foobar_") and v2.name != v.name
|
|
||||||
assert v2.name.split('_', 1)[1].isdigit()
|
|
||||||
+
|
|
||||||
+def test_source_locations():
|
|
||||||
+ # Invent some random offsets into the code:
|
|
||||||
+ co = sample_function.__code__
|
|
||||||
+ codelocA = CodeLoc(co, 42)
|
|
||||||
+ codelocB = CodeLoc(co, 87)
|
|
||||||
+
|
|
||||||
+ assert str(codelocA) == 'sample_function@42'
|
|
||||||
+ assert str(codelocB) == 'sample_function@87'
|
|
||||||
+
|
|
||||||
+ assert cmp(codelocA, codelocB) < 0
|
|
||||||
+ assert cmp(codelocB, codelocA) > 0
|
|
||||||
+
|
|
||||||
+ oplocA = OperationLoc([codelocA])
|
|
||||||
+ oplocB = OperationLoc([codelocB])
|
|
||||||
+
|
|
||||||
+ assert str(oplocA) == '[sample_function@42]'
|
|
||||||
+ assert str(oplocB) == '[sample_function@87]'
|
|
||||||
+
|
|
||||||
+ assert cmp(oplocA, oplocB) < 0
|
|
||||||
+ assert cmp(oplocB, oplocA) > 0
|
|
||||||
+
|
|
||||||
diff -up pypy-pypy-release-1.7/pypy/rpython/rtyper.py.more-readable-c-code pypy-pypy-release-1.7/pypy/rpython/rtyper.py
|
|
||||||
--- pypy-pypy-release-1.7/pypy/rpython/rtyper.py.more-readable-c-code 2011-11-19 02:44:54.000000000 -0500
|
|
||||||
+++ pypy-pypy-release-1.7/pypy/rpython/rtyper.py 2011-11-21 16:15:36.601466455 -0500
|
|
||||||
@@ -800,7 +800,7 @@ class HighLevelOp(object):
|
|
||||||
return vars
|
|
||||||
|
|
||||||
def genop(self, opname, args_v, resulttype=None):
|
|
||||||
- return self.llops.genop(opname, args_v, resulttype)
|
|
||||||
+ return self.llops.genop(opname, args_v, resulttype, self.spaceop.oploc)
|
|
||||||
|
|
||||||
def gendirectcall(self, ll_function, *args_v):
|
|
||||||
return self.llops.gendirectcall(ll_function, *args_v)
|
|
||||||
@@ -935,7 +935,7 @@ class LowLevelOpList(list):
|
|
||||||
v.concretetype))
|
|
||||||
return v
|
|
||||||
|
|
||||||
- def genop(self, opname, args_v, resulttype=None):
|
|
||||||
+ def genop(self, opname, args_v, resulttype=None, oploc=None):
|
|
||||||
try:
|
|
||||||
for v in args_v:
|
|
||||||
v.concretetype
|
|
||||||
@@ -944,7 +944,7 @@ class LowLevelOpList(list):
|
|
||||||
" and pass its result to genop(),"
|
|
||||||
" never hop.args_v directly.")
|
|
||||||
vresult = Variable()
|
|
||||||
- self.append(SpaceOperation(opname, args_v, vresult))
|
|
||||||
+ self.append(SpaceOperation(opname, args_v, vresult, oploc))
|
|
||||||
if resulttype is None:
|
|
||||||
vresult.concretetype = Void
|
|
||||||
return None
|
|
||||||
diff -up pypy-pypy-release-1.7/pypy/translator/backendopt/inline.py.more-readable-c-code pypy-pypy-release-1.7/pypy/translator/backendopt/inline.py
|
|
||||||
--- pypy-pypy-release-1.7/pypy/translator/backendopt/inline.py.more-readable-c-code 2011-11-19 02:44:54.000000000 -0500
|
|
||||||
+++ pypy-pypy-release-1.7/pypy/translator/backendopt/inline.py 2011-11-21 16:15:36.601466455 -0500
|
|
||||||
@@ -4,6 +4,7 @@ from pypy.translator.simplify import get
|
|
||||||
from pypy.translator.unsimplify import copyvar
|
|
||||||
from pypy.objspace.flow.model import Variable, Constant, Block, Link
|
|
||||||
from pypy.objspace.flow.model import SpaceOperation, c_last_exception
|
|
||||||
+from pypy.objspace.flow.model import OperationLoc
|
|
||||||
from pypy.objspace.flow.model import FunctionGraph
|
|
||||||
from pypy.objspace.flow.model import mkentrymap, checkgraph
|
|
||||||
from pypy.annotation import model as annmodel
|
|
||||||
@@ -231,6 +232,7 @@ class BaseInliner(object):
|
|
||||||
self.varmap = {}
|
|
||||||
self._copied_blocks = {}
|
|
||||||
self.op = block.operations[index_operation]
|
|
||||||
+ self.callsite_oploc = self.op.oploc
|
|
||||||
self.graph_to_inline = self.get_graph_from_op(self.op)
|
|
||||||
self.exception_guarded = False
|
|
||||||
if (block.exitswitch == c_last_exception and
|
|
||||||
@@ -290,7 +292,9 @@ class BaseInliner(object):
|
|
||||||
|
|
||||||
def copy_operation(self, op):
|
|
||||||
args = [self.get_new_name(arg) for arg in op.args]
|
|
||||||
- result = SpaceOperation(op.opname, args, self.get_new_name(op.result))
|
|
||||||
+ new_oploc = OperationLoc(self.callsite_oploc.codelocs[:] + op.oploc.codelocs[:])
|
|
||||||
+ result = SpaceOperation(op.opname, args, self.get_new_name(op.result),
|
|
||||||
+ new_oploc)
|
|
||||||
return result
|
|
||||||
|
|
||||||
def copy_block(self, block):
|
|
||||||
diff -up pypy-pypy-release-1.7/pypy/translator/c/funcgen.py.more-readable-c-code pypy-pypy-release-1.7/pypy/translator/c/funcgen.py
|
|
||||||
--- pypy-pypy-release-1.7/pypy/translator/c/funcgen.py.more-readable-c-code 2011-11-19 02:44:54.000000000 -0500
|
|
||||||
+++ pypy-pypy-release-1.7/pypy/translator/c/funcgen.py 2011-11-21 16:15:36.602466455 -0500
|
|
||||||
@@ -1,4 +1,6 @@
|
|
||||||
import sys
|
|
||||||
+import inspect
|
|
||||||
+import dis
|
|
||||||
from pypy.translator.c.support import USESLOTS # set to False if necessary while refactoring
|
|
||||||
from pypy.translator.c.support import cdecl
|
|
||||||
from pypy.translator.c.support import llvalue_from_constant, gen_assignments
|
|
||||||
@@ -22,6 +24,38 @@ LOCALVAR = 'l_%s'
|
|
||||||
|
|
||||||
KEEP_INLINED_GRAPHS = False
|
|
||||||
|
|
||||||
+def block_comparator(blk0, blk1):
|
|
||||||
+ '''
|
|
||||||
+ Sort function for blocks, putting them in an ordering that attempts to
|
|
||||||
+ maximize readability of the generated C code
|
|
||||||
+ '''
|
|
||||||
+ # print 'comparing %r and %r' % (blk0, blk1)
|
|
||||||
+ # Put the start/end block at the top/bottom:
|
|
||||||
+ if blk0.isstartblock:
|
|
||||||
+ return -1
|
|
||||||
+
|
|
||||||
+ if blk1.isstartblock:
|
|
||||||
+ return 1
|
|
||||||
+
|
|
||||||
+ # Order blocks by the offset, where present:
|
|
||||||
+ if blk0.operations:
|
|
||||||
+ if blk1.operations:
|
|
||||||
+ return cmp(blk0.operations[0].oploc, blk1.operations[0].oploc)
|
|
||||||
+ else:
|
|
||||||
+ return -1
|
|
||||||
+ else:
|
|
||||||
+ if blk1.operations:
|
|
||||||
+ return 1
|
|
||||||
+ else:
|
|
||||||
+ return 0
|
|
||||||
+
|
|
||||||
+def escape_c_comments(py_src):
|
|
||||||
+ # Escape C comments within RPython source, to avoid generating bogus
|
|
||||||
+ # comments in our generated C source:
|
|
||||||
+ py_src = py_src.replace('/*', '')
|
|
||||||
+ py_src = py_src.replace('*/', '')
|
|
||||||
+ return py_src
|
|
||||||
+
|
|
||||||
class FunctionCodeGenerator(object):
|
|
||||||
"""
|
|
||||||
Collects information about a function which we have to generate
|
|
||||||
@@ -207,14 +241,57 @@ class FunctionCodeGenerator(object):
|
|
||||||
|
|
||||||
def cfunction_body(self):
|
|
||||||
graph = self.graph
|
|
||||||
- yield 'goto block0;' # to avoid a warning "this label is not used"
|
|
||||||
+ # Try to print python source code:
|
|
||||||
+ if hasattr(graph, 'func'):
|
|
||||||
+ filename = inspect.getfile(graph.func)
|
|
||||||
+ #yield '/* name: %r */' % filename
|
|
||||||
+ try:
|
|
||||||
+ src, startline = inspect.getsourcelines(graph.func)
|
|
||||||
+ except IOError:
|
|
||||||
+ pass # No source found
|
|
||||||
+ except IndexError:
|
|
||||||
+ pass # Bulletproofing
|
|
||||||
+ else:
|
|
||||||
+ yield '/* Python source %r' % filename
|
|
||||||
+ for i, line in enumerate(src):
|
|
||||||
+ line = line.rstrip()
|
|
||||||
+ line = escape_c_comments(line)
|
|
||||||
+ # FuncNode.funcgen_implementation treats lines ending in ':'
|
|
||||||
+ # as C blocks, which messes up the formatting.
|
|
||||||
+ # Work around this:
|
|
||||||
+ if line.endswith(':'):
|
|
||||||
+ line += ' '
|
|
||||||
+ yield ' * %4d : %s' % (startline + i, line)
|
|
||||||
+ yield ' */'
|
|
||||||
+
|
|
||||||
+ label = graph.startblock.get_base_label(self.blocknum[graph.startblock])
|
|
||||||
+ yield 'goto %s;' % label # to avoid a warning "this label is not used"
|
|
||||||
+
|
|
||||||
+ # Sort the blocks into a (hopefully) readable order:
|
|
||||||
+ blocks = list(graph.iterblocks_by_source())
|
|
||||||
+ blocks.sort(block_comparator)
|
|
||||||
|
|
||||||
# generate the body of each block
|
|
||||||
- for block in graph.iterblocks():
|
|
||||||
+ for block in blocks:
|
|
||||||
+ cursrcloc = None
|
|
||||||
myblocknum = self.blocknum[block]
|
|
||||||
yield ''
|
|
||||||
- yield 'block%d:' % myblocknum
|
|
||||||
+ yield '%s:' % block.get_base_label(myblocknum)
|
|
||||||
+ #yield "/* repr(block): %r */" % (block, )
|
|
||||||
+ #yield "/* type(block): %r */" % (type(block), )
|
|
||||||
for i, op in enumerate(block.operations):
|
|
||||||
+ #yield "/* type(op): %r */" % (type(op), )
|
|
||||||
+ #yield "/* op.oploc: %s */" % (op.oploc, )
|
|
||||||
+ codeloc = op.oploc.codelocs[-1]
|
|
||||||
+ if codeloc:
|
|
||||||
+ srcloc = codeloc.get_source_loc()
|
|
||||||
+ if srcloc != cursrcloc:
|
|
||||||
+ try:
|
|
||||||
+ yield "/* %s:%d : %s */" % (codeloc.code.co_name, srcloc.linenum, escape_c_comments(srcloc.get_text()))
|
|
||||||
+ cursrcloc = srcloc
|
|
||||||
+ except IOError:
|
|
||||||
+ pass
|
|
||||||
+
|
|
||||||
for line in self.gen_op(op):
|
|
||||||
yield line
|
|
||||||
if len(block.exits) == 0:
|
|
||||||
@@ -306,7 +383,7 @@ class FunctionCodeGenerator(object):
|
|
||||||
assignments.append((a2typename, dest, src))
|
|
||||||
for line in gen_assignments(assignments):
|
|
||||||
yield line
|
|
||||||
- label = 'block%d' % self.blocknum[link.target]
|
|
||||||
+ label = link.target.get_base_label(self.blocknum[link.target])
|
|
||||||
if link.target in self.innerloops:
|
|
||||||
loop = self.innerloops[link.target]
|
|
||||||
if link is loop.links[-1]: # link that ends a loop
|
|
||||||
diff -up pypy-pypy-release-1.7/pypy/translator/c/test/test_genc.py.more-readable-c-code pypy-pypy-release-1.7/pypy/translator/c/test/test_genc.py
|
|
||||||
--- pypy-pypy-release-1.7/pypy/translator/c/test/test_genc.py.more-readable-c-code 2011-11-19 02:44:54.000000000 -0500
|
|
||||||
+++ pypy-pypy-release-1.7/pypy/translator/c/test/test_genc.py 2011-11-21 16:15:36.602466455 -0500
|
|
||||||
@@ -1,4 +1,5 @@
|
|
||||||
import autopath, sys, os, py
|
|
||||||
+import re
|
|
||||||
from pypy.rpython.lltypesystem.lltype import *
|
|
||||||
from pypy.annotation import model as annmodel
|
|
||||||
from pypy.translator.translator import TranslationContext
|
|
||||||
@@ -532,3 +533,130 @@ def test_inhibit_tail_call():
|
|
||||||
else:
|
|
||||||
assert 0, "the call was not found in the C source"
|
|
||||||
assert 'PYPY_INHIBIT_TAIL_CALL();' in lines[i+1]
|
|
||||||
+
|
|
||||||
+def get_generated_c_source(fn, types):
|
|
||||||
+ # Return a (optimized fn, c source code, c source filename) 3-tuple
|
|
||||||
+ t = Translation(fn)
|
|
||||||
+ t.annotate(types)
|
|
||||||
+ c_filename_path = t.source_c()
|
|
||||||
+ h = c_filename_path.open()
|
|
||||||
+ src = h.read()
|
|
||||||
+ h.close()
|
|
||||||
+ c_fn = t.compile_c()
|
|
||||||
+ return (c_fn, src, c_filename_path)
|
|
||||||
+
|
|
||||||
+def extract_c_function(c_src, fname):
|
|
||||||
+ # Extract the source for a given C function out of a the given src string
|
|
||||||
+ # Makes assumptions about the layout of the source
|
|
||||||
+ pattern = '^(.+) \**%s\(.*\) {$' % fname
|
|
||||||
+ within_fn = False
|
|
||||||
+ result = ''
|
|
||||||
+ for line in c_src.splitlines():
|
|
||||||
+ if within_fn:
|
|
||||||
+ result += line + '\n'
|
|
||||||
+ if line.startswith('}'):
|
|
||||||
+ return result
|
|
||||||
+ else:
|
|
||||||
+ m = re.match(pattern, line)
|
|
||||||
+ if m:
|
|
||||||
+ within_fn = True
|
|
||||||
+ result += line + '\n'
|
|
||||||
+ return result
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+def test_generated_c_source():
|
|
||||||
+ # Verify that generate C source "looks good"
|
|
||||||
+ # We'll use is_perfect_number, as it contains a loop and a conditional
|
|
||||||
+
|
|
||||||
+ # Generate C source code
|
|
||||||
+ from pypy.translator.test.snippet import is_perfect_number
|
|
||||||
+ c_fn, c_src, c_filename_path = get_generated_c_source(is_perfect_number,
|
|
||||||
+ [int])
|
|
||||||
+
|
|
||||||
+ # Locate the C source for the type-specialized function:
|
|
||||||
+ c_fn_src = extract_c_function(c_src, 'pypy_g_is_perfect_number')
|
|
||||||
+
|
|
||||||
+ # Verify that the C source contains embedded comments containing the lines
|
|
||||||
+ # of the python source:
|
|
||||||
+ expected_comment_lines = [
|
|
||||||
+ '/* is_perfect_number:31 : while div < n: */',
|
|
||||||
+ '/* is_perfect_number:32 : if n % div == 0: */',
|
|
||||||
+ '/* is_perfect_number:33 : sum += div */',
|
|
||||||
+ '/* is_perfect_number:34 : div += 1 */',
|
|
||||||
+ '/* is_perfect_number:35 : return n == sum */']
|
|
||||||
+ for exp_line in expected_comment_lines:
|
|
||||||
+ assert exp_line in c_fn_src
|
|
||||||
+
|
|
||||||
+ # Verify that the lines occur in the correct order
|
|
||||||
+ # ...we do this by filtering the function's generated C source to just
|
|
||||||
+ # those lines containing our comments (and dropping whitespace):
|
|
||||||
+ lines = c_fn_src.splitlines()
|
|
||||||
+ lines = [line.strip()
|
|
||||||
+ for line in lines
|
|
||||||
+ if '/* is_perfect_number:' in line]
|
|
||||||
+
|
|
||||||
+ # ...we should now have exact equality: the ordering should be as expected,
|
|
||||||
+ # and each comment should appear exactly once:
|
|
||||||
+ assert lines == expected_comment_lines
|
|
||||||
+
|
|
||||||
+ # Ensure that the generated C function does the right thing:
|
|
||||||
+ assert c_fn(5) == False
|
|
||||||
+ assert c_fn(6) == True
|
|
||||||
+ assert c_fn(7) == False
|
|
||||||
+
|
|
||||||
+ assert c_fn(5.0) == False
|
|
||||||
+ assert c_fn(6.0) == True
|
|
||||||
+ assert c_fn(7.0) == False
|
|
||||||
+
|
|
||||||
+ assert c_fn(5L) == False
|
|
||||||
+ assert c_fn(6L) == True
|
|
||||||
+ assert c_fn(7L) == False
|
|
||||||
+
|
|
||||||
+ try:
|
|
||||||
+ c_fn('hello world')
|
|
||||||
+ except:
|
|
||||||
+ pass
|
|
||||||
+ else:
|
|
||||||
+ raise 'Was expected exception'
|
|
||||||
+
|
|
||||||
+def test_escaping_c_comments():
|
|
||||||
+ # Ensure that c comments within RPython code get escaped when we generate
|
|
||||||
+ # our .c code (to avoid generating bogus C)
|
|
||||||
+ # See e.g. pypy.module.cpyext.dictobject's PyDict_Next, which has a
|
|
||||||
+ # docstring embedding a C comment
|
|
||||||
+ def c_style_comment(a, b):
|
|
||||||
+ '''Here is a C-style comment within an RPython docstring:
|
|
||||||
+ /* hello world */
|
|
||||||
+ '''
|
|
||||||
+ # and here's one in a string literal:
|
|
||||||
+ return '/* hello world a:%s b:%s */' % (a, b)
|
|
||||||
+
|
|
||||||
+ def cplusplus_style_comment(a, b):
|
|
||||||
+ '''Here is a C++-style comment within an RPython docstring:
|
|
||||||
+ // hello world
|
|
||||||
+ '''
|
|
||||||
+ # and here are some in string literals, and one as the floor division
|
|
||||||
+ # operator:
|
|
||||||
+ return '// hello world: a // b = %s' % (a // b)
|
|
||||||
+
|
|
||||||
+ for fn_name, exp_output in [('c_style_comment',
|
|
||||||
+ '/* hello world a:6 b:3 */'),
|
|
||||||
+ ('cplusplus_style_comment',
|
|
||||||
+ '// hello world: a // b = 2')]:
|
|
||||||
+ fn = locals()[fn_name]
|
|
||||||
+
|
|
||||||
+ c_fn, c_src, c_filename_path = get_generated_c_source(fn, [int, int])
|
|
||||||
+ # If the above survived, then the C compiler managed to handle
|
|
||||||
+ # the generated C code
|
|
||||||
+
|
|
||||||
+ # Verify that the generated code works (i.e. that we didn't
|
|
||||||
+ # accidentally change the meaning):
|
|
||||||
+ assert c_fn(6, 3) == exp_output
|
|
||||||
+
|
|
||||||
+ # Ensure that at least part of the docstrings made it into the C
|
|
||||||
+ # code:
|
|
||||||
+ c_fn_src = extract_c_function(c_src, 'pypy_g_' + fn_name)
|
|
||||||
+ assert 'Here is a ' in c_fn_src
|
|
||||||
+ assert 'style comment within an RPython docstring' in c_fn_src
|
|
||||||
+
|
|
||||||
diff -up pypy-pypy-release-1.7/pypy/translator/driver.py.more-readable-c-code pypy-pypy-release-1.7/pypy/translator/driver.py
|
|
||||||
--- pypy-pypy-release-1.7/pypy/translator/driver.py.more-readable-c-code 2011-11-19 02:44:54.000000000 -0500
|
|
||||||
+++ pypy-pypy-release-1.7/pypy/translator/driver.py 2011-11-21 16:15:36.603466455 -0500
|
|
||||||
@@ -535,6 +535,7 @@ class TranslationDriver(SimpleTaskEngine
|
|
||||||
dstname = self.compute_exe_name() + '.staticdata.info'
|
|
||||||
shutil.copy(str(fname), str(dstname))
|
|
||||||
self.log.info('Static data info written to %s' % dstname)
|
|
||||||
+ return c_source_filename
|
|
||||||
|
|
||||||
#
|
|
||||||
task_source_c = taskdef(task_source_c, ['database_c'], "Generating c source")
|
|
||||||
diff -up pypy-pypy-release-1.7/pypy/translator/gensupp.py.more-readable-c-code pypy-pypy-release-1.7/pypy/translator/gensupp.py
|
|
||||||
--- pypy-pypy-release-1.7/pypy/translator/gensupp.py.more-readable-c-code 2011-11-19 02:44:54.000000000 -0500
|
|
||||||
+++ pypy-pypy-release-1.7/pypy/translator/gensupp.py 2011-11-21 16:15:36.603466455 -0500
|
|
||||||
@@ -14,8 +14,8 @@ def ordered_blocks(graph):
|
|
||||||
allblocks = []
|
|
||||||
for block in graph.iterblocks():
|
|
||||||
# first we order by offset in the code string
|
|
||||||
- if block.operations:
|
|
||||||
- ofs = block.operations[0].offset
|
|
||||||
+ if block.operations and block.operations[0].oploc.codelocs[0]:
|
|
||||||
+ ofs = block.operations[0].oploc.codelocs[0].offset
|
|
||||||
else:
|
|
||||||
ofs = sys.maxint
|
|
||||||
# then we order by input variable name or value
|
|
||||||
diff -up pypy-pypy-release-1.7/pypy/translator/interactive.py.more-readable-c-code pypy-pypy-release-1.7/pypy/translator/interactive.py
|
|
||||||
--- pypy-pypy-release-1.7/pypy/translator/interactive.py.more-readable-c-code 2011-11-19 02:44:54.000000000 -0500
|
|
||||||
+++ pypy-pypy-release-1.7/pypy/translator/interactive.py 2011-11-21 16:15:36.604466454 -0500
|
|
||||||
@@ -138,7 +138,7 @@ class Translation(object):
|
|
||||||
def source_c(self, argtypes=None, **kwds):
|
|
||||||
self.update_options(argtypes, kwds)
|
|
||||||
self.ensure_backend('c')
|
|
||||||
- self.driver.source_c()
|
|
||||||
+ return self.driver.source_c()
|
|
||||||
|
|
||||||
def source_cl(self, argtypes=None, **kwds):
|
|
||||||
self.update_options(argtypes, kwds)
|
|
||||||
diff -up pypy-pypy-release-1.7/pypy/translator/llsupport/wrapper.py.more-readable-c-code pypy-pypy-release-1.7/pypy/translator/llsupport/wrapper.py
|
|
||||||
--- pypy-pypy-release-1.7/pypy/translator/llsupport/wrapper.py.more-readable-c-code 2011-11-19 02:44:54.000000000 -0500
|
|
||||||
+++ pypy-pypy-release-1.7/pypy/translator/llsupport/wrapper.py 2011-11-21 16:15:36.604466454 -0500
|
|
||||||
@@ -59,6 +59,8 @@ def new_wrapper(func, translator, newnam
|
|
||||||
# "return result"
|
|
||||||
block = Block(wrapper_inputargs)
|
|
||||||
wgraph = FunctionGraph('pyfn_' + (newname or func.func_name), block)
|
|
||||||
+ if hasattr(graph, 'func'):
|
|
||||||
+ wgraph.func = graph.func
|
|
||||||
translator.update_call_graph(wgraph, graph, object())
|
|
||||||
translator.graphs.append(wgraph)
|
|
||||||
block.operations[:] = newops
|
|
||||||
diff -up pypy-pypy-release-1.7/pypy/translator/simplify.py.more-readable-c-code pypy-pypy-release-1.7/pypy/translator/simplify.py
|
|
||||||
--- pypy-pypy-release-1.7/pypy/translator/simplify.py.more-readable-c-code 2011-11-19 02:44:54.000000000 -0500
|
|
||||||
+++ pypy-pypy-release-1.7/pypy/translator/simplify.py 2011-11-21 16:15:36.605466454 -0500
|
|
||||||
@@ -292,7 +292,7 @@ def join_blocks(graph):
|
|
||||||
return renaming.get(v, v)
|
|
||||||
def rename_op(op):
|
|
||||||
args = [rename(a) for a in op.args]
|
|
||||||
- op = SpaceOperation(op.opname, args, rename(op.result), op.offset)
|
|
||||||
+ op = SpaceOperation(op.opname, args, rename(op.result), op.oploc)
|
|
||||||
# special case...
|
|
||||||
if op.opname == 'indirect_call':
|
|
||||||
if isinstance(op.args[0], Constant):
|
|
@ -1,12 +0,0 @@
|
|||||||
diff -rup pypy-pypy-f66246c46ca3/lib-python/2.7/test/test_subprocess.py pypy-pypy-f66246c46ca3/lib-python/2.7/test/test_subprocess.py
|
|
||||||
--- pypy-pypy-f66246c46ca3/lib-python/2.7/test/test_subprocess.py 2013-05-27 10:35:37.762237806 +0200
|
|
||||||
+++ pypy-pypy-f66246c46ca3/lib-python/2.7/test/test_subprocess.py 2013-05-28 10:13:03.182536196 +0200
|
|
||||||
@@ -587,7 +587,7 @@ class ProcessTestCase(BaseTestCase):
|
|
||||||
for i in range(1024):
|
|
||||||
# Windows raises IOError. Others raise OSError.
|
|
||||||
with self.assertRaises(EnvironmentError) as c:
|
|
||||||
- subprocess.Popen(['nonexisting_i_hope'],
|
|
||||||
+ subprocess.Popen(['/usr/bin/nonexisting_i_hope'],
|
|
||||||
stdout=subprocess.PIPE,
|
|
||||||
stderr=subprocess.PIPE)
|
|
||||||
# ignore errors that indicate the command was not found
|
|
Loading…
Reference in New Issue
Block a user