[kaffe] CVS kaffe (guilhem): More JNI splitting

Kaffe CVS cvs-commits at kaffe.org
Sat Jun 26 00:02:31 PDT 2004


PatchSet 4869 
Date: 2004/06/26 05:57:37
Author: guilhem
Branch: HEAD
Tag: (none) 
Log:
More JNI splitting

        * kaffe/kaffevm/jni/jni.c, kaffe/kaffevm/jni/jni_i.h:
        Moved out functions concerning native call handling to jni-native.c
        and jni_native.h.

        * kaffe/kaffevm/jni/jni-native.c, kaffe/kaffevm/jni/jni_native.h:
        New files.

        * kaffe/kaffevm/jni/Makefile.am: Added jni-native.c and jni_native.h.

        * kaffe/kaffevm/jni/Makefile.in: Regenerated.

Members: 
	ChangeLog:1.2435->1.2436 
	kaffe/kaffevm/jni/Makefile.am:1.3->1.4 
	kaffe/kaffevm/jni/Makefile.in:1.4->1.5 
	kaffe/kaffevm/jni/jni-arrays.c:1.1->1.2 
	kaffe/kaffevm/jni/jni-native.c:INITIAL->1.1 
	kaffe/kaffevm/jni/jni.c:1.3->1.4 
	kaffe/kaffevm/jni/jni_i.h:1.2->1.3 
	kaffe/kaffevm/jni/jni_native.h:INITIAL->1.1 

Index: kaffe/ChangeLog
diff -u kaffe/ChangeLog:1.2435 kaffe/ChangeLog:1.2436
--- kaffe/ChangeLog:1.2435	Fri Jun 25 16:04:33 2004
+++ kaffe/ChangeLog	Sat Jun 26 05:57:37 2004
@@ -1,4 +1,17 @@
-2004-06-52  Guilhem Lavaux <guilhem at kaffe.org>
+2004-06-26  Guilhem Lavaux <guilhem at kaffe.org>
+
+	* kaffe/kaffevm/jni/jni.c, kaffe/kaffevm/jni/jni_i.h:
+	Moved out functions concerning native call handling to jni-native.c
+	and jni_native.h.
+
+	* kaffe/kaffevm/jni/jni-native.c, kaffe/kaffevm/jni/jni_native.h:
+	New files.
+
+	* kaffe/kaffevm/jni/Makefile.am: Added jni-native.c and jni_native.h.
+
+	* kaffe/kaffevm/jni/Makefile.in: Regenerated.
+
+2004-06-25  Guilhem Lavaux <guilhem at kaffe.org>
 
 	* kaffe/kaffevm/jni/jni.c, kaffe/kaffevm/jni/jni_funcs.h:
 	Moved out functions concerning Field handling to jni-fields.c.
Index: kaffe/kaffe/kaffevm/jni/Makefile.am
diff -u kaffe/kaffe/kaffevm/jni/Makefile.am:1.3 kaffe/kaffe/kaffevm/jni/Makefile.am:1.4
--- kaffe/kaffe/kaffevm/jni/Makefile.am:1.3	Fri Jun 25 16:04:35 2004
+++ kaffe/kaffe/kaffevm/jni/Makefile.am	Sat Jun 26 05:57:45 2004
@@ -29,9 +29,11 @@
 	jni-base.c \
 	jni-callmethod.c \
 	jni-fields.c \
-	jni-arrays.c
+	jni-arrays.c \
+	jni-native.c
 
 noinst_HEADERS= \
 	jni_i.h \
 	jnirefs.h \
