Example #1
0
 def test_handling_of_set_lineno(self):
     code = Bytecode()
     code.first_lineno = 3
     code.extend([
         Instr("LOAD_CONST", 7),
         Instr("STORE_NAME", "x"),
         SetLineno(4),
         Instr("LOAD_CONST", 8),
         Instr("STORE_NAME", "y"),
         SetLineno(5),
         Instr("LOAD_CONST", 9),
         Instr("STORE_NAME", "z"),
     ])
     self.assertEqual(code.compute_stacksize(), 1)
Example #2
0
    def test_legalize(self):
        concrete = ConcreteBytecode()
        concrete.first_lineno = 3
        concrete.consts = [7, 8, 9]
        concrete.names = ["x", "y", "z"]
        concrete.extend(
            [
                ConcreteInstr("LOAD_CONST", 0),
                ConcreteInstr("STORE_NAME", 0),
                ConcreteInstr("LOAD_CONST", 1, lineno=4),
                ConcreteInstr("STORE_NAME", 1),
                SetLineno(5),
                ConcreteInstr("LOAD_CONST", 2, lineno=6),
                ConcreteInstr("STORE_NAME", 2),
            ]
        )

        concrete.legalize()
        self.assertListEqual(
            list(concrete),
            [
                ConcreteInstr("LOAD_CONST", 0, lineno=3),
                ConcreteInstr("STORE_NAME", 0, lineno=3),
                ConcreteInstr("LOAD_CONST", 1, lineno=4),
                ConcreteInstr("STORE_NAME", 1, lineno=4),
                ConcreteInstr("LOAD_CONST", 2, lineno=5),
                ConcreteInstr("STORE_NAME", 2, lineno=5),
            ],
        )
Example #3
0
    def test_extended_lnotab2(self):
        # x = 7
        # 200 blank lines
        # y = 8
        base_code = compile("x = 7" + "\n" * 200 + "y = 8", "", "exec")
        concrete = ConcreteBytecode(
            [
                ConcreteInstr("LOAD_CONST", 0),
                ConcreteInstr("STORE_NAME", 0),
                SetLineno(201),
                ConcreteInstr("LOAD_CONST", 1),
                ConcreteInstr("STORE_NAME", 1),
                ConcreteInstr("LOAD_CONST", 2),
                ConcreteInstr("RETURN_VALUE"),
            ]
        )
        concrete.consts = [None, 7, 8]
        concrete.names = ["x", "y"]
        concrete.first_lineno = 1

        code = concrete.to_code()
        self.assertEqual(code.co_code, base_code.co_code)
        self.assertEqual(code.co_firstlineno, base_code.co_firstlineno)
        self.assertEqual(code.co_lnotab, base_code.co_lnotab)
        if sys.version_info >= (3, 10):
            self.assertEqual(code.co_linetable, base_code.co_linetable)
Example #4
0
 def test_copy(self):
     concrete = ConcreteBytecode()
     concrete.first_lineno = 3
     concrete.consts = [7, 8, 9]
     concrete.names = ["x", "y", "z"]
     concrete.extend([
         ConcreteInstr("LOAD_CONST", 0),
         ConcreteInstr("STORE_NAME", 0),
         SetLineno(4),
         ConcreteInstr("LOAD_CONST", 1),
         ConcreteInstr("STORE_NAME", 1),
         SetLineno(5),
         ConcreteInstr("LOAD_CONST", 2),
         ConcreteInstr("STORE_NAME", 2),
     ])
     self.assertEqual(concrete, concrete.copy())
Example #5
0
    def test_legalize(self):
        code = Bytecode()
        code.first_lineno = 3
        code.extend(
            [
                Instr("LOAD_CONST", 7),
                Instr("STORE_NAME", "x"),
                Instr("LOAD_CONST", 8, lineno=4),
                Instr("STORE_NAME", "y"),
                Label(),
                SetLineno(5),
                Instr("LOAD_CONST", 9, lineno=6),
                Instr("STORE_NAME", "z"),
            ]
        )

        code.legalize()
        self.assertListEqual(
            code,
            [
                Instr("LOAD_CONST", 7, lineno=3),
                Instr("STORE_NAME", "x", lineno=3),
                Instr("LOAD_CONST", 8, lineno=4),
                Instr("STORE_NAME", "y", lineno=4),
                Label(),
                Instr("LOAD_CONST", 9, lineno=5),
                Instr("STORE_NAME", "z", lineno=5),
            ],
        )
