(self, offset, code)
return branch_targets
compute branch targets for the given code segment.

        we can do it in a single pass:
        scan instructions, tracking new blocks, and maintaining a stack of nested blocks.
        when we hit a branch instruction, use the stack to resolve the branch target.
        the branch target will always come from the enclosing scope.

        Args:
          offset (int): offset of the given code segment.
          code (bytes): raw bytecode.

        Returns:
          Dict[int, Dict[int, int]]: map from instruction addresses to map from relative depth to branch target address.
compute branch targets for the given code segment.
compute branch targets for the given code segment .
def _compute_function_branch_targets(self, offset, code):
        '''
        compute branch targets for the given code segment.

        we can do it in a single pass:
        scan instructions, tracking new blocks, and maintaining a stack of nested blocks.
        when we hit a branch instruction, use the stack to resolve the branch target.
        the branch target will always come from the enclosing scope.

        Args:
          offset (int): offset of the given code segment.
          code (bytes): raw bytecode.

        Returns:
          Dict[int, Dict[int, int]]: map from instruction addresses to map from relative depth to branch target address.
        '''
        # map from virtual address to map from relative depth to virtual address
        branch_targets = {}
        # map from block index to block instance, with fields including `offset` and `depth`
        blocks = {}
        # stack of block indexes
        block_stack = []
        p = offset

        for bc in wasm.decode.decode_bytecode(code):
            if bc.op.id in {wasm.opcodes.OP_BLOCK, wasm.opcodes.OP_LOOP, wasm.opcodes.OP_IF}:
                # enter a new block, so capture info, and push it onto the current depth stack
                block_index = len(blocks)
                block = {
                    'index': block_index,
                    'offset': p,
                    'depth': len(block_stack),
                    'type': {
                        wasm.opcodes.OP_BLOCK: 'block',
                        wasm.opcodes.OP_LOOP: 'loop',
                        wasm.opcodes.OP_IF: 'if',
                    }[bc.op.id],
                }
                blocks[block_index] = block
                block_stack.insert(0, block_index)
                branch_targets[p] = {
                    # reference to block that is starting
                    'block': block
                }

            elif bc.op.id in {wasm.opcodes.OP_END}:
                if len(block_stack) == 0:
                    # end of function
                    branch_targets[p] = {
                        'block': {
                            'type': 'function',
                            'offset': offset,     # start of function
                            'end_offset': p,      # end of function
                            'depth': 0,           # top level always has depth 0
                        }
                    }
                    break

                # leaving a block, so pop from the depth stack
                block_index = block_stack.pop(0)
                block = blocks[block_index]
                block['end_offset'] = p + bc.len
                branch_targets[p] = {
                    # reference to block that is ending
                    'block': block
                }

            elif bc.op.id in {wasm.opcodes.OP_BR, wasm.opcodes.OP_BR_IF}:
                block_index = block_stack[bc.imm.relative_depth]
                block = blocks[block_index]
                branch_targets[p] = {
                    bc.imm.relative_depth: block
                }

            elif bc.op.id in {wasm.opcodes.OP_ELSE}:
                # TODO: not exactly sure of the semantics here
                raise NotImplementedError('else')

            elif bc.op.id in {wasm.opcodes.OP_BR_TABLE}:
                # TODO: not exactly sure what one of these looks like yet.
                raise NotImplementedError('br table')
                # probably will populate `branch_targets` with multiple entries

            p += bc.len

        return branch_targets
def _compute_function_branch_targets ( self , offset , code ) : # map from virtual address to map from relative depth to virtual address branch_targets = { } # map from block index to block instance, with fields including `offset` and `depth` blocks = { } # stack of block indexes block_stack = [ ] p = offset for bc in wasm . decode . decode_bytecode ( code ) : if bc . op . id in { wasm . opcodes . OP_BLOCK , wasm . opcodes . OP_LOOP , wasm . opcodes . OP_IF } : # enter a new block, so capture info, and push it onto the current depth stack block_index = len ( blocks ) block = { 'index' : block_index , 'offset' : p , 'depth' : len ( block_stack ) , 'type' : { wasm . opcodes . OP_BLOCK : 'block' , wasm . opcodes . OP_LOOP : 'loop' , wasm . opcodes . OP_IF : 'if' , } [ bc . op . id ] , } blocks [ block_index ] = block block_stack . insert ( 0 , block_index ) branch_targets [ p ] = { # reference to block that is starting 'block' : block } elif bc . op . id in { wasm . opcodes . OP_END } : if len ( block_stack ) == 0 : # end of function branch_targets [ p ] = { 'block' : { 'type' : 'function' , 'offset' : offset , # start of function 'end_offset' : p , # end of function 'depth' : 0 , # top level always has depth 0 } } break # leaving a block, so pop from the depth stack block_index = block_stack . pop ( 0 ) block = blocks [ block_index ] block [ 'end_offset' ] = p + bc . len branch_targets [ p ] = { # reference to block that is ending 'block' : block } elif bc . op . id in { wasm . opcodes . OP_BR , wasm . opcodes . OP_BR_IF } : block_index = block_stack [ bc . imm . relative_depth ] block = blocks [ block_index ] branch_targets [ p ] = { bc . imm . relative_depth : block } elif bc . op . id in { wasm . opcodes . OP_ELSE } : # TODO: not exactly sure of the semantics here raise NotImplementedError ( 'else' ) elif bc . op . id in { wasm . opcodes . OP_BR_TABLE } : # TODO: not exactly sure what one of these looks like yet. raise NotImplementedError ( 'br table' ) # probably will populate `branch_targets` with multiple entries p += bc . len return branch_targets