-	jni_funcs.h
+	jni_funcs.h \
+	jni_native.h
Index: kaffe/kaffe/kaffevm/jni/Makefile.in
diff -u kaffe/kaffe/kaffevm/jni/Makefile.in:1.4 kaffe/kaffe/kaffevm/jni/Makefile.in:1.5
--- kaffe/kaffe/kaffevm/jni/Makefile.in:1.4	Fri Jun 25 16:04:35 2004
+++ kaffe/kaffe/kaffevm/jni/Makefile.in	Sat Jun 26 05:57:45 2004
@@ -75,7 +75,7 @@
 LTLIBRARIES = $(noinst_LTLIBRARIES)
 libkaffejni_la_LIBADD =
 am_libkaffejni_la_OBJECTS = jni.lo jni-base.lo jni-callmethod.lo \
-	jni-fields.lo jni-arrays.lo
+	jni-fields.lo jni-arrays.lo jni-native.lo
 libkaffejni_la_OBJECTS = $(am_libkaffejni_la_OBJECTS)
 DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/config -I$(top_builddir)/include/kaffe
 depcomp = $(SHELL) $(top_srcdir)/scripts/depcomp
@@ -83,7 +83,8 @@
 @AMDEP_TRUE at DEP_FILES = ./$(DEPDIR)/jni-arrays.Plo \
 @AMDEP_TRUE@	./$(DEPDIR)/jni-base.Plo \
 @AMDEP_TRUE@	./$(DEPDIR)/jni-callmethod.Plo \
- at AMDEP_TRUE@	./$(DEPDIR)/jni-fields.Plo ./$(DEPDIR)/jni.Plo
+ at AMDEP_TRUE@	./$(DEPDIR)/jni-fields.Plo \
+ at AMDEP_TRUE@	./$(DEPDIR)/jni-native.Plo ./$(DEPDIR)/jni.Plo
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
 	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
 LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) \
@@ -362,12 +363,14 @@
 	jni-base.c \
 	jni-callmethod.c \
 	jni-fields.c \
-	jni-arrays.c
+	jni-arrays.c \
+	jni-native.c
 
 noinst_HEADERS = \
 	jni_i.h \
 	jnirefs.h \
-	jni_funcs.h
+	jni_funcs.h \
+	jni_native.h
 
 all: all-am
 
@@ -424,6 +427,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/jni-base.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/jni-callmethod.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/jni-fields.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/jni-native.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/jni.Plo at am__quote@
 
 .c.o:
Index: kaffe/kaffe/kaffevm/jni/jni-arrays.c
diff -u kaffe/kaffe/kaffevm/jni/jni-arrays.c:1.1 kaffe/kaffe/kaffevm/jni/jni-arrays.c:1.2
--- kaffe/kaffe/kaffevm/jni/jni-arrays.c:1.1	Fri Jun 25 16:04:35 2004
+++ kaffe/kaffe/kaffevm/jni/jni-arrays.c	Sat Jun 26 05:57:45 2004
@@ -20,6 +20,7 @@
 #include "Arrays.h"
 #include "jnirefs.h"
 #include "exception.h"
+#include "object.h"
 
 jobject
 KaffeJNI_GetObjectArrayElement(JNIEnv* env UNUSED, jobjectArray arr, jsize elem)
