unsigned Method::get_num_ref_args() { unsigned nargs; if(is_static()) nargs = 0; else nargs = 1; Arg_List_Iterator iter = get_argument_list(); Java_Type typ; while((typ = curr_arg(iter)) != JAVA_TYPE_END) { switch(typ) { case JAVA_TYPE_CLASS: case JAVA_TYPE_ARRAY: nargs++; break; default: break; } iter = advance_arg_iterator(iter); } return nargs; } //Method::get_num_ref_args
int process_options(generator & gen, int arg_count, char *args[]) { std::unordered_map<std::string, process_option_func> options( { { "template", process_set_template_file } }); for(int arg_it = 1; arg_it < arg_count; ++arg_it) { std::string curr_arg(args[arg_it]); // All options begin with `--` if(curr_arg.find("--") != 0) { // Return index of first non-flag return arg_it; } else { curr_arg.erase(0, 2); } // Transform input from `--<arg_name>=<value>` to `--<arg_name>` and `<value>` auto arg_value_separator_pos = curr_arg.find('='); if(arg_value_separator_pos == std::string::npos || arg_value_separator_pos >= curr_arg.size()) { std::cerr << "Malformed option specified: \"" << curr_arg << "\"" << std::endl; continue; } std::string curr_val(curr_arg, arg_value_separator_pos + 1); curr_arg.erase(arg_value_separator_pos); // Call appropriate handler if one exists auto handler_find_it = options.find(curr_arg); if(handler_find_it != options.end()) { handler_find_it->second(gen, curr_val); } else { std::cerr << "Invalid option specified: \"" << curr_arg << "\"" << std::endl; } } return arg_count; }
Class_Handle get_curr_arg_class(Arg_List_Iterator it, Method_Handle m) { Global_Env *env = VM_Global_State::loader_env; Java_Type UNUSED t = curr_arg(it); assert(t == JAVA_TYPE_CLASS || t == JAVA_TYPE_ARRAY); Arg_List_Iterator next = advance_arg_iterator(it); size_t len = ((char *)next) - ((char *)it); const char* name = (const char*)it; String* n; if(name[0] == 'L') { n = env->string_pool.lookup(name+1, len-2); } else { n = env->string_pool.lookup(name, len); } Class* clss = ((Method *)m)->get_class(); Class* c = clss->get_class_loader()->LoadClass(env, n); return c; } //get_curr_arg_class
unsigned Method::get_num_args() { unsigned nargs; if(is_static()) { nargs = 0; } else { nargs = 1; } Arg_List_Iterator iter = get_argument_list(); Java_Type UNUSED typ; while((typ = curr_arg(iter)) != JAVA_TYPE_END) { nargs++; iter = advance_arg_iterator(iter); } return nargs; } //Method::get_num_args
void Method::calculate_arguments_slot_num() { //This method counts length of method parameters in slots. //See 4.4.3 paragraph 5 in specification. unsigned slot_num = 0; if (!is_static()) { slot_num = 1; } Arg_List_Iterator iter = get_argument_list(); Java_Type typ; while((typ = curr_arg(iter)) != JAVA_TYPE_END) { switch(typ) { case JAVA_TYPE_LONG: case JAVA_TYPE_DOUBLE: slot_num += 2; break; default: slot_num += 1; break; } iter = advance_arg_iterator(iter); } _arguments_slot_num = slot_num; } // Method::calculate_arguments_slot_num
void JIT_execute_method_default(JIT_Handle jh, jmethodID methodID, jvalue *return_value, jvalue *args) { //assert(("Doesn't compile", 0)); //abort(); #if 1 Method *meth = (Method*) methodID; assert(!hythread_is_suspend_enabled()); void *entry_point = meth->get_code_addr(); int nargs = meth->get_num_args(); uint64 arg_words[255]; int double_nargs = 0; double double_args[8]; int num_arg_words = 0; int arg_num = 0; int num_ref_args = 0; Arg_List_Iterator iter = meth->get_argument_list(); uint64 i64; Java_Type typ; char msg[300]; if(!meth->is_static()) { ObjectHandle h = (ObjectHandle) args[arg_num++].l; // this pointer i64 = 0; if (h) i64 = (uint64) h->object; if (VM_Global_State::loader_env->compress_references) { // 20030318 We are in unmanaged code where null is represented by 0/NULL. Convert a null reference // to the representation of null in managed code (heap_base). if (i64 == 0) { i64 = (uint64)VM_Global_State::loader_env->heap_base; } } arg_words[num_arg_words++] = i64; num_ref_args++; } while((typ = curr_arg(iter)) != JAVA_TYPE_END) { ObjectHandle h; *msg = '\0'; switch(typ) { case JAVA_TYPE_LONG: i64 = args[arg_num++].j; arg_words[num_arg_words++] = i64; break; case JAVA_TYPE_CLASS: case JAVA_TYPE_ARRAY: h = (ObjectHandle) args[arg_num++].l; i64 = 0; if (h) i64 = (uint64) h->object; if (VM_Global_State::loader_env->compress_references) { // 20030318 We are in unmanaged code where null is represented by 0/NULL. Convert a null reference // to the representation of null in managed code (heap_base). if (i64 == 0) { i64 = (uint64)VM_Global_State::loader_env->heap_base; } } arg_words[num_arg_words++] = i64; num_ref_args++; #ifdef _DEBUG { if (! VM_Global_State::loader_env->compress_references || i64 != (uint64)VM_Global_State::loader_env->heap_base) { ManagedObject *object = (ManagedObject *)i64; if(object) { Class *clss = object->vt()->clss; sprintf(msg, " of class '%s'", clss->get_name()->bytes); } } } #endif break; case JAVA_TYPE_SHORT: i64 = (uint64)args[arg_num++].s; arg_words[num_arg_words++] = i64; break; case JAVA_TYPE_CHAR: i64 = (uint64)args[arg_num++].c; arg_words[num_arg_words++] = i64; break; case JAVA_TYPE_BYTE: i64 = (uint64)args[arg_num++].b; arg_words[num_arg_words++] = i64; break; case JAVA_TYPE_BOOLEAN: i64 = (uint64)args[arg_num++].z; arg_words[num_arg_words++] = i64; break; case JAVA_TYPE_DOUBLE: double_args[double_nargs] = args[arg_num++].d; double_nargs++; break; case JAVA_TYPE_FLOAT: double_args[double_nargs] = (double)args[arg_num++].f; double_nargs++; break; default: i64 = (uint64)args[arg_num++].i; arg_words[num_arg_words++] = i64; break; } iter = advance_arg_iterator(iter); } // assert(nargs <= 8); double double_result; static void* addr_execute = get_vm_execute_java_method(); struct{ void* fun; void* gp; } fptr; fptr.fun = addr_execute; fptr.gp = get_vm_gp_value(); // gashiman - changed _cdecl to __cdecl to work on linux uint64 (__cdecl *fpp_exec)(void *entry_point, int nargs, uint64 args[], double *double_result_addr, int double_nargs, double double_args[], void *thread_pointer, uint64 tid) = (uint64 (__cdecl * )(void *entry_point, int nargs, uint64 args[], double *double_result_addr, int double_nargs, double double_args[], void *thread_pointer, uint64 tid))&fptr; IDATA id = hythread_get_self_id(); uint64 int_result = (uint64)fpp_exec(entry_point, nargs, arg_words, &double_result, double_nargs, double_args, p_TLS_vmthread, id); // Save the result Java_Type ret_type = meth->get_return_java_type(); switch(ret_type) { case JAVA_TYPE_VOID: break; case JAVA_TYPE_ARRAY: case JAVA_TYPE_CLASS: { ObjectHandle h = 0; if (VM_Global_State::loader_env->compress_references) { // 20030318 Convert a null reference in managed code (represented by heap_base) // to the representation of null in unmanaged code (0 or NULL). if ((uint64)int_result == (uint64)VM_Global_State::loader_env->heap_base) { int_result = 0; } } if (int_result) { h = oh_allocate_local_handle(); h->object = (ManagedObject*) int_result; } return_value->l = h; } break; case JAVA_TYPE_LONG: return_value->j = int_result; break; case JAVA_TYPE_INT: *((I_32 *)return_value) = (I_32) int_result; break; case JAVA_TYPE_SHORT: *((int16 *)return_value) = (int16) int_result; break; case JAVA_TYPE_CHAR: *((uint16 *)return_value) = (uint16) int_result; break; case JAVA_TYPE_BYTE: *((I_8 *)return_value) = (I_8) int_result; break; case JAVA_TYPE_BOOLEAN: *((U_8 *)return_value) = (U_8) int_result; break; case JAVA_TYPE_DOUBLE: *((double *)return_value) = double_result; break; case JAVA_TYPE_FLOAT: *((float *)return_value) = (float) double_result; break; default: #ifdef _DEBUG std::clog << "Returned to C from " << meth->get_class()->get_name()->bytes << "." << meth->get_name()->bytes << meth->get_descriptor()->bytes << "\n"; #endif //DIE("Return type ");// << (int)ret_type << " is not implemented\n"); std::clog << "Return type " << (int)ret_type << " is not implemented\n"; } #endif } //vm_execute_java_method_array