Example #1
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)
Example #2
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
Example #3
0
def test_call():
    w_global = ModuleDict()
    populate_module(w_global)
    #
    code = make_code(Op.LOAD, 0,
                     Op.LOAD, 1,
                     Op.LOADGLOBAL, 0,
                     Op.CALL, 2,
                     Op.RET)
    w_lt = symbol('<')
    w_func = W_BytecodeFunction(code, 2, 2, '', [],
                                [w_lt], [], w_global, 'lessthan')

    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],
                                [], [w_func], w_global, 'main')

    w_retval = execute_function(w_main, [])
    assert w_retval is w_true
Example #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
Example #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
Example #6
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)
Example #7
0
def test_add():
    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_add = symbol('+')
    w_global = ModuleDict()
    populate_module(w_global)
    w_func = W_BytecodeFunction(code, 0, 0, '', [w_one, w_two],
                                [w_add], [], w_global, 'main')
    w_retval = execute_function(w_func, [])
    assert w_retval.to_int() == 3
Example #8
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
Example #9
0
 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
Example #10
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
Example #11
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
Example #12
0
        if tailp:
            frame.leave_with_retval(w_closure)
        else:
            frame.push(w_closure)

class W_DumpBytecodeFunction(W_NativeClosure):
    _symbol_ = 'dump-bytecode-function'

    def call(self, args_w):
        assert len(args_w) == 1
        w_arg, = args_w
        assert isinstance(w_arg, W_BytecodeClosure)
        assert not w_arg.upvals_w
        return dump_bytecode_function(w_arg.w_func)

name2type = {
    'symbol': W_Symbol,
    'string': W_String,
    'integer': W_Integer,
    'void': W_Unspecified,
    'boolean': W_Boolean,
}

for val in globals().values():
    if (isinstance(val, type) and issubclass(val, (W_NativeClosure,
                                                   W_NativeClosureX)) and
            hasattr(val, '_symbol_')):
        prelude_registry.append((symbol(val._symbol_), val()))
del val

Example #13
0
 def call(self, args_w):
     assert len(args_w) == 1
     w_str, = args_w
     assert isinstance(w_str, W_String)
     return symbol(w_str.content())
Example #14
0
def w_tag(s, w_x):
    return W_Pair(symbol(s), W_Pair(w_x, w_nil))
Example #15
0
def w_tag(s, w_x):
    return W_Pair(symbol(s), W_Pair(w_x, w_nil))
Example #16
0
            frame.leave_with_retval(w_closure)
        else:
            frame.push(w_closure)


class W_DumpBytecodeFunction(W_NativeClosure):
    _symbol_ = 'dump-bytecode-function'

    def call(self, args_w):
        assert len(args_w) == 1
        w_arg, = args_w
        assert isinstance(w_arg, W_BytecodeClosure)
        assert not w_arg.upvals_w
        return dump_bytecode_function(w_arg.w_func)


name2type = {
    'symbol': W_Symbol,
    'string': W_String,
    'integer': W_Integer,
    'void': W_Unspecified,
    'boolean': W_Boolean,
}

for val in globals().values():
    if (isinstance(val, type)
            and issubclass(val, (W_NativeClosure, W_NativeClosureX))
            and hasattr(val, '_symbol_')):
        prelude_registry.append((symbol(val._symbol_), val()))
del val
Example #17
0
 def call(self, args_w):
     assert len(args_w) == 1
     w_str, = args_w
     assert isinstance(w_str, W_String)
     return symbol(w_str.content())
Example #18
0
from tvm.asm.assembler import load_bytecode_function
from tvm.lang.reader import read_string
from tvm.lang.model import symbol
from tvm.util import localpath
from tvm.lang.env import ModuleDict
from tvm.rt.prelude import populate_module
from tvm.rt.execution import execute_function

with open(localpath(__file__, 'stage2-compiled-lib.ss')) as f:
    content = f.read()

w_lib_expr = read_string(content)[0]
lib_module = ModuleDict()
populate_module(lib_module)
w_lib_function = load_bytecode_function(w_lib_expr, lib_module)
execute_function(w_lib_function, [])

w_macro_expander = lib_module.getitem(symbol("expand-builtin-macro")).w_func
w_code_compiler = lib_module.getitem(symbol("compile-program")).w_func

def compile_expr(w_expr, w_module):
    w_expanded = execute_function(w_macro_expander, [w_expr])
    w_compiled = execute_function(w_code_compiler, [w_expanded])
    return load_bytecode_function(w_compiled, w_module)