Object* VMMethod::uncommon_interpreter(STATE, VMMethod* const vmm, CallFrame* const call_frame, int32_t entry_ip, native_int sp, CallFrame* const method_call_frame, int32_t unwind_count, int32_t* input_unwinds) { VMMethod* method_vmm = method_call_frame->cm->backend_method(); // 500 is a number picked after doing some tuning on a specific benchmark. // Not sure if it's the right value, but it seems to work fine. if(++method_vmm->uncommon_count > 500) { if(state->shared.config.jit_show_uncommon) { std::cerr << "[[[ Deoptimizing uncommon method ]]]\n"; call_frame->print_backtrace(state); std::cerr << "Method Call Frame:\n"; method_call_frame->print_backtrace(state); } method_vmm->uncommon_count = 0; method_vmm->deoptimize(state, method_call_frame->cm); } #include "vm/gen/instruction_locations.hpp" opcode* stream = vmm->opcodes; InterpreterState is; Object** stack_ptr = call_frame->stk + sp; int current_unwind = unwind_count; UnwindInfo unwinds[kMaxUnwindInfos]; for(int i = 0, j = 0; j < unwind_count; i += 3, j++) { UnwindInfo& uw = unwinds[j]; uw.target_ip = input_unwinds[i]; uw.stack_depth = input_unwinds[i + 1]; uw.type = (UnwindType)input_unwinds[i + 2]; } continue_to_run: try { #undef DISPATCH #define DISPATCH goto *insn_locations[stream[call_frame->inc_ip()]]; #undef next_int #undef cache_ip #undef flush_ip #define next_int ((opcode)(stream[call_frame->inc_ip()])) #define cache_ip(which) #define flush_ip() #include "vm/gen/instruction_implementations.hpp" } catch(TypeError& e) { flush_ip(); Exception* exc = Exception::make_type_error(state, e.type, e.object, e.reason); exc->locations(state, Location::from_call_stack(state, call_frame)); state->thread_state()->raise_exception(exc); call_frame->scope->flush_to_heap(state); return NULL; } catch(const RubyException& exc) { exc.exception->locations(state, Location::from_call_stack(state, call_frame)); state->thread_state()->raise_exception(exc.exception); return NULL; } // No reason to be here! abort(); exception: ThreadState* th = state->thread_state(); // switch(th->raise_reason()) { case cException: if(current_unwind > 0) { UnwindInfo* info = &unwinds[--current_unwind]; stack_position(info->stack_depth); call_frame->set_ip(info->target_ip); cache_ip(info->target_ip); goto continue_to_run; } else { call_frame->scope->flush_to_heap(state); return NULL; } case cBreak: // If we're trying to break to here, we're done! if(th->destination_scope() == call_frame->scope->on_heap()) { stack_push(th->raise_value()); th->clear_break(); goto continue_to_run; // Don't return here, because we want to loop back to the top // and keep running this method. } // Otherwise, fall through and run the unwinds case cReturn: case cCatchThrow: // Otherwise, we're doing a long return/break unwind through // here. We need to run ensure blocks. while(current_unwind > 0) { UnwindInfo* info = &unwinds[--current_unwind]; if(info->for_ensure()) { stack_position(info->stack_depth); call_frame->set_ip(info->target_ip); cache_ip(info->target_ip); // Don't reset ep here, we're still handling the return/break. goto continue_to_run; } } // Ok, no ensures to run. if(th->raise_reason() == cReturn) { call_frame->scope->flush_to_heap(state); // If we're trying to return to here, we're done! if(th->destination_scope() == call_frame->scope->on_heap()) { Object* val = th->raise_value(); th->clear_return(); return val; } else { // Give control of this exception to the caller. return NULL; } } else { // It's cBreak thats not for us! call_frame->scope->flush_to_heap(state); // Give control of this exception to the caller. return NULL; } case cExit: call_frame->scope->flush_to_heap(state); return NULL; default: break; } // switch std::cout << "bug!\n"; call_frame->print_backtrace(state); abort(); return NULL; }
Object* BlockAsMethod::block_executor(STATE, CallFrame* call_frame, Executable* exec, Module* mod, Arguments& args) { BlockAsMethod* bm = as<BlockAsMethod>(exec); Fixnum* splat = bm->block_env()->compiled_code()->splat(); size_t required = bm->block_env()->compiled_code()->required_args()->to_native(); size_t total_args = bm->block_env()->compiled_code()->total_args()->to_native(); /* * These are the block shapes, required args, and splat that we may see, * along with the arity check that we must perform: * * block shape required args splat check * -------------|---------------|-------|------- * { || } | 0 | nil | == * { } | 0 | -2 | none * { |a| } | 1 | nil | none (1.8), == (>= 1.9) * { |*a| } | 0 | 0 | none * { |a, b| } | 2 | nil | == * { |a, *b| } | 1 | 1 | >= * * NOTE that when taking one argument, any arguments passed are put * into an array and the local gets the array (or an empty array if * no arguments are passed). This is handled by the bytecode prologue * of the block. */ bool exception = false; size_t expected = 0; if(splat->nil_p()) { if((!LANGUAGE_18_ENABLED(state) || required != 1)) { if(args.total() > total_args) { exception = true; expected = total_args; } if(args.total() < required) { exception = true; expected = required; } } } else { if(required > args.total()) { exception = true; expected = required; } } if(exception) { Exception* exc = Exception::make_argument_error(state, expected, args.total(), args.name()); exc->locations(state, Location::from_call_stack(state, call_frame)); state->raise_exception(exc); return NULL; } BlockInvocation invocation(args.recv(), bm->block_env()->compiled_code()->scope(), CallFrame::cIsLambda | CallFrame::cBlockAsMethod); invocation.module = mod; return bm->block_env()->invoke(state, call_frame, bm->block_env(), args, invocation); }
void RestBaseHandler::handleError (Exception const& ex) { generateError(HttpResponse::responseCode(ex.code()), ex.code(), ex.what()); }
Object* Proc::call(STATE, CallFrame* call_frame, Arguments& args) { bool lambda_style = CBOOL(lambda_); int flags = 0; // Check the arity in lambda mode if(lambda_style && !block_->nil_p()) { flags = CallFrame::cIsLambda; int total = block_->code()->total_args()->to_native(); int required = block_->code()->required_args()->to_native(); bool arity_ok = false; if(Fixnum* fix = try_as<Fixnum>(block_->code()->splat())) { switch(fix->to_native()) { case -2: arity_ok = true; break; case -4: // splat = -4 means { |(a, b)| } if(args.total() == 1) { Array* ary = 0; Object* obj = args.get_argument(0); if(!(ary = try_as<Array>(obj))) { if(CBOOL(obj->respond_to(state, state->symbol("to_ary"), cFalse))) { obj = obj->send(state, call_frame, state->symbol("to_ary")); if(!(ary = try_as<Array>(obj))) { Exception::type_error(state, "to_ary must return an Array", call_frame); return 0; } } } if(ary) args.use_argument(ary); } // fall through for arity check case -3: // splat = -3 is used to distinguish { |a, | } from { |a| } if(args.total() == (size_t)required) arity_ok = true; break; default: if(args.total() >= (size_t)required) { arity_ok = true; } } /* For blocks taking one argument { |a| }, in 1.8, there is a warning * issued but no exception raised when less than or more than one * argument is passed. If more than one is passed, 'a' receives an Array * of all the arguments. */ } else if(required == 1 && LANGUAGE_18_ENABLED(state)) { arity_ok = true; } else { arity_ok = args.total() <= (size_t)total && args.total() >= (size_t)required; } if(!arity_ok) { Exception* exc = Exception::make_argument_error(state, required, args.total(), state->symbol("__block__")); exc->locations(state, Location::from_call_stack(state, call_frame)); state->raise_exception(exc); return NULL; } } Object* ret; if(bound_method_->nil_p()) { ret = block_->call(state, call_frame, args, flags); } else if(NativeMethod* nm = try_as<NativeMethod>(bound_method_)) { ret = nm->execute(state, call_frame, nm, G(object), args); } else if(NativeFunction* nf = try_as<NativeFunction>(bound_method_)) { ret = nf->call(state, args, call_frame); } else { Dispatch dis(state->symbol("__yield__")); ret = dis.send(state, call_frame, args); } return ret; }
void ExceptionStore::setException(const Exception &e) { if (hasException() == false) exceptionHolder = ExceptionHolder(e.clone()); }
ExceptionDlg::ExceptionDlg(wxWindow* parent, const Exception& exp) : BaseDialog(parent, "Exception", wxDefaultPosition, wxSize(600, 480)) { InitLayout(exp.What()); }
UInt32 RTSPPacket::build(Exception& ex,UInt8* data,UInt32 size) { if (_data) return 0; exception.set(Exception::NIL); /// read data ReadingStep step(CMD); UInt8* current(data); const UInt8* end(current+size); const char* signifiant(NULL); const char* key(NULL); // headers for (; current <= end;++current) { if (memcmp(current, EXPAND("\r\n")) == 0 || memcmp(current, EXPAND("\0\n")) == 0) { if (!ex && signifiant) { // KEY = VALUE UInt8* endValue(current); while (isblank(*--endValue)); *(endValue+1) = 0; if (!key) { // version case! String::ToNumber(signifiant+5, version); } else { headers[key] = signifiant; parseHeader(ex,key,signifiant); key = NULL; } } step = LEFT; current += 2; signifiant = (const char*)current; ++current; // here no continue, the "\r\n" check is not required again } if (ex) continue; // try to go to "\r\n\r\n" // http header, byte by byte UInt8 byte = *current; if ((step == LEFT || step == CMD || step == PATH) && (isspace(byte) || byte==0)) { if (step == CMD) { if ((command = RTSP::ParseCommand(ex, signifiant)) == RTSP::COMMAND_UNKNOWN) { exception = ex; continue; } if(command == RTSP::COMMAND_DESCRIBE) // Only for DESCRIBE : content = application/sdp responseType = HTTP::CONTENT_APPLICATON; signifiant = NULL; step = PATH; } else if (step == PATH) { // parse query *current = 0; size_t filePos = Util::UnpackUrl(signifiant, path,query); url.assign(signifiant); // Get trackID if(filePos != string::npos && path.size() > 9 && String::ICompare(path.substr(filePos),"trackID=",8)==0) { trackID = String::ToNumber<UInt8>(ex, 0, path.substr(filePos+8)); path.erase(filePos - 1); // remove trackID part filePos = path.find_last_of('/'); if (filePos != string::npos) filePos++; } // Record file directory and path file.setPath(path); if (filePos != string::npos) path.erase(filePos - 1); else file.makeFolder(); signifiant = NULL; step = VERSION; } else ++signifiant; // for trim begin of key or value } else if (step > PATH && !key && (byte == ':' || byte == 0)) { // KEY key = signifiant; step = LEFT; UInt8* endValue(current); while (isblank(*--endValue)); *(endValue+1) = 0; signifiant = (const char*)current + 1; } else if (step == CMD || step == PATH || step == VERSION) { if (!signifiant) signifiant = (const char*)current; if (step == CMD && (current-data)>13) // not a RTSP valid command, consumes all exception = ex.set(Exception::PROTOCOL, "invalid RTSP command"); } else step = RIGHT; } _data = data; return _size = current - data; }
void Messagebox::show(Exception e, const QString &msg, unsigned icon_type, unsigned buttons, const QString &yes_lbl, const QString &no_lbl, const QString &cancel_lbl, const QString &yes_ico, const QString &no_ico, const QString &cancel_ico) { vector<Exception> list; vector<Exception>::reverse_iterator itr,itr_end; QTreeWidgetItem *item=nullptr,*item1=nullptr,*item2=nullptr; QLabel *label=nullptr; int idx=0; Exception *ex=nullptr; QString str_aux, title; QFont font=this->font(); show_raw_info_tb->blockSignals(true); show_raw_info_tb->setChecked(false); show_raw_info_tb->blockSignals(false); raw_info_txt->setPlainText(e.getExceptionsText()); e.getExceptionsList(list); itr=list.rbegin(); itr_end=list.rend(); while(itr!=itr_end) { ex=&(*itr); item=new QTreeWidgetItem; str_aux=QString("[%1] - %2") .arg(idx) .arg(ex->getMethod()); item->setIcon(0,QPixmap(QString(":/icones/icones/funcao.png"))); exceptions_trw->insertTopLevelItem(0,item); label=new QLabel; label->setFont(font); label->setWordWrap(true); label->setText(str_aux); exceptions_trw->setItemWidget(item, 0, label); item1=new QTreeWidgetItem(item); item1->setIcon(0,QPixmap(QString(":/icones/icones/codigofonte.png"))); item1->setText(0,ex->getFile() + " (" + ex->getLine() + ")"); item2=new QTreeWidgetItem(item); item2->setIcon(0,QPixmap(QString(":/icones/icones/msgbox_alerta.png"))); item2->setText(0,Exception::getErrorCode(ex->getErrorType()) + " (" + QString("%1").arg(ex->getErrorType()) + ")"); item1=new QTreeWidgetItem(item); item1->setIcon(0,QPixmap(":/icones/icones/msgbox_erro.png")); label=new QLabel; label->setWordWrap(true); label->setFont(font); label->setStyleSheet("color: #ff0000;"); exceptions_trw->setItemWidget(item1, 0, label); label->setText(ex->getErrorMessage()); if(!ex->getExtraInfo().isEmpty()) { item1=new QTreeWidgetItem(item); item1->setIcon(0,QPixmap(QString(":/icones/icones/msgbox_info.png"))); label=new QLabel; label->setWordWrap(true); label->setFont(font); label->setStyleSheet("color: #000080;"); label->setTextInteractionFlags(Qt::TextSelectableByMouse); exceptions_trw->setItemWidget(item1, 0, label); label->setText(ex->getExtraInfo()); } itr++; idx++; } switch(icon_type) { case ERROR_ICON: title=trUtf8("Error"); break; case ALERT_ICON: title=trUtf8("Alert"); break; case INFO_ICON: title=trUtf8("Information"); break; default: title=""; break; } if(msg.isEmpty()) str_aux=e.getErrorMessage(); else str_aux=msg; if(str_aux.contains("`") && str_aux.contains("'")) { str_aux.replace("`", "<strong>"); str_aux.replace("\'","</strong>"); str_aux.replace("(", "<em>("); str_aux.replace(")", ")</em>"); } this->show(title, str_aux, icon_type, buttons, yes_lbl, no_lbl, cancel_lbl, yes_ico, no_ico, cancel_ico); }
Exception::Exception(const Exception &other) : std::exception(), m_message(other.cause()) { }
void ExceptionTest::testConstructorEmpty() { Exception exception; QCOMPARE(exception.what(), ""); QCOMPARE(exception.message(), QString("")); }
Object* Proc::call(STATE, Arguments& args) { bool lambda_style = CBOOL(lambda()); int flags = 0; Proc* self = this; OnStack<1> os(state, self); // Check the arity in lambda mode if(lambda_style && !block()->nil_p()) { flags = CallFrame::cIsLambda; int total = self->block()->compiled_code()->total_args()->to_native(); int required = self->block()->compiled_code()->required_args()->to_native(); bool arity_ok = false; if(Fixnum* fix = try_as<Fixnum>(self->block()->compiled_code()->splat())) { switch(fix->to_native()) { case -2: arity_ok = true; break; case -4: // splat = -4 means { |(a, b)| } if(args.total() == 1) { Array* ary = 0; Object* obj = args.get_argument(0); if(!(ary = try_as<Array>(obj))) { if(CBOOL(obj->respond_to(state, G(sym_to_ary), cFalse))) { if(!(ary = try_as<Array>(obj->send(state, G(sym_to_ary))))) { Exception::type_error(state, "to_ary must return an Array"); return 0; } } } if(ary) args.use_argument(ary); } // fall through for arity check case -3: // splat = -3 is used to distinguish { |a, | } from { |a| } if(args.total() == (size_t)required) arity_ok = true; break; default: if(args.total() >= (size_t)required) { arity_ok = true; } } } else { arity_ok = args.total() <= (size_t)total && args.total() >= (size_t)required; } if(!arity_ok) { Exception* exc = Exception::make_argument_error(state, required, args.total(), block()->compiled_code()->name()); exc->locations(state, Location::from_call_stack(state)); state->raise_exception(exc); return NULL; } } if(self->bound_method()->nil_p()) { if(self->block()->nil_p()) { Dispatch dispatch(state->symbol("__yield__")); return dispatch.send(state, args); } else { return self->block()->call(state, args, flags); } } else if(NativeMethod* nm = try_as<NativeMethod>(self->bound_method())) { return nm->execute(state, nm, G(object), args); } else if(NativeFunction* nf = try_as<NativeFunction>(self->bound_method())) { return nf->call(state, args); } else { Exception* exc = Exception::make_type_error(state, BlockEnvironment::type, self->bound_method(), "NativeMethod nor NativeFunction bound to proc"); exc->locations(state, Location::from_call_stack(state)); state->raise_exception(exc); return NULL; } }
UInt8 RTMFPHandshake::handshakeHandler(UInt8 id,const SocketAddress& address, BinaryReader& request,BinaryWriter& response) { switch(id){ case 0x30: { request.read7BitValue(); // = epdLen + 2 (useless) UInt16 epdLen = request.read7BitValue()-1; UInt8 type = request.read8(); string epd; request.read(epdLen,epd); string tag; request.read(16,tag); response.write8(tag.size()).write(tag); if(type == 0x0f) { const UInt8* peerId((const UInt8*)epd.c_str()); RTMFPSession* pSessionWanted = _sessions.findByPeer<RTMFPSession>(peerId); if(pSessionWanted) { if(pSessionWanted->failed()) return 0x00; // TODO no way in RTMFP to tell "died!" /// Udp hole punching UInt32 times = attempt(tag); RTMFPSession* pSession(NULL); if(times > 0 || address.host() == pSessionWanted->peer.address.host()) // try in first just with public address (excepting if the both peer are on the same machine) pSession = _sessions.findByAddress<RTMFPSession>(address,Socket::DATAGRAM); bool hasAnExteriorPeer(pSessionWanted->p2pHandshake(tag,address,times,pSession)); // public address RTMFP::WriteAddress(response,pSessionWanted->peer.address, RTMFP::ADDRESS_PUBLIC); DEBUG("P2P address initiator exchange, ",pSessionWanted->peer.address.toString()); if (hasAnExteriorPeer && pSession->peer.serverAddress.host()!=pSessionWanted->peer.address.host()) { // the both peer see the server in a different way (and serverAddress.host()!= public address host written above), // Means an exterior peer, but we can't know which one is the exterior peer // so add an interiorAddress build with how see eachone the server on the both side SocketAddress interiorAddress(pSession->peer.serverAddress.host(), pSessionWanted->peer.address.port()); RTMFP::WriteAddress(response,interiorAddress, RTMFP::ADDRESS_PUBLIC); DEBUG("P2P address initiator exchange, ",interiorAddress.toString()); } // local address for(const SocketAddress& address : pSessionWanted->peer.localAddresses) { RTMFP::WriteAddress(response,address, RTMFP::ADDRESS_LOCAL); DEBUG("P2P address initiator exchange, ",address.toString()); } // add the turn address (RelayServer) if possible and required if (pSession && times>0) { UInt8 timesBeforeTurn(0); if(pSession->peer.parameters().getNumber("timesBeforeTurn",timesBeforeTurn) && timesBeforeTurn>=times) { UInt16 port = invoker.relayer.relay(pSession->peer.address,pSessionWanted->peer.address,20); // 20 sec de timeout is enough for RTMFP! if (port > 0) { SocketAddress address(pSession->peer.serverAddress.host(), port); RTMFP::WriteAddress(response, address, RTMFP::ADDRESS_REDIRECTION); } // else ERROR already display by RelayServer class } } return 0x71; } DEBUG("UDP Hole punching, session ", Util::FormatHex(peerId, ID_SIZE, LOG_BUFFER), " wanted not found") set<SocketAddress> addresses; peer.onRendezVousUnknown(peerId,addresses); set<SocketAddress>::const_iterator it; for(it=addresses.begin();it!=addresses.end();++it) { if(it->host().isWildcard()) continue; if(address == *it) WARN("A client tries to connect to himself (same ", address.toString()," address)"); RTMFP::WriteAddress(response,*it,RTMFP::ADDRESS_REDIRECTION); DEBUG("P2P address initiator exchange, ",it->toString()); } return addresses.empty() ? 0 : 0x71; } if(type == 0x0a){ /// RTMFPHandshake HelloAttempt& attempt = AttemptCounter::attempt<HelloAttempt>(tag); Peer& peer(*_pPeer); // Fill peer infos peer.properties().clear(); string serverAddress; Util::UnpackUrl(epd, serverAddress, (string&)peer.path,(string&)peer.query); peer.setServerAddress(serverAddress); Util::UnpackQuery(peer.query, peer.properties()); Exception ex; set<SocketAddress> addresses; peer.onHandshake(attempt.count+1,addresses); if(!addresses.empty()) { set<SocketAddress>::iterator it; for(it=addresses.begin();it!=addresses.end();++it) { if (it->host().isWildcard()) RTMFP::WriteAddress(response, peer.serverAddress, RTMFP::ADDRESS_REDIRECTION); else RTMFP::WriteAddress(response, *it, RTMFP::ADDRESS_REDIRECTION); } return 0x71; } // New RTMFPCookie RTMFPCookie* pCookie = attempt.pCookie; if (!pCookie) { pCookie = new RTMFPCookie(*this, invoker, tag, _pPeer); if (!pCookie->run(ex)) { delete pCookie; ERROR("RTMFPCookie creation, ", ex.error()) return 0; } _pPeer.reset(new Peer((Handler&)invoker)); // reset peer _cookies.emplace(pCookie->value(), pCookie); attempt.pCookie = pCookie; } // response response.write8(COOKIE_SIZE); response.write(pCookie->value(),COOKIE_SIZE); // instance id (certificat in the middle) response.write(_certificat,sizeof(_certificat)); return 0x70; } else
Object* VMMethod::interpreter(STATE, VMMethod* const vmm, InterpreterCallFrame* const call_frame) { #include "vm/gen/instruction_locations.hpp" if(unlikely(state == 0)) { VMMethod::instructions = const_cast<void**>(insn_locations); return NULL; } InterpreterState is; #ifdef X86_ESI_SPEEDUP register void** ip_ptr asm ("esi") = vmm->addresses; #else register void** ip_ptr = vmm->addresses; #endif Object** stack_ptr = call_frame->stk - 1; int current_unwind = 0; UnwindInfo unwinds[kMaxUnwindInfos]; continue_to_run: try { #undef DISPATCH #define DISPATCH goto **ip_ptr++ #undef next_int #define next_int ((opcode)(*ip_ptr++)) #define cache_ip(which) ip_ptr = vmm->addresses + which #define flush_ip() call_frame->calculate_ip(ip_ptr) #include "vm/gen/instruction_implementations.hpp" } catch(TypeError& e) { flush_ip(); Exception* exc = Exception::make_type_error(state, e.type, e.object, e.reason); exc->locations(state, Location::from_call_stack(state, call_frame)); state->thread_state()->raise_exception(exc); call_frame->scope->flush_to_heap(state); return NULL; } catch(const RubyException& exc) { exc.exception->locations(state, Location::from_call_stack(state, call_frame)); state->thread_state()->raise_exception(exc.exception); return NULL; } // There is no reason to be here. Either the bytecode loop exits, // or it jumps to exception; abort(); // If control finds it's way down here, there is an exception. exception: ThreadState* th = state->thread_state(); // switch(th->raise_reason()) { case cException: if(current_unwind > 0) { UnwindInfo* info = &unwinds[--current_unwind]; stack_position(info->stack_depth); call_frame->set_ip(info->target_ip); cache_ip(info->target_ip); goto continue_to_run; } else { call_frame->scope->flush_to_heap(state); return NULL; } case cBreak: // If we're trying to break to here, we're done! if(th->destination_scope() == call_frame->scope->on_heap()) { stack_push(th->raise_value()); th->clear_break(); goto continue_to_run; // Don't return here, because we want to loop back to the top // and keep running this method. } // Otherwise, fall through and run the unwinds case cReturn: case cCatchThrow: // Otherwise, we're doing a long return/break unwind through // here. We need to run ensure blocks. while(current_unwind > 0) { UnwindInfo* info = &unwinds[--current_unwind]; if(info->for_ensure()) { stack_position(info->stack_depth); call_frame->set_ip(info->target_ip); cache_ip(info->target_ip); // Don't reset ep here, we're still handling the return/break. goto continue_to_run; } } // Ok, no ensures to run. if(th->raise_reason() == cReturn) { call_frame->scope->flush_to_heap(state); // If we're trying to return to here, we're done! if(th->destination_scope() == call_frame->scope->on_heap()) { Object* val = th->raise_value(); th->clear_return(); return val; } else { // Give control of this exception to the caller. return NULL; } } else { // Not for us! call_frame->scope->flush_to_heap(state); // Give control of this exception to the caller. return NULL; } case cExit: call_frame->scope->flush_to_heap(state); return NULL; default: break; } // switch std::cout << "bug!\n"; call_frame->print_backtrace(state); abort(); return NULL; }
Object* VMMethod::debugger_interpreter_continue(STATE, VMMethod* const vmm, CallFrame* const call_frame, int sp, InterpreterState& is, int current_unwind, UnwindInfo* unwinds) { #include "vm/gen/instruction_locations.hpp" opcode* stream = vmm->opcodes; Object** stack_ptr = call_frame->stk + sp; continue_to_run: try { #undef DISPATCH #define DISPATCH \ if(Object* bp = call_frame->find_breakpoint(state)) { \ if(!Helpers::yield_debugger(state, call_frame, bp)) goto exception; \ } \ goto *insn_locations[stream[call_frame->inc_ip()]]; #undef next_int #undef cache_ip #undef flush_ip #define next_int ((opcode)(stream[call_frame->inc_ip()])) #define cache_ip(which) #define flush_ip() #include "vm/gen/instruction_implementations.hpp" } catch(TypeError& e) { flush_ip(); Exception* exc = Exception::make_type_error(state, e.type, e.object, e.reason); exc->locations(state, Location::from_call_stack(state, call_frame)); state->thread_state()->raise_exception(exc); call_frame->scope->flush_to_heap(state); return NULL; } catch(const RubyException& exc) { exc.exception->locations(state, Location::from_call_stack(state, call_frame)); state->thread_state()->raise_exception(exc.exception); return NULL; } // No reason to be here! abort(); exception: ThreadState* th = state->thread_state(); // switch(th->raise_reason()) { case cException: if(current_unwind > 0) { UnwindInfo* info = &unwinds[--current_unwind]; stack_position(info->stack_depth); call_frame->set_ip(info->target_ip); cache_ip(info->target_ip); goto continue_to_run; } else { call_frame->scope->flush_to_heap(state); return NULL; } case cBreak: // If we're trying to break to here, we're done! if(th->destination_scope() == call_frame->scope->on_heap()) { stack_push(th->raise_value()); th->clear_break(); goto continue_to_run; // Don't return here, because we want to loop back to the top // and keep running this method. } // Otherwise, fall through and run the unwinds case cReturn: case cCatchThrow: // Otherwise, we're doing a long return/break unwind through // here. We need to run ensure blocks. while(current_unwind > 0) { UnwindInfo* info = &unwinds[--current_unwind]; if(info->for_ensure()) { stack_position(info->stack_depth); call_frame->set_ip(info->target_ip); cache_ip(info->target_ip); // Don't reset ep here, we're still handling the return/break. goto continue_to_run; } } // Ok, no ensures to run. if(th->raise_reason() == cReturn) { call_frame->scope->flush_to_heap(state); // If we're trying to return to here, we're done! if(th->destination_scope() == call_frame->scope->on_heap()) { Object* val = th->raise_value(); th->clear_return(); return val; } else { // Give control of this exception to the caller. return NULL; } } else { // It's cBreak thats not for us! call_frame->scope->flush_to_heap(state); // Give control of this exception to the caller. return NULL; } case cExit: call_frame->scope->flush_to_heap(state); return NULL; default: break; } // switch std::cout << "bug!\n"; call_frame->print_backtrace(state); abort(); return NULL; }
Exception::Exception(const Exception & e) : std::exception() { str = e.errorString(); }
Object* MachineCode::execute_specialized(STATE, CallFrame* previous, Executable* exec, Module* mod, Arguments& args) { CompiledCode* code = as<CompiledCode>(exec); MachineCode* mcode = code->machine_code(); StackVariables* scope = ALLOCA_STACKVARIABLES(mcode->number_of_locals); // Originally, I tried using msg.module directly, but what happens is if // super is used, that field is read. If you combine that with the method // being called recursively, msg.module can change, causing super() to // look in the wrong place. // // Thus, we have to cache the value in the StackVariables. scope->initialize(args.recv(), args.block(), mod, mcode->number_of_locals); InterpreterCallFrame* frame = ALLOCA_CALLFRAME(mcode->stack_size); // If argument handling fails.. if(ArgumentHandler::call(state, mcode, scope, args) == false) { Exception* exc = Exception::make_argument_error(state, mcode->total_args, args.total(), args.name()); exc->locations(state, Location::from_call_stack(state, previous)); state->raise_exception(exc); return NULL; } frame->prepare(mcode->stack_size); frame->previous = previous; frame->constant_scope_ = code->scope(); frame->dispatch_data = 0; frame->compiled_code = code; frame->flags = 0; frame->optional_jit_data = 0; frame->top_scope_ = 0; frame->scope = scope; frame->arguments = &args; GCTokenImpl gct; #ifdef ENABLE_LLVM // A negative call_count means we've disabled usage based JIT // for this method. if(mcode->call_count >= 0) { if(mcode->call_count >= state->shared().config.jit_call_til_compile) { LLVMState* ls = LLVMState::get(state); OnStack<3> os(state, exec, mod, code); ls->compile_callframe(state, gct, code, frame); } else { mcode->call_count++; } } #endif #ifdef RBX_PROFILER if(unlikely(state->vm()->tooling())) { // Check the stack and interrupts here rather than in the interpreter // loop itself. OnStack<2> os(state, exec, code); if(!state->check_interrupts(gct, frame, frame)) return NULL; state->checkpoint(gct, frame); tooling::MethodEntry method(state, exec, scope->module(), args, code); RUBINIUS_METHOD_ENTRY_HOOK(state, scope->module(), args.name(), previous); Object* result = (*mcode->run)(state, mcode, frame); RUBINIUS_METHOD_RETURN_HOOK(state, scope->module(), args.name(), previous); return result; } else { if(!state->check_interrupts(gct, frame, frame)) return NULL; state->checkpoint(gct, frame); RUBINIUS_METHOD_ENTRY_HOOK(state, scope->module(), args.name(), previous); Object* result = (*mcode->run)(state, mcode, frame); RUBINIUS_METHOD_RETURN_HOOK(state, scope->module(), args.name(), previous); return result; } #else if(!state->check_interrupts(gct, frame, frame)) return NULL; state->checkpoint(gct, frame); RUBINIUS_METHOD_ENTRY_HOOK(state, scope->module(), args.name(), previous); Object* result = (*mcode->run)(state, mcode, frame); RUBINIUS_METHOD_RETURN_HOOK(state, scope->module(), args.name(), previous); return result; #endif }
TaskFailedNotification::TaskFailedNotification(Task* pTask, const Exception& exc): TaskNotification(pTask), _pException(exc.clone()) { }
Object* NativeMethod::executor_implementation(STATE, CallFrame* previous, Executable* exec, Module* mod, Arguments& args) { NativeMethod* nm = as<NativeMethod>(exec); int arity = nm->arity()->to_int(); if(arity >= 0 && (size_t)arity != args.total()) { Exception* exc = Exception::make_argument_error( state, arity, args.total(), args.name()); exc->locations(state, Location::from_call_stack(state, previous)); state->raise_exception(exc); return NULL; } NativeMethodEnvironment* env = native_method_environment.get(); // Optionally get the handles back to the proper state. if(state->shared().config.capi_global_flush) { std::list<capi::Handle*>* handles = env->state()->memory()->cached_capi_handles(); for(std::list<capi::Handle*>::iterator i = handles->begin(); i != handles->end(); ++i) { (*i)->update(env); } } NativeMethodFrame nmf(env->current_native_frame()); CallFrame* call_frame = ALLOCA_CALLFRAME(0); call_frame->previous = previous; call_frame->constant_scope_ = 0; call_frame->dispatch_data = (void*)&nmf; call_frame->compiled_code = 0; call_frame->flags = CallFrame::cNativeMethod; call_frame->optional_jit_data = 0; call_frame->top_scope_ = 0; call_frame->scope = 0; call_frame->arguments = &args; CallFrame* saved_frame = env->current_call_frame(); env->set_current_call_frame(call_frame); env->set_current_native_frame(&nmf); // Register the CallFrame, because we might GC below this. state->set_call_frame(call_frame); // Be sure to do this after installing nmf as the current // native frame. nmf.setup( env->get_handle(args.recv()), env->get_handle(args.block()), env->get_handle(exec), env->get_handle(mod)); // We've got things setup (they can be GC'd properly), so we need to // wait before entering the extension code. ENTER_CAPI(state); Object* ret; ExceptionPoint ep(env); #ifdef RBX_PROFILER // This is organized like this so that we don't jump past the destructor of // MethodEntry. It's duplicated, but it's much easier to understand than // trying to de-dup it. OnStack<2> os(state, exec, mod); if(unlikely(state->vm()->tooling())) { tooling::MethodEntry method(state, exec, mod, args); RUBINIUS_METHOD_NATIVE_ENTRY_HOOK(state, mod, args.name(), call_frame); PLACE_EXCEPTION_POINT(ep); if(unlikely(ep.jumped_to())) { ret = NULL; } else { ret = ArgumentHandler::invoke(state, nm, env, args); } RUBINIUS_METHOD_NATIVE_RETURN_HOOK(state, mod, args.name(), call_frame); } else { RUBINIUS_METHOD_NATIVE_ENTRY_HOOK(state, mod, args.name(), call_frame); PLACE_EXCEPTION_POINT(ep); if(unlikely(ep.jumped_to())) { ret = NULL; } else { ret = ArgumentHandler::invoke(state, nm, env, args); } RUBINIUS_METHOD_NATIVE_RETURN_HOOK(state, mod, args.name(), call_frame); } #else RUBINIUS_METHOD_NATIVE_ENTRY_HOOK(state, mod, args.name(), call_frame); PLACE_EXCEPTION_POINT(ep); if(unlikely(ep.jumped_to())) { ret = NULL; } else { ret = ArgumentHandler::invoke(state, nm, env, args); } RUBINIUS_METHOD_NATIVE_RETURN_HOOK(state, mod, args.name(), call_frame); #endif env->set_current_call_frame(saved_frame); env->set_current_native_frame(nmf.previous()); ep.pop(env); LEAVE_CAPI(state); OnStack<1> os_ret(state, ret); // Handle any signals that occurred while the native method // was running. if(!state->check_async(call_frame)) return NULL; return ret; }
Object* VMMethod::execute_specialized(STATE, CallFrame* previous, Dispatch& msg, Arguments& args) { CompiledMethod* cm = as<CompiledMethod>(msg.method); VMMethod* vmm = cm->backend_method(); #ifdef ENABLE_LLVM // A negative call_count means we've disabled usage based JIT // for this method. if(vmm->call_count >= 0) { if(vmm->call_count >= state->shared.config.jit_call_til_compile) { LLVMState* ls = LLVMState::get(state); ls->compile_callframe(state, cm, previous); } else { vmm->call_count++; } } #endif size_t scope_size = sizeof(StackVariables) + (vmm->number_of_locals * sizeof(Object*)); StackVariables* scope = reinterpret_cast<StackVariables*>(alloca(scope_size)); // Originally, I tried using msg.module directly, but what happens is if // super is used, that field is read. If you combine that with the method // being called recursively, msg.module can change, causing super() to // look in the wrong place. // // Thus, we have to cache the value in the StackVariables. scope->initialize(args.recv(), args.block(), msg.module, vmm->number_of_locals); InterpreterCallFrame* frame = ALLOCA_CALLFRAME(vmm->stack_size); // If argument handling fails.. if(ArgumentHandler::call(state, vmm, scope, args) == false) { Exception* exc = Exception::make_argument_error(state, vmm->required_args, args.total(), msg.name); exc->locations(state, Location::from_call_stack(state, previous)); state->thread_state()->raise_exception(exc); return NULL; } frame->prepare(vmm->stack_size); frame->previous = previous; frame->flags = 0; frame->arguments = &args; frame->dispatch_data = &msg; frame->cm = cm; frame->scope = scope; #ifdef RBX_PROFILER if(unlikely(state->shared.profiling())) { profiler::MethodEntry method(state, msg, args, cm); return (*vmm->run)(state, vmm, frame); } else { return (*vmm->run)(state, vmm, frame); } #else return (*vmm->run)(state, vmm, frame); #endif }
Exception* Exception::make_lje(STATE, CallFrame* call_frame) { Exception* exc = Exception::make_exception(state, G(jump_error), "no block given"); exc->locations(state, System::vm_backtrace(state, Fixnum::from(0), call_frame)); return exc; }
UInt32 HTTPPacket::build(Exception& ex,UInt8* data,UInt32 size) { if (_data) return 0; exception.set(Exception::NIL); /// read data ReadingStep step(CMD); UInt8* current(data); const UInt8* end(current+size-4); // 4 == /r/n/r/n const char* signifiant(NULL); const char* key(NULL); // headers for (; current <= end;++current) { if (memcmp(current, EXPAND("\r\n")) == 0 || memcmp(current, EXPAND("\0\n")) == 0) { if (!ex && signifiant) { // KEY = VALUE UInt8* endValue(current); while (isblank(*--endValue)); *(endValue+1) = 0; if (!key) { // version case! String::ToNumber(signifiant+5, version); } else { headers[key] = signifiant; parseHeader(ex,key,signifiant); key = NULL; } } step = LEFT; current += 2; signifiant = (const char*)current; if (memcmp(current, EXPAND("\r\n")) == 0) { current += 2; content = current; current += contentLength; if (ex || current > (end+4)) break; // wait next _data = data; return _size = current - data; } ++current; // here no continue, the "\r\n" check is not required again } if (ex) continue; // try to go to "\r\n\r\n" // http header, byte by byte UInt8 byte = *current; if ((step == LEFT || step == CMD || step == PATH) && (isspace(byte) || byte==0)) { if (step == CMD) { if(!signifiant) // Space before signifiant ex.set(Exception::PROTOCOL,"Unexpected space before command"); // by default command == GET if (!signifiant || (command = HTTP::ParseCommand(ex, signifiant)) == HTTP::COMMAND_UNKNOWN) { exception.set(ex); continue; } signifiant = NULL; step = PATH; } else if (step == PATH) { // parse query *current = 0; size_t filePos = Util::UnpackUrl(signifiant, path,query); filePath.append(path); if (filePos != string::npos) path.erase(filePos - 1); else filePath.append("/"); signifiant = NULL; step = VERSION; } else ++signifiant; // for trim begin of key or value } else if (step != CMD && !key && (byte == ':' || byte == 0)) { // KEY key = signifiant; step = LEFT; UInt8* endValue(current); while (isblank(*--endValue)); *(endValue+1) = 0; signifiant = (const char*)current + 1; } else if (step == CMD || step == PATH || step == VERSION) { if (!signifiant) signifiant = (const char*)current; if (step == CMD && (current-data)>7) // not a HTTP valid packet, consumes all exception.set(ex.set(Exception::PROTOCOL, "invalid HTTP packet")); } else step = RIGHT; } if (ex) return current - data; return 0; // wait next data }
void Exception::internal_error(STATE, CallFrame* call_frame, const char* reason) { Exception* exc = Exception::make_exception(state, G(exc_vm_internal), reason); exc->locations(state, System::vm_backtrace(state, Fixnum::from(0), call_frame)); state->thread_state()->raise_exception(exc); }
Exception::Exception(Exception &e) : m_str() { m_str.clear(); m_str << e.message(); }
void Exception::frozen_error(STATE, CallFrame* call_frame) { Exception* exc = Exception::make_exception(state, G(exc_type), "unable to modify frozen object"); exc->locations(state, System::vm_backtrace(state, Fixnum::from(0), call_frame)); state->thread_state()->raise_exception(exc); }
//----------------------------------------------------------------------------- // Exceptions translators //----------------------------------------------------------------------------- void canio_ex_translator(const Exception& e) { PyErr_SetString(PyExc_RuntimeError, e.what().c_str()); }
bool AbstractSocket::waitUntilReady(bool read, int64_t timeout) { Exception* e = NULL; // wait for readability/writability int error = SocketTools::poll(read, mFileDescriptor, timeout); if(error < 0) { if(errno == EINTR) { if(read) { // interrupted exception e = new Exception( "Socket read interrupted.", "monarch.io.InterruptedException"); e->getDetails()["error"] = strerror(errno); } else { // interrupted exception e = new Exception( "Socket write interrupted.", "monarch.io.InterruptedException"); e->getDetails()["error"] = strerror(errno); } } else { if(read) { // error occurred, get string message e = new Exception( "Could not read from socket.", SOCKET_EXCEPTION_TYPE); e->getDetails()["error"] = strerror(errno); } else { // error occurred, get string message e = new Exception( "Could not write to socket.", SOCKET_EXCEPTION_TYPE); e->getDetails()["error"] = strerror(errno); } // clear file descriptor and close if its bad if(errno == EBADF) { mFileDescriptor = -1; close(); } } } else if(error == 0) { if(read) { // read timeout occurred e = new Exception( "Socket read timed out.", SOCKET_TIMEOUT_EXCEPTION_TYPE); e->getDetails()["error"] = strerror(errno); } else { // write timeout occurred e = new Exception( "Socket write timed out.", SOCKET_TIMEOUT_EXCEPTION_TYPE); e->getDetails()["error"] = strerror(errno); } } else { // get the last error on the socket int lastError; socklen_t lastErrorLength = sizeof(lastError); getsockopt( mFileDescriptor, SOL_SOCKET, SO_ERROR, (char*)&lastError, &lastErrorLength); if(lastError != 0 && lastError != EINPROGRESS) { if(read) { // error occurred, get string message e = new Exception( "Could not read from socket.", SOCKET_EXCEPTION_TYPE); e->getDetails()["error"] = strerror(lastError); } else { // error occurred, get string message e = new Exception( "Could not write to socket.", SOCKET_EXCEPTION_TYPE); e->getDetails()["error"] = strerror(lastError); } } } if(e != NULL) { ExceptionRef ref = e; Exception::set(ref); } return e == NULL; }
CMSException CMSExceptionSupport::create( const std::string& msg, const Exception& cause ) { CMSException exception( msg, cause.clone() ); return exception; }
void Translator::_writeException(const Exception& exception){ _output << exception.getId() << std::endl; _output << exception.getMessage() << std::endl; }
void ErrorHandler::exception(const Exception& exc) { pi_dbg_error(exc.what()); }
Exception::Exception(const std::string& msg, const Exception& nested, int code) :_msg(msg),_nested(nested.clone()),_code(code) { }