Ejemplo n.º 1
0
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
}
Ejemplo n.º 2
0
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");
    }
}
Ejemplo n.º 3
0
static VALUE
get_errinfo(void)
{
    VALUE exc = rb_vm_current_exception();
    if (NIL_P(exc)) {
	exc = rb_errinfo();
    }
    return exc;
}
Ejemplo n.º 4
0
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);
}