diff options
author | Larry Hastings <larry@hastings.org> | 2013-11-23 22:49:22 (GMT) |
---|---|---|
committer | Larry Hastings <larry@hastings.org> | 2013-11-23 22:49:22 (GMT) |
commit | 3a9079742f2d71e6968823e155f3778473113538 (patch) | |
tree | 742dd59d633f184a06858baec56ab83c20192e59 /Lib | |
parent | 8d0d369067462080f5ea9d50416a12bee0ef3a6a (diff) | |
download | cpython-3a9079742f2d71e6968823e155f3778473113538.zip cpython-3a9079742f2d71e6968823e155f3778473113538.tar.gz cpython-3a9079742f2d71e6968823e155f3778473113538.tar.bz2 |
Issue #19722: Added opcode.stack_effect(), which accurately
computes the stack effect of bytecode instructions.
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/opcode.py | 13 | ||||
-rw-r--r-- | Lib/test/test__opcode.py | 22 |
2 files changed, 35 insertions, 0 deletions
diff --git a/Lib/opcode.py b/Lib/opcode.py index 78d1229..0bd1ee6 100644 --- a/Lib/opcode.py +++ b/Lib/opcode.py @@ -8,6 +8,19 @@ __all__ = ["cmp_op", "hasconst", "hasname", "hasjrel", "hasjabs", "haslocal", "hascompare", "hasfree", "opname", "opmap", "HAVE_ARGUMENT", "EXTENDED_ARG", "hasnargs"] +# It's a chicken-and-egg I'm afraid: +# We're imported before _opcode's made. +# With exception unheeded +# (stack_effect is not needed) +# Both our chickens and eggs are allayed. +# --Larry Hastings, 2013/11/23 + +try: + from _opcode import stack_effect + __all__.append('stack_effect') +except ImportError: + pass + cmp_op = ('<', '<=', '==', '!=', '>', '>=', 'in', 'not in', 'is', 'is not', 'exception match', 'BAD') diff --git a/Lib/test/test__opcode.py b/Lib/test/test__opcode.py new file mode 100644 index 0000000..cab8769 --- /dev/null +++ b/Lib/test/test__opcode.py @@ -0,0 +1,22 @@ +import dis +import _opcode +from test.support import run_unittest +import unittest + +class OpcodeTests(unittest.TestCase): + + def test_stack_effect(self): + self.assertEqual(_opcode.stack_effect(dis.opmap['POP_TOP']), -1) + self.assertEqual(_opcode.stack_effect(dis.opmap['DUP_TOP_TWO']), 2) + self.assertEqual(_opcode.stack_effect(dis.opmap['BUILD_SLICE'], 0), -1) + self.assertEqual(_opcode.stack_effect(dis.opmap['BUILD_SLICE'], 1), -1) + self.assertEqual(_opcode.stack_effect(dis.opmap['BUILD_SLICE'], 3), -2) + self.assertRaises(ValueError, _opcode.stack_effect, 30000) + self.assertRaises(ValueError, _opcode.stack_effect, dis.opmap['BUILD_SLICE']) + self.assertRaises(ValueError, _opcode.stack_effect, dis.opmap['POP_TOP'], 0) + +def test_main(): + run_unittest(OpcodeTests) + +if __name__ == "__main__": + test_main() |