Example #6
0
    def test_legalize(self):
        code = Bytecode()
        code.first_lineno = 3
        code.extend(
            [
                Instr("LOAD_CONST", 7),
                Instr("STORE_NAME", "x"),
                Instr("LOAD_CONST", 8, lineno=4),
                Instr("STORE_NAME", "y"),
                SetLineno(5),
                Instr("LOAD_CONST", 9, lineno=6),
                Instr("STORE_NAME", "z"),
            ]
        )

        blocks = ControlFlowGraph.from_bytecode(code)
        blocks.legalize()
        self.assertBlocksEqual(
            blocks,
            [
                Instr("LOAD_CONST", 7, lineno=3),
                Instr("STORE_NAME", "x", lineno=3),
                Instr("LOAD_CONST", 8, lineno=4),
                Instr("STORE_NAME", "y", lineno=4),
                Instr("LOAD_CONST", 9, lineno=5),
                Instr("STORE_NAME", "z", lineno=5),
            ],
        )
Example #7
0
    def test_negative_lnotab(self):
        # x = 7
        # y = 8
        concrete = ConcreteBytecode([
            ConcreteInstr("LOAD_CONST", 0),
            ConcreteInstr("STORE_NAME", 0),
            # line number goes backward!
            SetLineno(2),
            ConcreteInstr("LOAD_CONST", 1),
            ConcreteInstr("STORE_NAME", 1)
        ])
        concrete.consts = [7, 8]
        concrete.names = ['x', 'y']
        concrete.first_lineno = 5

        if sys.version_info >= (3, 6):
            code = concrete.to_code()
            expected = b'd\x00Z\x00d\x01Z\x01'
            self.assertEqual(code.co_code, expected)
            self.assertEqual(code.co_firstlineno, 5)
            self.assertEqual(code.co_lnotab, b'\x04\xfd')
        else:
            with self.assertRaises(ValueError) as cm:
                code = concrete.to_code()
            self.assertEqual(
                str(cm.exception),
                "negative line number delta is not supported "
                "on Python < 3.6")
Example #8
0
    def set_lineno(self, lno):
        if (lno > 0):
            self.co_code.append(SetLineno(lno))

        if not self.co_firstlineno:
            self.co_firstlineno = self._last_line = lno
            return

        append = self.co_lnotab.append
        incr_line = lno - self._last_line
        incr_addr = len(self.co_code) - self._last_lineofs
        if not incr_line:
            return

        if incr_addr <= 0 or incr_line <= 0:
            return

        while incr_addr > 255:
            append(255)
            append(0)
            incr_addr -= 255

        while incr_line > 255:
            append(incr_addr)
            append(255)
            incr_line -= 255
            incr_addr = 0

        if incr_addr or incr_line:
            append(incr_addr)
            append(incr_line)

        self._last_line = lno
        self._last_lineofs = len(self.co_code)
Example #9
0
    def test_to_code_lnotab(self):

        # We use an actual function for the simple case to
        # ensure we get lnotab right
        def f():
            #
            #
            x = 7  # noqa
            y = 8  # noqa
            z = 9  # noqa

        fl = f.__code__.co_firstlineno
        concrete = ConcreteBytecode()
        concrete.consts = [None, 7, 8, 9]
        concrete.varnames = ["x", "y", "z"]
        concrete.first_lineno = fl
        concrete.extend(
            [
                SetLineno(fl + 3),
                ConcreteInstr("LOAD_CONST", 1),
                ConcreteInstr("STORE_FAST", 0),
                SetLineno(fl + 4),
                ConcreteInstr("LOAD_CONST", 2),
                ConcreteInstr("STORE_FAST", 1),
                SetLineno(fl + 5),
                ConcreteInstr("LOAD_CONST", 3),
                ConcreteInstr("STORE_FAST", 2),
                ConcreteInstr("LOAD_CONST", 0),
                ConcreteInstr("RETURN_VALUE"),
            ]
        )

        code = concrete.to_code()
        self.assertEqual(code.co_code, f.__code__.co_code)
        self.assertEqual(code.co_lnotab, f.__code__.co_lnotab)
        if sys.version_info >= (3, 10):
            self.assertEqual(code.co_linetable, f.__code__.co_linetable)
