📄 support.c
字号:
/* * support.c * * Copyright (c) 1996, 1997 * Transvirtual Technologies, Inc. All rights reserved. * * Copyright (c) 2004 * Kaffe.org contributors. See ChangeLog for details. 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-io.h"#include "debug.h"#include "jni_md.h"#include "jsyscall.h"#include "gtypes.h"#include "gc.h"#include "constants.h"#include "file.h"#include "files.h"#include "access.h"#include "classMethod.h"#include "readClass.h"#include "jar.h"#include "kaffeh-support.h"#include "utf8const.h"#if defined(HAVE_SYS_TYPES_H)#include <sys/types.h>#endif /* defined(HAVE_SYS_TYPES_H) */#include <zzip/zzip.h>#if defined(__WIN32__) || defined (__amigaos__)#define PATHSEP ';'#else#define PATHSEP ':'#endifextern char realClassPath[];extern char className[];extern FILE* include;extern FILE* jni_include;extern int flag_jni;static int objectDepth = -1;static int outputField = 1; /* Output object fields? Only skipped on java.lang.Class and java.lang.Object */struct _Collector;static inline intbinary_open(const char *file, int mode, int perm, int *);/* circular list containing all native methods of the class that's currently being processed (sorted by name) */struct _methodRing { struct _methodRing* next; struct _methodRing* prev; const char* name; const char* sig; u2 access_flags; bool needs_mangled_sig;} *methodRing;static int kread(int fd, void *buf, size_t len, ssize_t *out){ *out = read(fd, buf, len); return (*out == -1) ? errno : 0;}/* With Tru64, stat and fstat() are silly macros, convert them to functions. */#if defined(stat)static intkstat (const char *file_name, struct stat *buf){ return stat (file_name, buf);}#else#define kstat stat#endif#if defined(fstat)static intkfstat (int fd, struct stat *buf){ return fstat (fd, buf);}#else#define kfstat fstat#endif/* * We use a very simple 'fake' threads subsystem */SystemCallInterface Kaffe_SystemCallInterface ={ binary_open, kread, close, kfstat, kstat,};/* * Ensure that files are opened in binary mode; the MS-Windows port * depends on this. */static inline intbinary_open(const char *file, int mode, int perm, int *out) { *out = open(file, mode | O_BINARY, perm); return *out == -1 ? errno : 0;}/* * Init include file. */voidinitInclude(void){ if (include == NULL) { return; } fprintf(include, "/* DO NOT EDIT THIS FILE - it is machine generated */\n"); fprintf(include, "#include <native.h>\n"); fprintf(include, "\n"); fprintf(include, "#ifndef _Included_%s\n", className); fprintf(include, "#define _Included_%s\n", className); fprintf(include, "\n"); fprintf(include, "#ifdef __cplusplus\n"); fprintf(include, "extern \"C\" {\n"); fprintf(include, "#endif\n");}/* * Start include file. */voidstartInclude(void){ if (include == NULL) { return; } fprintf(include, "\n"); fprintf(include, "/* Header for class %s */\n", className); fprintf(include, "\n"); if ((strcmp (className, "java_lang_Object") == 0) || (strcmp (className, "java_lang_Class") == 0)) { outputField = 0; } else { outputField = 1; fprintf(include, "typedef struct H%s {\n", className); fprintf(include, " /* Fields from java/lang/Object: */\n"); fprintf(include, " Hjava_lang_Object base;\n"); }}/* * End include file. */voidendInclude(void){ if (include == NULL) { return; } fprintf(include, "\n"); fprintf(include, "#ifdef __cplusplus\n"); fprintf(include, "}\n"); fprintf(include, "#endif\n"); fprintf(include, "\n"); fprintf(include, "#endif\n");}voidinitJniInclude(void){ if (jni_include == NULL) { return; } fprintf(jni_include, "/* DO NOT EDIT THIS FILE - it is machine generated */\n"); fprintf(jni_include, "#include <jni.h>\n"); fprintf(jni_include, "\n"); fprintf(jni_include, "#ifndef _Included_%s\n", className); fprintf(jni_include, "#define _Included_%s\n", className); fprintf(jni_include, "\n"); fprintf(jni_include, "#ifdef __cplusplus\n"); fprintf(jni_include, "extern \"C\" {\n"); fprintf(jni_include, "#endif\n"); fprintf(jni_include, "\n");}voidstartJniInclude(void){}voidendJniInclude(void){ if (jni_include == NULL) { return; } fprintf(jni_include, "\n"); fprintf(jni_include, "#ifdef __cplusplus\n"); fprintf(jni_include, "}\n"); fprintf(jni_include, "#endif\n"); fprintf(jni_include, "\n"); fprintf(jni_include, "#endif\n");}booladdSourceFile(Hjava_lang_Class* c UNUSED, int idx UNUSED, errorInfo *einfo UNUSED){ return true;}booladdInnerClasses(Hjava_lang_Class* c UNUSED, size_t len, classFile* fp, errorInfo *einfo UNUSED){ /* checkBufSize() done in caller. */ seekm(fp, len); return true;}/* * Return the JNI type */static const char *jniType(const char *sig){ switch (sig[0]) { case '[': switch (sig[1]) { case 'Z': return "jbooleanArray"; case 'B': return "jbyteArray"; case 'C': return "jcharArray"; case 'S': return "jshortArray"; case 'I': return "jintArray"; case 'J': return "jlongArray"; case 'F': return "jfloatArray"; case 'D': return "jdoubleArray"; case 'L': case '[': return "jobjectArray"; default: dprintf("bogus array type `%c'", sig[1]); exit(EXIT_FAILURE); } case 'L': if (strncmp(sig, "Ljava/lang/Class;", 17) == 0) return "jclass"; if (strncmp(sig, "Ljava/lang/String;", 18) == 0) return "jstring"; return "jobject"; case 'I': return "jint"; case 'Z': return "jboolean"; case 'S': return "jshort"; case 'B': return "jbyte"; case 'C': return "jchar"; case 'F': return "jfloat"; case 'J': return "jlong"; case 'D': return "jdouble"; case 'V': return "void"; default: dprintf("bogus signature type `%c'", sig[0]); exit(EXIT_FAILURE); }}/* * Print a properly mangled method name or argument signature. */static voidfprintfJni (FILE *f, const char *s) { while (*s != '\0' && *s != ')') { switch (*s) { case '/': fprintf (f, "_"); break; case '_': fprintf (f, "_1"); break; case ';': fprintf (f, "_2"); break; case '[': fprintf (f, "_3"); break; case '$': fprintf (f, "_00024"); break; default: fprintf (f, "%c", *s); break; } s++; }}intstartFields(Hjava_lang_Class* this, u2 fct, errorInfo *einfo UNUSED){ this->fields = malloc(fct * sizeof(Field)); CLASS_NFIELDS(this) = 0; /* incremented by addField() */ return true;}Field*addField(Hjava_lang_Class* this, u2 access_flags, u2 name_index, u2 signature_index, struct _errorInfo* einfo UNUSED){ Field* f; if (CLASS_CONST_TAG(this, name_index) != CONSTANT_Utf8) { dprintf("addField(): no method name.\n"); /* XXX */ return (NULL); } if (CLASS_CONST_TAG(this, signature_index) != CONSTANT_Utf8) { dprintf("addField(): no signature name.\n"); /* XXX */ return (NULL); } DBG(CLASSFILE, dprintf("addField(%s.%s)\n", CLASS_CNAME(this), CLASS_CONST_UTF8(this, name_index)->data); ); f = &(this->fields[CLASS_NFIELDS(this)++]); /* * Store enough info for the field attribute "ConstantValue" handler (setFieldValue) * to print the field name/signature/access. */ f->name = CLASS_CONST_UTF8(this, name_index); f->type = (Hjava_lang_Class*)CLASS_CONST_UTF8(this, signature_index); f->accflags = access_flags; f->bsize = 0; /* not used by kaffeh */ f->info.idx = 0; /* not used by kaffeh */ if (include != NULL) { /* * Non-static fields are represented in the struct. */ if ((!(access_flags & ACC_STATIC) && outputField)) { const char* arg; int argsize = 0; arg = translateSig(CLASS_CONST_UTF8(this, signature_index)->data, NULL, &argsize); fprintf(include, " %s %s;\n", arg, CLASS_CONST_UTF8(this, name_index)->data); } } return f;}static voidconstValueToString(Hjava_lang_Class* this, u2 idx, char *cval){ /* XXX use snprintf() */ /* Pull the constant value for this field out of the constant pool */ switch (CLASS_CONST_TAG(this, idx)) { case CONSTANT_Integer: sprintf(cval, "%dL", (jint)CLASS_CONST_DATA(this, idx)); break; case CONSTANT_Float: { sprintf(cval, "%.7Ef", *(jfloat*)&CLASS_CONST_DATA(this,idx)); break; } case CONSTANT_Long: {#if SIZEOF_VOID_P == 8 sprintf(cval, "%ldLL", (jlong)CLASS_CONST_DATA(this,idx));#else union { jint i[2]; jlong l; } u;#if defined(WORDS_BIGENDIAN) u.i[0] = (jint)CLASS_CONST_DATA(this,idx); u.i[1] = (jint)CLASS_CONST_DATA(this,idx+1);#else u.i[0] = (jint)CLASS_CONST_DATA(this,idx+1); u.i[1] = (jint)CLASS_CONST_DATA(this,idx);#endif sprintf(cval, "%lldLL", u.l);#endif break; } case CONSTANT_Double: { union { jint i[2]; jlong l; jdouble d; } u;#if SIZEOF_VOID_P == 8 u.l = (jlong)CLASS_CONST_DATA(this,idx);#else#if defined(WORDS_BIGENDIAN) u.i[0] = (jint)CLASS_CONST_DATA(this,idx); u.i[1] = (jint)CLASS_CONST_DATA(this,idx+1);#else u.i[0] = (jint)CLASS_CONST_DATA(this,idx+1); u.i[1] = (jint)CLASS_CONST_DATA(this,idx);#endif#endif sprintf(cval, "%.16E", u.d); break; } case CONSTANT_String: /* Note, readConstantPool() puts the Utf8 pointer right into the constant pool for us. */ sprintf(cval, "\"%s\"", CLASS_CONST_UTF8(this, idx)->data); break; default: sprintf(cval, "?unsupported type tag %d?", CLASS_CONST_TAG(this, idx)); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -