def translate_slice_idxs(vm, i, j, upper): i = translate_slice_idx(vm, i, upper) j = translate_slice_idx(vm, j, upper) if j < i: vm.raise_helper("Indices_Exception", \ [Builtins.Con_Int(vm, i), Builtins.Con_Int(vm, j)]) return i, j
def _instr_exbi(self, instr, cf): class_ = Builtins.type_check_class(self, cf.stack_pop()) bind_o = cf.stack_pop() nm_start, nm_size = Target.unpack_exbi(instr) nm = Target.extract_str(cf.pc.mod.bc, nm_start + cf.bc_off, nm_size) pa = Builtins.Con_Partial_Application(self, class_.get_field(self, nm), [bind_o]) cf.stack_push(pa) cf.bc_off += Target.align(nm_start + nm_size)
def translate_slice_idx(vm, i, upper): if i < 0: i = upper + i if i < 0 or i > upper: vm.raise_helper("Bounds_Exception", \ [Builtins.Con_Int(vm, i), Builtins.Con_Int(vm, upper)]) return i
def _instr_unpack_assign(self, instr, cf): o = cf.stack_get(cf.stackpe - 1) o = Builtins.type_check_list(self, o) ne = len(o.l) if ne != Target.unpack_unpack_assign(instr): self.raise_helper("Unpack_Exception", \ [Builtins.Con_Int(self, Target.unpack_unpack_assign(instr)), \ Builtins.Con_Int(self, ne)]) for i in range(ne - 1, -1, -1): cf.stack_push(o.l[i]) cf.bc_off += Target.INTSIZE
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
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
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)])
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
def raise_(self, ex): ex = Builtins.type_check_exception(self, ex) if ex.call_chain is None: cc = [] # Call chain cf = self.cur_cf while cf is not None: cc.append((cf.pc, cf.func, cf.bc_off)) cf = cf.parent ex.call_chain = cc raise Con_Raise_Exception(ex)
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)
def _instr_func_defn(self, instr, cf): is_bound, max_stack_size, has_loop = Target.unpack_func_defn(instr) np_o = cf.stack_pop() assert isinstance(np_o, Builtins.Con_Int) nv_o = cf.stack_pop() assert isinstance(nv_o, Builtins.Con_Int) name = cf.stack_pop() new_pc = BC_PC(cf.pc.mod, cf.bc_off + 2 * Target.INTSIZE) container = cf.func.get_slot(self, "container") f = Builtins.Con_Func(self, name, is_bound, new_pc, max_stack_size, np_o.v, nv_o.v, \ container, cf.closure, has_loop=has_loop) cf.stack_push(f) cf.bc_off += Target.INTSIZE
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)
def init(self, vm_path,argv): self.vm_path = vm_path self.argv = argv Builtins.bootstrap_con_object(self) Builtins.bootstrap_con_class(self) Builtins.bootstrap_con_dict(self) Builtins.bootstrap_con_func(self) Builtins.bootstrap_con_int(self) Builtins.bootstrap_con_float(self) Builtins.bootstrap_con_list(self) Builtins.bootstrap_con_module(self) Builtins.bootstrap_con_partial_application(self) Builtins.bootstrap_con_set(self) Builtins.bootstrap_con_string(self) Builtins.bootstrap_con_exception(self) import Modules for init_func in Modules.BUILTIN_MODULES: self.set_mod(init_func(self)) self.get_mod("Exceptions").import_(self) self.get_mod("POSIX_File").import_(self) self.get_mod("Sys").import_(self)
def init(self, vm_path, argv): self.vm_path = vm_path self.argv = argv Builtins.bootstrap_con_object(self) Builtins.bootstrap_con_class(self) Builtins.bootstrap_con_dict(self) Builtins.bootstrap_con_func(self) Builtins.bootstrap_con_int(self) Builtins.bootstrap_con_float(self) Builtins.bootstrap_con_list(self) Builtins.bootstrap_con_module(self) Builtins.bootstrap_con_partial_application(self) Builtins.bootstrap_con_set(self) Builtins.bootstrap_con_string(self) Builtins.bootstrap_con_exception(self) import Modules for init_func in Modules.BUILTIN_MODULES: self.set_mod(init_func(self)) self.get_mod("Exceptions").import_(self) self.get_mod("POSIX_File").import_(self) self.get_mod("Sys").import_(self)
def entry_point(argv): vm_path = _get_vm_path(argv) verbosity = 0 mk_fresh = False i = 1 for i in range(1, len(argv)): arg = argv[i] if len(arg) == 0 or (len(arg) == 1 and arg[0] == "-"): _usage(vm_path) return 1 if arg[0] == "-": for c in arg[1:]: if c == "v": verbosity += 1 elif c == "f": mk_fresh = True else: _usage(vm_path) return 1 else: break if i < len(argv): filename = argv[i] if i + 1 < len(argv): args = argv[i + 1 : ] else: args = [] else: filename = None args = [] if filename is None: convergeip = _find_con_exec(vm_path, "convergei") if convergeip is None: return 1 filename = convergeip progp = _canon_path(filename) bc, start = _read_bc(progp, "CONVEXEC") if len(bc) == 0: _error(vm_path, "No such file '%s'." % filename) return 1 if start == -1: bc, start, rtn = _make_mode(vm_path, progp, bc, verbosity, mk_fresh) if rtn != 0: return rtn if start == -1: _error(vm_path, "No valid bytecode to run.") return 1 assert start >= 0 useful_bc = rffi.str2charp(bc[start:]) vm = VM.new_vm(vm_path, args) _import_lib(vm, "Stdlib.cvl", vm_path, STDLIB_DIRS) _import_lib(vm, "Compiler.cvl", vm_path, COMPILER_DIRS) try: main_mod_id = Bytecode.add_exec(vm, useful_bc) mod = vm.get_mod(main_mod_id) mod.import_(vm) vm.apply(mod.get_defn(vm, "main")) except VM.Con_Raise_Exception, e: ex_mod = vm.get_builtin(Builtins.BUILTIN_EXCEPTIONS_MODULE) sys_ex_class = ex_mod.get_defn(vm, "System_Exit_Exception") if vm.get_slot_apply(sys_ex_class, "instantiated", [e.ex_obj], allow_fail=True) is not None: code = Builtins.type_check_int(vm, e.ex_obj.get_slot(vm, "code")) return int(code.v) else: pb = vm.import_stdlib_mod(Stdlib_Modules.STDLIB_BACKTRACE).get_defn(vm, "print_best") vm.apply(pb, [e.ex_obj]) return 1
def entry_point(argv): vm_path = _get_vm_path(argv) verbosity = 0 mk_fresh = False i = 1 for i in range(1, len(argv)): arg = argv[i] if len(arg) == 0 or (len(arg) == 1 and arg[0] == "-"): _usage(vm_path) return 1 if arg[0] == "-": for c in arg[1:]: if c == "v": verbosity += 1 elif c == "f": mk_fresh = True else: _usage(vm_path) return 1 else: break if i < len(argv): filename = argv[i] if i + 1 < len(argv): args = argv[i + 1:] else: args = [] else: filename = None args = [] if filename is None: convergeip = _find_con_exec(vm_path, "convergei") if convergeip is None: return 1 filename = convergeip progp = _canon_path(filename) bc, start = _read_bc(progp, "CONVEXEC") if len(bc) == 0: _error(vm_path, "No such file '%s'." % filename) return 1 if start == -1: bc, start, rtn = _make_mode(vm_path, progp, bc, verbosity, mk_fresh) if rtn != 0: return rtn if start == -1: _error(vm_path, "No valid bytecode to run.") return 1 assert start >= 0 useful_bc = rffi.str2charp(bc[start:]) vm = VM.new_vm(vm_path, args) _import_lib(vm, "Stdlib.cvl", vm_path, STDLIB_DIRS) _import_lib(vm, "Compiler.cvl", vm_path, COMPILER_DIRS) try: main_mod_id = Bytecode.add_exec(vm, useful_bc) mod = vm.get_mod(main_mod_id) mod.import_(vm) vm.apply(mod.get_defn(vm, "main")) except VM.Con_Raise_Exception, e: ex_mod = vm.get_builtin(Builtins.BUILTIN_EXCEPTIONS_MODULE) sys_ex_class = ex_mod.get_defn(vm, "System_Exit_Exception") if vm.get_slot_apply(sys_ex_class, "instantiated", [e.ex_obj], allow_fail=True) is not None: code = Builtins.type_check_int(vm, e.ex_obj.get_slot(vm, "code")) return int(code.v) else: pb = vm.import_stdlib_mod( Stdlib_Modules.STDLIB_BACKTRACE).get_defn(vm, "print_best") vm.apply(pb, [e.ex_obj]) return 1
# Copyright 2016 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Built-in Python identifiers.""" # pylint: disable=invalid-name from '__go__/grumpy' import Builtins for k, v in Builtins.iteritems(): globals()[k] = v
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
def Interpreter(toks): for i in range(len(toks)): if toks[i]['key'] == 'print': Builtins.bPrint(PrimitiveTypes.ToText(toks[i]['args'])) elif toks[i]['key'] == 'set': Builtins.bSet(toks[i]['args'])
def _instr_set(self, instr, cf): ne = Target.unpack_set(instr) l = cf.stack_get_slice_del(cf.stackpe - ne) cf.stack_push(Builtins.Con_Set(self, l)) cf.bc_off += Target.INTSIZE