Esempio n. 1
0
def test_immutable_upval():
    w_global = ModuleDict()
    populate_module(w_global)
    #
    inner_code = make_code(
        Op.LOADUPVAL,
        0,  # n
        Op.RET)
    w_inner_func = W_BytecodeFunction(inner_code, 0, 1, '\0', [], [], [], None)

    outer_code = make_code(Op.BUILDUPVAL, 0, Op.LOADCONST, 0, Op.STOREUPVAL, 0,
                           Op.BUILDCLOSURE, 0, Op.RET)
    w_one = W_Integer(1)
    w_outer_func = W_BytecodeFunction(outer_code, 0, 1, '', [w_one], [],
                                      [w_inner_func], None)

    main_code = make_code(
        Op.BUILDCLOSURE,
        0,
        Op.CALL,
        0,  # outer() => inner
        Op.CALL,
        0,  # inner() => 1
        Op.RET)
    w_main = W_BytecodeFunction(main_code, 0, 0, '', [], [], [w_outer_func],
                                None)
    #
    w_retval = execute_function(w_main, [])
    assert w_retval.to_int() == 1
Esempio n. 2
0
def test_mutable_upval():
    w_global = ModuleDict()
    populate_module(w_global)
    w_one = W_Integer(1)
    w_two = W_Integer(2)
    #
    inner_code = make_code(
        Op.LOADUPVAL,
        0,  # n
        Op.LOADCONST,
        0,  # 2
        Op.LOADGLOBAL,
        0,  # '+
        Op.CALL,
        2,
        Op.STOREUPVAL,
        0,  # n
        Op.LOADCONST,
        1,  # void
        Op.RET)
    w_inner_func = W_BytecodeFunction(inner_code, 0, 1, '\0',
                                      [w_two, w_unspec], [symbol('+')], [],
                                      w_global)

    outer_code = make_code(
        Op.BUILDUPVAL,
        0,
        Op.LOADCONST,
        0,  # 1
        Op.STOREUPVAL,
        0,
        Op.BUILDCLOSURE,
        0,  # inner
        Op.CALL,
        0,  # inner(), which changes the upval to 3
        Op.POP,
        Op.LOADUPVAL,
        0,
        Op.RET)
    w_outer_func = W_BytecodeFunction(outer_code, 0, 1, '', [w_one], [],
                                      [w_inner_func], None)

    main_code = make_code(
        Op.BUILDCLOSURE,
        0,
        Op.CALL,
        0,  # outer() => 3
        Op.RET)
    w_main = W_BytecodeFunction(main_code, 0, 0, '', [], [], [w_outer_func],
                                None)
    #
    w_retval = execute_function(w_main, [])
    assert w_retval.to_int() == 3
Esempio n. 3
0
def test_tailcall1():
    w_global = ModuleDict()
    populate_module(w_global)
    #
    code = make_code(Op.LOAD, 0, Op.LOAD, 1, Op.LOADGLOBAL, 0, Op.TAILCALL, 2)
    w_lt = symbol('<')
    w_func = W_BytecodeFunction(code, 2, 2, '', [], [w_lt], [], w_global,
                                'tailcaller')

    maincode = make_code(Op.LOADCONST, 0, Op.LOADCONST, 1, Op.BUILDCLOSURE, 0,
                         Op.CALL, 2, Op.RET)

    w_one = W_Integer(1)
    w_two = W_Integer(2)
    w_main = W_BytecodeFunction(maincode, 0, 0, '', [w_one, w_two], None,
                                [w_func], w_global)
    w_retval = execute_function(w_main, [])
    assert w_retval is w_true
