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 + -
显示快捷键?