invoker.c

来自「This is a resource based on j2me embedde」· C语言 代码 · 共 764 行 · 第 1/2 页

C
764
字号
/* * @(#)invoker.c	1.29 06/10/25 * * Copyright  1990-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER *  * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation.  *  * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt).  *  * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA  *  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions.  */#include "util.h"#include "invoker.h"#include "eventHandler.h"#include "threadControl.h"#include "outStream.h"static jrawMonitorID invokerLock;void invoker_initialize(void){    invokerLock = debugMonitorCreate("JDWP Invocation Lock");}void invoker_reset(void){}void invoker_lock(void){    debugMonitorEnter(invokerLock);}void invoker_unlock(void){    debugMonitorExit(invokerLock);}static jbytereturnTypeTag(char *signature){    char *tagPtr = strchr(signature, SIGNATURE_END_ARGS);    JDI_ASSERT(tagPtr);    tagPtr++;    /* 1st character after the end of args */    return (jbyte)*tagPtr;}static jbytenextArgumentTypeTag(void **cursor){    char *tagPtr = *cursor;    jbyte argumentTag = (jbyte)*tagPtr;    if (*tagPtr != SIGNATURE_END_ARGS) {        /* Skip any array modifiers */        while (*tagPtr == JDWP_TAG(ARRAY)) {            tagPtr++;        }        /* Skip class name */        if (*tagPtr == JDWP_TAG(OBJECT)) {            tagPtr = strchr(tagPtr, SIGNATURE_END_CLASS) + 1;            JDI_ASSERT(tagPtr);        } else {            /* Skip primitive sig */            tagPtr++;        }    }    *cursor = tagPtr;    return argumentTag;}static jbytefirstArgumentTypeTag(char *signature, void **cursor){    JDI_ASSERT(signature[0] == SIGNATURE_BEGIN_ARGS);    *cursor = signature + 1; /* skip to the first arg */    return nextArgumentTypeTag(cursor);}/* * Note: argument refs may be destroyed on out-of-memory error  */static jvmtiErrorcreateGlobalRefs(JNIEnv *env, InvokeRequest *request) {    jvmtiError error;    jclass clazz = NULL;    jobject instance = NULL;    jint argIndex;    jbyte argumentTag;    jvalue *argument;    void *cursor;    jobject *argRefs = NULL;    error = JVMTI_ERROR_NONE;        if ( request->argumentCount > 0 ) {        /*LINTED*/        argRefs = jvmtiAllocate((jint)(request->argumentCount*sizeof(jobject)));        if ( argRefs==NULL ) {            error = AGENT_ERROR_OUT_OF_MEMORY;        } else {            /*LINTED*/            (void)memset(argRefs, 0, request->argumentCount*sizeof(jobject));        }    }        if ( error == JVMTI_ERROR_NONE ) {        saveGlobalRef(env, request->clazz, &clazz);        if (clazz == NULL) {            error = AGENT_ERROR_OUT_OF_MEMORY;        }    }    if ( error == JVMTI_ERROR_NONE && request->instance != NULL ) {        saveGlobalRef(env, request->instance, &instance);        if (instance == NULL) {            error = AGENT_ERROR_OUT_OF_MEMORY;        }    }    if ( error == JVMTI_ERROR_NONE && argRefs!=NULL ) {        argIndex = 0;        argumentTag = firstArgumentTypeTag(request->methodSignature, &cursor);        argument = request->arguments;        while (argumentTag != SIGNATURE_END_ARGS) {            if ( argIndex > request->argumentCount ) {                break;            }            if ((argumentTag == JDWP_TAG(OBJECT)) ||                (argumentTag == JDWP_TAG(ARRAY))) {                /* Create a global ref for any non-null argument */                if (argument->l != NULL) {                    saveGlobalRef(env, argument->l, &argRefs[argIndex]);                    if (argRefs[argIndex] == NULL) {                        error = AGENT_ERROR_OUT_OF_MEMORY;                        break;                    }                }            }            argument++;            argIndex++;            argumentTag = nextArgumentTypeTag(&cursor);        }    }#ifdef FIXUP /* Why isn't this an error? */    /* Make sure the argument count matches */    if ( error == JVMTI_ERROR_NONE && argIndex != request->argumentCount ) {        error = AGENT_ERROR_INVALID_COUNT;    }#endif    /* Finally, put the global refs into the request if no errors */    if ( error == JVMTI_ERROR_NONE ) {        request->clazz = clazz;        request->instance = instance;        if ( argRefs!=NULL ) {            argIndex = 0;            argumentTag = firstArgumentTypeTag(request->methodSignature, &cursor);            argument = request->arguments;            while ( argIndex < request->argumentCount ) {                if ((argumentTag == JDWP_TAG(OBJECT)) ||                    (argumentTag == JDWP_TAG(ARRAY))) {                    argument->l = argRefs[argIndex];                }                argument++;                argIndex++;                argumentTag = nextArgumentTypeTag(&cursor);            }            jvmtiDeallocate(argRefs);        }        return JVMTI_ERROR_NONE;        } else {        /* Delete global references */        if ( clazz != NULL ) {            tossGlobalRef(env, &clazz);        }        if ( instance != NULL ) {            tossGlobalRef(env, &instance);        }        if ( argRefs!=NULL ) {            for ( argIndex=0; argIndex < request->argumentCount; argIndex++ ) {                if ( argRefs[argIndex] != NULL ) {                    tossGlobalRef(env, &argRefs[argIndex]);                }            }            jvmtiDeallocate(argRefs);        }    }        return error;}static jvmtiErrorfillInvokeRequest(JNIEnv *env, InvokeRequest *request,                  jbyte invokeType, jbyte options, jint id,                  jthread thread, jclass clazz, jmethodID method,                   jobject instance,                   jvalue *arguments, jint argumentCount){    jvmtiError error;    if (!request->available) {        /*         * Thread is not at a point where it can invoke.         */        return AGENT_ERROR_INVALID_THREAD;    }    if (request->pending) {        /*         * Pending invoke         */        return AGENT_ERROR_ALREADY_INVOKING;    }    request->invokeType = invokeType;    request->options = options;    request->detached = JNI_FALSE;    request->id = id;    request->clazz = clazz;    request->method = method;    request->instance = instance;    request->arguments = arguments;    request->arguments = arguments;    request->argumentCount = argumentCount;    request->returnValue.j = 0;    request->exception = 0;    /*     * Squirrel away the method signature     */    error = methodSignature(method, NULL, &request->methodSignature,  NULL);    if (error != JVMTI_ERROR_NONE) {        return error;    }    /*     * The given references for class and instance are not guaranteed     * to be around long enough for invocation, so create new ones     * here.     */    error = createGlobalRefs(env, request);    if (error != JVMTI_ERROR_NONE) {        jvmtiDeallocate(request->methodSignature);        return error;    }    request->pending = JNI_TRUE;    request->available = JNI_FALSE;    return JVMTI_ERROR_NONE;}voidinvoker_enableInvokeRequests(jthread thread) {    InvokeRequest *request;         JDI_ASSERT(thread);    request = threadControl_getInvokeRequest(thread);    if (request == NULL) {        EXIT_ERROR(AGENT_ERROR_INVALID_THREAD, "getting thread invoke request");    }    request->available = JNI_TRUE;}jvmtiError invoker_requestInvoke(jbyte invokeType, jbyte options, jint id,                      jthread thread, jclass clazz, jmethodID method,                       jobject instance,                       jvalue *arguments, jint argumentCount){    JNIEnv *env = getEnv();    InvokeRequest *request;    jvmtiError error = JVMTI_ERROR_NONE;    debugMonitorEnter(invokerLock);    request = threadControl_getInvokeRequest(thread);    if (request != NULL) {        error = fillInvokeRequest(env, request, invokeType, options, id,                                  thread, clazz, method, instance,                                   arguments, argumentCount);     }    debugMonitorExit(invokerLock);    if (error == JVMTI_ERROR_NONE) {        if (options & JDWP_INVOKE_OPTIONS(SINGLE_THREADED) ) {            /* true means it is okay to unblock the commandLoop thread */            (void)threadControl_resumeThread(thread, JNI_TRUE);        } else {            (void)threadControl_resumeAll();        }    }    return error;}static voidinvokeConstructor(JNIEnv *env, InvokeRequest *request){    jobject object;    object = JNI_FUNC_PTR(env,NewObjectA)(env, request->clazz,                                     request->method,                                      request->arguments);    request->returnValue.l = NULL;    if (object != NULL) {        saveGlobalRef(env, object, &(request->returnValue.l));    }}static void invokeStatic(JNIEnv *env, InvokeRequest *request){    switch(returnTypeTag(request->methodSignature)) {        case JDWP_TAG(OBJECT):        case JDWP_TAG(ARRAY): {            jobject object;            object = JNI_FUNC_PTR(env,CallStaticObjectMethodA)(env,                                       request->clazz,                                       request->method,                                       request->arguments);            request->returnValue.l = NULL;            if (object != NULL) {                saveGlobalRef(env, object, &(request->returnValue.l));            }            break;        }        case JDWP_TAG(BYTE):            request->returnValue.b = JNI_FUNC_PTR(env,CallStaticByteMethodA)(env,                                                       request->clazz,                                                       request->method,                                                       request->arguments);            break;        case JDWP_TAG(CHAR):            request->returnValue.c = JNI_FUNC_PTR(env,CallStaticCharMethodA)(env,                                                       request->clazz,                                                       request->method,                                                       request->arguments);            break;        case JDWP_TAG(FLOAT):            request->returnValue.f = JNI_FUNC_PTR(env,CallStaticFloatMethodA)(env,                                                       request->clazz,                                                       request->method,                                                       request->arguments);            break;        case JDWP_TAG(DOUBLE):            request->returnValue.d = JNI_FUNC_PTR(env,CallStaticDoubleMethodA)(env,                                                       request->clazz,                                                       request->method,                                                       request->arguments);            break;        case JDWP_TAG(INT):            request->returnValue.i = JNI_FUNC_PTR(env,CallStaticIntMethodA)(env,                                                       request->clazz,

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?