extern "C" VALUE rb_rescue(VALUE (*b_proc)(ANYARGS), VALUE data1, VALUE (*r_proc)(ANYARGS), VALUE data2) { try { return (*b_proc)(data1); } catch (jruby::JavaException& ex) { JLocalEnv env; jthrowable t = ex.getCause(env); if (!env->IsInstanceOf(t, RaiseException_class)) { // Not a ruby exception, just propagate throw; } jobject rubyException = env->GetObjectField(t, RaiseException_exception_field); checkExceptions(env); VALUE exc = objectToValue(env, rubyException); if (rb_obj_is_kind_of(exc, rb_eStandardError)) { VALUE result = (*r_proc)(data2); env->CallStaticVoidMethod(JRuby_class, JRuby_clearErrorInfo, jruby::getRuntime()); return result; } rb_raise(rb_eTypeError, "wrong exception type raised (expected StandardError subclass)"); return Qnil; } }
int RubyString::length() { // If already synced with java, just return the cached length value if (rwdata.rstring != NULL) { return rwdata.rstring->len; } JLocalEnv env; jobject byteList = env->GetObjectField(obj, RubyString_value_field); return env->GetIntField(byteList, ByteList_length_field); }
extern "C" VALUE rb_rescue2(VALUE (*b_proc)(ANYARGS), VALUE data1, VALUE (*r_proc)(ANYARGS), VALUE data2, ...) { try { return (*b_proc)(data1); } catch (jruby::JavaException& ex) { JLocalEnv env; jthrowable t = ex.getCause(env); if (!env->IsInstanceOf(t, RaiseException_class)) { // Not a ruby exception, just propagate throw; } jobject rubyException = env->GetObjectField(t, RaiseException_exception_field); checkExceptions(env); VALUE exc = objectToValue(env, rubyException); va_list ap; va_start(ap, data2); VALUE eclass = 0; bool handle = false; while ((eclass = va_arg(ap, VALUE)) != 0) { if (rb_obj_is_kind_of(exc, eclass)) { handle = true; break; } } va_end(ap); if (handle) { VALUE result = (*r_proc)(data2); env->CallStaticVoidMethod(JRuby_class, JRuby_clearErrorInfo, jruby::getRuntime()); return result; } rb_raise(rb_eTypeError, "wrong exception type raised"); return Qnil; } }