void Environment::run_file(std::string file) { if(!state->probe->nil_p()) state->probe->load_runtime(state, file); std::ifstream stream(file.c_str()); if(!stream) throw std::runtime_error("Unable to open file to run"); CompiledFile* cf = CompiledFile::load(stream); if(cf->magic != "!RBIX") throw std::runtime_error("Invalid file"); // TODO check version number cf->execute(state); if(!G(current_task)->exception()->nil_p()) { // Reset the context so we can show the backtrace // HACK need to use write barrier aware stuff? Exception* exc = G(current_task)->exception(); G(current_task)->active(state, exc->context()); std::ostringstream msg; msg << "exception detected at toplevel: "; if(!exc->message()->nil_p()) { msg << exc->message()->c_str(); } msg << " (" << exc->klass()->name()->c_str(state) << ")"; Assertion::raise(msg.str().c_str()); } }
Object* ThreadState::state_as_object(STATE) { if(raise_reason_ == cNone && current_exception_.get()->nil_p()) return cNil; Exception* exc = Exception::create(state); exc->klass(state, G(exc_vm_internal)); exc->set_ivar(state, state->symbol("reason"), Fixnum::from(raise_reason_)); exc->set_ivar(state, state->symbol("destination"), destination_scope()); exc->set_ivar(state, state->symbol("throw_dest"), throw_dest()); exc->set_ivar(state, state->symbol("exception"), current_exception()); exc->set_ivar(state, state->symbol("value"), raise_value()); return exc; }
void Environment::run_file(std::string path) { std::stringstream stream; std::ifstream file(path.c_str(), std::ios::ate|std::ios::binary); if(!file) { std::string msg = std::string("Unable to open file to run: "); msg.append(path); throw std::runtime_error(msg); } std::streampos length = file.tellg(); std::vector<char> buffer(length); file.seekg(0, std::ios::beg); file.read(&buffer[0], length); stream.rdbuf()->pubsetbuf(&buffer[0], length); CompiledFile* cf = CompiledFile::load(stream); if(cf->magic != "!RBIX") throw std::runtime_error("Invalid file"); if((signature_ > 0 && cf->signature != signature_) || cf->version != version_) { throw BadKernelFile(path); } cf->execute(state); if(state->vm()->thread_state()->raise_reason() == cException) { Exception* exc = as<Exception>(state->vm()->thread_state()->current_exception()); std::ostringstream msg; msg << "exception detected at toplevel: "; if(!exc->message()->nil_p()) { if(String* str = try_as<String>(exc->message())) { msg << str->c_str(state); } else { msg << "<non-string Exception message>"; } } else if(Exception::argument_error_p(state, exc)) { msg << "given " << as<Fixnum>(exc->get_ivar(state, state->symbol("@given")))->to_native() << ", expected " << as<Fixnum>(exc->get_ivar(state, state->symbol("@expected")))->to_native(); } msg << " (" << exc->klass()->debug_str(state) << ")"; std::cout << msg.str() << "\n"; exc->print_locations(state); Assertion::raise(msg.str().c_str()); } delete cf; }
void Environment::run_file(std::string file) { if(!state->probe->nil_p()) state->probe->load_runtime(state, file); std::ifstream stream(file.c_str()); if(!stream) { std::string msg = std::string("Unable to open file to run: "); msg.append(file); throw std::runtime_error(msg); } CompiledFile* cf = CompiledFile::load(stream); if(cf->magic != "!RBIX") throw std::runtime_error("Invalid file"); if(signature_ > 0) { if(cf->version != signature_) throw BadKernelFile(file); } /** @todo Redundant? CompiledFile::execute() does this. --rue */ state->thread_state()->clear_exception(true); // TODO check version number cf->execute(state); if(state->thread_state()->raise_reason() == cException) { Exception* exc = as<Exception>(state->thread_state()->raise_value()); std::ostringstream msg; msg << "exception detected at toplevel: "; if(!exc->message()->nil_p()) { if(String* str = try_as<String>(exc->message())) { msg << str->c_str(); } else { msg << "<non-string Exception message>"; } } else if(Exception::argument_error_p(state, exc)) { msg << "given " << as<Fixnum>(exc->get_ivar(state, state->symbol("@given")))->to_native() << ", expected " << as<Fixnum>(exc->get_ivar(state, state->symbol("@expected")))->to_native(); } msg << " (" << exc->klass()->name()->c_str(state) << ")"; std::cout << msg.str() << "\n"; exc->print_locations(state); Assertion::raise(msg.str().c_str()); } delete cf; }
void Environment::run_file(std::string file) { std::ifstream stream(file.c_str()); if(!stream) { std::string msg = std::string("Unable to open file to run: "); msg.append(file); throw std::runtime_error(msg); } CompiledFile* cf = CompiledFile::load(stream); if(cf->magic != "!RBIX") { std::ostringstream msg; msg << "attempted to open a bytecode file with invalid magic identifier" << ": path: " << file << ", magic: " << cf->magic; throw std::runtime_error(msg.str().c_str()); } if((signature_ > 0 && cf->signature != signature_) || cf->version != version_) { throw BadKernelFile(file); } cf->execute(state); if(state->vm()->thread_state()->raise_reason() == cException) { Exception* exc = as<Exception>(state->vm()->thread_state()->current_exception()); std::ostringstream msg; msg << "exception detected at toplevel: "; if(!exc->reason_message()->nil_p()) { if(String* str = try_as<String>(exc->reason_message())) { msg << str->c_str(state); } else { msg << "<non-string Exception message>"; } } else if(Exception::argument_error_p(state, exc)) { msg << "given " << as<Fixnum>(exc->get_ivar(state, state->symbol("@given")))->to_native() << ", expected " << as<Fixnum>(exc->get_ivar(state, state->symbol("@expected")))->to_native(); } msg << " (" << exc->klass()->debug_str(state) << ")"; std::cout << msg.str() << "\n"; exc->print_locations(state); Assertion::raise(msg.str().c_str()); } delete cf; }
Object* CompiledCode::execute_script(STATE) { state->thread_state()->clear(); Arguments args(state->symbol("script"), G(main)); scope(state, ConstantScope::create(state)); scope()->module(state, G(object)); execute(state, this, G(object), args); /* We have to assume that this can fail before the Kernel is able to * handle that failure, so we manually process exceptional behavior here. * * TODO: Fix this by ensuring normal Exceptions can be raised */ if(state->vm()->thread_state()->raise_reason() == cException) { Exception* exc = as<Exception>(state->vm()->thread_state()->current_exception()); std::ostringstream msg; msg << "exception detected at toplevel: "; if(!exc->reason_message()->nil_p()) { if(String* str = try_as<String>(exc->reason_message())) { msg << str->c_str(state); } else { msg << "<non-string Exception message>"; } } else if(Exception::argument_error_p(state, exc)) { msg << "given " << as<Fixnum>(exc->get_ivar(state, state->symbol("@given")))->to_native() << ", expected " << as<Fixnum>(exc->get_ivar(state, state->symbol("@expected")))->to_native(); } msg << " (" << exc->klass()->debug_str(state) << ")"; std::cout << msg.str() << "\n"; exc->print_locations(state); Assertion::raise(msg.str().c_str()); } return cNil; }