Esempio n. 4
0
def load_bytecode_function(w_expr, w_module):
    fields_w, w_rest = w_expr.to_list()
    assert w_rest.is_null()
    assert len(fields_w) == 9
    assert fields_w[0].to_string() == 'BYTECODE-FUNCTION'
    #
    (w_tag, w_funcname), _ = fields_w[1].to_list()
    assert w_tag.to_string() == 'NAME'
    funcname = w_funcname.to_string()
    #
    (w_tag, w_code), _ = fields_w[2].to_list()
    assert w_tag.to_string() == 'CODE'
    codelist_w, _ = w_code.to_list()
    code = ''.join([chr(c.to_int()) for c in codelist_w])
    #
    (w_tag, w_nb_args, w_has_vararg), _ = fields_w[3].to_list()
    assert w_tag.to_string() == 'NB-ARGS'
    nb_args = w_nb_args.to_int()
    assert nb_args >= 0
    has_vararg = w_has_vararg.to_bool()
    #
    (w_tag, w_nb_locals), _ = fields_w[4].to_list()
    assert w_tag.to_string() == 'NB-LOCALS'
    nb_locals = w_nb_locals.to_int()
    assert nb_locals >= 0
    #
    (w_tag, w_upval_descrs), _ = fields_w[5].to_list()
    assert w_tag.to_string() == 'UPVAL-DESCRS'
    descrlist_w, _ = w_upval_descrs.to_list()
    descr_chars = []
    for w_descr in descrlist_w:
        (w_from, w_to), _ = w_descr.to_list()
        descr_chars.append(chr(w_from.to_int()))
        descr_chars.append(chr(w_to.to_int()))
    upval_descrs = ''.join(descr_chars)
    #
    (w_tag, w_consts), _ = fields_w[6].to_list()
    assert w_tag.to_string() == 'CONSTS'
    consts_w, _ = w_consts.to_list()
    #
    (w_tag, w_names), _ = fields_w[7].to_list()
    assert w_tag.to_string() == 'NAMES'
    names_w, _ = w_names.to_list()
    #
    (w_tag, w_functions), _ = fields_w[8].to_list()
    assert w_tag.to_string() == 'FUNCTIONS'
    func_literals_w, _ = w_functions.to_list()
    functions_w = [
        load_bytecode_function(w_literal, w_module)
        for w_literal in func_literals_w
    ]
    return W_BytecodeFunction(code, nb_args, has_vararg, nb_locals,
                              upval_descrs, consts_w[:], names_w[:],
                              functions_w[:], w_module, funcname)
Esempio n. 5
0
def test_cond():
    code = make_code(Op.LOADCONST, 0, Op.LOADCONST, 1, Op.LOADGLOBAL, 0,
                     Op.CALL, 2, Op.RET)
    w_one = W_Integer(1)
    w_two = W_Integer(2)
    w_lt = symbol('<')
    w_global = ModuleDict()
    populate_module(w_global)
    w_func = W_BytecodeFunction(code, 0, 0, '', [w_one, w_two], [w_lt], [],
                                w_global, 'main')
    w_retval = execute_function(w_func, [])
    assert w_retval is w_true
Esempio n. 6
0
def test_fibo():
    w_global = ModuleDict()
    populate_module(w_global)
    #
    w_two = W_Integer(2)
    w_lt = symbol('<')
    w_one = W_Integer(1)
    w_sub = symbol('-')
    w_fibo = symbol('fibo')
    w_add = symbol('+')
    consts_w = [w_two, w_one]
    names_w = [w_lt, w_sub, w_fibo, w_add]
    code = make_code(
        Op.LOAD,
        0,  # n
        Op.LOADCONST,
        0,  # 2
        Op.LOADGLOBAL,
        0,  # '<
        Op.CALL,
        2,  # push (< n 2)
        Op.JIFNOT,
        14,
        0,  # to recur_case
        Op.LOAD,
        0,  # n
        Op.RET,  # return n
        # recur_case
        Op.LOAD,
        0,  # n
        Op.LOADCONST,
        1,  # 1
        Op.LOADGLOBAL,
        1,  # '-
        Op.CALL,
        2,  # push (- n 1)
        Op.LOADGLOBAL,
        2,  # 'fibo
        Op.CALL,
        1,  # push (fibo (- n 1))
        Op.LOAD,
        0,  # n
        Op.LOADCONST,
        0,  # 2
        Op.LOADGLOBAL,
        1,  # '-
        Op.CALL,
        2,  # push (- n 2)
        Op.LOADGLOBAL,
        2,  # 'fibo
        Op.CALL,
        1,  # push (fibo (- n 2))
        Op.LOADGLOBAL,
        3,  # '+
        Op.TAILCALL,
        2)
    w_func = W_BytecodeFunction(code, 1, 1, '', consts_w, names_w, [],
                                w_global)

    maincode = make_code(Op.BUILDCLOSURE, 0, Op.STOREGLOBAL, 0, Op.LOADCONST,
                         0, Op.LOADGLOBAL, 0, Op.CALL, 1, Op.RET)

    w_ten = W_Integer(10)
    w_main = W_BytecodeFunction(maincode, 0, 0, '', [w_ten], [w_fibo],
                                [w_func], w_global)

    w_retval = execute_function(w_main, [])
    assert w_retval.to_int() == 55