예제 #1
0
    def _instr_unpack_args(self, instr, cf):
        num_fargs, has_vargs = Target.unpack_unpack_args(instr)
        num_fargs = jit.promote(num_fargs)
        has_vargs = jit.promote(has_vargs)
        if not has_vargs:
            nargs = jit.promote(cf.nargs)
        else:
            nargs = cf.nargs
        if nargs > num_fargs and not has_vargs:
            msg = "Too many parameters (%d passed, but a maximum of %d allowed)." % \
              (nargs, num_fargs)
            self.raise_helper("Parameters_Exception",
                              [Builtins.Con_String(self, msg)])

        if num_fargs > 0:
            arg_offset = cf.bc_off + Target.INTSIZE + num_fargs * Target.INTSIZE
            for i in range(num_fargs - 1, -1, -1):
                arg_offset -= Target.INTSIZE
                arg_info = Target.read_word(cf.pc.mod.bc, arg_offset)
                if i >= nargs:
                    if not Target.unpack_unpack_args_is_mandatory(arg_info):
                        msg = "No value passed for parameter %d." % (i + 1)
                        self.raise_helper("Parameters_Exception",
                                          [Builtins.Con_String(self, msg)])
                else:
                    if nargs > num_fargs:
                        o = cf.stack_pop_n(nargs - num_fargs)
                    else:
                        o = cf.stack_pop()
                    assert isinstance(o, Builtins.Con_Object)
                    cf.closure.vars[Target.unpack_unpack_args_arg_num(
                        arg_info)] = o

        if has_vargs:
            arg_offset = cf.bc_off + Target.INTSIZE + num_fargs * Target.INTSIZE
            arg_info = Target.read_word(cf.pc.mod.bc, arg_offset)
            if nargs <= num_fargs:
                l = []
            else:
                j = cf.stackpe
                i = j - (nargs - num_fargs)
                assert i >= 0 and j >= 0
                l = cf.stack_get_slice(i, j)
                cf.stackpe = i + 1
            cf.closure.vars[Target.unpack_unpack_args_arg_num(
                arg_info)] = Builtins.Con_List(self, l)
            cf.bc_off += Target.INTSIZE + (num_fargs + 1) * Target.INTSIZE
        else:
            cf.bc_off += Target.INTSIZE + num_fargs * Target.INTSIZE
예제 #2
0
    def apply_closure(self, func, args=None, allow_fail=False):
        if not args:
            nargs = 0
        else:
            nargs = len(args)

        if isinstance(func, Builtins.Con_Partial_Application):
            real_func = func.f
            cf, stack_count = self._add_continuation_frame(
                real_func, nargs + 1)
            cf.stack_extend(func.args)
        else:
            real_func = func
            cf, stack_count = self._add_continuation_frame(func, nargs)

        if args:
            cf.stack_extend(list(args))

        assert isinstance(real_func, Builtins.Con_Func)
        if stack_count > 1 or real_func.has_loop:
            o = self.execute_proc_jit_hidden(cf)
        else:
            o = self.execute_proc(cf)
        self._remove_continuation_frame()

        if o is self.get_builtin(Builtins.BUILTIN_FAIL_OBJ):
            o = None
        if not allow_fail and o is None:
            self.raise_helper("VM_Exception", [Builtins.Con_String(self, \
              "Function attempting to return fail, but caller can not handle failure.")])

        return o, cf.closure
예제 #3
0
    def import_stdlib_mod(self, ptl_mod_id):
        if not ptl_mod_id.startswith(os.sep):
            return self.get_mod(ptl_mod_id)

        for cnd_mod_id in self.mods.keys():
            bt_cnd_mod_id = cnd_mod_id

            # XXX. The next two operations are pure evil and are basically a poor-man's
            # bootstrapping. They're intended to convert between module IDs across different
            # platforms. The potential problems with the below are fairly obvious, although
            # unlikely to actually manifest themselves in real life.
            if CASE_SENSITIVE_FILENAMES == 0:
                bt_cnd_mod_id = bt_cnd_mod_id.lower()

            if os.sep == "/":
                bt_cnd_mod_id = bt_cnd_mod_id.replace("\\", "/")
            elif os.sep == "\\":
                bt_cnd_mod_id = bt_cnd_mod_id.replace("/", "\\")
            else:
                self.raise_helper(
                    "VM_Exception",
                    [Con_String(vm, "Unknown separator %s." % os.sep)])

            if bt_cnd_mod_id.endswith(ptl_mod_id):
                mod = self.get_mod(cnd_mod_id)
                mod.import_(self)
                return mod

        self.raise_helper("Import_Exception",
                          [Builtins.Con_String(self, ptl_mod_id)])
예제 #4
0
 def _instr_module_lookup(self, instr, cf):
     o = cf.stack_pop()
     nm_start, nm_size = Target.unpack_mod_lookup(instr)
     nm = Target.extract_str(cf.pc.mod.bc, cf.bc_off + nm_start, nm_size)
     if isinstance(o, Builtins.Con_Module):
         v = o.get_defn(self, nm)
     else:
         v = self.get_slot_apply(o, "get_defn",
                                 [Builtins.Con_String(self, nm)])
     cf.stack_push(v)
     cf.bc_off += Target.align(nm_start + nm_size)
