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

📄 external.c

📁 kaffe Java 解释器语言,源码,Java的子集系统,开放源代码
💻 C
字号:
/* * external.c * Handle method calls to other languages. * * Copyright (c) 1996, 1997, 1998, 1999 *	Transvirtual Technologies, Inc.  All rights reserved. * * Copyright (c) 2004 *      Kaffe.org contributors. See ChangeLogs for details. All rights reserved. * * See the file "license.terms" for information on usage and redistribution  * of this file.  */#if defined(HAVE_STDARG_H)#include <stdarg.h>#endif /* defined(HAVE_STDARG_H) */#include <stdio.h>#include "config.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 "system.h"#include "support.h"#include "md.h"#include "system.h"#include "jthread.h"#include "jsignal.h"#include "stats.h"#define LT_NON_POSIX_NAMESPACE#include "ltdl.h"#include "feedback.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 LIBRARYHANDLE#define LIBRARYHANDLE lt_dlhandle#endif#ifndef LIBRARYINITstatic inline lt_ptr_t kdlmalloc(size_t len) { 	void *ptr = gc_malloc(len, GC_ALLOC_NATIVELIB);	addToCounter(&ltmem, "vmmem-libltdl", 1, GCSIZEOF(ptr));	return (ptr);}static inline lt_ptr_t kdlrealloc(lt_ptr_t ptr0, size_t len) {	jlong len0;	void *ptr;	len0 = (jlong)GCSIZEOF(ptr0);	ptr = gc_realloc(ptr0, len, GC_ALLOC_NATIVELIB);	addToCounter(&ltmem, "vmmem-libltdl", 1, ((jlong)GCSIZEOF(ptr))-len0);	return (ptr);}static inline void kdlfree(lt_ptr_t ptr) { 	addToCounter(&ltmem, "vmmem-libltdl", 1, -((jlong)GCSIZEOF(ptr)));	KFREE(ptr); }#define LIBRARYINIT() ((lt_dlmalloc=kdlmalloc),(lt_dlrealloc=kdlrealloc),(lt_dlfree=kdlfree),lt_dlinit())#endif#ifndef LIBRARYSUFFIX#define LIBRARYSUFFIX ""#endif#ifndef LIBRARYLOAD#define LIBRARYLOAD(desc,filename) ((desc)=lt_dlopenext((filename)))#endif#ifndef LIBRARYUNLOAD#define LIBRARYUNLOAD(desc)		(lt_dlclose(desc))#endif#ifndef LIBRARYERROR#define LIBRARYERROR() lt_dlerror()#endifstatic struct _libHandle {	LIBRARYHANDLE	desc;	char*		name;	int		ref;} libHandle[MAXLIBS];#ifndef LIBRARYFUNCTIONstatic inline lt_ptr_t findLibraryFunction(const char *name) {  int i = 0;  lt_ptr_t ptr = 0;  while (!ptr && libHandle[i].ref && i < MAXLIBS) {    ptr = lt_dlsym(libHandle[i].desc, name);DBG(NATIVELIB,    if (ptr == NULL) {	dprintf("Couldn't find %s in library handle %d == %s.\nError message is %s.\n",		name,		i,		lt_dlgetinfo(libHandle[i].desc) == NULL ? "unknown" : lt_dlgetinfo(libHandle[i].desc)->name,		lt_dlerror());    }    else {	dprintf("Found %s in library handle %d == %s.\n",		name,        	i,        	lt_dlgetinfo(libHandle[i].desc) == NULL ? "unknown" : lt_dlgetinfo(libHandle[i].desc)->name);    })    ++i;  }  return ptr;}#define LIBRARYFUNCTION(ptr,name) ((ptr)=findLibraryFunction(name))#endifstatic char *libraryPath = "";extern jint Kaffe_JNI_native(Method*);extern JavaVM Kaffe_JavaVM;/* * Error stub function.  Point unresolved link errors here to avoid * problems. */staticvoid*error_stub(void){	return (0);}voidinitNative(void){	char lib[MAXLIBPATH];	char* lpath;	char* nptr;	char* ptr;	int len;	DBG(INIT, dprintf("initNative()\n"); )	lpath = (char*)Kaffe_JavaVMArgs[0].libraryhome;	if (lpath == 0) {		lpath = getenv(LIBRARYPATH);	}#ifdef __riscos__        __unixify(lpath, 0, lib, MAXLIBPATH, __RISCOSIFY_FILETYPE_NOTSPECIFIED);        lpath = strdup(lib);#endif	len = 0;	if (lpath != 0) {		len += strlen(lpath);	}	/*	 * Build a library path from the given library path.	 */	libraryPath = gc_malloc(len+1, GC_ALLOC_NATIVELIB);	addToCounter(&ltmem, "vmmem-libltdl", 1, GCSIZEOF(libraryPath));	if (lpath != 0) {		strcat(libraryPath, lpath);	}	DBG(INIT, dprintf("got lpath %s and libraryPath %s\n", lpath, libraryPath); )	LIBRARYINIT();	/* 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, 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);		if (loadNativeLibrary(lib, NULL, 0) >= 0) {			DBG(INIT, dprintf("initNative() done\n"); )			return;		}	}	dprintf("Failed to locate native library \"%s\" in path:\n", NATIVELIBRARY);	dprintf("\t%s\n", libraryPath);	dprintf("Aborting.\n");	fflush(stderr);	EXIT(1);}intloadNativeLibrary(char* lib, char *errbuf, size_t errsiz){	int retval;	retval = loadNativeLibrary2(lib, 1, errbuf, errsiz);	return( retval );}/* * 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. */intloadNativeLibrary2(char* path, int default_refs, char *errbuf, size_t errsiz){	struct _libHandle *lib;	int index;	void *func;	/* 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 (index = 0; index < MAXLIBS; index++) {		lib = &libHandle[index];		if (lib->desc == 0) {			goto open;		}		if (strcmp(lib->name, path) == 0) {			lib->ref++;DBG(NATIVELIB,			dprintf("Native lib %s\n"			    "\tLOAD desc=%p index=%d ++ref=%d\n",			    lib->name, lib->desc, index, lib->ref);    )			return index;		}	}	if (errbuf != 0) {		assert(errsiz > 0);		strncpy(errbuf, "Too many open libraries", errsiz);		errbuf[errsiz - 1] = '\0';	}	return -1;	/* Open the library */	open:#if 0	/* If this file doesn't exist, ignore it */	if (access(path, R_OK) != 0) {		if (errbuf != 0) {			assert(errsiz > 0);			strncpy(errbuf, SYS_ERROR(errno), errsiz);			errbuf[errsiz - 1] = '\0';		}		return -1;	}#endif/* if we tested for existence here, libltdl wouldn't be able to look   for system-dependent library names */	blockAsyncSignals();	{                LIBRARYLOAD(lib->desc, path);                if (lib->desc == 0)				{				const char *err = LIBRARYERROR();								/* XXX Bleh, silly guessing system. */				if( err == 0 )				{					if (errbuf != 0)						strncpy(errbuf,							"Unknown error",							errsiz);				}				else if( (strstr(err, "ile not found") ||					  strstr(err, "annot open")) )				{                                char *last_sep = strrchr (path, file_separator[0]);#ifdef HAVE_SNPRINTF                                snprintf (errbuf, errsiz, "%s: not found",                                          last_sep==NULL?path:last_sep+1);#else                                /* possible buffer overflow problem */                                if(errbuf != 0)                                    sprintf (errbuf, "%s: not found",                                          last_sep==NULL?path:last_sep+1);#endif				}				else				{					/* We'll assume its a real error. */					if (errbuf != 0)						strncpy(errbuf, err, errsiz);				}			}		}	unblockAsyncSignals();	if (lib->desc == 0) {		return -1;	}        lib->name = gc_malloc(strlen(path)+1, GC_ALLOC_NATIVELIB);        strcpy (lib->name, path);	lib->ref = default_refs;	addToCounter(&ltmem, "vmmem-libltdl", 1, GCSIZEOF(lib->name));DBG(NATIVELIB,	dprintf("Native lib %s\n"	    "\tLOAD desc=%p index=%d ++ref=%d\n",	    lib->name, lib->desc, index, lib->ref);    )#if defined(KAFFE_FEEDBACK)	feedbackLibrary(path, true);#endif         func = loadNativeLibrarySym("JNI_OnLoad"); 	if (func != NULL) {	    JavaVM *jvm = &Kaffe_JavaVM;	    /* Call JNI_OnLoad */	    ((jint(JNICALL *)(JavaVM *, void *))func)(jvm, NULL);	}	return index;}/* * 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. */voidunloadNativeLibrary(int index){	struct _libHandle *lib;	assert(index > 0 && index < MAXLIBS);	lib = &libHandle[index];DBG(NATIVELIB,	dprintf("Native lib %s\n"	    "\tUNLOAD desc=%p index=%d --ref=%d\n",	    lib->name, lib->desc, index, lib->ref - 1);    )	assert(lib->desc != 0);	assert(lib->ref > 0);	if (--lib->ref == 0) {		blockAsyncSignals();		LIBRARYUNLOAD(lib->desc);		unblockAsyncSignals();		KFREE(lib->name);		lib->desc = 0;	}}/* * Get pointer to symbol from symbol name. */void*loadNativeLibrarySym(char* name){	void* func;	blockAsyncSignals();	LIBRARYFUNCTION(func, name);	unblockAsyncSignals();	return (func);}boolnative(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 != 0) {		/* Fill it in */		extern void Kaffe_KNI_wrapper(Method* xmeth, void* func);		Kaffe_KNI_wrapper(m, func);		return (true);	}	/* Try to locate the nature function using the JNI interface */        if (Kaffe_JNI_native(m)) {                return (true);        }DBG(NATIVELIB,	dprintf("Failed to locate native function:\n\t%s.%s%s\n",		m->class->name->data, m->name->data, METHOD_SIGD(m));    )#if defined(TRANSLATOR)	{		/* Work around for KFREE() ? : bug in gcc 2.7.2 */		void *nc = METHOD_NATIVECODE(m);		KFREE(nc);	}#endif	SET_METHOD_NATIVECODE(m, (void*)error_stub);	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 (false);}/* * Return the library path. */char*getLibraryPath(void){	return (libraryPath);}

⌨️ 快捷键说明

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