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

📄 external.c

📁 基于LWVCL开发的库
💻 C
字号:
/* * external.c * Handle method calls to other languages. * * Copyright (c) 1996, 1997, 1998, 1999 *	Transvirtual Technologies, Inc.  All rights reserved. * * Copyright (c) 2004, 2007 *      Kaffe.org contributors. See ChangeLogs for details. All rights reserved. * * See the file "license.terms" for information on usage and redistribution  * of this file.  */#include "config.h"#if defined(HAVE_STDARG_H)#include <stdarg.h>#endif /* defined(HAVE_STDARG_H) */#include <stdio.h>#include "debug.h"#include "config-std.h"#include "config-mem.h"#include "config-io.h"#include "gtypes.h"#include "access.h"#include "object.h"#include "constants.h"#include "classMethod.h"#include "slots.h"#include "external.h"#include "errors.h"#include "exception.h"#include "slib.h"#include "support.h"#include "md.h"#include "system.h"#include "jthread.h"#include "jsignal.h"#include "stats.h"#include "locks.h"#if defined(KAFFE_FEEDBACK)#include "feedback.h"#endif#include "jni_i.h"#ifdef __riscos__#include <unixlib/local.h>#endif#ifndef STUB_PREFIX#define STUB_PREFIX ""#define STUB_PREFIX_LEN 0#endif#ifndef STUB_POSTFIX#define STUB_POSTFIX ""#endif#ifndef LIBRARYSUFFIX#define LIBRARYSUFFIX ""#endifstatic struct _libHandle {	LIBRARYHANDLE	desc;	char*		name;	Hjava_lang_ClassLoader*		loader;} libHandle[MAXLIBS];static iStaticLock	libraryLock; /* mutex on all intern operations */static char *libraryPath = NULL;voidinitNative(void){	char lib[MAXLIBPATH];	const char* lpath;	char* nptr;	char* ptr;	unsigned int len;	DBG(INIT, dprintf("initNative()\n"); );	initStaticLock(&libraryLock);	lpath = (const char*)Kaffe_JavaVMArgs.libraryhome;	if (lpath == NULL) {		lpath = getenv(LIBRARYPATH);	}#ifdef __riscos__        __unixify(lpath, 0, lib, MAXLIBPATH, __RISCOSIFY_FILETYPE_NOTSPECIFIED);        lpath = strdup(lib);#endif	len = 0;	if (lpath != NULL) {		len += strlen(lpath);	}#ifdef JNI_LIBRARY_PATH	len += strlen (path_separator);	len += strlen (JNI_LIBRARY_PATH);#endif	/*	 * Build a library path from the given library path.	 */	libraryPath = gc_malloc(len+1, KGC_ALLOC_NATIVELIB);	addToCounter(&ltmem, "vmmem-libltdl", 1, GCSIZEOF(libraryPath));	if (lpath != NULL) {		strcat(libraryPath, lpath);	}#ifdef JNI_LIBRARY_PATH	strcat (libraryPath, path_separator);	strcat (libraryPath, JNI_LIBRARY_PATH);#endif	DBG(INIT, dprintf("got lpath %s and libraryPath %s\n", lpath, libraryPath); );	KaffeLib_Init();	/* Find the default library */	for (ptr = libraryPath; ptr != 0; ptr = nptr) {		nptr = strstr(ptr, path_separator);		if (nptr == 0) {			strcpy(lib, ptr);		}		else if (nptr == ptr) {			nptr += strlen(path_separator);			continue;		}		else {			strncpy(lib, ptr, (size_t)(nptr - ptr));			lib[nptr-ptr] = '\0';			nptr += strlen(path_separator);		}		strcat(lib, "/"); /* should be file_separator, libltdl				     does not handle backslashes yet */		strcat(lib, NATIVELIBRARY);		strcat(lib, LIBRARYSUFFIX);	       	DBG(INIT, dprintf("trying to load %s\n", lib); );		if (loadNativeLibrary(lib, NULL, NULL, 0) >= 0) {			DBG(INIT, dprintf("initNative() done\n"); );			return;		}	}	dprintf("Failed to locate native library \"%s\" in path:\n", lib);	dprintf("\t%s\n", libraryPath);	dprintf("Aborting.\n");	fflush(stderr);	KAFFEVM_EXIT(1);}/* * Get pointer to symbol from symbol name. */staticvoid*loadNativeLibrarySymFromLib(struct _libHandle *lib, const char* name){  void* func = NULL;  lockStaticMutex(&libraryLock);    func = KaffeLib_GetSymbol(lib->desc, name);    DBG(NATIVELIB,  if (func == NULL) {    dprintf("Couldn't find %s in library %s.\nError message is %s.\n",            name,            lib->name,            KaffeLib_GetError());  }  else {    dprintf("Found %s in library %s.\n",            name,            lib->name);  });  unlockStaticMutex(&libraryLock);  return func;}/* * Link in a native library. If successful, returns an index >= 0 that * can be passed to unloadNativeLibrary(). Otherwise, returns -1 and * fills errbuf (if not NULL) with the error message. Assumes synchronization. */intloadNativeLibrary(const char* path, struct Hjava_lang_ClassLoader* loader, char *errbuf, size_t errsiz){	struct _libHandle *lib;	int libIndex;	void *func;	lockStaticMutex(&libraryLock);	/* Find a library handle.  If we find the library has already	 * been loaded, don't bother to get it again, just increase the	 * reference count.	 */	for (libIndex = 0; libIndex < MAXLIBS; libIndex++) {		lib = &libHandle[libIndex];		if (lib->desc == 0) {			goto open;		}		if (strcmp(lib->name, path) != 0)			continue;		if (lib->loader != loader) {			if (errbuf != NULL) {				strncpy(errbuf, "Already loaded\n", errsiz);			}			unlockStaticMutex(&libraryLock);			return -1;		}DBG(NATIVELIB,			dprintf("Native lib %s\n"			    "\tLOAD desc=%p index=%d loader=%p\n",			    lib->name, lib->desc, libIndex, lib->loader);    );		unlockStaticMutex(&libraryLock); 		return libIndex;	}	if (errbuf != 0) {		assert(errsiz > 0);		DBG(NATIVELIB, dprintf("Too many open libraries\n"); );		strncpy(errbuf, "Too many open libraries", errsiz);		errbuf[errsiz - 1] = '\0';	}	unlockStaticMutex(&libraryLock);	return -1;	/* Open the library */	open:       /* if we tested for existence here, libltdl wouldn't be able to look          for system-dependent library names */	{                lib->desc = KaffeLib_Load(path);                if (lib->desc == NULL)				{				const char *err = KaffeLib_GetError();				DBG(NATIVELIB, dprintf("Error loading %s: %s\n", path, err); );				strncpy(errbuf, err, errsiz);							unlockStaticMutex(&libraryLock);				return -1;			}		}        lib->name = gc_malloc(strlen(path)+1, KGC_ALLOC_NATIVELIB);        strcpy (lib->name, path);	lib->loader = loader;	addToCounter(&ltmem, "vmmem-libltdl", 1, GCSIZEOF(lib->name));	unlockStaticMutex(&libraryLock);DBG(NATIVELIB,	dprintf("Native lib %s\n"	    "\tLOAD desc=%p index=%d loader=%p\n",	    lib->name, lib->desc, libIndex, lib->loader);    );#if defined(KAFFE_FEEDBACK)	feedbackLibrary(path, true);#endif         func = loadNativeLibrarySymFromLib(lib, "JNI_OnLoad"); 	if (func != NULL) {	    JavaVM *jvm = KaffeJNI_GetKaffeVM();	    /* Call JNI_OnLoad */	    ((jint(JNICALL *)(JavaVM *, void *))func)(jvm, NULL);	}	return libIndex;}/* * Unlink a native library. Assumes synchronization. * Note that libnative is always at index zero and should * never be unloaded. So index should never equal zero here. */voidunloadNativeLibraries(struct Hjava_lang_ClassLoader* loader){	int libIndex;	lockStaticMutex(&libraryLock);	/* we should never ever unload libraries of the bootstrap loader */	assert (loader != NULL);	for (libIndex = 0; libIndex < MAXLIBS; libIndex++) {		struct _libHandle* lib = &libHandle[libIndex];		if (lib->desc == NULL)			continue;		if (lib->loader != loader)			continue;DBG(NATIVELIB,    dprintf("Native lib %s\n"	    "\tUNLOAD desc=%p index=%d loader=%p\n",	    lib->name, lib->desc, libIndex, lib->loader);    );		KaffeLib_Unload(lib->desc);		KFREE(lib->name);		lib->desc = NULL;	}	unlockStaticMutex(&libraryLock);}/* * Get pointer to symbol from symbol name. */void*loadNativeLibrarySym(const char* name){  int i = 0;  void* func = NULL;  while (!func && i < MAXLIBS && libHandle[i].desc!=NULL) {    func = loadNativeLibrarySymFromLib(&libHandle[i], name);    ++i;  }  return func;}static voidstrcatJNI(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;}/* * Look up a native function using the JNI interface system. */static nativecode*Kaffe_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 != NULL) {		meth->kFlags |= KFLAG_JNI;	}	return (func);}/** * Try to find the native implementation of a java method. * *  */nativecode*native(Method* m, errorInfo *einfo){	char stub[MAXSTUBLEN];	const char* s;	int i;	void* func;	/* Construct the stub name */	strcpy(stub, STUB_PREFIX);	s = m->class->name->data;	for (i = STUB_PREFIX_LEN; *s != 0; s++, i++) {		if (*s == '/') {			stub[i] = '_';		}		else {			stub[i] = *s;		}	}	stub[i] = '_';	stub[i+1] = 0;	strcat(stub, m->name->data);	strcat(stub, STUB_POSTFIX);DBG(NATIVELIB,		dprintf("Method = %s.%s%s\n", m->class->name->data, 		m->name->data, METHOD_SIGD(m));	dprintf("Native stub = '%s'\n", stub);    );	/* Find the native method */	func = loadNativeLibrarySym(stub);	if (func != NULL) {		return (func);	}	/* Try to locate the nature function using the JNI interface */	func = Kaffe_JNI_native(m);        if (func != NULL) {                return (func);        }DBG(NATIVELIB,	dprintf("Failed to locate native function:\n\t%s.%s%s\n",		m->class->name->data, m->name->data, METHOD_SIGD(m));    );	postExceptionMessage(einfo, JAVA_LANG(UnsatisfiedLinkError),		"Failed to locate native function:\t%s.%s%s",		m->class->name->data, m->name->data, METHOD_SIGD(m));	return (NULL);}/* * Return the library path. */char*getLibraryPath(void){	return (libraryPath);}

⌨️ 快捷键说明

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