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
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
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
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)
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
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