static #if __LP64__ // This method can't be inlined in 32-bit because @try compiles as a call // to setjmp(). force_inline #endif VALUE __rb_vm_objc_dispatch(rb_vm_objc_stub_t *stub, IMP imp, id rcv, SEL sel, int argc, const VALUE *argv) { @try { return (*stub)(imp, rcv, sel, argc, argv); } @catch (id exc) { bool created = false; VALUE rbexc = rb_oc2rb_exception(exc, &created); #if __LP64__ if (rb_vm_current_exception() == Qnil) { rb_vm_set_current_exception(rbexc); throw; } #endif if (created) { rb_exc_raise(rbexc); } throw; } abort(); // never reached }
static void err_append(const char *s) { if (rb_vm_parse_in_eval()) { VALUE err = rb_errinfo(); if (err == Qnil) { err = rb_exc_new2(rb_eSyntaxError, s); rb_set_errinfo(err); } else { VALUE str = rb_obj_as_string(err); rb_str_cat2(str, "\n"); rb_str_cat2(str, s); rb_set_errinfo(rb_exc_new3(rb_eSyntaxError, str)); } } else { VALUE err = rb_vm_current_exception(); if (err == Qnil) { err = rb_exc_new2(rb_eSyntaxError, "compile error"); rb_vm_set_current_exception(err); } rb_write_error(s); rb_write_error("\n"); } }
static VALUE get_errinfo(void) { VALUE exc = rb_vm_current_exception(); if (NIL_P(exc)) { exc = rb_errinfo(); } return exc; }
static VALUE eval_string(VALUE self, VALUE klass, VALUE src, VALUE scope, const char *file, const int line) { rb_vm_binding_t *b = NULL; if (scope != Qnil) { if (!rb_obj_is_kind_of(scope, rb_cBinding)) { rb_raise(rb_eTypeError, "wrong argument type %s (expected Binding)", rb_obj_classname(scope)); } b = (rb_vm_binding_t *)DATA_PTR(scope); } bool old_parse_in_eval = rb_vm_parse_in_eval(); rb_vm_set_parse_in_eval(true); if (b != NULL) { // Binding must be added because the parser needs it. rb_vm_add_binding(b); } NODE *node = rb_compile_string(file, src, line); if (b != NULL) { // We remove the binding now but we still pass it to the VM, which // will use it for compilation. rb_vm_pop_binding(); } rb_vm_set_parse_in_eval(old_parse_in_eval); if (node == NULL) { VALUE exc = rb_vm_current_exception(); if (exc != Qnil) { rb_vm_raise_current_exception(); } else { rb_raise(rb_eSyntaxError, "compile error"); } } return rb_vm_run_under(klass, self, file, node, b, true); }