Fallout from more precise token attributes

This commit is contained in:
rocky
2018-02-28 23:35:52 -05:00
parent 413df51dfa
commit e23315b2e6
8 changed files with 39 additions and 8 deletions

View File

@@ -66,7 +66,7 @@ def test_grammar():
expect_dup_rhs = frozenset([('COME_FROM',), ('CONTINUE',), ('JUMP_ABSOLUTE',), expect_dup_rhs = frozenset([('COME_FROM',), ('CONTINUE',), ('JUMP_ABSOLUTE',),
('LOAD_CONST',), ('LOAD_CONST',),
('JUMP_BACK',), ('JUMP_FORWARD',)]) ('JUMP_BACK',), ('JUMP_FORWARD',)])
reduced_dup_rhs = {k: dup_rhs[k] for k in dup_rhs if k not in expect_dup_rhs} reduced_dup_rhs = dict((k, dup_rhs[k]) for k in dup_rhs if k not in expect_dup_rhs)
for k in reduced_dup_rhs: for k in reduced_dup_rhs:
print(k, reduced_dup_rhs[k]) print(k, reduced_dup_rhs[k])
# assert not reduced_dup_rhs, reduced_dup_rhs # assert not reduced_dup_rhs, reduced_dup_rhs

View File

@@ -8,5 +8,5 @@
9 STORE_NAME 2 'b' 9 STORE_NAME 2 'b'
12 JUMP_FORWARD 0 'to 15' 12 JUMP_FORWARD 0 'to 15'
15_0 COME_FROM 12 '12' 15_0 COME_FROM 12 '12'
15 LOAD_CONST 0 '' 15 LOAD_CONST 0 None
18 RETURN_VALUE 18 RETURN_VALUE

View File

@@ -11,5 +11,5 @@
6 15 LOAD_CONST 1 2 6 15 LOAD_CONST 1 2
18 STORE_NAME 2 'd' 18 STORE_NAME 2 'd'
21_0 COME_FROM 12 '12' 21_0 COME_FROM 12 '12'
21 LOAD_CONST 2 '' 21 LOAD_CONST 2 None
24 RETURN_VALUE 24 RETURN_VALUE

View File

@@ -39,7 +39,9 @@ from collections import namedtuple
from array import array from array import array
from xdis.code import iscode from xdis.code import iscode
from xdis.bytecode import Bytecode, op_has_argument, instruction_size from xdis.bytecode import (
Bytecode, op_has_argument, instruction_size,
_get_const_info)
from xdis.util import code2num from xdis.util import code2num
from uncompyle6.scanner import Scanner from uncompyle6.scanner import Scanner
@@ -233,7 +235,13 @@ class Scanner2(Scanner):
# (id(const), const.co_filename, const.co_name) # (id(const), const.co_filename, const.co_name)
pattr = '<code_object ' + const.co_name + '>' pattr = '<code_object ' + const.co_name + '>'
else: else:
if oparg < len(co.co_consts):
argval, _ = _get_const_info(oparg, co.co_consts)
# Why don't we use _ above for "pattr" rather than "const"?
# This *is* a little hoaky, but we have to coordinate with
# other parts like n_LOAD_CONST in pysource.py for example.
pattr = const pattr = const
pass
elif op in self.opc.NAME_OPS: elif op in self.opc.NAME_OPS:
pattr = names[oparg] pattr = names[oparg]
elif op in self.opc.JREL_OPS: elif op in self.opc.JREL_OPS:

View File

