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

📄 jni.c

📁 java virtual machince kaffe
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * jni.c * Java Native Interface. * * Copyright (c) 1996, 1997 *	Transvirtual Technologies, Inc.  All rights reserved. * * Copyright (c) 2004-2005 * 	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"#include "config-std.h"#include "config-mem.h"#include "jni.h"#include "jnirefs.h"#include "classMethod.h"#include "soft.h"#include "support.h"#include "itypes.h"#include "object.h"#include "errors.h"#include "native.h"#include "file.h"#include "baseClasses.h"#include "stringSupport.h"#include "readClass.h"#include "access.h"#include "lookup.h"#include "thread.h"#include "external.h"#include "gc.h"#include "locks.h"#include "md.h"#include "exception.h"#include "jvmpi_kaffe.h"#include "jni_i.h"#include "jni_funcs.h"#include "native-wrapper.h"#include "kaffe_jni.h"#include "stackTrace.h"extern struct JNINativeInterface Kaffe_JNINativeInterface;extern KaffeVM_Arguments Kaffe_JavaVMInitArgs;static JavaVM Kaffe_JavaVM;JavaVM*KaffeJNI_GetKaffeVM(void){  return &Kaffe_JavaVM;}static jint Kaffe_GetVersion(JNIEnv*);static jclass Kaffe_FindClass(JNIEnv*, const char*);static jint Kaffe_ThrowNew(JNIEnv*, jclass, const char*);static jint Kaffe_Throw(JNIEnv* env, jobject obj);/* * Everything from this point to Kaffe_GetVersion is not * exception-aware.  Asynchronous exceptions should not be delivered * to them. * * Everything from Kaffe_GetVersion to Kaffe_GetJavaVM * should be bracketed with BEGIN and END _EXCEPTION_HANDLING. */void NONRETURNINGKaffeJNI_FatalError(JNIEnv* env UNUSED, const char* mess){	kprintf(stderr, "FATAL ERROR: %s\n", mess);	abort();}static jintKaffe_GetVersion(JNIEnv* env UNUSED){       return Kaffe_JavaVMArgs.version;}/* * take a VM error and throw it as JNI error  */static voidpostError(JNIEnv* env, errorInfo* info){	(*env)->Throw(env, error2Throwable(info));}static jclassKaffe_DefineClass(JNIEnv* env, const char *name UNUSED, jobject loader,		  const jbyte* buf, jsize len){  Hjava_lang_Class* cls, *dup_cls;  classFile hand;  errorInfo info;  jobject loader_local;  classEntry *centry;  BEGIN_EXCEPTION_HANDLING(NULL);  loader_local = unveil(loader); /* save clobbered reg.  */  classFileInit(&hand, NULL, (unsigned char*)buf, (size_t)len,		CP_BYTEARRAY);  cls = newClass();  if (cls == NULL) {    postOutOfMemory(&info);  } else {    cls = readClass(cls, &hand, loader_local, &info);  }  if (cls == NULL) {    postError(env, &info);  }  /*   * See if an entry for that name and class loader already exists   * create one if not.   */  centry = lookupClassEntry(cls->name, loader_local, &info);  if (centry == 0) {    throwError(&info);  }  if( classMappingLoad(centry, &dup_cls, &info) )    {      if(dup_cls != NULL)	{	  postExceptionMessage(&info,			       JAVA_LANG(ClassFormatError),			       "Duplicate name: %s",			       centry->name->data);	  throwError(&info);	}      /*       * While it is not necessary that one be able to actually *use*       * the returned class object at this point, it is mandatory       * that the returned clazz object is a functional Class object.       *       * The following call will make sure that the returned class       * object has its dispatch table set.  The transition       * PRELOADED->PREPARED in processClass sets class->head.dtable.       *       * Presumably, it shouldn't be necessary here, but is at the       * moment - XXX       */      else if( processClass(cls,			    CSTATE_PREPARED,			    &info) == false )	{	  throwError(&info);	}    }  else    {      throwError(&info);    }  END_EXCEPTION_HANDLING();  return cls;}static jclassKaffe_FindClass(JNIEnv *env UNUSED, const char* name){	stackTraceInfo          *trace;	Utf8Const* utf8;	Hjava_lang_ClassLoader  *loader;	Hjava_lang_Class	*clazz;	errorInfo		einfo;	int			i;	char*			pathname;	BEGIN_EXCEPTION_HANDLING(NULL);	/* convert name to the form used inside the vm */	pathname = checkPtr(KMALLOC(strlen (name) + 1));	classname2pathname (name, pathname);	/* create a new utf8 constant */	utf8 = utf8ConstFromString(pathname);	/* free the internal form of name */	KFREE(pathname);	/* bail out if we could not create the utf8 constant */	if (utf8 == NULL)	{		postOutOfMemory (&einfo);		throwError (&einfo);	}	/* Quote from the JNI documentation:	 *	 * "In the Java 2 Platform, FindClass locates the class loader associated with the current native method.	 *  If the native code belongs to a system class, no class loader will be involved. Otherwise, the proper	 *  class loader will be invoked to load and link the named class. When FindClass is called through the	 *  Invocation Interface, there is no current native method or its associated class loader. In that case,	 *  the result of ClassLoader.getBaseClassLoader is used."	 *	 * So we ...	 */	/* ... get the stacktrace ... */	trace = (stackTraceInfo *)buildStackTrace (NULL);	if (trace == NULL)	{		postOutOfMemory (&einfo);		goto error_out;	}	/* ... find the first java method on the stack ... */	for (i=0; trace[i].meth != ENDOFSTACK; i++)	{		if ((trace[i].meth != NULL) &&		    (trace[i].meth->class != NULL))			break;	}	/* ... determine the loader to be used ... */	if (trace[i].meth == ENDOFSTACK) {		jvalue retval;		do_execute_java_class_method (&retval, "java/lang/ClassLoader",					      NULL,					      "getSystemClassLoader",					      "()Ljava/lang/ClassLoader;");		loader = (Hjava_lang_ClassLoader *)retval.l;	} else {		loader = trace[i].meth->class->loader;	}	/* ... and finally call loadArray or loadClass.	 *	 * Why don't we delegate to Class.forName? Our implementation of	 * VMClassLoader.loadClass denies access to classes in internal	 * packages like kaffe.lang or gnu.classpath (for security reasons).	 * However, when FindClass is invoked from the native method of a	 * class defined by the bootstrap loader, that is not correct.	 * Therefore, we call loadClass / loadArray directly, which corresponds	 * to what getClass() does. 	 */	if (utf8->data[0] == '[')	{		clazz = loadArray (utf8, loader, &einfo);	}	else	{		clazz = loadClass (utf8, loader, &einfo);	}	if (clazz == NULL)	{		goto error_out;	}	if (processClass (clazz, CSTATE_COMPLETE, &einfo) == false)	{		goto error_out;	}	ADD_REF(clazz);	utf8ConstRelease(utf8);	END_EXCEPTION_HANDLING();	return (clazz);error_out:	utf8ConstRelease(utf8);	throwError (&einfo);	/* This is to make gcc silent on one warning */	return NULL;}static jclassKaffe_GetSuperClass(JNIEnv* env UNUSED, jclass cls){	jclass clz, cls_local;	BEGIN_EXCEPTION_HANDLING(NULL);	cls_local = unveil(cls); /* save clobbered reg.  */	clz = ((Hjava_lang_Class*)cls_local)->superclass;	END_EXCEPTION_HANDLING();	return (clz);}static jbooleanKaffe_IsAssignableFrom(JNIEnv* env UNUSED, jclass cls1, jclass cls2){	jboolean r;	jclass cls1_local;	jclass cls2_local;	BEGIN_EXCEPTION_HANDLING(0);	cls1_local = unveil(cls1);	cls2_local = unveil(cls2);	if (instanceof(cls2_local, cls1_local) != 0) {		r = JNI_TRUE;	}	else {		r = JNI_FALSE;	}	END_EXCEPTION_HANDLING();	return (r);}static jintKaffe_Throw(JNIEnv* env UNUSED, jobject obj){	jobject obj_local;	BEGIN_EXCEPTION_HANDLING(0);	if( obj )	{		obj_local = unveil(obj);		assert(((Hjava_lang_Object *)obj_local)->vtable);		thread_data->exceptObj =		  (struct Hjava_lang_Throwable*)obj_local;	}	END_EXCEPTION_HANDLING();	return (0);}static jintKaffe_ThrowNew(JNIEnv* env UNUSED, jclass cls, const char* mess){	Hjava_lang_Object* eobj;	jclass cls_local;	BEGIN_EXCEPTION_HANDLING(0);	cls_local = unveil(cls);	eobj = execute_java_constructor(NULL, NULL, cls_local,					"(Ljava/lang/String;)V",					checkPtr(stringC2Java(mess)));	thread_data->exceptObj = (struct Hjava_lang_Throwable*)eobj;	END_EXCEPTION_HANDLING();	return (0);}static jobjectKaffe_ExceptionOccurred(JNIEnv* env UNUSED){	jobject obj;	BEGIN_EXCEPTION_HANDLING(NULL);	obj = thread_data->exceptObj;	if (obj != NULL)	  ADD_REF(obj);	END_EXCEPTION_HANDLING();	return (obj);}static jbooleanKaffe_ExceptionCheck(JNIEnv* env UNUSED){	jboolean result;	jobject obj;	BEGIN_EXCEPTION_HANDLING(0);	obj = thread_data->exceptObj;	result = (obj == NULL) ? JNI_FALSE : JNI_TRUE;	END_EXCEPTION_HANDLING();	return (result);}static voidKaffe_ExceptionDescribe(JNIEnv* env UNUSED){	const char* cname;	Hjava_lang_Class* class;	Hjava_lang_Throwable *eobj;	BEGIN_EXCEPTION_HANDLING_VOID();	eobj = thread_data->exceptObj;	while (eobj != NULL) {		/* Don't use the java stack printer because the exception		 * may arise in the IO codec.		 */	       Hjava_lang_String *msg;	       char *realname;	       class = OBJECT_CLASS(&eobj->base);	       cname = CLASS_CNAME(class);	       realname = KMALLOC(strlen(cname)+1);	       pathname2classname(cname, realname);			       	       msg = unhand(eobj)->detailMessage;	       if (msg != NULL) {		       char *cmsg = checkPtr(stringJava2C(msg));		       kprintf(stderr, "%s: %s\n", realname, cmsg);		       KFREE(cmsg);		       unhand(eobj)->detailMessage = NULL;	       } else {		       kprintf(stderr, "%s\n", realname);	       }       	       KFREE(realname);	       	       printStackTrace (eobj, NULL, true);	       if (eobj->cause != eobj) {		       eobj = eobj->cause;		       kprintf(stderr, "caused by: ");	       } else		       eobj = NULL;	}	END_EXCEPTION_HANDLING();}static voidKaffe_ExceptionClear(JNIEnv* env UNUSED){	BEGIN_EXCEPTION_HANDLING_VOID();	thread_data->exceptObj = NULL;	END_EXCEPTION_HANDLING();}static jobjectKaffe_AllocObject(JNIEnv* env UNUSED, jclass cls){	jobject obj;	Hjava_lang_Class* clazz;	jclass cls_local;	BEGIN_EXCEPTION_HANDLING(NULL);	cls_local = unveil(cls);	clazz = (Hjava_lang_Class*)cls_local;	if (CLASS_IS_INTERFACE(clazz) || CLASS_IS_ABSTRACT(clazz)) {		throwException(InstantiationException(clazz->name->data));	}	obj = newObject(clazz);	ADD_REF(obj);	END_EXCEPTION_HANDLING();	return (obj);}static jobjectKaffe_NewObjectV(JNIEnv* env UNUSED, jclass cls, jmethodID meth, va_list args){	Hjava_lang_Object* obj;	Hjava_lang_Class* clazz;	jvalue retval;	Method* m = (Method*)meth;	jclass cls_local;	BEGIN_EXCEPTION_HANDLING(NULL);	cls_local = unveil(cls);	clazz = (Hjava_lang_Class*)cls_local;	if (CLASS_IS_INTERFACE(clazz) || CLASS_IS_ABSTRACT(clazz) || !METHOD_IS_CONSTRUCTOR(m)) {		throwException(InstantiationException(clazz->name->data));	}	obj = newObject(clazz);	KaffeVM_callMethodV(m, METHOD_NATIVECODE(m), obj, args, &retval);	ADD_REF(obj);	END_EXCEPTION_HANDLING();	return (obj);}static jobjectKaffe_NewObject(JNIEnv* env UNUSED, jclass cls, jmethodID meth, ...){	jobject obj;	va_list args;	jclass cls_local;	BEGIN_EXCEPTION_HANDLING(NULL);	cls_local = unveil(cls);	va_start(args, meth);	obj = Kaffe_NewObjectV(env, cls_local, meth, args);	va_end(args);	END_EXCEPTION_HANDLING();	return (obj);}static jobjectKaffe_NewObjectA(JNIEnv* env UNUSED, jclass cls, jmethodID meth, jvalue* args){	Hjava_lang_Object* obj;	Hjava_lang_Class* clazz;	jvalue retval;	Method* m = (Method*)meth;	jclass cls_local;	BEGIN_EXCEPTION_HANDLING(NULL);	cls_local = unveil(cls);	clazz = (Hjava_lang_Class*)cls_local;	if (CLASS_IS_INTERFACE(clazz) || CLASS_IS_ABSTRACT(clazz) || !METHOD_IS_CONSTRUCTOR(m)) {		throwException(InstantiationException(clazz->name->data));	}	obj = newObject(clazz);	KaffeVM_callMethodA(m, METHOD_NATIVECODE(m), obj, args, &retval, 0);	ADD_REF(obj);	END_EXCEPTION_HANDLING();	return (obj);}static jclassKaffe_GetObjectClass(JNIEnv* env UNUSED, jobject obj){	jclass cls;	jobject obj_local;	BEGIN_EXCEPTION_HANDLING(NULL);	obj_local = unveil(obj);	cls = ((Hjava_lang_Object*)obj_local)->vtable->class;	END_EXCEPTION_HANDLING();	return (cls);}static jbooleanKaffe_IsInstanceOf(JNIEnv* env UNUSED, jobject obj, jclass cls){	jboolean r;	jobject obj_local;	jclass cls_local;	BEGIN_EXCEPTION_HANDLING(0);	obj_local = unveil(obj);	cls_local = unveil(cls);	if (soft_instanceof((Hjava_lang_Class*)cls_local,			    (Hjava_lang_Object*)obj_local) != 0) {		r = JNI_TRUE;	}	else {		r = JNI_FALSE;	}	END_EXCEPTION_HANDLING();	return (r);}

⌨️ 快捷键说明

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