Exemple #1
0
def make_loop_bytecode(bytecode, loop, args, returns):
    # Add return None
    co_consts = tuple(bytecode.co_consts)
    if None not in co_consts:
        co_consts += (None,)

    if returns:
        for out in returns:
            # Load output
            loadfast = ByteCodeInst.get(loop[-1].next, "LOAD_FAST",
                                         bytecode.co_varnames.index(out))
            loadfast.lineno = loop[-1].lineno
            loop.append(loadfast)

        # Build tuple
        buildtuple = ByteCodeInst.get(loop[-1].next, "BUILD_TUPLE",
                                    len(returns))
        buildtuple.lineno = loop[-1].lineno
        loop.append(buildtuple)

    else:
        # Load None
        load_none = ByteCodeInst.get(loop[-1].next, "LOAD_CONST",
                                     co_consts.index(None))
        load_none.lineno = loop[-1].lineno
        loop.append(load_none)

    # Return TOS
    return_value = ByteCodeInst.get(loop[-1].next, "RETURN_VALUE", 0)
    return_value.lineno = loop[-1].lineno
    loop.append(return_value)

    # Function name
    loop_qualname = bytecode.func_qualname + ".__numba__loop%d__" % loop[0].offset

    # Argspec
    argspectype = type(bytecode.argspec)
    argspec = argspectype(args=args, varargs=(), keywords=(), defaults=())

    # Code table
    codetable = utils.SortedMap((i.offset, i) for i in loop)

    # Custom bytecode object
    lbc = CustomByteCode(func=bytecode.func,
                         func_qualname=loop_qualname,
                         # Enforced in separate_loops()
                         is_generator=False,
                         argspec=argspec,
                         filename=bytecode.filename,
                         co_names=bytecode.co_names,
                         co_varnames=bytecode.co_varnames,
                         co_consts=co_consts,
                         co_freevars=bytecode.co_freevars,
                         table=codetable,
                         labels=bytecode.labels)

    return lbc
Exemple #2
0
def make_loop_bytecode(bytecode, loop, args):
    # Add return None
    co_consts = tuple(bytecode.co_consts)
    if None not in co_consts:
        co_consts += (None,)

    # Load None
    load_none = ByteCodeInst.get(loop[-1].next, "LOAD_CONST",
                                 co_consts.index(None))
    load_none.lineno = loop[-1].lineno
    loop.append(load_none)

    # Return None
    return_value = ByteCodeInst.get(loop[-1].next, "RETURN_VALUE", 0)
    return_value.lineno = loop[-1].lineno
    loop.append(return_value)

    # Function name
    loopfuncname = bytecode.func_name+"__numba__loop%d__" % loop[0].offset

    # Argspec
    argspectype = type(bytecode.argspec)
    argspec = argspectype(args=args, varargs=(), keywords=(), defaults=())

    # Code table
    codetable = utils.SortedMap((i.offset, i) for i in loop)

    # Custom bytecode object
    lbc = CustomByteCode(func=bytecode.func,
                         func_name=loopfuncname,
                         argspec=argspec,
                         filename=bytecode.filename,
                         co_names=bytecode.co_names,
                         co_varnames=bytecode.co_varnames,
                         co_consts=co_consts,
                         co_freevars=bytecode.co_freevars,
                         table=codetable,
                         labels=bytecode.labels)

    return lbc