예제 #5
0
def mk_mod(vm, bc, mod_off):
    mod_size = read_word(bc, mod_off + BC_MOD_SIZE)
    assert mod_off >= 0 and mod_size >= 0

    mod_bc = rffi.ptradd(bc, mod_off)

    name = _extract_sstr(mod_bc, BC_MOD_NAME, BC_MOD_NAME_SIZE)
    id_ = _extract_sstr(mod_bc, BC_MOD_ID, BC_MOD_ID_SIZE)
    src_path = _extract_sstr(mod_bc, BC_MOD_SRC_PATH, BC_MOD_SRC_PATH_SIZE)

    imps = []
    j = read_word(mod_bc, BC_MOD_IMPORTS)
    for k in range(read_word(mod_bc, BC_MOD_NUM_IMPORTS)):
        assert j > 0
        imp_size = read_word(mod_bc, j)
        assert imp_size > 0
        j += INTSIZE
        imps.append(rffi.charpsize2str(rffi.ptradd(mod_bc, j), imp_size))
        j += align(imp_size)
        j += INTSIZE + align(read_word(mod_bc, j))

    num_vars = read_word(mod_bc, BC_MOD_NUM_TL_VARS_MAP)
    tlvars_map = {}
    j = read_word(mod_bc, BC_MOD_TL_VARS_MAP)
    for k in range(num_vars):
        assert j > 0
        var_num = read_word(mod_bc, j)
        j += INTSIZE
        tlvar_size = read_word(mod_bc, j)
        assert tlvar_size > 0
        j += INTSIZE
        n = rffi.charpsize2str(rffi.ptradd(mod_bc, j), tlvar_size)
        tlvars_map[n] = var_num
        j += align(tlvar_size)

    num_consts = read_word(mod_bc, BC_MOD_NUM_CONSTANTS)

    mod = Builtins.new_bc_con_module(vm, mod_bc, name, id_, src_path, imps,
                                     tlvars_map, num_consts)
    init_func_off = read_word(mod_bc, BC_MOD_INSTRUCTIONS)
    pc = BC_PC(mod, init_func_off)
    max_stack_size = 512  # XXX!
    mod.init_func = Builtins.Con_Func(vm, Builtins.Con_String(vm, "$$init$$"), False, pc, \
      max_stack_size, 0, num_vars, mod, None)

    return mod
예제 #6
0
    def decode_args(self, mand="", opt="", vargs=False, self_of=None):
        cf = self.cur_cf
        nargs = cf.nargs  # Number of arguments passed

        mand = jit.promote_string(mand)
        opt = jit.promote_string(opt)
        self_of = jit.promote(self_of)

        if nargs < len(mand):
            if vargs:
                self.raise_helper("Parameters_Exception", [Builtins.Con_String(self, \
                  "Too few parameters (%d passed, but at least %d needed)." % (nargs, len(mand)))])
            else:
                self.raise_helper("Parameters_Exception", [Builtins.Con_String(self, \
                  "Too few parameters (%d passed, but %d needed)." % (nargs, len(mand)))])
        elif nargs > (len(mand) + len(opt)) and not vargs:
            raise Exception("XXX")

        if nargs == 0:
            if vargs:
                return (None, [])
            else:
                return (None, None)

        nrmp = [None] * (len(mand) + len(opt))  # Normal params
        i = 0
        while i < (len(mand) + len(opt)):
            if i >= nargs:
                for j in range(i, nargs):
                    nrmp[j] = None
                break

            if i < len(mand):
                t = mand[i]
            else:
                t = opt[i - len(mand)]

            o = cf.stack_get(cf.stackpe - nargs + i)

            if t == "!":
                assert self_of is not None
                if not isinstance(o, self_of):
                    raise Exception("XXX")
                nrmp[i] = o
                i += 1
                continue

            if t >= "a":
                if o is self.get_builtin(Builtins.BUILTIN_NULL_OBJ):
                    nrmp[i] = None
                    i += 1
                    continue
                t = chr(ord("A") + ord(t) - ord("a"))

            if t == "O":
                nrmp[i] = o
            else:
                if t == "C":
                    Builtins.type_check_class(self, o)
                elif t == "D":
                    Builtins.type_check_dict(self, o)
                elif t == "E":
                    Builtins.type_check_exception(self, o)
                elif t == "F":
                    Builtins.type_check_func(self, o)
                elif t == "I":
                    Builtins.type_check_int(self, o)
                elif t == "L":
                    Builtins.type_check_list(self, o)
                elif t == "M":
                    Builtins.type_check_module(self, o)
                elif t == "N":
                    Builtins.type_check_number(self, o)
                elif t == "S":
                    Builtins.type_check_string(self, o)
                elif t == "W":
                    Builtins.type_check_set(self, o)
                else:
                    print t
                    raise Exception("XXX")
                nrmp[i] = o

            i += 1

        if vargs:
            vap = [None] * (nargs - i)
            for j in range(i, nargs):
                vap[j - i] = cf.stack_get(cf.stackpe - nargs + j)
        else:
            vap = None

        cf.stack_del_from(cf.stackpe - nargs)

        return (nrmp, vap)
예제 #7
0
 def get_mod(self, mod_id):
     m = self.find_mod(mod_id)
     if m is None:
         self.raise_helper("Import_Exception",
                           [Builtins.Con_String(self, mod_id)])
     return m