Pastie now auto-senses if line-wrap is a bad or good idea. Feedback?
## mark a section (Learn more)
diff --git a/vm/builtin/nativemethod.cpp b/vm/builtin/nativemethod.cpp index b989390..8f513ea 100644 --- a/vm/builtin/nativemethod.cpp +++ b/vm/builtin/nativemethod.cpp @@ -101,7 +101,16 @@ namespace rubinius { env->set_state(state); NativeMethod* nm = as<NativeMethod>(msg.method); - Object* ret = nm->call(state, env, msg); + Object* ret; + + try { + ret = nm->call(state, env, msg); + } catch(SubtendException& e) { + Exception* exc = Exception::make_exception( + state, as<Class>(env->get_object(e.exc_handle)), e.reason); + state->thread_state()->raise_exception(exc); + ret = NULL; + } env->set_current_native_frame(nmf.previous()); diff --git a/vm/exception.cpp b/vm/exception.cpp index 2b6a506..cb4760f 100644 --- a/vm/exception.cpp +++ b/vm/exception.cpp @@ -22,6 +22,16 @@ namespace rubinius { // Not reached. } + SubtendException::SubtendException(intptr_t exc_handle, const char* reason) + : exc_handle(exc_handle), reason(NULL) + { + if(reason) this->reason = strdup(reason); + } + + void SubtendException::raise(intptr_t exc_handle, const char* reason) { + throw SubtendException(exc_handle, reason); + } + void Assertion::raise(const char* reason) { VM* state = VM::current_state(); abort(); diff --git a/vm/exception.hpp b/vm/exception.hpp index 40d2bb9..9755be0 100644 --- a/vm/exception.hpp +++ b/vm/exception.hpp @@ -113,6 +113,19 @@ namespace rubinius { */ void show(STATE); }; + + // @todo: should this subclass VMException? + class SubtendException { + public: + + intptr_t exc_handle; + char* reason; + + SubtendException(intptr_t exc_handle, const char* reason); + ~SubtendException() { if(reason) free(reason); } + + static void raise(intptr_t exc_handle, const char* reason); + }; }; #endif diff --git a/vm/subtend/ruby.cpp b/vm/subtend/ruby.cpp index b7e3345..bd7f6bd 100644 --- a/vm/subtend/ruby.cpp +++ b/vm/subtend/ruby.cpp @@ -20,6 +20,7 @@ #include "builtin/string.hpp" #include "builtin/symbol.hpp" +#include "vm/exception.hpp" #include "vm/global_cache.hpp" #include "vm/message.hpp" #include "vm/object_utils.hpp" @@ -49,6 +50,7 @@ using rubinius::NativeMethodEnvironment; using rubinius::Object; using rubinius::SendSite; using rubinius::String; +using rubinius::SubtendException; using rubinius::Symbol; using rubinius::VM; @@ -936,8 +938,17 @@ extern "C" { return value; } +#define RB_RAISE_BUFSIZE 256 + void rb_raise(VALUE error_handle, const char* format_string, ...) { - throw std::runtime_error(std::string("rb_raise: ") + format_string); /* Yeah, not 'exactly' correct. */ + va_list args; + char reason[RB_RAISE_BUFSIZE]; + + va_start(args, format_string); + vsnprintf(reason, RB_RAISE_BUFSIZE, format_string, args); + va_end(args); + + SubtendException::raise(error_handle, reason); } VALUE rb_require(const char* name) {
This paste will be private.
From the Design Piracy series on my blog: