Пример #1
0
static Class_Handle method_get_return_type_class(Method_Handle m)
{
    assert(hythread_is_suspend_enabled());
    Method *method = (Method *)m;
    Global_Env *env = VM_Global_State::loader_env;
    Java_Type UNUSED t = method->get_return_java_type();
    assert(t == JAVA_TYPE_CLASS || t == JAVA_TYPE_ARRAY);
    const char *descr = method->get_descriptor()->bytes;
    while(*descr != ')')
        descr++;
    descr++;
    String *n;
    if(descr[0] == 'L') {
        descr++;
        size_t len = strlen(descr);
        n = env->string_pool.lookup(descr, len-1);
    } else {
        n = env->string_pool.lookup(descr);
    }

    Class *clss = method->get_class();
    Class *c = clss->get_class_loader()->LoadVerifyAndPrepareClass(env, n);
    return c;
} //method_get_return_type_class
Пример #2
0
void
JIT_execute_method_default(JIT_Handle jit, jmethodID methodID, jvalue *return_value, jvalue *args) {

    // Detecting errors with object headears on stack when using destructive
    // unwinding.
    void *lastFrame = p_TLS_vmthread->lastFrame;
    p_TLS_vmthread->lastFrame = (void*)&lastFrame;
    //printf("execute: push: prev = 0x%p, curr=0x%p\n", lastFrame, &lastFrame);

//    fprintf(stderr, "Not implemented\n");

    Method *method = (Method*) methodID;
    TRACE("enter method "
          << method->get_class()->get_name()->bytes << " "
          << method->get_name()->bytes << " "
          << method->get_descriptor()->bytes);
    int sz = method->get_num_arg_slots();
    void *meth_addr = method->get_code_addr();
    U_32 *arg_words = (U_32*) STD_ALLOCA(sz * sizeof(U_32));

    int argId = sz;
    int pos = 0;

    assert(!hythread_is_suspend_enabled());
    if (!method->is_static()) {
        ObjectHandle handle = (ObjectHandle) args[pos++].l;
        assert(handle);
        arg_words[--argId] = (unsigned) handle->object;
    }

    const char *mtype = method->get_descriptor()->bytes + 1;
    assert(mtype != 0);

    for(; *mtype != ')'; mtype++) {
        switch(*mtype) {
        case JAVA_TYPE_CLASS:
        case JAVA_TYPE_ARRAY:
        {
            ObjectHandle handle = (ObjectHandle) args[pos++].l;
            arg_words[--argId] = (unsigned) (handle ? handle->object : 0);

            while(*mtype == '[') mtype++;
            if (*mtype == 'L')
                while(*mtype != ';') mtype++;
        }
        break;

        case JAVA_TYPE_SHORT:
            // sign extend
            arg_words[--argId] = (U_32)(I_32) args[pos++].s;
            break;
        case JAVA_TYPE_BYTE:
            // sign extend
            arg_words[--argId] = (U_32)(I_32) args[pos++].b;
            break;
        case JAVA_TYPE_INT:
            // sign extend
            arg_words[--argId] = (U_32)(I_32) args[pos++].i;
            break;

        case JAVA_TYPE_FLOAT:
            arg_words[--argId] = (I_32) args[pos++].i;
            break;
        case JAVA_TYPE_BOOLEAN:
            arg_words[--argId] = (I_32) args[pos++].z;
            break;
        case JAVA_TYPE_CHAR:
            // zero extend
            arg_words[--argId] = (I_32) args[pos++].c;
            break;

        case JAVA_TYPE_LONG:
        case JAVA_TYPE_DOUBLE:
            *(jlong*)&arg_words[argId-2] = args[pos++].j;
            argId -= 2;
            break;
        default:
            LDIE(53, "Unexpected java type");
        }
    }
    assert(argId >= 0);

    jvalue *resultPtr = (jvalue*) return_value;
    Java_Type ret_type = method->get_return_java_type();

    arg_words += argId;
    argId = sz - argId;

    static const IntFuncPtr invoke_managed_func = gen_invoke_int_managed_func();
    static const FloatFuncPtr invoke_float_managed_func = gen_invoke_float_managed_func();
    static const DoubleFuncPtr invoke_double_managed_func = gen_invoke_double_managed_func();

    switch(ret_type) {
    case JAVA_TYPE_VOID:
        invoke_managed_func(arg_words, argId, meth_addr);
        break;
    case JAVA_TYPE_CLASS:
    case JAVA_TYPE_ARRAY:
    case JAVA_TYPE_STRING:
    {
        ManagedObject *ref = ((RefFuncPtr)invoke_managed_func)(arg_words, argId, meth_addr);
        ObjectHandle h = oh_allocate_local_handle();

        if (ref != NULL) {
            h->object = ref;
            resultPtr->l = h;
        } else {
            resultPtr->l = NULL;
        }
    }
    break;

    case JAVA_TYPE_BOOLEAN:
    case JAVA_TYPE_BYTE:
    case JAVA_TYPE_CHAR:
    case JAVA_TYPE_SHORT:
    case JAVA_TYPE_INT:
        resultPtr->i = invoke_managed_func(arg_words, argId, meth_addr);
        break;

    case JAVA_TYPE_FLOAT:
        resultPtr->f = invoke_float_managed_func(arg_words, argId, meth_addr);
        break;

    case JAVA_TYPE_LONG:
        resultPtr->j = ((LongFuncPtr)invoke_managed_func)(arg_words, argId, meth_addr);
        break;

    case JAVA_TYPE_DOUBLE:
        resultPtr->d = invoke_double_managed_func(arg_words, argId, meth_addr);
        break;

    default:
        LDIE(53, "Unexpected java type");
    }

    if (exn_raised()) {
        TRACE("Exception occured: " << exn_get_name());
        if ((resultPtr != NULL) && (ret_type != JAVA_TYPE_VOID)) {
            resultPtr->l = 0; //clear result
        }
    }

    TRACE("exit method "
          << method->get_class()->get_name()->bytes << " "
          << method->get_name()->bytes << " "
          << method->get_descriptor()->bytes);

    // Detecting errors with object headears on stack when using destructive
    // unwinding.
    //printf("execute:  pop: prev = 0x%p, curr=0x%p\n", &lastFrame, lastFrame);
    p_TLS_vmthread->lastFrame = lastFrame;
}
Пример #3
0
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