Slightly better assert detection

This commit is contained in:
rocky
2018-03-08 08:31:50 -05:00
parent f5ac06013f
commit 51dec051df
2 changed files with 26 additions and 1 deletions

View File

@@ -1,8 +1,21 @@
# Copyright (c) 2015-2017 Rocky Bernstein # Copyright (c) 2015-2017 Rocky Bernstein
# Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com> # Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com>
#
# Copyright (c) 1999 John Aycock # Copyright (c) 1999 John Aycock
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
""" """
A spark grammar for Python 2.x. Base grammar for Python 2.x.
However instead of terminal symbols being the usual ASCII text, However instead of terminal symbols being the usual ASCII text,
e.g. 5, myvariable, "for", etc. they are CPython Bytecode tokens, e.g. 5, myvariable, "for", etc. they are CPython Bytecode tokens,
@@ -175,6 +188,7 @@ class Python2Parser(PythonParser):
def p_expr2(self, args): def p_expr2(self, args):
""" """
expr ::= LOAD_LOCALS expr ::= LOAD_LOCALS
expr ::= LOAD_ASSERT
expr ::= slice0 expr ::= slice0
expr ::= slice1 expr ::= slice1
expr ::= slice2 expr ::= slice2
@@ -505,6 +519,7 @@ class Python2Parser(PythonParser):
self.check_reduce['aug_assign1'] = 'AST' self.check_reduce['aug_assign1'] = 'AST'
self.check_reduce['aug_assign2'] = 'AST' self.check_reduce['aug_assign2'] = 'AST'
self.check_reduce['or'] = 'AST'
# self.check_reduce['_stmts'] = 'AST' # self.check_reduce['_stmts'] = 'AST'
# Dead code testing... # Dead code testing...
@@ -522,6 +537,9 @@ class Python2Parser(PythonParser):
if lhs in ('aug_assign1', 'aug_assign2') and ast[0] and ast[0][0] == 'and': if lhs in ('aug_assign1', 'aug_assign2') and ast[0] and ast[0][0] == 'and':
return True return True
if rule == ('or', ('expr', 'jmp_true', 'expr', '\\e_come_from_opt')):
expr2 = ast[2]
return expr2 == 'expr' and expr2[0] == 'LOAD_ASSERT'
return False return False
class Python2ParserSingle(Python2Parser, PythonParserSingle): class Python2ParserSingle(Python2Parser, PythonParserSingle):

View File

@@ -37,6 +37,7 @@ from __future__ import print_function
from collections import namedtuple from collections import namedtuple
from array import array from array import array
from copy import copy
from xdis.code import iscode from xdis.code import iscode
from xdis.bytecode import ( from xdis.bytecode import (
@@ -54,6 +55,7 @@ class Scanner2(Scanner):
# This is the 2.5+ default # This is the 2.5+ default
# For <2.5 it is <generator expression> # For <2.5 it is <generator expression>
self.genexpr_name = '<genexpr>' self.genexpr_name = '<genexpr>'
self.load_asserts = set([])
@staticmethod @staticmethod
def unmangle_name(name, classname): def unmangle_name(name, classname):
@@ -139,6 +141,9 @@ class Scanner2(Scanner):
# 'LOAD_ASSERT' is used in assert statements. # 'LOAD_ASSERT' is used in assert statements.
self.load_asserts = set() self.load_asserts = set()
for i in self.op_range(0, codelen): for i in self.op_range(0, codelen):
self.offset2inst_index[inst.offset] = i
# We need to detect the difference between: # We need to detect the difference between:
# raise AssertionError # raise AssertionError
# and # and
@@ -159,7 +164,9 @@ class Scanner2(Scanner):
# Get jump targets # Get jump targets
# Format: {target offset: [jump offsets]} # Format: {target offset: [jump offsets]}
load_asserts_save = copy(self.load_asserts)
jump_targets = self.find_jump_targets(show_asm) jump_targets = self.find_jump_targets(show_asm)
self.load_asserts = load_asserts_save
# print("XXX2", jump_targets) # print("XXX2", jump_targets)
last_stmt = self.next_stmt[0] last_stmt = self.next_stmt[0]