@@ -55,7 +56,7 @@
 KaffeJNI_NewObjectArray(JNIEnv* env UNUSED, jsize len, jclass cls, jobject init)
 {
 	HArrayOfObject* obj;
-	int i;
+	unsigned int i;
 
 	BEGIN_EXCEPTION_HANDLING(0);
 
===================================================================
Checking out kaffe/kaffe/kaffevm/jni/jni-native.c
RCS:  /home/cvs/kaffe/kaffe/kaffe/kaffevm/jni/jni-native.c,v
VERS: 1.1
***************
--- /dev/null	Sun Aug  4 19:57:58 2002
+++ kaffe/kaffe/kaffevm/jni/jni-native.c	Sat Jun 26 07:02:30 2004
@@ -0,0 +1,597 @@
+/*
+ * jni_native.c
+ * Java Native Interface - Handles native JNI call wrapping.
+ *
+ * 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"
+#include "config-std.h"
+#include "jtypes.h"
+#include "jni_i.h"
+#include "jnirefs.h"
+#include "threadData.h"
+#include "classMethod.h"
+#include "jni_native.h"
+#include "locks.h"
+#include "native.h"
+#include "external.h"
+#if defined(TRANSLATOR)
+#include "machine.h"
+#include "slots.h"
+#include "seq.h"
+#include "constpool.h"
+#include "registers.h"
+#include "labels.h"
+#include "codeproto.h"
+#include "basecode.h"
+#include "icode.h"
+#include "machine.h"
+#if defined(KAFFE_FEEDBACK)
+#include "feedback.h"
+#endif
+#endif
+
+static void
+strcatJNI(char* to, const char* from)
+{
+	char* ptr;
+
+	ptr = &to[strlen(to)];
+	for (; *from != 0; from++) {
+		switch (*from) {
+		case '(':
+			/* Ignore */
+			break;
+		case ')':
+			/* Terminate here */
+			goto end;
+		case '_':
+			*ptr++ = '_';
+			*ptr++ = '1';
+			break;
+		case ';':
+			*ptr++ = '_';
+			*ptr++ = '2';
+			break;
+		case '[':
+			*ptr++ = '_';
+			*ptr++ = '3';
+			break;
+		case '/':
+			*ptr++ = '_';
+			break;
+		default:
+			*ptr++ = *from;
+			break;
+		}
+	}
+
+	end:;
+	*ptr = 0;
+}
+
+#if defined(NEED_JNIREFS)
+static void
+addJNIref(jref obj)
+{
+	jnirefs* table;
+	int idx;
+
+	table = THREAD_DATA()->jnireferences;
+
+	if (table->used == JNIREFS) {
+		abort();	/* FIX ME */
+	}
+
+	idx = table->next;
+	for (;;) {
+		if (table->objects[idx] == 0) {
+			table->objects[idx] = obj;
+			table->used++;
+			table->next = (idx + 1) % JNIREFS;
+			return;
+		}
+		idx = (idx + 1) % JNIREFS;
+	}
+}
+
+static void
+removeJNIref(jref obj)
+{
+	int idx;
+	jnirefs* table;
+
+	table = THREAD_DATA()->jnireferences;
+
+	for (idx = 0; idx < JNIREFS; idx++) {
+		if (table->objects[idx] == obj) {
+			table->objects[idx] = 0;
+			table->used--;
+			return;
+		}
+	}
+}
+#endif /* NEED_JNIREFS */
+
+#if defined(TRANSLATOR)
+
+static void*
+startJNIcall(void)
+{
+	threadData 	*thread_data = THREAD_DATA();
+#if defined(NEED_JNIREFS)
+	jnirefs* table;
+
+	table = gc_malloc(sizeof(jnirefs), &gcNormal);
+	table->prev = thread_data->jnireferences;
+	thread_data->jnireferences = table;
+#endif
+	/* No pending exception when we enter JNI routine */
+	thread_data->exceptObj = 0;
+	return( &thread_data->jniEnv ); 
+}
+
+static void
+finishJNIcall(void)
+{
+	jref eobj;
+	threadData	*thread_data = THREAD_DATA();
+
+#if defined(NEED_JNIREFS)
+	{
+		jnirefs* table;
+
+		table = thread_data->jnireferences;
+		thread_data->jnireferences = table->prev;
+	}
+#endif
+	/* If we have a pending exception, throw it */
+	eobj = thread_data->exceptObj;
+	if (eobj != 0) {
+		thread_data->exceptObj = 0;
+		throwExternalException(eobj);
+	}
+}
+
+/*
+ * Wrap up a native function in a calling wrapper, with JNI or KNI.
+ */
+static void
+Kaffe_wrapper(Method* xmeth, void* func, bool use_JNI)
+{
+	errorInfo info;
+	int count;
+	nativeCodeInfo ncode;
+	SlotInfo* tmp = 0;
+	bool success = true;
+	int j;
+	int an;
+	int iLockRoot;
+
+	isStatic = METHOD_IS_STATIC(xmeth) ? 1 : 0;
+	count = sizeofSigMethod(xmeth, false);
+	count += 1 - isStatic;
+
+#if defined(KAFFE_FEEDBACK)
+	if( kaffe_feedback_file )
+		lockMutex(kaffe_feedback_file);
+#endif
+	/* Construct a wrapper to call the JNI method with the correct
+	 * arguments.
+	 */
+	enterTranslator();
+
+#if defined(KAFFE_PROFILER)
+	if (profFlag) {
+		profiler_get_clicks(xmeth->jitClicks);
+		xmeth->callsCount = 0;
+		xmeth->totalClicks = 0;
+		xmeth->totalChildrenClicks = 0;
+	}
+#endif
+	globalMethod = xmeth;
+
+	maxArgs = maxLocal = count; /* make sure args are spilled if needed */
+	maxStack = 0;
+	success = initInsnSequence(xmeth, 0, maxLocal, maxStack, &info);
+	if (!success) {
+		goto done;
+	}
+
+	start_basic_block();
+	prologue(xmeth);
+
+	if (use_JNI) {
+		/* Start a JNI call */
+		slot_alloctmp(tmp);
+		begin_func_sync();
+		call_soft(startJNIcall);
+		end_func_sync();
+		return_ref(tmp);
+
+#if defined(NEED_JNIREFS)
+		{
+			int j;
+			int jcount;
+
+			/* Make the necesary JNI ref calls first */
+			if (!METHOD_IS_STATIC(xmeth)) {
+				pusharg_ref(local(0), 0);
+				end_sub_block();
+				call_soft(addJNIref);
+				popargs();
+			}
+			j = METHOD_NARGS(xmeth);
+			jcount = count;
+			while (j > 0) {
+				j--;
+				jcount -= sizeofSigChar(*METHOD_ARG_TYPE(xmeth, j));
+				switch (*METHOD_ARG_TYPE(xmeth, j)) {
+				case 'L':
+				case '[':
+					pusharg_ref(local(jcount), 0);
+					end_sub_block();
+					call_soft(addJNIref);
+					popargs();
+				}
+			}
+			start_sub_block();
+		}
+#endif
+	}
+
+	/* Add synchronisation if necessary */
+	if (xmeth->accflags & ACC_SYNCHRONISED) {
+		mon_enter(xmeth, local(0));
+	}
+
+#if defined(PUSHARG_FORWARDS)
+
+	if (use_JNI) {
+		/* Push the JNI info */
+		pusharg_ref(tmp, 0);
+
+		/* If static, push the class, else push the object */
+		if (METHOD_IS_STATIC(xmeth)) {
+			pusharg_ref_const(xmeth->class, 1);
+			an = 0;
+		}
+		else {
+			pusharg_ref(local(0), 1);
+			an = 1;
+		}
+		count = 2;
+	}
+	else {
+		/* If static, nothing, else push the object */
+		if (!METHOD_IS_STATIC(xmeth)) {
+			pusharg_ref(local(0), 0);
+			an = 1;
+		}
+		else {
+			an = 0;
+		}
+		count = an;
+	}
+
+	/* Push the specified arguments */
+	for (j = 0; j < METHOD_NARGS(xmeth); j++) {
+		switch (*METHOD_ARG_TYPE(xmeth, j)) {
+		case 'L':
+		case '[':
+			pusharg_ref(local(an), count);
+			break;
+		case 'I':
+		case 'Z':
+		case 'S':
+		case 'B':
+		case 'C':
+			pusharg_int(local(an), count);
+			break;
+		case 'F':
+			pusharg_float(local(an), count);
+			break;
+		case 'J':
+			pusharg_long(local(an), count);
+			count += pusharg_long_idx_inc - 1;
+			an++;
+			break;
+		case 'D':
+			pusharg_double(local(an), count);
+			count += pusharg_long_idx_inc - 1;
+			an++;
+			break;
+		}
+		count++;
+		an++;
+	}
+
+#else
+	/* TODO: Deal with 64bits where J and D use only one slot.  */
+	/* Push the specified arguments */
+	count = maxArgs;
+	if (use_JNI) {
+		count++;
+		if (isStatic) {
+			count++;
+		}
+	}
+	an = maxArgs;
+
+	for (j = METHOD_NARGS(xmeth); --j >= 0; ) {
+		count--;
+		an--;
+		switch (*METHOD_ARG_TYPE(xmeth, j)) {
+		case 'L':
+		case '[':
+			pusharg_ref(local(an), count);
+			break;
+		case 'I':
+		case 'Z':
+		case 'S':
+		case 'B':
+		case 'C':
+			pusharg_int(local(an), count);
+			break;
+		case 'F':
+			pusharg_float(local(an), count);
+			break;
+		case 'J':
+			count--;
+			an--;
+			pusharg_long(local(an), count);
+			break;
+		case 'D':
+			count--;
+			an--;
+			pusharg_double(local(an), count);
+			break;
+		}
+	}
+
+	if (use_JNI) {
+		/* If static, push the class, else push the object */
+		if (METHOD_IS_STATIC(xmeth)) {
+			pusharg_ref_const(xmeth->class, 1);
+		}
+		else {
+			pusharg_ref(local(0), 1);
+		}
+
+		/* Push the JNI info */
+		pusharg_ref(tmp, 0);
+	}
+	else {
+		/* If static, nothing, else push the object */
+		if (!METHOD_IS_STATIC(xmeth)) {
+			pusharg_ref(local(0), 0);
+		}
+	}
+
+#endif
+
+	/* Make the call */
+	end_sub_block();
+	call_soft(func);
+	popargs();
+
+	if (use_JNI) {
+		slot_freetmp(tmp);
+	}
+	
+	start_sub_block();
+
+	/* Determine return type */
+	switch (*METHOD_RET_TYPE(xmeth)) {
+	case 'L':
+	case '[':
+		slot_alloctmp(tmp);
+		return_ref(tmp);
+		/* Remove synchronisation if necessary */
+		if (xmeth->accflags & ACC_SYNCHRONISED) {
+			mon_exit(xmeth, local(0));
+		}
+		if (use_JNI) {
+			end_sub_block();
+			call_soft(finishJNIcall);
+			start_sub_block();
+		}
+		returnarg_ref(tmp);
+		break;
+	case 'I':
+	case 'Z':
+	case 'S':
+	case 'B':
+	case 'C':
+		slot_alloctmp(tmp);
+		return_int(tmp);
+		/* Remove synchronisation if necessary */
+		if (xmeth->accflags & ACC_SYNCHRONISED) {
+			mon_exit(xmeth, local(0));
+		}
+		if (use_JNI) {
+			end_sub_block();
+			call_soft(finishJNIcall);
+			start_sub_block();
+		}
+		returnarg_int(tmp);
+		break;
+	case 'F':
+		slot_alloctmp(tmp);
+		return_float(tmp);
+		/* Remove synchronisation if necessary */
+		if (xmeth->accflags & ACC_SYNCHRONISED) {
+			mon_exit(xmeth, local(0));
+		}
+		if (use_JNI) {
+			end_sub_block();
+			call_soft(finishJNIcall);
+			start_sub_block();
+		}
+		returnarg_float(tmp);
+		break;
+	case 'J':
+		slot_alloc2tmp(tmp);
+		return_long(tmp);
+		/* Remove synchronisation if necessary */
+		if (xmeth->accflags & ACC_SYNCHRONISED) {
+			mon_exit(xmeth, local(0));
+		}
+		if (use_JNI) {
+			end_sub_block();
+			call_soft(finishJNIcall);
+			start_sub_block();
+		}
+		returnarg_long(tmp);
+		break;
+	case 'D':
+		slot_alloc2tmp(tmp);
+		return_double(tmp);
+		/* Remove synchronisation if necessary */
+		if (xmeth->accflags & ACC_SYNCHRONISED) {
+			mon_exit(xmeth, local(0));
+		}
+		if (use_JNI) {
+			end_sub_block();
+			call_soft(finishJNIcall);
+			start_sub_block();
+		}
+		returnarg_double(tmp);
+		break;
+	case 'V':
+		/* Remove synchronisation if necessary */
+		if (xmeth->accflags & ACC_SYNCHRONISED) {
+			mon_exit(xmeth, local(0));
+		}
+		if (use_JNI)
+			call_soft(finishJNIcall);
+#if defined(ENABLE_JVMPI)
+		softcall_exit_method(globalMethod);
+#endif
+		ret();
+		break;
+	}
+
+	end_function();
+
+	/* Generate the code */
+	if (tmpslot > maxTemp) {
+		maxTemp = tmpslot;
+	}
+	/* The codeinfo argument is only used in linkLabel, and it is 
+	 * only needed if we have labels referring to bytecode.  This is
+	 * not the case here.
+	 */
+	success = finishInsnSequence(0, &ncode, &info);
+	if (!success) {
+		goto done;
+	}
+
+	assert(xmeth->exception_table == 0);
+	installMethodCode(0, xmeth, &ncode);
+
+	if (use_JNI)
+		xmeth->accflags |= ACC_JNI;
+
+done:
+#if defined(TRANSLATOR) && defined(JIT3)
+	resetConstants();
+#endif
+	resetLabels();
+
+#if defined(KAFFE_PROFILER)
+	if (profFlag) {
+		profiler_click_t end;
+
+		profiler_get_clicks(end);
+		xmeth->jitClicks = end - xmeth->jitClicks;
+	}
+#endif
+	globalMethod = 0;
+
+	leaveTranslator();
+#if defined(KAFFE_FEEDBACK)
+	if( kaffe_feedback_file )
+		unlockMutex(kaffe_feedback_file);
+#endif
+	if (!success) {
+		throwError(&info);
+	}
+}
+
+void
+KaffeVM_JNI_wrapper(Method* xmeth, void* func)
+{
+	Kaffe_wrapper(xmeth, func, true);
+}
+
+void
+KaffeVM_KNI_wrapper(Method* xmeth, void* func)
+{
+    	/* to build stackStace, we must be able to lookup this native
+	   method.  So always create a wrapper.  */
+	Kaffe_wrapper(xmeth, func, false);
+}
+#endif
+#if defined(INTERPRETER)
+/*
+ * Wrap up a native function in a calling wrapper.  The interpreter
+ * lets the callMethod[AV] macros functions handle the JNI specifics.
+ */
+void
+KaffeVM_JNI_wrapper(Method* xmeth, void* func)
+{
+	SET_METHOD_NATIVECODE(xmeth, func);
+	xmeth->accflags |= ACC_JNI;
+}
+
+void
+KaffeVM_KNI_wrapper(Method* xmeth, void* func)
+{
+	SET_METHOD_NATIVECODE(xmeth, func);
+}
+#endif /* INTERPRETER */
+
+
+/*
+ * Look up a native function using the JNI interface system.
+ */
+jint
+KaffeVM_JNI_native(Method* meth)
+{
+	char name[1024];
+	void* func;
+
+	/* Build the simple JNI name for the method */
+#if defined(NO_SHARED_LIBRARIES)
+        strcpy(name, "Java_");
+#elif defined(HAVE_DYN_UNDERSCORE)
+	strcpy(name, "_Java_");
+#else
+	strcpy(name, "Java_");
+#endif
+	strcatJNI(name, meth->class->name->data);
+	strcat(name, "_");
+	strcatJNI(name, meth->name->data);
+
+	func = loadNativeLibrarySym(name);
+	if (func == NULL) {
+		/* Try the long signatures */
+		strcat(name, "__");
+		strcatJNI(name, METHOD_SIGD(meth));
+		func = loadNativeLibrarySym(name);
+		if (func == 0) {
+			return (JNI_FALSE);
+		}
+	}
+
+	/* Wrap the function in a calling wrapper */
+	KaffeVM_JNI_wrapper(meth, func);
+
+	return (JNI_TRUE);
+}
Index: kaffe/kaffe/kaffevm/jni/jni.c
diff -u kaffe/kaffe/kaffevm/jni/jni.c:1.3 kaffe/kaffe/kaffevm/jni/jni.c:1.4
--- kaffe/kaffe/kaffevm/jni/jni.c:1.3	Fri Jun 25 16:04:35 2004
+++ kaffe/kaffe/kaffevm/jni/jni.c	Sat Jun 26 05:57:45 2004
@@ -43,13 +43,11 @@
 #include "basecode.h"
 #include "icode.h"
 #include "machine.h"
