diff --git a/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Prepare.cpp b/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Prepare.cpp index 26745d4..4512ef8 100644 --- a/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Prepare.cpp +++ b/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Prepare.cpp @@ -728,6 +728,85 @@ void Class::add_any_fake_methods() } //add_any_fake_methods +extern bool dump_stubs; + +// It's a rutime helper. So should be named as rth_prepare_throw_abstract_method_error +void rth_prepare_throw_abstract_method_error(Class_Handle clss, Method_Handle method) +{ + char* buf = (char*)STD_ALLOCA(clss->get_name()->len + method->get_name()->len + + method->get_descriptor()->len + 2); // . + \0 + sprintf(buf, "%s.%s%s", clss->get_name()->bytes, + method->get_name()->bytes, method->get_descriptor()->bytes); + tmn_suspend_enable(); + + // throw exception here because it's a helper + exn_throw_by_name("java/lang/AbstractMethodError", buf); + tmn_suspend_disable(); +} + +NativeCodePtr prepare_gen_throw_abstract_method_error(Class_Handle clss, Method_Handle method) +{ + NativeCodePtr addr = NULL; + void (*p_throw_ame)(Class_Handle, Method_Handle) = + rth_prepare_throw_abstract_method_error; + LilCodeStub* cs = lil_parse_code_stub("entry 0:rth::void;" + "push_m2n 0, 0;" + "m2n_save_all;" + "out platform:pint,pint:void;" + "o0=%0i:pint;" + "o1=%1i:pint;" + "call.noret %2i;", + clss, method, p_throw_ame); + assert(cs && lil_is_valid(cs)); + addr = LilCodeGenerator::get_platform()->compile(cs); + + DUMP_STUB(addr, "rth_prepare_throw_abstract_method_error", lil_cs_get_code_size(cs)); + + lil_free_code_stub(cs); + + return addr; +} + +// It's a rutime helper. So should be named as rth_prepare_throw_illegal_access_error +void rth_prepare_throw_illegal_access_error(Class_Handle to, Method_Handle from) +{ + char* buf = (char*)STD_ALLOCA(from->get_class()->get_name()->len + + to->get_name()->len + from->get_name()->len + + from->get_descriptor()->len + 12); // from + to + . + \0 + sprintf(buf, "from %s to %s.%s%s", from->get_class()->get_name()->bytes, + to->get_name()->bytes, + from->get_name()->bytes, from->get_descriptor()->bytes); + tmn_suspend_enable(); + + // throw exception here because it's a helper + exn_throw_by_name("java/lang/IllegalAccessError", buf); + tmn_suspend_disable(); +} + +NativeCodePtr prepare_gen_throw_illegal_access_error(Class_Handle to, Method_Handle from) +{ + NativeCodePtr addr = NULL; + void (*p_throw_iae)(Class_Handle, Method_Handle) = + rth_prepare_throw_illegal_access_error; + LilCodeStub* cs = lil_parse_code_stub("entry 0:rth::void;" + "push_m2n 0, 0;" + "m2n_save_all;" + "out platform:pint,pint:void;" + "o0=%0i:pint;" + "o1=%1i:pint;" + "call.noret %2i;", + to, from, p_throw_iae); + assert(cs && lil_is_valid(cs)); + addr = LilCodeGenerator::get_platform()->compile(cs); + + DUMP_STUB(addr, "rth_prepare_throw_illegal_access_error", lil_cs_get_code_size(cs)); + + lil_free_code_stub(cs); + + return addr; +} + + void Class::assign_offsets_to_methods(Global_Env* env) { // At this point we have an array of the interfaces implemented by @@ -767,8 +846,13 @@ void Class::assign_offsets_to_methods(Gl // check if the method hasn't already been initialized or even compiled assert(method.get_code_addr() == NULL); // initialize method's code address - method.set_code_addr((char*)compile_gen_compile_me(&method)); - + if(!method.is_abstract()) { + // Compile me stub if method is implemented + method.set_code_addr((char*)compile_gen_compile_me(&method)); + } else { + // Throw AME stub if method is declared abstract in this class + method.set_code_addr((char*)prepare_gen_throw_abstract_method_error(this, &method)); + } if(!method.is_static()) { // A virtual method. Look it up in virtual method tables of the // super classes; if not found, then assign a new offset. @@ -1021,85 +1105,6 @@ void Class::point_vtable_entries_to_stub } } } - -extern bool dump_stubs; - -// It's a rutime helper. So should be named as rth_prepare_throw_abstract_method_error -void prepare_throw_abstract_method_error(Class_Handle clss, Method_Handle method) -{ - char* buf = (char*)STD_ALLOCA(clss->get_name()->len + method->get_name()->len - + method->get_descriptor()->len + 2); // . + \0 - sprintf(buf, "%s.%s%s", clss->get_name()->bytes, - method->get_name()->bytes, method->get_descriptor()->bytes); - tmn_suspend_enable(); - - // throw exception here because it's a helper - exn_throw_by_name("java/lang/AbstractMethodError", buf); - tmn_suspend_disable(); -} - -NativeCodePtr prepare_gen_throw_abstract_method_error(Class_Handle clss, Method_Handle method) -{ - NativeCodePtr addr = NULL; - void (*p_throw_ame)(Class_Handle, Method_Handle) = - prepare_throw_abstract_method_error; - LilCodeStub* cs = lil_parse_code_stub("entry 0:rth::void;" - "push_m2n 0, 0;" - "m2n_save_all;" - "out platform:pint,pint:void;" - "o0=%0i:pint;" - "o1=%1i:pint;" - "call.noret %2i;", - clss, method, p_throw_ame); - assert(cs && lil_is_valid(cs)); - addr = LilCodeGenerator::get_platform()->compile(cs); - - DUMP_STUB(addr, "prepare_throw_abstract_method_error", lil_cs_get_code_size(cs)); - - lil_free_code_stub(cs); - - return addr; -} - -// It's a rutime helper. So should be named as rth_prepare_throw_illegal_access_error -void prepare_throw_illegal_access_error(Class_Handle to, Method_Handle from) -{ - char* buf = (char*)STD_ALLOCA(from->get_class()->get_name()->len - + to->get_name()->len + from->get_name()->len - + from->get_descriptor()->len + 12); // from + to + . + \0 - sprintf(buf, "from %s to %s.%s%s", from->get_class()->get_name()->bytes, - to->get_name()->bytes, - from->get_name()->bytes, from->get_descriptor()->bytes); - tmn_suspend_enable(); - - // throw exception here because it's a helper - exn_throw_by_name("java/lang/IllegalAccessError", buf); - tmn_suspend_disable(); -} - -NativeCodePtr prepare_gen_throw_illegal_access_error(Class_Handle to, Method_Handle from) -{ - NativeCodePtr addr = NULL; - void (*p_throw_iae)(Class_Handle, Method_Handle) = - prepare_throw_illegal_access_error; - LilCodeStub* cs = lil_parse_code_stub("entry 0:rth::void;" - "push_m2n 0, 0;" - "m2n_save_all;" - "out platform:pint,pint:void;" - "o0=%0i:pint;" - "o1=%1i:pint;" - "call.noret %2i;", - to, from, p_throw_iae); - assert(cs && lil_is_valid(cs)); - addr = LilCodeGenerator::get_platform()->compile(cs); - - DUMP_STUB(addr, "rth_throw_linking_exception", lil_cs_get_code_size(cs)); - - lil_free_code_stub(cs); - - return addr; -} - Intfc_Table* Class::create_and_populate_interface_table() { Intfc_Table* intfc_table;