Skip to content

Commit

Permalink
Fixed rb_raise.
Browse files Browse the repository at this point in the history
  • Loading branch information
Brian Ford committed Mar 5, 2009
1 parent a42b8d8 commit bd9b337
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 26 deletions.
21 changes: 15 additions & 6 deletions vm/builtin/nativemethod.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

#include "vm.hpp"

#include "exception.hpp"
#include "exception_point.hpp"
#include "message.hpp"
#include "native_libraries.hpp"
#include "primitives.hpp"

Expand All @@ -11,8 +14,6 @@
#include "builtin/string.hpp"
#include "builtin/tuple.hpp"

#include "message.hpp"

namespace rubinius {

typedef TypedRoot<Object*> RootHandle;
Expand Down Expand Up @@ -91,7 +92,6 @@ namespace rubinius {
return create<GenericFunctor>(state);
}


Object* NativeMethod::executor_implementation(STATE, CallFrame* call_frame, Message& msg) {
NativeMethodEnvironment* env = native_method_environment.get();
NativeMethodFrame nmf(env->current_native_frame());
Expand All @@ -101,9 +101,20 @@ namespace rubinius {
env->set_state(state);

NativeMethod* nm = as<NativeMethod>(msg.method);
Object* ret = nm->call(state, env, msg);

Object* ret;
ExceptionPoint ep(env);

PLACE_EXCEPTION_POINT(ep);

if(unlikely(ep.jumped_to())) {
ret = NULL;
} else {
ret = nm->call(state, env, msg);
}

env->set_current_native_frame(nmf.previous());
ep.pop(env);

return ret;
}
Expand Down Expand Up @@ -256,6 +267,4 @@ namespace rubinius {
}
}



}
10 changes: 10 additions & 0 deletions vm/builtin/nativemethod.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
namespace rubinius {

/* Forwards */
class ExceptionPoint;
class Message;
class NativeMethodFrame;

Expand Down Expand Up @@ -99,6 +100,14 @@ namespace rubinius {
current_native_frame_ = frame;
}

ExceptionPoint* current_ep() {
return current_ep_;
}

void set_current_ep(ExceptionPoint* ep) {
current_ep_ = ep;
}

/** Set of Handles available in current Frame (convenience.) */
Handles& handles();

Expand All @@ -113,6 +122,7 @@ namespace rubinius {
NativeMethodFrame* current_native_frame_;
/** Global object handles. */
Handles global_handles_;
ExceptionPoint* current_ep_;
};


Expand Down
24 changes: 24 additions & 0 deletions vm/exception_point.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include "exception_point.hpp"
#include "builtin/nativemethod.hpp"

namespace rubinius {
ExceptionPoint::ExceptionPoint(NativeMethodEnvironment* env)
: jumped_to_(false)
, previous_(env->current_ep())
{
env->set_current_ep(this);
}

void ExceptionPoint::return_to(NativeMethodEnvironment* env) {
jumped_to_ = true;
env->set_current_ep(this);
_longjmp(__jump_buffer, 1);

// If control reaches here, longjmp failed, i.e. disaster.
abort();
}

void ExceptionPoint::pop(NativeMethodEnvironment* env) {
env->set_current_ep(previous_);
}
}
28 changes: 9 additions & 19 deletions vm/exception_point.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#include <setjmp.h>

namespace rubinius {
class NativeMethodEnvironment;

class ExceptionPoint {
bool jumped_to_;
ExceptionPoint* previous_;
Expand All @@ -11,12 +13,7 @@ namespace rubinius {
jmp_buf __jump_buffer;

public:
ExceptionPoint(Task* task)
: jumped_to_(false)
, previous_(task->current_ep)
{
task->current_ep = this;
}
ExceptionPoint(NativeMethodEnvironment* env);

bool jumped_to() {
return jumped_to_;
Expand All @@ -26,23 +23,16 @@ namespace rubinius {
jumped_to_ = false;
}

void return_to(Task* task) {
jumped_to_ = true;
task->current_ep = this;
_longjmp(__jump_buffer, 1);
abort(); // HUH!
}

void unwind_to_previous(Task* task) {
previous_->return_to(task);
}
void return_to(NativeMethodEnvironment* env);

void pop(Task* task) {
task->current_ep = previous_;
void unwind_to_previous(NativeMethodEnvironment* env) {
previous_->return_to(env);
}

void pop(NativeMethodEnvironment* env);
};
}
#define PLACE_EXCEPTIONPOINT(ep) _setjmp(ep.__jump_buffer)

#define PLACE_EXCEPTION_POINT(ep) _setjmp(ep.__jump_buffer)

#endif
19 changes: 18 additions & 1 deletion vm/subtend/ruby.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
#include "builtin/string.hpp"
#include "builtin/symbol.hpp"

#include "vm/exception.hpp"
#include "vm/exception_point.hpp"
#include "vm/global_cache.hpp"
#include "vm/message.hpp"
#include "vm/object_utils.hpp"
Expand All @@ -38,6 +40,7 @@ using rubinius::ByteArray;
using rubinius::Class;
using rubinius::ClassType;
using rubinius::Data;
using rubinius::Exception;
using rubinius::Fixnum;
using rubinius::Integer;
using rubinius::Message;
Expand Down Expand Up @@ -936,8 +939,22 @@ 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);

NativeMethodEnvironment* env = NativeMethodEnvironment::get();
Exception* exc = Exception::make_exception(
env->state(), as<Class>(env->get_object(error_handle)), reason);
env->state()->thread_state()->raise_exception(exc);

env->current_ep()->return_to(env);
}

VALUE rb_require(const char* name) {
Expand Down

0 comments on commit bd9b337

Please sign in to comment.