Exemple #3
0
def insert_loop_call(bytecode, loop, args,
                     outer, outerlabels, outernames, dispatcher_factory):
    endloopoffset = loop[-1].next
    # Accepted. Create a bytecode object for the loop
    args = tuple(args)

    lbc = make_loop_bytecode(bytecode, loop, args)

    # Generate dispatcher for this inner loop, and append it to the
    # consts tuple.
    disp = dispatcher_factory(lbc)
    disp_idx = len(bytecode.co_consts)
    bytecode.co_consts += (disp,)

    # Insert jump to the end
    jmp = ByteCodeInst.get(loop[0].offset, 'JUMP_ABSOLUTE',
                           outer[-1].next)
    jmp.lineno = loop[0].lineno
    insert_instruction(outer, jmp)

    outerlabels.add(outer[-1].next)

    # Prepare arguments
    loadfn = ByteCodeInst.get(outer[-1].next, "LOAD_CONST", disp_idx)
    loadfn.lineno = loop[0].lineno
    insert_instruction(outer, loadfn)

    for arg in args:
        loadarg = ByteCodeInst.get(outer[-1].next, 'LOAD_FAST',
                                   bytecode.co_varnames.index(arg))
        loadarg.lineno = loop[0].lineno
        insert_instruction(outer, loadarg)

    # Call function
    assert len(args) < 256
    call = ByteCodeInst.get(outer[-1].next, "CALL_FUNCTION", len(args))
    call.lineno = loop[0].lineno
    insert_instruction(outer, call)

    poptop = ByteCodeInst.get(outer[-1].next, "POP_TOP", None)
    poptop.lineno = loop[0].lineno
    insert_instruction(outer, poptop)

    jmpback = ByteCodeInst.get(outer[-1].next, 'JUMP_ABSOLUTE',
                               endloopoffset)

    jmpback.lineno = loop[0].lineno
    insert_instruction(outer, jmpback)

    return disp
Exemple #4
0
def insert_loop_call(bytecode, loop, args, lbclist, outer, outerlabels,
                     outernames):
    endloopoffset = loop[-1].next
    # Accepted. Create a bytecode object for the loop
    args = tuple(args)
    lbc = make_loop_bytecode(bytecode, loop, args)
    lbclist.append(lbc)


    # Insert jump to the end
    jmp = ByteCodeInst.get(loop[0].offset, 'JUMP_ABSOLUTE',
                           outer[-1].next)
    jmp.lineno = loop[0].lineno
    insert_instruction(outer, jmp)

    outerlabels.add(outer[-1].next)

    # Prepare arguments
    outernames.append(lbc.func_name)
    loadfn = ByteCodeInst.get(outer[-1].next, "LOAD_GLOBAL",
                              outernames.index(lbc.func_name))
    loadfn.lineno = loop[0].lineno
    insert_instruction(outer, loadfn)

    for arg in args:
        loadarg = ByteCodeInst.get(outer[-1].next, 'LOAD_FAST',
                                   bytecode.co_varnames.index(arg))
        loadarg.lineno = loop[0].lineno
        insert_instruction(outer, loadarg)

    # Call function
    assert len(args) < 256
    call = ByteCodeInst.get(outer[-1].next, "CALL_FUNCTION", len(args))
    call.lineno = loop[0].lineno
    insert_instruction(outer, call)

    poptop = ByteCodeInst.get(outer[-1].next, "POP_TOP", None)
    poptop.lineno = loop[0].lineno
    insert_instruction(outer, poptop)

    jmpback = ByteCodeInst.get(outer[-1].next, 'JUMP_ABSOLUTE',
                               endloopoffset)

    jmpback.lineno = loop[0].lineno
    insert_instruction(outer, jmpback)