Example #10
0
    def test_extended_lnotab(self):
        # x = 7
        # y = 8
        concrete = ConcreteBytecode([
            ConcreteInstr("LOAD_CONST", 0),
            SetLineno(1 + 128),
            ConcreteInstr("STORE_NAME", 0),
            # line number goes backward!
            SetLineno(1 + 129),
            ConcreteInstr("LOAD_CONST", 1),
            SetLineno(1),
            ConcreteInstr("STORE_NAME", 1),
        ])
        concrete.consts = [7, 8]
        concrete.names = ["x", "y"]
        concrete.first_lineno = 1

        with self.assertRaises(ValueError) as cm:
            code = concrete.to_code()
        self.assertEqual(
            str(cm.exception),
            "negative line number delta is not supported "
            "on Python < 3.6",
        )
Example #11
0
    def test_setlineno(self):
        # x = 7
        # y = 8
        # z = 9
        code = Bytecode()
        code.first_lineno = 3
        code.extend([Instr("LOAD_CONST", 7),
                     Instr("STORE_NAME", 'x'),
                     SetLineno(4),
                     Instr("LOAD_CONST", 8),
                     Instr("STORE_NAME", 'y'),
                     SetLineno(5),
                     Instr("LOAD_CONST", 9),
                     Instr("STORE_NAME", 'z')])

        concrete = code.to_concrete_bytecode()
        self.assertEqual(concrete.consts, [7, 8, 9])
        self.assertEqual(concrete.names, ['x', 'y', 'z'])
        code.extend([ConcreteInstr("LOAD_CONST", 0, lineno=3),
                     ConcreteInstr("STORE_NAME", 0, lineno=3),
                     ConcreteInstr("LOAD_CONST", 1, lineno=4),
                     ConcreteInstr("STORE_NAME", 1, lineno=4),
                     ConcreteInstr("LOAD_CONST", 2, lineno=5),
                     ConcreteInstr("STORE_NAME", 2, lineno=5)])
Example #12
0
    def test_extended_lnotab(self):
        # x = 7
        # 200 blank lines
        # y = 8
        concrete = ConcreteBytecode([
            ConcreteInstr("LOAD_CONST", 0),
            SetLineno(1 + 128),
            ConcreteInstr("STORE_NAME", 0),
            # line number goes backward!
            SetLineno(1 + 129),
            ConcreteInstr("LOAD_CONST", 1),
            SetLineno(1),
            ConcreteInstr("STORE_NAME", 1),
        ])
        concrete.consts = [7, 8]
        concrete.names = ["x", "y"]
        concrete.first_lineno = 1

        code = concrete.to_code()
        expected = b"d\x00Z\x00d\x01Z\x01"
        self.assertEqual(code.co_code, expected)
        self.assertEqual(code.co_firstlineno, 1)
        self.assertEqual(code.co_lnotab,
                         b"\x02\x7f\x00\x01\x02\x01\x02\x80\x00\xff")
Example #13
0
    def test_negative_lnotab(self):
        # x = 7
        # y = 8
        concrete = ConcreteBytecode([
            ConcreteInstr("LOAD_CONST", 0),
            ConcreteInstr("STORE_NAME", 0),
            # line number goes backward!
            SetLineno(2),
            ConcreteInstr("LOAD_CONST", 1),
            ConcreteInstr("STORE_NAME", 1),
        ])
        concrete.consts = [7, 8]
        concrete.names = ["x", "y"]
        concrete.first_lineno = 5

        code = concrete.to_code()
        expected = b"d\x00Z\x00d\x01Z\x01"
        self.assertEqual(code.co_code, expected)
        self.assertEqual(code.co_firstlineno, 5)
        self.assertEqual(code.co_lnotab, b"\x04\xfd")
Example #14
0
 def test_equality(self):
     lineno = SetLineno(1)
     self.assertNotEqual(lineno, 1)
     self.assertEqual(lineno, SetLineno(1))
     self.assertNotEqual(lineno, SetLineno(2))
Example #15
0
 def test_lineno(self):
     lineno = SetLineno(1)
     self.assertEqual(lineno.lineno, 1)