-#if defined(KAFFE_FEEDBACK)
-#include "feedback.h"
-#endif
 #endif
 #include "jvmpi_kaffe.h"
 #include "jni_i.h"
 #include "jni_funcs.h"
+#include "jni_native.h"
 
 extern int Kaffe_Java_Major_Version;
 extern int Kaffe_Java_Minor_Version;
@@ -57,13 +55,6 @@
 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);
-#endif
-
 static jint Kaffe_GetVersion(JNIEnv*);
 static jclass Kaffe_FindClass(JNIEnv*, const char*);
 static jint Kaffe_ThrowNew(JNIEnv*, jclass, const char*);
@@ -806,7 +797,7 @@
 			if (strcmp(meth[i].name->data, methodArray[j].name) == 0 &&
 			    strcmp(METHOD_SIGD(&meth[i]), methodArray[j].signature) == 0 &&
 			    (meth[i].accflags & ACC_NATIVE) != 0) {
-				Kaffe_JNI_wrapper(&meth[i], methodArray[j].fnPtr); 
+				KaffeVM_JNI_wrapper(&meth[i], methodArray[j].fnPtr); 
 				goto found;
 			}
 		}
@@ -934,566 +925,6 @@
 	default:
 		return (JNI_EVERSION);
 	}
-}
-
-static void
-strcatJNI(char* to, const char* from)
-{
-	char* ptr;
-
-	ptr = &to[strlen(to)];
-	for (; *from != 0; from++) {
-		switch (*from) {
-		case '(':
-			/* Ignore */
-			break;
-		case ')':
-			/* Terminate here */
-			goto end;
-		case '_':
-			*ptr++ = '_';
-			*ptr++ = '1';
-			break;
-		case ';':
-			*ptr++ = '_';
-			*ptr++ = '2';
-			break;
-		case '[':
-			*ptr++ = '_';
-			*ptr++ = '3';
-			break;
-		case '/':
-			*ptr++ = '_';
-			break;
-		default:
-			*ptr++ = *from;
-			break;
-		}
-	}
-
-	end:;
-	*ptr = 0;
-}
-
-#if defined(TRANSLATOR)
-/*
- * Wrap up a native function in a calling wrapper, with JNI or KNI.
- */
-static void
-Kaffe_wrapper(Method* xmeth, void* func, bool use_JNI)
-{
-	errorInfo info;
-	int count;
-	nativeCodeInfo ncode;
-	SlotInfo* tmp = 0;
-	bool success = true;
-	int j;
-	int an;
-	int iLockRoot;
-
-	isStatic = METHOD_IS_STATIC(xmeth) ? 1 : 0;
-	count = sizeofSigMethod(xmeth, false);
-	count += 1 - isStatic;
-
-#if defined(KAFFE_FEEDBACK)
-	if( kaffe_feedback_file )
-		lockMutex(kaffe_feedback_file);
-#endif
-	/* Construct a wrapper to call the JNI method with the correct
-	 * arguments.
-	 */
-	enterTranslator();
-
-#if defined(KAFFE_PROFILER)
-	if (profFlag) {
-		profiler_get_clicks(xmeth->jitClicks);
-		xmeth->callsCount = 0;
-		xmeth->totalClicks = 0;
-		xmeth->totalChildrenClicks = 0;
-	}
-#endif
-	globalMethod = xmeth;
-
-	maxArgs = maxLocal = count; /* make sure args are spilled if needed */
-	maxStack = 0;
-	success = initInsnSequence(xmeth, 0, maxLocal, maxStack, &info);
-	if (!success) {
-		goto done;
-	}
-
-	start_basic_block();
-	prologue(xmeth);
-
-	if (use_JNI) {
-		/* Start a JNI call */
-		slot_alloctmp(tmp);
-		begin_func_sync();
-		call_soft(startJNIcall);
-		end_func_sync();
-		return_ref(tmp);
-
-#if defined(NEED_JNIREFS)
-		{
-			int j;
-			int jcount;
-
-			/* Make the necesary JNI ref calls first */
-			if (!METHOD_IS_STATIC(xmeth)) {
-				pusharg_ref(local(0), 0);
-				end_sub_block();
-				call_soft(addJNIref);
-				popargs();
-			}
-			j = METHOD_NARGS(xmeth);
-			jcount = count;
-			while (j > 0) {
-				j--;
-				jcount -= sizeofSigChar(*METHOD_ARG_TYPE(xmeth, j));
-				switch (*METHOD_ARG_TYPE(xmeth, j)) {
-				case 'L':
-				case '[':
-					pusharg_ref(local(jcount), 0);
-					end_sub_block();
-					call_soft(addJNIref);
-					popargs();
-				}
-			}
-			start_sub_block();
-		}
-#endif
-	}
-
-	/* Add synchronisation if necessary */
-	if (xmeth->accflags & ACC_SYNCHRONISED) {
-		mon_enter(xmeth, local(0));
-	}
-
-#if defined(PUSHARG_FORWARDS)
-
-	if (use_JNI) {
-		/* Push the JNI info */
-		pusharg_ref(tmp, 0);
-
-		/* If static, push the class, else push the object */
-		if (METHOD_IS_STATIC(xmeth)) {
-			pusharg_ref_const(xmeth->class, 1);
-			an = 0;
-		}
-		else {
-			pusharg_ref(local(0), 1);
-			an = 1;
-		}
-		count = 2;
-	}
-	else {
-		/* If static, nothing, else push the object */
-		if (!METHOD_IS_STATIC(xmeth)) {
-			pusharg_ref(local(0), 0);
-			an = 1;
-		}
-		else {
-			an = 0;
-		}
-		count = an;
-	}
-
-	/* Push the specified arguments */
-	for (j = 0; j < METHOD_NARGS(xmeth); j++) {
-		switch (*METHOD_ARG_TYPE(xmeth, j)) {
-		case 'L':
-		case '[':
-			pusharg_ref(local(an), count);
-			break;
-		case 'I':
-		case 'Z':
-		case 'S':
-		case 'B':
-		case 'C':
-			pusharg_int(local(an), count);
-			break;
-		case 'F':
-			pusharg_float(local(an), count);
-			break;
-		case 'J':
-			pusharg_long(local(an), count);
-			count += pusharg_long_idx_inc - 1;
-			an++;
-			break;
-		case 'D':
-			pusharg_double(local(an), count);
-			count += pusharg_long_idx_inc - 1;
-			an++;
-			break;
-		}
-		count++;
-		an++;
-	}
-
-#else
-	/* TODO: Deal with 64bits where J and D use only one slot.  */
-	/* Push the specified arguments */
-	count = maxArgs;
-	if (use_JNI) {
-		count++;
-		if (isStatic) {
-			count++;
-		}
-	}
-	an = maxArgs;
-
-	for (j = METHOD_NARGS(xmeth); --j >= 0; ) {
-		count--;
-		an--;

*** Patch too long, truncated ***




More information about the kaffe mailing list