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

📄 jni.c

📁 kaffe Java 解释器语言,源码,Java的子集系统,开放源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * jni.c * Java Native Interface. * * Copyright (c) 1996, 1997 *	Transvirtual Technologies, Inc.  All rights reserved. * * 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"#if defined(TRANSLATOR)#include "constpool.h"#include "seq.h"#include "slots.h"#include "registers.h"#include "labels.h"#include "codeproto.h"#include "basecode.h"#include "icode.h"#include "machine.h"#include "feedback.h"#endif#include "jvmpi_kaffe.h"/* * Define the version of JNI we support. */static int java_major_version = 1;static int java_minor_version = 1;/* * Keep track of how many VM's are active. Right now * we only support one at a time. */static int Kaffe_NumVM = 0;/* * If we must manage the JNI references for the native layer then we * add extra functions to the JNI calls and returns to manage the * referencing. */#if defined(NEED_JNIREFS)static void addJNIref(jref);static void removeJNIref(jref);#define	ADD_REF(O)		addJNIref(O)#define	REMOVE_REF(O)		removeJNIref(O)#else#define	ADD_REF(O)#define	REMOVE_REF(O)#endif/* * Find the function to be called when meth is invoked on obj */static inline void*getMethodFunc (Method* meth, Hjava_lang_Object *obj){	if (obj && CLASS_IS_INTERFACE (meth->class)) {		register short *implementors;		register Hjava_lang_Class *clazz;				assert (meth->idx >= 0);		implementors = meth->class->implementors;		clazz = OBJECT_CLASS(obj);		assert (implementors != NULL && clazz->impl_index <= implementors[0]);				return clazz->itable2dtable[implementors[clazz->impl_index] + meth->idx + 1]; 		} else {		return meth->idx >= 0 ? obj->dtable->method[meth->idx] : METHOD_INDIRECTMETHOD (meth);	}}/* * Define how to set the frame pointer in a VmExceptHandler. */#if defined(TRANSLATOR)#define KAFFE_JNI_SETEXCEPTFP(ebufp) {				\        vmExcept_setJNIFrame(ebufp,(uintp)__builtin_frame_address(0));\        }#else/* * Stack frame info isn't needed (and isn't available) in the * interpreter (see dispatchException/unwindStackFrame in exception.c) * However, we have to at least tag the VmExceptHandler as * a JNIFrame so the stack trace code can ignore it. */#define KAFFE_JNI_SETEXCEPTFP(ebufp) {   \	vmExcept_setJNIFrame(ebufp, (uintp)ebufp); \        }#endif /* * Define how we handle exceptions in JNI. * * Each BEGIN_EXCEPTION_HANDLING macro must be matched by an * END_EXCEPTION_HANDLING macro call in the same scope.  Each should * be used only once in a given JNI entrypoint. */#define	BEGIN_EXCEPTION_HANDLING(X)			\	VmExceptHandler ebuf;				\	threadData *thread_data = THREAD_DATA();	\	KAFFE_JNI_SETEXCEPTFP(&ebuf); 			\	ebuf.prev = thread_data->exceptPtr;\	if (JTHREAD_SETJMP(ebuf.jbuf) != 0) {		\		thread_data->exceptPtr = ebuf.prev;	\		return X;				\	}						\	thread_data->exceptPtr = &ebuf#define	BEGIN_EXCEPTION_HANDLING_VOID()			\	VmExceptHandler ebuf; 				\	threadData *thread_data = THREAD_DATA();	\	KAFFE_JNI_SETEXCEPTFP(&ebuf); 			\	ebuf.prev = thread_data->exceptPtr;	\	if (JTHREAD_SETJMP(ebuf.jbuf) != 0) {		\		thread_data->exceptPtr = ebuf.prev; \		return;					\	}						\	thread_data->exceptPtr = &ebuf#define	END_EXCEPTION_HANDLING()			\	thread_data->exceptPtr = ebuf.prev/* * Get and set fields. */#define	GET_FIELD(T,O,F)	*(T*)((char*)(O) + FIELD_BOFFSET((Field*)(F)))#define	SET_FIELD(T,O,F,V)	*(T*)((char*)(O) + FIELD_BOFFSET((Field*)(F))) = (V)#define	GET_STATIC_FIELD(T,F)	*(T*)FIELD_ADDRESS((Field*)F)#define	SET_STATIC_FIELD(T,F,V)	*(T*)FIELD_ADDRESS((Field*)F) = (V)extern struct JNINativeInterface Kaffe_JNINativeInterface;extern JavaVMInitArgs Kaffe_JavaVMInitArgs;extern JavaVM Kaffe_JavaVM;static void Kaffe_JNI_wrapper(Method*, void*);#if defined(TRANSLATOR)static void *startJNIcall(void);static void finishJNIcall(void);static void Kaffe_wrapper(Method* xmeth, void* func, bool use_JNI);#endifstatic 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);jintJNI_GetDefaultJavaVMInitArgs(JavaVMInitArgs* args){	if (args->version != ((java_major_version << 16) | java_minor_version)) {		return (-1);	}	memcpy(args, &Kaffe_JavaVMInitArgs, sizeof(JavaVMInitArgs));	args->version = (java_major_version << 16) | java_minor_version;	return (0);}jintJNI_CreateJavaVM(JavaVM** vm, JNIEnv** env, JavaVMInitArgs* args){	if (args->version != ((java_major_version << 16) | java_minor_version)) {		return (-1);	}	/* We can only init. one KVM */	if (Kaffe_NumVM != 0) {		return (-1);	}	/* Setup the machine */	Kaffe_JavaVMArgs[0] = *args;	initialiseKaffe();	/* Setup JNI for main thread */#if defined(NEED_JNIREFS)	THREAD_DATA()->jnireferences = (jnirefs *)gc_malloc(sizeof(jnirefs), &gcNormal);#endif	/* Return the VM and JNI we're using */	*vm = &Kaffe_JavaVM;	*env = THREAD_JNIENV();	Kaffe_NumVM++;#if defined(ENABLE_JVMPI)	if( JVMPI_EVENT_ISENABLED(JVMPI_EVENT_JVM_INIT_DONE) )	{		JVMPI_Event ev;		ev.event_type = JVMPI_EVENT_JVM_INIT_DONE;		jvmpiPostEvent(&ev);	}#endif		return (0);}jintJNI_GetCreatedJavaVMs(JavaVM** vm, jsize buflen, jsize* nvm){	vm[0] = &Kaffe_JavaVM;	*nvm = Kaffe_NumVM;	return (0);}/* * 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. */static voidKaffe_FatalError(JNIEnv* env, const char* mess){	kprintf(stderr, "FATAL ERROR: %s\n", mess);	exit(1);}static voidKaffe_DeleteGlobalRef(JNIEnv* env, jref obj){#if defined(ENABLE_JVMPI)	if( JVMPI_EVENT_ISENABLED(JVMPI_EVENT_JNI_GLOBALREF_FREE) )	{		JVMPI_Event ev;		ev.event_type = JVMPI_EVENT_JNI_GLOBALREF_FREE;		ev.u.jni_globalref_free.ref_id = obj;		jvmpiPostEvent(&ev);	}#endif	gc_rm_ref(obj);}static voidKaffe_DeleteLocalRef(JNIEnv* env, jref obj){	REMOVE_REF(obj);}static jbooleanKaffe_IsSameObject(JNIEnv* env, jobject obj1, jobject obj2){	if (obj1 == obj2) {		return (JNI_TRUE);	}	else {		return (JNI_FALSE);	}}static voidKaffe_ReleaseStringChars(JNIEnv* env, jstring data, const jchar* chars){	/* Does nothing */}static jintKaffe_GetVersion(JNIEnv* env){	return ((java_major_version << 16) | java_minor_version);}/* * take a VM error and throw it as JNI error  */static voidpostError(JNIEnv* env, errorInfo* info){	Kaffe_Throw(env, error2Throwable(info));}static jrefKaffe_NewGlobalRef(JNIEnv* env, jref obj){	BEGIN_EXCEPTION_HANDLING(0);	if (!gc_add_ref(obj)) {		errorInfo info;		postOutOfMemory(&info);		postError(env, &info);	}#if defined(ENABLE_JVMPI)	if( JVMPI_EVENT_ISENABLED(JVMPI_EVENT_JNI_GLOBALREF_ALLOC) )	{		JVMPI_Event ev;		ev.event_type = JVMPI_EVENT_JNI_GLOBALREF_ALLOC;		ev.u.jni_globalref_alloc.obj_id = obj;		ev.u.jni_globalref_alloc.ref_id = obj;		jvmpiPostEvent(&ev);	}#endif	END_EXCEPTION_HANDLING();	return obj;}static jclassKaffe_DefineClass(JNIEnv* env, jobject loader, const jbyte* buf, jsize len){	Hjava_lang_Class* cls;	classFile hand;	errorInfo info;	BEGIN_EXCEPTION_HANDLING(0);	classFileInit(&hand, buf, len, CP_BYTEARRAY);	cls = newClass();	if (cls == 0) {		postOutOfMemory(&info);	} else {		cls = readClass(cls, &hand, loader, &info);	}	if (cls == 0) {		postError(env, &info);	}	END_EXCEPTION_HANDLING();	return (cls);}/* * For this routine, we defer most of the work to Class.forName(), * which handles the task of figuring out the right ClassLoader to * use based on the calling method, which requires examining the * stack backtrace. */static jclassKaffe_FindClass(JNIEnv* env, const char* name){	jstring nameString;	Utf8Const* utf8;	jvalue retval;	BEGIN_EXCEPTION_HANDLING(0);	/* We accepts slashes, but Class.forName() does not */	utf8 = checkPtr(utf8ConstNew(name, -1));	nameString = utf8Const2JavaReplace(utf8, '/', '.');	utf8ConstRelease(utf8);	checkPtr(nameString);	/* Call Class.forName() */	retval = do_execute_java_class_method("java.lang.Class", NULL,	    "forName", "(Ljava/lang/String;)Ljava/lang/Class;", nameString);	ADD_REF(retval.l);	END_EXCEPTION_HANDLING();	return (retval.l);}static jclassKaffe_GetSuperClass(JNIEnv* env, jclass cls){	jclass ret;	BEGIN_EXCEPTION_HANDLING(0);	ret = ((Hjava_lang_Class*)cls)->superclass;	END_EXCEPTION_HANDLING();	return (ret);}static jboolKaffe_IsAssignableFrom(JNIEnv* env, jclass cls1, jclass cls2){	jbool ret;	BEGIN_EXCEPTION_HANDLING(0);	if (instanceof(cls2, cls1) != 0) {		ret = JNI_TRUE;	}	else {		ret = JNI_FALSE;	}	END_EXCEPTION_HANDLING();	return (ret);}static jintKaffe_Throw(JNIEnv* env, jobject obj){	BEGIN_EXCEPTION_HANDLING(0);	if( obj )	{		assert(((Hjava_lang_Object *)obj)->dtable);				thread_data->exceptObj = (struct Hjava_lang_Throwable*)obj;	}	END_EXCEPTION_HANDLING();	return (0);}static jintKaffe_ThrowNew(JNIEnv* env, jclass cls, const char* mess){	Hjava_lang_Object* eobj;	BEGIN_EXCEPTION_HANDLING(0);	eobj = execute_java_constructor(NULL, NULL, cls,					"(Ljava/lang/String;)V",					checkPtr(stringC2Java((char*)mess)));	thread_data->exceptObj = (struct Hjava_lang_Throwable*)eobj;	END_EXCEPTION_HANDLING();	return (0);}static jobjectKaffe_ExceptionOccurred(JNIEnv* env){	jobject obj;	BEGIN_EXCEPTION_HANDLING(0);	obj = thread_data->exceptObj;	ADD_REF(obj);	END_EXCEPTION_HANDLING();	return (obj);}static jbooleanKaffe_ExceptionCheck(JNIEnv* env){	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){	BEGIN_EXCEPTION_HANDLING_VOID();	if (thread_data->exceptObj != 0) {		do_execute_java_method(thread_data->exceptObj, "printStackTrace", "()V",				       0, 0, thread_data->exceptObj); 	}	END_EXCEPTION_HANDLING();}static voidKaffe_ExceptionClear(JNIEnv* env){	BEGIN_EXCEPTION_HANDLING_VOID();	thread_data->exceptObj = 0;	END_EXCEPTION_HANDLING();}static jobjectKaffe_AllocObject(JNIEnv* env, jclass cls){	jobject obj;	Hjava_lang_Class* clazz;	BEGIN_EXCEPTION_HANDLING(0);	clazz = (Hjava_lang_Class*)cls;	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, jclass cls, jmethodID meth, va_list args){	Hjava_lang_Object* obj;	Hjava_lang_Class* clazz;	jvalue retval;	Method* m = (Method*)meth;	BEGIN_EXCEPTION_HANDLING(0);	clazz = (Hjava_lang_Class*)cls;	if (CLASS_IS_INTERFACE(clazz) || CLASS_IS_ABSTRACT(clazz) || !METHOD_IS_CONSTRUCTOR(m)) {		throwException(InstantiationException(clazz->name->data));	}	obj = newObject(clazz);	callMethodV(m, METHOD_INDIRECTMETHOD(m), obj, args, &retval);	ADD_REF(obj);	END_EXCEPTION_HANDLING();	return (obj);}static jobjectKaffe_NewObject(JNIEnv* env, jclass cls, jmethodID meth, ...){	jobject obj;	va_list args;	BEGIN_EXCEPTION_HANDLING(0);	va_start(args, meth);	obj = Kaffe_NewObjectV(env, cls, meth, args);	va_end(args);	END_EXCEPTION_HANDLING();	return (obj);}static jobjectKaffe_NewObjectA(JNIEnv* env, jclass cls, jmethodID meth, jvalue* args){	Hjava_lang_Object* obj;	Hjava_lang_Class* clazz;	jvalue retval;	Method* m = (Method*)meth;	BEGIN_EXCEPTION_HANDLING(0);	clazz = (Hjava_lang_Class*)cls;	if (CLASS_IS_INTERFACE(clazz) || CLASS_IS_ABSTRACT(clazz) || !METHOD_IS_CONSTRUCTOR(m)) {		throwException(InstantiationException(clazz->name->data));	}	obj = newObject(clazz);	callMethodA(m, METHOD_INDIRECTMETHOD(m), obj, args, &retval, 0);	ADD_REF(obj);	END_EXCEPTION_HANDLING();	return (obj);}static jclassKaffe_GetObjectClass(JNIEnv* env, jobject obj){	jclass cls;	BEGIN_EXCEPTION_HANDLING(0);	cls = ((Hjava_lang_Object*)obj)->dtable->class;	END_EXCEPTION_HANDLING();	return (cls);}static jboolKaffe_IsInstanceOf(JNIEnv* env, jobject obj, jclass cls){	jbool ret;	BEGIN_EXCEPTION_HANDLING(0);	if (soft_instanceof((Hjava_lang_Class*)cls, (Hjava_lang_Object*)obj) != 0) {		ret = JNI_TRUE;	}	else {		ret = JNI_FALSE;	}	END_EXCEPTION_HANDLING();	return (ret);}static jmethodIDKaffe_GetMethodID(JNIEnv* env, jclass cls, const char* name, const char* sig){	Method* meth;	errorInfo info;	BEGIN_EXCEPTION_HANDLING(0);	meth = lookupClassMethod((Hjava_lang_Class*)cls, (char*)name, (char*)sig, &info);	if (meth == 0) {		postError(env, &info);	} 	else if (METHOD_IS_STATIC(meth)) {		postExceptionMessage(&info, JAVA_LANG(NoSuchMethodError), "%s", name);		postError(env, &info);		meth = 0;	}	END_EXCEPTION_HANDLING();		return (meth);}static jobjectKaffe_CallObjectMethodV(JNIEnv* env, jobject obj, jmethodID meth, va_list args){	jvalue retval;	Hjava_lang_Object* o = (Hjava_lang_Object*)obj;	Method* m = (Method*)meth;	BEGIN_EXCEPTION_HANDLING(0);	if (METHOD_IS_STATIC(m)) {		throwException(NoSuchMethodError(m->name->data));

⌨️ 快捷键说明

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