bool field_can_link(Class* clss, Field* field, bool _static, bool putfield, bool _throw) { ASSERT_RAISE_AREA; if(_static?(!field->is_static()):(field->is_static())) { if(_throw) { exn_raise_by_name("java/lang/IncompatibleClassChangeError", field->get_class()->get_name()->bytes); } return false; } if(putfield && field->is_final()) { for(int fn = 0; fn < clss->get_number_of_fields(); fn++) { if(clss->get_field(fn) == field) { return true; } } if(_throw) { unsigned buf_size = clss->get_name()->len + field->get_class()->get_name()->len + field->get_name()->len + 15; char* buf = (char*)STD_ALLOCA(buf_size); memset(buf, 0, buf_size); sprintf(buf, " from %s to %s.%s", clss->get_name()->bytes, field->get_class()->get_name()->bytes, field->get_name()->bytes); jthrowable exc_object = exn_create("java/lang/IllegalAccessError", buf); exn_raise_object(exc_object); } return false; } return true; }
jthrowable create_exception(Exception* exception) { ASSERT_RAISE_AREA; assert(hythread_is_suspend_enabled()); if ( NULL != exception->exc_class) { jthrowable exc_cause = NULL; Class* exc_class = exception->exc_class; const char* exc_message = exception->exc_message; if (NULL != exception->exc_cause) { tmn_suspend_disable_recursive(); exc_cause = oh_allocate_local_handle(); exc_cause->object = exception->exc_cause; tmn_suspend_enable_recursive(); } exn_clear(); jthrowable exc_exception = NULL; exc_exception = exn_create(exc_class, exc_message, exc_cause); return exc_exception; } else { return NULL; } }
void exn_raise_by_class_internal(Class* exc_class, const char* exc_message, jthrowable exc_cause) { #ifdef VM_LAZY_EXCEPTION CTRACE(("%s", "exn_raise_object(), propagating lazy & non-destructively")); tmn_suspend_disable_recursive(); p_TLS_vmthread->thread_exception.exc_class = exc_class; p_TLS_vmthread->thread_exception.exc_message = exc_message; if (exc_cause != NULL) { p_TLS_vmthread->thread_exception.exc_cause = exc_cause->object; } else { p_TLS_vmthread->thread_exception.exc_cause = NULL; } tmn_suspend_enable_recursive(); #else assert(hythread_is_suspend_enabled()); jthrowable exc_object = exn_create(exc_class, exc_message, exc_cause); if (exn_raised()){ return; } exn_raise_object_internal(exc_object); #endif }
//FIXME LAZY EXCEPTION (2006.05.06) //Find all usage and change to lazy use jthrowable exn_get() { assert(hythread_is_suspend_enabled()); // we can check heap references for equality to NULL // without disabling gc, because GC wouldn't change // null to non-null and vice versa. vm_thread_t vm_thread = p_TLS_vmthread; if ((NULL == vm_thread->thread_exception.exc_object) && (NULL == vm_thread->thread_exception.exc_class)) { return NULL; } // returned value which will contains jthrowable value of // curent thread exception jobject exc; if (NULL != vm_thread->thread_exception.exc_object) { tmn_suspend_disable(); exc = oh_allocate_local_handle(); exc->object = (ManagedObject *) vm_thread->thread_exception.exc_object; tmn_suspend_enable(); } else if (NULL != vm_thread->thread_exception.exc_class) { exc = exn_create((Exception*)&(vm_thread->thread_exception)); } else { LDIE(59, "It's impossible internal error in exception handling."); } return exc; } // exn_get
static void class_report_failure(Class* target, uint16 cp_index, const char* exnname, std::stringstream& exnmsg) { TRACE2("resolve.testing", "class_report_failure: " << exnmsg.str().c_str()); jthrowable exn = exn_create(exnname, exnmsg.str().c_str()); // ppervov: FIXME: should throw OOME class_report_failure(target, cp_index, exn); }
void interp_throw_exception(const char* exc_name, const char* exc_message) { M2N_ALLOC_MACRO; assert(!hythread_is_suspend_enabled()); hythread_suspend_enable(); assert(hythread_is_suspend_enabled()); jthrowable exc_object = exn_create(exc_name, exc_message); exn_raise_object(exc_object); hythread_suspend_disable(); M2N_FREE_MACRO; }
jthrowable exn_create(const char *exc_name, const char *exc_message, jthrowable cause) { ASSERT_RAISE_AREA; assert(hythread_is_suspend_enabled()); Class *exc_class = get_exc_class(exc_name); if (exc_class == NULL) { assert(exn_raised()); return NULL; } return exn_create(exc_class, exc_message, cause); } // exn_create
void exn_throw_by_class_internal(Class* exc_class, const char* exc_message, jthrowable exc_cause) { BEGIN_RAISE_AREA; // functions can be invoked in suspend disabled and enabled state if (!hythread_is_suspend_enabled()) { // exception is throwing, so suspend can be enabled safely tmn_suspend_enable(); } assert(hythread_is_suspend_enabled()); #ifdef VM_LAZY_EXCEPTION //set_unwindable(false); jvalue args[3]; Method* exc_init = prepare_exc_creating( exc_class, args, exc_message, exc_cause); if (NULL == exc_init) { CTRACE(("%s", "exn_throw_by_class(),create exception and delegating to exn_throw_for_JIT()")); jthrowable exc_object = exn_create(exc_class, exc_message, exc_cause); exn_rethrow_if_pending(); //set_unwindable(true); exn_throw_object_internal(exc_object); } else { CTRACE(("%s", "exn_throw_by_class(), lazy delegating to exn_throw_for_JIT()")); //set_unwindable(true); // no return, so enable isn't required tmn_suspend_disable(); exn_throw_for_JIT(NULL, exc_class, exc_init, NULL, args); //tmn_suspend_enable(); } #else jthrowable exc_object = exn_create(exc_class, exc_message, exc_cause); exn_rethrow_if_pending(); exn_throw_object_internal(exc_object); #endif END_RAISE_AREA; }
static bool method_can_link_special(Class* clss, unsigned index, Method* method, bool _throw) { ASSERT_RAISE_AREA; ConstantPool& cp = clss->get_constant_pool(); unsigned class_idx = cp.get_ref_class_index(index); unsigned class_name_idx = cp.get_class_name_index(class_idx); String* ref_class_name = cp.get_utf8_string(class_name_idx); if(method->get_name() == VM_Global_State::loader_env->Init_String && method->get_class()->get_name() != ref_class_name) { if(_throw) { exn_raise_by_name("java/lang/NoSuchMethodError", method->get_name()->bytes); } return false; } if(method->is_static()) { if(_throw) { exn_raise_by_name("java/lang/IncompatibleClassChangeError", method->get_class()->get_name()->bytes); } return false; } if(method->is_abstract()) { if(_throw) { tmn_suspend_enable(); unsigned buf_size = clss->get_name()->len + method->get_name()->len + method->get_descriptor()->len + 5; char* buf = (char*)STD_ALLOCA(buf_size); memset(buf, 0, buf_size); sprintf(buf, "%s.%s%s", clss->get_name()->bytes, method->get_name()->bytes, method->get_descriptor()->bytes); jthrowable exc_object = exn_create("java/lang/AbstractMethodError", buf); exn_raise_object(exc_object); tmn_suspend_disable(); } return false; } return true; }
// Create an exception from a given type and a message. // Set cause to the current thread exception. static void compile_raise_exception(const char* name, const char* message, Method* method) { assert(hythread_is_suspend_enabled()); jthrowable old_exc = exn_get(); exn_clear(); const char* c = method->get_class()->get_name()->bytes; const char* m = method->get_name()->bytes; const char* d = method->get_descriptor()->bytes; size_t sz = 3 + // a space, a dot, and a terminator strlen(message) + method->get_class()->get_name()->len + method->get_name()->len + method->get_descriptor()->len; char* msg_raw = (char*)STD_MALLOC(sz); assert(msg_raw); sprintf(msg_raw, "%s%s.%s%s", message, c, m, d); assert(strlen(msg_raw) < sz); jthrowable new_exc = exn_create(name, msg_raw, old_exc); exn_raise_object(new_exc); STD_FREE(msg_raw); }
static bool method_can_link_virtual(Class* clss, unsigned cp_index, Method* method, bool _throw) { ASSERT_RAISE_AREA; if(method->is_static()) { if(_throw) { exn_raise_by_name("java/lang/IncompatibleClassChangeError", method->get_class()->get_name()->bytes); } return false; } if(method->get_class()->is_interface()) { if(_throw) { char* buf = (char*)STD_ALLOCA(clss->get_name()->len + method->get_name()->len + method->get_descriptor()->len + 2); sprintf(buf, "%s.%s%s", clss->get_name()->bytes, method->get_name()->bytes, method->get_descriptor()->bytes); jthrowable exc_object = exn_create("java/lang/AbstractMethodError", buf); exn_raise_object(exc_object); } return false; } return true; }
jthrowable exn_create(const char* exc_name,const char *exc_message) { return exn_create(exc_name, exc_message, NULL); } // exn_create(const char *exception_name, const char *exc_message)
jthrowable exn_create(const char* exc_name, jthrowable exc_cause) { return exn_create(exc_name, NULL, exc_cause); } // exn_create(const char* exc_name, jthrowable cause)
jthrowable exn_create(const char* exc_name) { return exn_create(exc_name, NULL, NULL); }
jthrowable exn_create(Class* exc_class, const char* exc_message) { return exn_create(exc_class, exc_message , NULL); }
jthrowable exn_create(Class* exc_class, jthrowable exc_cause) { return exn_create(exc_class, NULL, exc_cause); }
IDATA jthread_throw_exception(const char *name, const char *message) { assert(hythread_is_suspend_enabled()); jobject jthe = exn_create(name); return jthread_throw_exception_object(jthe); }
jthrowable exn_create(Class* exc_class) { return exn_create(exc_class, NULL , NULL); }