[pypy-svn] r50432 - pypy/branch/simpler-pyassem/pypy/interpreter/astcompiler
arigo at codespeak.net
arigo at codespeak.net
Mon Jan 7 19:06:15 CET 2008
Author: arigo
Date: Mon Jan 7 19:06:14 2008
New Revision: 50432
Modified:
pypy/branch/simpler-pyassem/pypy/interpreter/astcompiler/pyassem.py
Log:
lnotab, copied from the previous pyassem.
Modified: pypy/branch/simpler-pyassem/pypy/interpreter/astcompiler/pyassem.py
==============================================================================
--- pypy/branch/simpler-pyassem/pypy/interpreter/astcompiler/pyassem.py (original)
+++ pypy/branch/simpler-pyassem/pypy/interpreter/astcompiler/pyassem.py Mon Jan 7 19:06:14 2008
@@ -45,6 +45,7 @@
self.co_code = []
# Pending label targets to fix: [(label, index-in-co_code-to-fix, abs)]
self.pending_label_fixes = []
+ self.lnotab = None
def setDocstring(self, w_docstring):
self.w_docstring = w_docstring
@@ -78,10 +79,18 @@
return intval & 0xFFFF
emitop_extended_arg._dont_inline_ = True
+ def emitop_setlineno(self, lineno):
+ if self.lnotab is None:
+ self.lnotab = LineAddrTable(lineno)
+ else:
+ self.lnotab.nextLine(len(self.co_code), lineno)
+ emitop_setlineno._dont_inline_ = True
+
def emitop_int(self, opname, intval):
assert intval >= 0
if opname == "SET_LINENO":
- return # XXX
+ self.emitop_setlineno(intval)
+ return
if intval > 0xFFFF:
intval = self.emitop_extended_arg(intval)
self.emit(opname)
@@ -340,6 +349,12 @@
argcount = self.argcount
if self.flags & CO_VARKEYWORDS:
argcount = argcount - 1
+ if self.lnotab is None: # obscure case
+ firstline = 0
+ lnotab = ""
+ else:
+ firstline = self.lnotab.firstline
+ lnotab = self.lnotab.getTable()
return PyCode( self.space, argcount, nlocals,
self.stacksize, self.flags,
''.join(self.co_code),
@@ -347,8 +362,8 @@
self.names,
self.varnames,
self.filename, self.name,
- 1, # XXX! self.firstline,
- "", # XXX! self.lnotab.getTable(),
+ firstline,
+ lnotab,
self.freevars,
self.cellvars
)
@@ -375,6 +390,61 @@
position = -1
# ____________________________________________________________
+# Encoding the line numbers in lnotab
+
+class LineAddrTable:
+ """lnotab
+
+ This class builds the lnotab, which is documented in compile.c.
+ Here's a brief recap:
+
+ For each SET_LINENO instruction after the first one, two bytes are
+ added to lnotab. (In some cases, multiple two-byte entries are
+ added.) The first byte is the distance in bytes between the
+ instruction for the last SET_LINENO and the current SET_LINENO.
+ The second byte is offset in line numbers. If either offset is
+ greater than 255, multiple two-byte entries are added -- see
+ compile.c for the delicate details.
+ """
+
+ def __init__(self, firstline):
+ self.firstline = firstline
+ self.lastline = firstline
+ self.lastoff = 0
+ self.lnotab = [] # list of characters
+
+ def nextLine(self, codeOffset, lineno):
+ # compute deltas
+ addr = codeOffset - self.lastoff
+ line = lineno - self.lastline
+ # Python assumes that lineno always increases with
+ # increasing bytecode address (lnotab is unsigned char).
+ # Depending on when SET_LINENO instructions are emitted
+ # this is not always true. Consider the code:
+ # a = (1,
+ # b)
+ # In the bytecode stream, the assignment to "a" occurs
+ # after the loading of "b". This works with the C Python
+ # compiler because it only generates a SET_LINENO instruction
+ # for the assignment.
+ if line >= 0:
+ push = self.lnotab.append
+ while addr > 255:
+ push(chr(255)); push(chr(0))
+ addr -= 255
+ while line > 255:
+ push(chr(addr)); push(chr(255))
+ line -= 255
+ addr = 0
+ if addr > 0 or line > 0:
+ push(chr(addr)); push(chr(line))
+ self.lastline = lineno
+ self.lastoff = codeOffset
+
+ def getTable(self):
+ return ''.join(self.lnotab)
+
+# ____________________________________________________________
# Stack depth tracking
def depth_UNPACK_SEQUENCE(count):
More information about the Pypy-commit
mailing list