mirror of https://github.com/python/cpython
patch by Neil Schemenauer to improve (fix?) line number generation
This commit is contained in:
parent
3620857d60
commit
92f3972090
|
@ -419,21 +419,32 @@ class LineAddrTable:
|
|||
# compute deltas
|
||||
addr = self.codeOffset - self.lastoff
|
||||
line = lineno - self.lastline
|
||||
while addr > 0 or line > 0:
|
||||
# write the values in 1-byte chunks that sum
|
||||
# to desired value
|
||||
trunc_addr = addr
|
||||
trunc_line = line
|
||||
if trunc_addr > 255:
|
||||
trunc_addr = 255
|
||||
if trunc_line > 255:
|
||||
trunc_line = 255
|
||||
self.lnotab.append(trunc_addr)
|
||||
self.lnotab.append(trunc_line)
|
||||
addr = addr - trunc_addr
|
||||
line = line - trunc_line
|
||||
self.lastline = lineno
|
||||
self.lastoff = self.codeOffset
|
||||
# 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:
|
||||
while addr > 0 or line > 0:
|
||||
# write the values in 1-byte chunks that sum
|
||||
# to desired value
|
||||
trunc_addr = addr
|
||||
trunc_line = line
|
||||
if trunc_addr > 255:
|
||||
trunc_addr = 255
|
||||
if trunc_line > 255:
|
||||
trunc_line = 255
|
||||
self.lnotab.append(trunc_addr)
|
||||
self.lnotab.append(trunc_line)
|
||||
addr = addr - trunc_addr
|
||||
line = line - trunc_line
|
||||
self.lastline = lineno
|
||||
self.lastoff = self.codeOffset
|
||||
|
||||
def getCode(self):
|
||||
return string.join(self.code, '')
|
||||
|
|
|
@ -70,6 +70,7 @@ class CodeGenerator:
|
|||
self.loops = misc.Stack()
|
||||
self.curStack = 0
|
||||
self.maxStack = 0
|
||||
self.last_lineno = None
|
||||
self._setupGraphDelegation()
|
||||
|
||||
def _setupGraphDelegation(self):
|
||||
|
@ -107,7 +108,8 @@ class CodeGenerator:
|
|||
self.emit(prefix + '_GLOBAL', name)
|
||||
|
||||
def set_lineno(self, node):
|
||||
"""Emit SET_LINENO if node has lineno attribute
|
||||
"""Emit SET_LINENO if node has lineno attribute and it is
|
||||
different than the last lineno emitted.
|
||||
|
||||
Returns true if SET_LINENO was emitted.
|
||||
|
||||
|
@ -117,8 +119,9 @@ class CodeGenerator:
|
|||
then, this method works around missing line numbers.
|
||||
"""
|
||||
lineno = getattr(node, 'lineno', None)
|
||||
if lineno is not None:
|
||||
if lineno is not None and lineno != self.last_lineno:
|
||||
self.emit('SET_LINENO', lineno)
|
||||
self.last_lineno = lineno
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
@ -414,6 +417,7 @@ class CodeGenerator:
|
|||
pass
|
||||
|
||||
def visitName(self, node):
|
||||
self.set_lineno(node)
|
||||
self.loadName(node.name)
|
||||
|
||||
def visitPass(self, node):
|
||||
|
|
|
@ -419,21 +419,32 @@ class LineAddrTable:
|
|||
# compute deltas
|
||||
addr = self.codeOffset - self.lastoff
|
||||
line = lineno - self.lastline
|
||||
while addr > 0 or line > 0:
|
||||
# write the values in 1-byte chunks that sum
|
||||
# to desired value
|
||||
trunc_addr = addr
|
||||
trunc_line = line
|
||||
if trunc_addr > 255:
|
||||
trunc_addr = 255
|
||||
if trunc_line > 255:
|
||||
trunc_line = 255
|
||||
self.lnotab.append(trunc_addr)
|
||||
self.lnotab.append(trunc_line)
|
||||
addr = addr - trunc_addr
|
||||
line = line - trunc_line
|
||||
self.lastline = lineno
|
||||
self.lastoff = self.codeOffset
|
||||
# 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:
|
||||
while addr > 0 or line > 0:
|
||||
# write the values in 1-byte chunks that sum
|
||||
# to desired value
|
||||
trunc_addr = addr
|
||||
trunc_line = line
|
||||
if trunc_addr > 255:
|
||||
trunc_addr = 255
|
||||
if trunc_line > 255:
|
||||
trunc_line = 255
|
||||
self.lnotab.append(trunc_addr)
|
||||
self.lnotab.append(trunc_line)
|
||||
addr = addr - trunc_addr
|
||||
line = line - trunc_line
|
||||
self.lastline = lineno
|
||||
self.lastoff = self.codeOffset
|
||||
|
||||
def getCode(self):
|
||||
return string.join(self.code, '')
|
||||
|
|
|
@ -70,6 +70,7 @@ class CodeGenerator:
|
|||
self.loops = misc.Stack()
|
||||
self.curStack = 0
|
||||
self.maxStack = 0
|
||||
self.last_lineno = None
|
||||
self._setupGraphDelegation()
|
||||
|
||||
def _setupGraphDelegation(self):
|
||||
|
@ -107,7 +108,8 @@ class CodeGenerator:
|
|||
self.emit(prefix + '_GLOBAL', name)
|
||||
|
||||
def set_lineno(self, node):
|
||||
"""Emit SET_LINENO if node has lineno attribute
|
||||
"""Emit SET_LINENO if node has lineno attribute and it is
|
||||
different than the last lineno emitted.
|
||||
|
||||
Returns true if SET_LINENO was emitted.
|
||||
|
||||
|
@ -117,8 +119,9 @@ class CodeGenerator:
|
|||
then, this method works around missing line numbers.
|
||||
"""
|
||||
lineno = getattr(node, 'lineno', None)
|
||||
if lineno is not None:
|
||||
if lineno is not None and lineno != self.last_lineno:
|
||||
self.emit('SET_LINENO', lineno)
|
||||
self.last_lineno = lineno
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
@ -414,6 +417,7 @@ class CodeGenerator:
|
|||
pass
|
||||
|
||||
def visitName(self, node):
|
||||
self.set_lineno(node)
|
||||
self.loadName(node.name)
|
||||
|
||||
def visitPass(self, node):
|
||||
|
|
Loading…
Reference in New Issue