Example #1
0
def analyze_loop(settings, code, index):
    instr = code[index]
    if not (instr[0] == byteplay.FOR_ITER and
            (index >= 2 and code[index - 2][0] == byteplay.GET_ITER)):
        return 0
    # Now we found GET_ITER and FOR_ITER instructions

    # Try to find SETUP_LOOP
    for rel_index in orig_xrange(index - 3, -1, -1):
        if code[rel_index][0] == byteplay.SETUP_LOOP:
            setup_index = rel_index
            break
    else:
        return 0

    # Try to find JUMP_ABSOLUTE and POP_BLOCK by label from FOR_ITER
    pop_block_label = instr[1]
    for rel_index in orig_xrange(index + 1, len(code) - 1):
        if code[rel_index][0] is pop_block_label:
            pop_block_index = rel_index + 1
            break
    else:
        return 0
    if not (code[pop_block_index - 2][0] == byteplay.JUMP_ABSOLUTE
            and code[pop_block_index - 2][1] is code[index - 1][0]
            and code[pop_block_index][0] == byteplay.POP_BLOCK):
        return 0
    # It's busy to check POP_BLOCK instruction existence to
    # distinguish real for-loops from a list comprehensions

    # Try to find marker of current line's number
    for rel_index in orig_xrange(setup_index - 1, -1, -1):
        if code[rel_index][0] == byteplay.SetLineno:
            head_lineno = code[rel_index][1]
            break
    else:
        head_lineno = None

    head = code[setup_index + 1:index - 2]
    body = code[index + 1:pop_block_index - 2]
    # Don't forget that "else_body" loop part is also exists

    settings['head_lineno'] = head_lineno
    try:
        state = recompiler.recompile_body(settings, body)
    except recompiler.RecompileError as err:
        if settings['profile']:
            profiler.exc(settings, 'Recompilation failed', err)
        return 0

    # Insert head_handler right before GET_ITER instruction
    head_hook = hook.create_head_hook(state, pop_block_label)
    code[index - 2:index - 2] = head_hook

    if settings['profile']:
        profiler.note(settings, 'Recompilation succeeded')

    # Return length of analyzed code
    return len(head_hook)
Example #2
0
def check_iterable(settings, iterable):
    if not isinstance(iterable, (xrange, CPMRange)):
        raise TypeError(
            'Iterator has type %s instead of type "xrange"' % type(iterable)
        )
    
    iters_count = iterable.__len__()
    if iters_count <= settings['iters_limit']:
        if settings['profile']:
            profiler.note(settings,
                    'Skipped optimization of %s iterations' % iters_count)
        return None
    
    start = iterable[0]
    step = iterable[1] - start
    last = iterable[-1]
    return start, step, iters_count, last
Example #3
0
def check_iterable(settings, iterable):
    if not isinstance(iterable, (xrange, CPMRange)):
        raise TypeError('Iterator has type %s instead of type "xrange"' %
                        type(iterable))

    iters_count = iterable.__len__()
    if iters_count <= settings['iters_limit']:
        if settings['profile']:
            profiler.note(
                settings,
                'Skipped optimization of %s iterations' % iters_count)
        return None

    start = iterable[0]
    step = iterable[1] - start
    last = iterable[-1]
    return start, step, iters_count, last
Example #4
0
def analyze_loop(settings, code, index):
    instr = code[index]
    if not (
        instr[0] == byteplay.FOR_ITER and
        (index >= 2 and code[index - 2][0] == byteplay.GET_ITER)
    ):
        return 0
    # Now we found GET_ITER and FOR_ITER instructions
    
    # Try to find SETUP_LOOP
    for rel_index in orig_xrange(index - 3, -1, -1):
        if code[rel_index][0] == byteplay.SETUP_LOOP:
            setup_index = rel_index
            break
    else:
        return 0
    
    # Try to find JUMP_ABSOLUTE and POP_BLOCK by label from FOR_ITER
    pop_block_label = instr[1]
    for rel_index in orig_xrange(index + 1, len(code) - 1):
        if code[rel_index][0] is pop_block_label:
            pop_block_index = rel_index + 1
            break
    else:
        return 0
    if not (
        code[pop_block_index - 2][0] == byteplay.JUMP_ABSOLUTE and
        code[pop_block_index - 2][1] is code[index - 1][0] and
        code[pop_block_index][0] == byteplay.POP_BLOCK
    ):
        return 0
    # It's busy to check POP_BLOCK instruction existence to
    # distinguish real for-loops from a list comprehensions
    
    # Try to find marker of current line's number
    for rel_index in orig_xrange(setup_index - 1, -1, -1):
        if code[rel_index][0] == byteplay.SetLineno:
            head_lineno = code[rel_index][1]
            break
    else:
        head_lineno = None
    
    head = code[setup_index + 1:index - 2]
    body = code[index + 1:pop_block_index - 2]
    # Don't forget that "else_body" loop part is also exists
    
    settings['head_lineno'] = head_lineno
    try:
        state = recompiler.recompile_body(settings, body)
    except recompiler.RecompileError as err:
        if settings['profile']:
            profiler.exc(settings, 'Recompilation failed', err)
        return 0
    
    # Insert head_handler right before GET_ITER instruction
    head_hook = hook.create_head_hook(state, pop_block_label)
    code[index - 2:index - 2] = head_hook
    
    if settings['profile']:
        profiler.note(settings, 'Recompilation succeeded')
    
    # Return length of analyzed code
    return len(head_hook)