How to use the bytecode.concrete.ConcreteInstr function in bytecode

To help you get started, we’ve selected a few bytecode examples, based on popular ways it is used in public projects.

Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.

github vstinner / bytecode / bytecode / cfg.py View on Github external
def __iter__(self):
        index = 0
        while index < len(self):
            instr = self[index]
            index += 1

            if not isinstance(instr, (SetLineno, Instr, ConcreteInstr)):
                raise ValueError("BasicBlock must only contain SetLineno, "
                                 "Instr and ConcreteInstr objects, "
                                 "but %s was found"
                                 % instr.__class__.__name__)

            if isinstance(instr, Instr) and instr.has_jump():
                if index < len(self):
                    raise ValueError("Only the last instruction of a basic "
                                     "block can be a jump")

                if not isinstance(instr.arg, BasicBlock):
                    raise ValueError("Jump target must a BasicBlock, got %s",
                                     type(instr.arg).__name__)

            yield instr
github vstinner / bytecode / bytecode / cfg.py View on Github external
if target_block is not None:
                used_blocks.add(id(target_block))

        labels = {}
        jumps = []
        instructions = []

        for block in self:
            if id(block) in used_blocks:
                new_label = Label()
                labels[id(block)] = new_label
                instructions.append(new_label)

            for instr in block:
                # don't copy SetLineno objects
                if isinstance(instr, (Instr, ConcreteInstr)):
                    instr = instr.copy()
                    if isinstance(instr.arg, BasicBlock):
                        jumps.append(instr)
                instructions.append(instr)

        # Map to new labels
        for instr in jumps:
            instr.arg = labels[id(instr.arg)]

        bytecode = _bytecode.Bytecode()
        bytecode._copy_attr_from(self)
        bytecode.argnames = list(self.argnames)
        bytecode[:] = instructions

        return bytecode
github vstinner / bytecode / bytecode / concrete.py View on Github external
def _check_instr(self, instr):
        if not isinstance(instr, (ConcreteInstr, SetLineno)):
            raise ValueError(
                "ConcreteBytecode must only contain "
                "ConcreteInstr and SetLineno objects, "
                "but %s was found" % type(instr).__name__
            )
github vstinner / bytecode / bytecode / concrete.py View on Github external
raise ValueError("EXTENDED_ARG followed " "by EXTENDED_ARG")
                        extended_arg = (extended_arg << 8) + instr.arg
                    else:
                        extended_arg = instr.arg

                    del instructions[index]
                    continue

                if extended_arg is not None:
                    if _WORDCODE:
                        arg = (extended_arg << 8) + instr.arg
                    else:
                        arg = (extended_arg << 16) + instr.arg
                    extended_arg = None

                    instr = ConcreteInstr(
                        instr.name,
                        arg,
                        lineno=instr.lineno,
                        extended_args=nb_extended_args,
                    )
                    instructions[index] = instr
                    nb_extended_args = 0

                index += 1

            if extended_arg is not None:
                raise ValueError("EXTENDED_ARG at the end of the code")

        bytecode = ConcreteBytecode()
        bytecode.name = code.co_name
        bytecode.filename = code.co_filename
github vstinner / bytecode / bytecode / cfg.py View on Github external
def _flat(self):
        instructions = []
        jumps = []

        for block in self:
            target_block = block.get_jump()
            if target_block is not None:
                instr = block[-1]
                instr = ConcreteInstr(instr.name, 0, lineno=instr.lineno)
                jumps.append((target_block, instr))

                instructions.extend(block[:-1])
                instructions.append(instr)
            else:
                instructions.extend(block)

        for target_block, instr in jumps:
            instr.arg = self.get_block_index(target_block)

        return instructions
github vstinner / bytecode / bytecode / cfg.py View on Github external
def get_instructions(self):
        instructions = []
        jumps = []

        for block in self:
            target_block = block.get_jump()
            if target_block is not None:
                instr = block[-1]
                instr = ConcreteInstr(instr.name, 0, lineno=instr.lineno)
                jumps.append((target_block, instr))

                instructions.extend(block[:-1])
                instructions.append(instr)
            else:
                instructions.extend(block)

        for target_block, instr in jumps:
            instr.arg = self.get_block_index(target_block)

        return instructions
github vstinner / bytecode / bytecode / concrete.py View on Github external
def from_code(code, *, extended_arg=False):
        line_starts = dict(dis.findlinestarts(code))

        # find block starts
        instructions = []
        offset = 0
        lineno = code.co_firstlineno
        while offset < len(code.co_code):
            if offset in line_starts:
                lineno = line_starts[offset]

            instr = ConcreteInstr.disassemble(lineno, code.co_code, offset)

            instructions.append(instr)
            offset += instr.size

        # replace jump targets with blocks
        # HINT : in some cases Python generate useless EXTENDED_ARG opcode
        # with a value of zero. Such opcodes do not increases the size of the
        # following opcode the way a normal EXTENDED_ARG does. As a
        # consequence, they need to be tracked manually as otherwise the
        # offsets in jump targets can end up being wrong.
        if not extended_arg:
            nb_extended_args = 0
            extended_arg = None
            index = 0
            while index < len(instructions):
                instr = instructions[index]
github vstinner / bytecode / bytecode / concrete.py View on Github external
arg = self.add_const(arg)
                elif instr.opcode in _opcode.haslocal:
                    arg = self.add(self.varnames, arg)
                elif instr.opcode in _opcode.hasname:
                    arg = self.add(self.names, arg)
                elif instr.opcode in _opcode.hasfree:
                    if isinstance(arg, CellVar):
                        arg = self.bytecode.cellvars.index(arg.name)
                    else:
                        assert isinstance(arg, FreeVar)
                        arg = ncells + self.bytecode.freevars.index(arg.name)
                elif instr.opcode in _opcode.hascompare:
                    if isinstance(arg, Compare):
                        arg = arg.value

                instr = ConcreteInstr(instr.name, arg, lineno=lineno)
                if is_jump:
                    self.jumps.append((len(self.instructions), label, instr))

            self.instructions.append(instr)