Exemple #5
0
def insert_loop_call(bytecode, loop, args, outer, outerlabels, returns,
                     dispatcher_factory):
    endloopoffset = loop[-1].next
    # Accepted. Create a bytecode object for the loop
    args = tuple(args)

    lbc = make_loop_bytecode(bytecode, loop, args, returns)

    # Generate dispatcher for this inner loop, and append it to the
    # consts tuple.
    disp = dispatcher_factory(lbc)
    disp_idx = len(bytecode.co_consts)
    bytecode.co_consts += (disp,)

    # Insert jump to the end
    insertpt = SubOffset(loop[0].next)
    jmp = ByteCodeInst.get(loop[0].offset, 'JUMP_ABSOLUTE', insertpt)
    jmp.lineno = loop[0].lineno
    insert_instruction(outer, jmp)

    outerlabels.add(outer[-1].next)

    # Prepare arguments
    loadfn = ByteCodeInst.get(insertpt, "LOAD_CONST", disp_idx)
    loadfn.lineno = loop[0].lineno
    insert_instruction(outer, loadfn)

    insertpt = insertpt.next()
    for arg in args:
        loadarg = ByteCodeInst.get(insertpt, 'LOAD_FAST',
                                   bytecode.co_varnames.index(arg))
        loadarg.lineno = loop[0].lineno
        insert_instruction(outer, loadarg)
        insertpt = insertpt.next()

    # Call function
    assert len(args) < 256
    call = ByteCodeInst.get(insertpt, "CALL_FUNCTION", len(args))
    call.lineno = loop[0].lineno
    insert_instruction(outer, call)

    insertpt = insertpt.next()

    if returns:
        # Unpack arguments
        unpackseq = ByteCodeInst.get(insertpt, "UNPACK_SEQUENCE",
                                  len(returns))
        unpackseq.lineno = loop[0].lineno
        insert_instruction(outer, unpackseq)
        insertpt = insertpt.next()

        for out in returns:
            # Store each variable
            storefast = ByteCodeInst.get(insertpt, "STORE_FAST",
                                      bytecode.co_varnames.index(out))
            storefast.lineno = loop[0].lineno
            insert_instruction(outer, storefast)
            insertpt = insertpt.next()
    else:
        # No return value
        poptop = ByteCodeInst.get(outer[-1].next, "POP_TOP", None)
        poptop.lineno = loop[0].lineno
        insert_instruction(outer, poptop)
        insertpt = insertpt.next()

    jmpback = ByteCodeInst.get(insertpt, 'JUMP_ABSOLUTE',
                               endloopoffset)

    jmpback.lineno = loop[0].lineno
    insert_instruction(outer, jmpback)

    return disp
Exemple #6
0
def insert_loop_call(bytecode, loop, args, outer, outerlabels, returns,
                     dispatcher_factory):
    endloopoffset = loop[-1].next
    # Accepted. Create a bytecode object for the loop
    args = tuple(args)

    lbc = make_loop_bytecode(bytecode, loop, args, returns)

    # Generate dispatcher for this inner loop, and append it to the
    # consts tuple.
    disp = dispatcher_factory(lbc)
    disp_idx = len(bytecode.co_consts)
    bytecode.co_consts += (disp, )

    # Insert jump to the end
    insertpt = SubOffset(loop[0].next)
    jmp = ByteCodeInst.get(loop[0].offset, 'JUMP_ABSOLUTE', insertpt)
    jmp.lineno = loop[0].lineno
    insert_instruction(outer, jmp)

    outerlabels.add(outer[-1].next)

    # Prepare arguments
    loadfn = ByteCodeInst.get(insertpt, "LOAD_CONST", disp_idx)
    loadfn.lineno = loop[0].lineno
    insert_instruction(outer, loadfn)

    insertpt = insertpt.next()
    for arg in args:
        loadarg = ByteCodeInst.get(insertpt, 'LOAD_FAST',
                                   bytecode.co_varnames.index(arg))
        loadarg.lineno = loop[0].lineno
        insert_instruction(outer, loadarg)
        insertpt = insertpt.next()

    # Call function
    assert len(args) < 256
    call = ByteCodeInst.get(insertpt, "CALL_FUNCTION", len(args))
    call.lineno = loop[0].lineno
    insert_instruction(outer, call)

    insertpt = insertpt.next()

    if returns:
        # Unpack arguments
        unpackseq = ByteCodeInst.get(insertpt, "UNPACK_SEQUENCE", len(returns))
        unpackseq.lineno = loop[0].lineno
        insert_instruction(outer, unpackseq)
        insertpt = insertpt.next()

        for out in returns:
            # Store each variable
            storefast = ByteCodeInst.get(insertpt, "STORE_FAST",
                                         bytecode.co_varnames.index(out))
            storefast.lineno = loop[0].lineno
            insert_instruction(outer, storefast)
            insertpt = insertpt.next()
    else:
        # No return value
        poptop = ByteCodeInst.get(outer[-1].next, "POP_TOP", None)
        poptop.lineno = loop[0].lineno
        insert_instruction(outer, poptop)
        insertpt = insertpt.next()

    jmpback = ByteCodeInst.get(insertpt, 'JUMP_ABSOLUTE', endloopoffset)

    jmpback.lineno = loop[0].lineno
    insert_instruction(outer, jmpback)

    return disp