示例#1
0
 def call(self, args_w):
     assert len(args_w) == 2
     w_x, w_y = args_w
     x, y = w_x.to_int(), w_y.to_int()
     if y < 0:
         return W_Integer(x >> (-y))
     else:
         return W_Integer(x << y)
示例#2
0
 def call(self, args_w):
     assert len(args_w) >= 1
     if len(args_w) == 1:
         return W_Integer(-args_w[0].to_int())
     else:
         lhs = args_w[0].to_int()
         for i in xrange(1, len(args_w)):
             w_arg = args_w[i]
             lhs -= w_arg.to_int()
         return W_Integer(lhs)
示例#3
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
示例#4
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
示例#5
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
示例#6
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
示例#7
0
def dump_bytecode_function(w_func):
    assert isinstance(w_func, W_BytecodeFunction)
    fields_w = [None] * 9
    fields_w[0] = symbol('BYTECODE-FUNCTION')
    fields_w[1] = list_to_pair([symbol('NAME'), symbol(w_func.name)])
    #
    code_w = [None] * len(w_func.code)
    for i in xrange(len(code_w)):
        code_w[i] = W_Integer(ord(w_func.code[i]))
    w_code = list_to_pair(code_w)
    fields_w[2] = list_to_pair([symbol('CODE'), w_code])
    fields_w[3] = list_to_pair([
        symbol('NB-ARGS'),
        W_Integer(w_func.nb_args),
        w_boolean(w_func.has_vararg)
    ])
    fields_w[4] = list_to_pair(
        [symbol('NB-LOCALS'), W_Integer(w_func.nb_locals)])
    upval_descrs_w = [None] * (len(w_func.upval_descrs) >> 1)
    i = 0
    while i < len(w_func.upval_descrs):
        c0, c1 = w_func.upval_descrs[i], w_func.upval_descrs[i + 1]
        upval_descrs_w[i >> 1] = list_to_pair(
            [W_Integer(ord(c0)), W_Integer(ord(c1))])
        i += 2
    #
    w_upval_descrs = list_to_pair(upval_descrs_w[:])
    fields_w[5] = list_to_pair([symbol('UPVAL-DESCRS'), w_upval_descrs])
    w_consts = list_to_pair(w_func.consts_w[:])
    fields_w[6] = list_to_pair([symbol('CONSTS'), w_consts])
    w_names = list_to_pair(w_func.names_w[:])
    fields_w[7] = list_to_pair([symbol('NAMES'), w_names])
    functions_w = [
        dump_bytecode_function(w_function) for w_function in w_func.functions_w
    ]
    w_functions = list_to_pair(functions_w[:])
    fields_w[8] = list_to_pair([symbol('FUNCTIONS'), w_functions])
    return list_to_pair(fields_w)
示例#8
0
文件: ffi.py 项目: overminder/YASI
 def call(self, args_w):
     assert len(args_w) == len(self.argtypes_w)
     argchain = ArgChain()
     buffers = []
     for i in xrange(len(args_w)):
         w_arg = args_w[i]
         assert isinstance(w_arg, self.argtypes_w[i])
         if isinstance(w_arg, W_Integer):
             argchain.arg(w_arg.ival)
         elif isinstance(w_arg, W_Symbol):
             sval = w_arg.sval
             assert sval is not None
             charp = rffi.str2charp(sval)
             buffers.append(charp)
             argchain.arg(charp)
         elif isinstance(w_arg, W_String):
             sval = w_arg.content()
             assert sval is not None
             charp = rffi.str2charp(sval)
             buffers.append(charp)
             argchain.arg(charp)
         elif isinstance(w_arg, W_Boolean):
             argchain.arg(w_arg.to_bool())
         else:
             assert 0, 'unsupported argument type'
     res = self.funcptr.call(argchain, rffi.LONG) # annotate type to LONG
     for charp in buffers:
         rffi.free_charp(charp)
     #
     if self.w_restype is W_Integer:
         w_retval = W_Integer(rffi.cast(rffi.LONG, res))
     elif self.w_restype is W_Boolean:
         w_retval = w_boolean(rffi.cast(rffi.LONG, res))
     elif self.w_restype is W_Symbol:
         # XXX who delete the returned pointer?
         w_retval = symbol(rffi.charp2str(rffi.cast(rffi.CCHARP, res)))
     elif self.w_restype is W_String:
         w_retval = W_String(rffi.charp2str(rffi.cast(rffi.CCHARP, res)))
     elif self.w_restype is W_Unspecified:
         w_retval = w_unspec
     else:
         assert 0, 'unsupported result type'
     return w_retval
示例#9
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
示例#10
0
 def call(self, args_w):
     lhs = 0
     for w_arg in args_w:
         lhs += w_arg.to_int()
     return W_Integer(lhs)
示例#11
0
 def call(self, args_w):
     assert len(args_w) == 2
     w_x, w_y = args_w
     return W_Integer(w_x.to_int() & w_y.to_int())