@@ -1,6 +1,19 @@
# Copyright (c) 2015-2017 by Rocky Bernstein # Copyright (c) 2015-2017 by Rocky Bernstein
# Copyright (c) 2005 by Dan Pascu <dan@windowmaker.org> # Copyright (c) 2005 by Dan Pascu <dan@windowmaker.org>
# Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com> # Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com>
#
# 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/>.
""" """
Python 2.6 bytecode scanner Python 2.6 bytecode scanner
@@ -20,6 +33,8 @@ from uncompyle6.scanner import L65536
# bytecode verification, verify(), uses JUMP_OPs from here # bytecode verification, verify(), uses JUMP_OPs from here
from xdis.opcodes import opcode_26 from xdis.opcodes import opcode_26
from xdis.bytecode import Bytecode from xdis.bytecode import Bytecode
from xdis.bytecode import _get_const_info
JUMP_OPS = opcode_26.JUMP_OPS JUMP_OPS = opcode_26.JUMP_OPS
class Scanner26(scan.Scanner2): class Scanner26(scan.Scanner2):
@@ -212,7 +227,13 @@ class Scanner26(scan.Scanner2):
# (id(const), const.co_filename, const.co_name) # (id(const), const.co_filename, const.co_name)
pattr = '<code_object ' + const.co_name + '>' pattr = '<code_object ' + const.co_name + '>'
else: else:
if oparg < len(co.co_consts):
argval, _ = _get_const_info(oparg, co.co_consts)
# Why don't we use _ above for "pattr" rather than "const"?
# This *is* a little hoaky, but we have to coordinate with
# other parts like n_LOAD_CONST in pysource.py for example.
pattr = const pattr = const
pass
elif op in self.opc.NAME_OPS: elif op in self.opc.NAME_OPS:
pattr = names[oparg] pattr = names[oparg]
elif op in self.opc.JREL_OPS: elif op in self.opc.JREL_OPS:

View File

@@ -14,7 +14,6 @@
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
""" """
Python 3 Generic bytecode scanner/deparser Python 3 Generic bytecode scanner/deparser
@@ -340,7 +339,8 @@ class Scanner3(Scanner):
# (id(const), const.co_filename, const.co_name) # (id(const), const.co_filename, const.co_name)
pattr = '<code_object ' + const.co_name + '>' pattr = '<code_object ' + const.co_name + '>'
else: else:
argval, _ = _get_const_info(inst.arg, co.co_consts) if isinstance(inst.arg, int) and inst.arg < len(co.co_consts):
argval, _ = _get_const_info(inst.arg, co.co_consts)
# Why don't we use _ above for "pattr" rather than "const"? # Why don't we use _ above for "pattr" rather than "const"?
# This *is* a little hoaky, but we have to coordinate with # This *is* a little hoaky, but we have to coordinate with
# other parts like n_LOAD_CONST in pysource.py for example. # other parts like n_LOAD_CONST in pysource.py for example.

View File

@@ -87,7 +87,7 @@ class Token():
if not self.has_arg: if not self.has_arg:
return "%s%s" % (prefix, offset_opname) return "%s%s" % (prefix, offset_opname)
argstr = "%6d " % self.attr if isinstance(self.attr, int) else (' '*7) argstr = "%6d " % self.attr if isinstance(self.attr, int) else (' '*7)
if op_has_argument(self.op, self.opc): if self.has_arg:
pattr = self.pattr pattr = self.pattr
if self.opc: if self.opc:
if self.op in self.opc.JREL_OPS: if self.op in self.opc.JREL_OPS:

View File

@@ -1294,7 +1294,9 @@ class SourceWalker(GenericASTTraversal, object):
def n_import_from(self, node): def n_import_from(self, node):
relative_path_index = 0 relative_path_index = 0
if self.version >= 2.5 and node[relative_path_index].attr > 0: if self.version >= 2.5 and node[relative_path_index].attr > 0:
node[2].pattr = '.'*node[relative_path_index].pattr + node[2].attr node[2].pattr = '.' * (node[relative_path_index].pattr + node[2].attr)
if isinstance(node[1].pattr, tuple):
node[1].pattr = '.'.join(node[1].pattr)
self.default(node) self.default(node)
n_import_from_star = n_import_from n_import_from_star = n_import_from