Fix assertion error in python source due to invalid lineno increment inside llvm_cbuilder.translator.
This commit is contained in:
parent
bc03c9a8b7
commit
b9584e1071
1 changed files with 22 additions and 9 deletions
|
|
@ -11,9 +11,20 @@ def translate(func):
|
||||||
wrapper = functools.wraps(func)
|
wrapper = functools.wraps(func)
|
||||||
caller_frame = inspect.currentframe().f_back
|
caller_frame = inspect.currentframe().f_back
|
||||||
tree = _get_ast(func)
|
tree = _get_ast(func)
|
||||||
tree = ast.copy_location(ast.Module(body=tree.body), tree)
|
tree = ast.Module(body=tree.body)
|
||||||
tree = ExpandControlFlow().visit(tree)
|
tree = ExpandControlFlow().visit(tree)
|
||||||
tree = ast.fix_missing_locations(tree)
|
|
||||||
|
# NOTE: A hack to fix assertion error in debug mode due to bad lineno.
|
||||||
|
# Lineno must increase monotonically for co_lnotab,
|
||||||
|
# the "line number table" to work correctly.
|
||||||
|
# This script just set all lineno to 1 and col_offset = to 0.
|
||||||
|
# This makes it impossible to do traceback, but it is not possible
|
||||||
|
# anyway since we are dynamically changing the source code.
|
||||||
|
for node in ast.walk(tree):
|
||||||
|
# only ast.expr and ast.stmt and their subclass has lineno and col_offset.
|
||||||
|
if isinstance(node, ast.expr) or isinstance(node, ast.stmt):
|
||||||
|
node.lineno = 1
|
||||||
|
node.col_offset = 0
|
||||||
|
|
||||||
# prepare locals for execution
|
# prepare locals for execution
|
||||||
local_dict = locals()
|
local_dict = locals()
|
||||||
|
|
@ -21,7 +32,8 @@ def translate(func):
|
||||||
local_dict.update(caller_frame.f_globals)
|
local_dict.update(caller_frame.f_globals)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return eval(compile(tree, '<string>', 'exec'))
|
compiled = compile(tree, '<string>', 'exec')
|
||||||
|
return eval(compiled)
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
logger.debug(ast.dump(tree))
|
logger.debug(ast.dump(tree))
|
||||||
from ArminRonacher import codegen # uses Armin Ronacher's codegen to debug
|
from ArminRonacher import codegen # uses Armin Ronacher's codegen to debug
|
||||||
|
|
@ -97,7 +109,7 @@ class ExpandControlFlow(ast.NodeTransformer):
|
||||||
ifelse = load_template(_if_else_template)
|
ifelse = load_template(_if_else_template)
|
||||||
ifelse = MacroExpander(mapping).visit(ifelse)
|
ifelse = MacroExpander(mapping).visit(ifelse)
|
||||||
newnode = self.generic_visit(ifelse)
|
newnode = self.generic_visit(ifelse)
|
||||||
return ast.copy_location(newnode, node)
|
return newnode
|
||||||
|
|
||||||
def visit_While(self, node):
|
def visit_While(self, node):
|
||||||
mapping = {
|
mapping = {
|
||||||
|
|
@ -107,7 +119,7 @@ class ExpandControlFlow(ast.NodeTransformer):
|
||||||
whileloop = load_template(_while_template)
|
whileloop = load_template(_while_template)
|
||||||
whileloop = MacroExpander(mapping).visit(whileloop)
|
whileloop = MacroExpander(mapping).visit(whileloop)
|
||||||
newnode = self.generic_visit(whileloop)
|
newnode = self.generic_visit(whileloop)
|
||||||
return ast.copy_location(newnode, node)
|
return newnode
|
||||||
|
|
||||||
def visit_For(self, node):
|
def visit_For(self, node):
|
||||||
try:
|
try:
|
||||||
|
|
@ -125,13 +137,13 @@ class ExpandControlFlow(ast.NodeTransformer):
|
||||||
forloop = load_template(_for_range_template)
|
forloop = load_template(_for_range_template)
|
||||||
forloop = MacroExpander(mapping).visit(forloop)
|
forloop = MacroExpander(mapping).visit(forloop)
|
||||||
newnode = self.generic_visit(forloop)
|
newnode = self.generic_visit(forloop)
|
||||||
return ast.copy_location(newnode, node)
|
return newnode
|
||||||
|
|
||||||
def visit_Return(self, node):
|
def visit_Return(self, node):
|
||||||
mapping = {'__RETURN__' : node.value}
|
mapping = {'__RETURN__' : node.value}
|
||||||
ret = load_template(_return_template)
|
ret = load_template(_return_template)
|
||||||
repl = MacroExpander(mapping).visit(ret)
|
repl = MacroExpander(mapping).visit(ret)
|
||||||
return ast.copy_location(repl, node)
|
return repl
|
||||||
|
|
||||||
def visit_Num(self, node):
|
def visit_Num(self, node):
|
||||||
'''convert immediate values
|
'''convert immediate values
|
||||||
|
|
@ -148,7 +160,7 @@ class ExpandControlFlow(ast.NodeTransformer):
|
||||||
'__VALUE__' : node,
|
'__VALUE__' : node,
|
||||||
}
|
}
|
||||||
constant = MacroExpander(mapping).visit(template).value
|
constant = MacroExpander(mapping).visit(template).value
|
||||||
newnode = ast.copy_location(constant, node)
|
newnode = constant
|
||||||
return newnode
|
return newnode
|
||||||
|
|
||||||
class MacroExpander(ast.NodeTransformer):
|
class MacroExpander(ast.NodeTransformer):
|
||||||
|
|
@ -187,6 +199,7 @@ class MacroExpander(ast.NodeTransformer):
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
if repl is not None and not isinstance(repl, list):
|
if repl is not None and not isinstance(repl, list):
|
||||||
return ast.copy_location(repl, node)
|
return repl
|
||||||
return node
|
return node
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue