⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 methodcalls.c

📁 linux下建立JAVA虚拟机的源码KAFFE
💻 C
字号:
/* * methodcalls.c * Implementation of method calls * * Copyright (c) 1996, 1997 *	Transvirtual Technologies, Inc.  All rights reserved. * * Copyright (c) 2004 *      The kaffe.org's developers. See ChangeLog for details. * * See the file "license.terms" for information on usage and redistribution  * of this file.  */#include "config.h"#if defined(HAVE_LIBFFI)#include "sysdepCallMethod-ffi.h"#else#define NEED_sysdepCallMethod 1#endif#include "locks.h"#include "machine.h"#include "methodcalls.h"#include "thread.h"#include "slots.h"#include "soft.h"#include "external.h"#include "jni_i.h"#include "exception.h"void *engine_buildTrampoline (Method *meth, void **where, errorInfo *einfo UNUSED){	*where = meth;	return meth;}static voidstartJNIcall(void){	threadData 	*thread_data = THREAD_DATA();	jnirefs* table;	table = gc_malloc	  (sizeof(jnirefs) + sizeof(jref)*DEFAULT_JNIREFS_NUMBER,	   KGC_ALLOC_STATIC_THREADDATA);	table->prev = thread_data->jnireferences;	thread_data->jnireferences = table;	table->frameSize = DEFAULT_JNIREFS_NUMBER;	table->localFrames = 1;	/* No pending exception when we enter JNI routine */	thread_data->exceptObj = NULL;}static voidfinishJNIcall(void){	jref eobj;	threadData	*thread_data = THREAD_DATA();	jnirefs* table;	int localFrames;	table = thread_data->jnireferences;	localFrames = table->localFrames;	for (localFrames = table->localFrames; localFrames >= 1; localFrames--)	  {	    thread_data->jnireferences = table->prev;	    gc_free(table);	    table = thread_data->jnireferences;	  }	/* If we have a pending exception, throw it */	eobj = thread_data->exceptObj;	if (eobj != 0) {		thread_data->exceptObj = NULL;		throwExternalException(eobj);	}}voidengine_callMethod (callMethodInfo *call){	Method *meth = (Method *)call->function;	if ((meth->accflags & ACC_NATIVE) == 0) {	  jint i;	  jint numArgs;	  errorInfo einfo;	  /* Calculate number of arguments */	  numArgs = sizeofSigMethod(meth, false);	  if (numArgs == -1) {	    postException(&einfo,  JAVA_LANG(InternalError));	    throwError(&einfo);	  }	  numArgs += (meth->accflags & ACC_STATIC ? 0 : 1);	  jvalue *newargs = (jvalue *)alloca(sizeof(jvalue) * numArgs);	  jvalue *curarg = newargs;	  for (i = 2; i < call->nrargs; i++, curarg++)	    {	      switch (call->calltype[i])		{		case 'J':		case 'D':		  *curarg = call->args[i];		  curarg++;		  break;		default:		  *curarg = call->args[i];		  break;		}	    }	  virtualMachine(meth, (slots*)newargs, (slots*)call->ret, THREAD_DATA()); 	    	}	else {		Hjava_lang_Object* syncobj = 0;		VmExceptHandler mjbuf;		threadData* thread_data = THREAD_DATA(); 		struct Hjava_lang_Throwable *save_except = NULL;		errorInfo einfo;		if (!METHOD_TRANSLATED(meth)) {			nativecode *func = native(meth, &einfo);			if (func == NULL) {				throwError(&einfo);			}			setMethodCodeStart(meth, func);			meth->accflags |= ACC_TRANSLATED;		}		call->function = getMethodCodeStart(meth);		if (meth->accflags & ACC_JNI)		{			if (meth->accflags & ACC_STATIC)			{				call->callsize[1] = PTR_TYPE_SIZE / SIZEOF_INT;				call->argsize += call->callsize[1];				call->calltype[1] = 'L';				call->args[1].l = meth->class;			}			else			{				call->nrargs -= 1;				call->args += 1;				call->callsize += 1;				call->calltype += 1;			}			/* Insert the JNI environment */			call->callsize[0] = PTR_TYPE_SIZE / SIZEOF_INT;			call->calltype[0] = 'L';			call->args[0].l = THREAD_JNIENV(); 			call->argsize += call->callsize[0]; 		}		else		{			call->nrargs -= 2;			call->args += 2;			call->callsize += 2;			call->calltype += 2;		}		if (meth->accflags & ACC_SYNCHRONISED) {			if (meth->accflags & ACC_STATIC) {				syncobj = &meth->class->head;			}			else if (meth->accflags & ACC_JNI) {				syncobj = (Hjava_lang_Object*)call->args[1].l;			}			else {				syncobj = (Hjava_lang_Object*)call->args[0].l;			}			lockObject(syncobj);		}		/* Put 0 in the biggest field. This is needed for some architecture which stores		 * the bytes out of order. */		if (call->ret != NULL)		  call->ret->j = 0;		setupExceptionHandling(&mjbuf, meth, syncobj, thread_data);		/* This exception has yet been handled by the VM creator.		 * We are putting it in stand by until it is cleared. For		 * that JNI call we're cleaning up the pointer and we will		 * put it again to the value afterward.		 */		if ((meth->accflags & ACC_JNI) != 0) {			if (thread_data->exceptObj != NULL)				save_except = thread_data->exceptObj;			else				save_except = NULL;			startJNIcall();		}		/* Make the call - system dependent */		sysdepCallMethod(call);		if (syncobj != 0) {			unlockObject(syncobj);		}		/* If we have a pending exception and this is JNI, throw it */		if ((meth->accflags & ACC_JNI) != 0) {		        if (call->rettype == 'L')			        call->ret->l = unveil(call->ret->l);		        finishJNIcall();			thread_data->exceptObj = save_except;		}		cleanupExceptionHandling(&mjbuf, thread_data);	}}void engine_dispatchException(uintp framePointer,			      uintp handler, 			      struct Hjava_lang_Throwable *throwable){  vmExcept_setPC((VmExceptHandler *)framePointer, handler);  vmExcept_jumpToHandler((VmExceptHandler *)framePointer); /* Does not return */}

⌨️ 快捷键说明

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