📄 support.c
字号:
voidsetFieldValue(Hjava_lang_Class* this, Field* f, u2 idx){ assert(f != NULL); if ((f->accflags & (ACC_STATIC|ACC_FINAL)) == (ACC_STATIC|ACC_FINAL)) { char cval[512]; constValueToString(this, idx, cval); if (cval[0] != '\0') { if (include != NULL) { fprintf(include, "#undef %s_%s\n#define %s_%s %s\n", className, f->name->data, className, f->name->data, cval); } if (jni_include != NULL) { fprintf(jni_include, "#undef %s_%s\n#define %s_%s %s\n", className, f->name->data, className, f->name->data, cval); } } }}voidfinishFields(Hjava_lang_Class* this UNUSED){ if (include == NULL) { return; } if (objectDepth == 0) { if (outputField) { fprintf(include, "} H%s;\n\n", className); } }}intstartMethods(Hjava_lang_Class* this UNUSED, u2 mct UNUSED, errorInfo *einfo UNUSED){ return true;}Method*addMethod(Hjava_lang_Class* this, u2 access_flags, u2 name_index, u2 signature_index, struct _errorInfo* einfo){ constants* cpool; const char* name; const char* sig; struct _methodRing* list; struct _methodRing* i; /* If we shouldn't generate method prototypes, quit now */ if (objectDepth > 0) { /* XXX set einfo */ return NULL; } assert(this != NULL); assert(einfo != NULL); cpool = CLASS_CONSTANTS(this); if (cpool->tags[name_index] != CONSTANT_Utf8) { dprintf("addMethod(): no method name.\n"); /* XXX */ return (NULL); } if (cpool->tags[signature_index] != CONSTANT_Utf8) { dprintf("addMethod(): no signature name.\n"); /* XXX */ return (NULL); } name = WORD2UTF(cpool->data[name_index])->data; sig = WORD2UTF(cpool->data[signature_index])->data; DBG(CLASSFILE, dprintf("addMethod: %s%s%s\n", name, sig, (access_flags & ACC_NATIVE) ? " (native)" : ""); ); /* Only generate stubs for native methods */ if (!(access_flags & ACC_NATIVE)) { /* Return "success"... */ return (Method*)1; } /* add the method into the list of native methods of this class */ list = (struct _methodRing *)malloc (sizeof (struct _methodRing)); list->name = name; list->sig = sig; list->access_flags = access_flags; list->needs_mangled_sig = false; if (methodRing == NULL) { methodRing = list; list->next = list->prev = list; } else { i = methodRing; do { if (!strcmp (list->name, i->name)) { /* iff the names are equal, both need a mangled sig */ list->needs_mangled_sig = true; i->needs_mangled_sig = true; /* insert list */ i->next->prev = list; list->next = i->next; i->next = list; list->prev = i; /* return success */ return (Method*)1; } i = i->next; } while (i != methodRing); /* if we didn't find a suitable place, add it at the end of the list */ i->prev->next = list; list->prev = i->prev; i->prev = list; list->next = i; } return (Method*)1;}voidfinishMethods (Hjava_lang_Class *this UNUSED){ const char *str; const char *tsig; struct _methodRing* i; struct _methodRing* tmp; /* don't do anything if there aren't any methods */ if (methodRing == NULL) { return; } i = methodRing; do { int args = 0; char* ret; /* Generate method prototype */ ret = strchr(i->sig,')'); ret++; if (include != NULL) { fprintf(include, "extern %s", translateSig(ret, 0, 0)); fprintf(include, " %s_%s(", className, i->name); if (!(i->access_flags & ACC_STATIC)) { fprintf(include, "struct H%s*", className); if (i->sig[1] != ')') { fprintf(include, ", "); } } else if (i->sig[1] == ')') { fprintf(include, "void"); } } if (jni_include != NULL) { fprintf(jni_include, "JNIEXPORT %s JNICALL Java_%s_", jniType(ret), className); fprintfJni(jni_include, i->name); /* append mangled sig if necessary */ if (i->needs_mangled_sig) { fprintf(jni_include, "__"); fprintfJni(jni_include, i->sig+1); } fprintf(jni_include, "(JNIEnv*"); if ((i->access_flags & ACC_STATIC)) { fprintf(jni_include, ", jclass"); } else { fprintf(jni_include, ", jobject"); } } str = i->sig + 1; args++; while (str[0] != ')') { if (jni_include != NULL) fprintf(jni_include, ", %s", jniType(str)); tsig = translateSig(str, &str, &args); if (include != NULL) { fprintf(include, "%s", tsig); if (str[0] != ')') { fprintf(include, ", "); } } } if (include != NULL) { fprintf(include, ");\n"); } if (jni_include != NULL) { fprintf(jni_include, ");\n"); } /* move to next method */ tmp = i; i = i->next; /* free old one */ free (tmp); } while (i != methodRing); /* we don't have any methods any more */ methodRing = NULL;}bool addCode(Method* m, size_t len, classFile* fp, errorInfo *einfo UNUSED){ /* Don't try dereferencing m! */ assert(m == (Method*)1); /* checkBufSize() done in caller. */ seekm(fp, len); return true;}booladdLineNumbers(Method* m, size_t len, classFile* fp, errorInfo *info UNUSED){ /* Don't try dereferencing m! */ assert(m == (Method*)1); /* checkBufSize() done in caller. */ seekm(fp, len); return true;}booladdLocalVariables(Method* m, size_t len, classFile* fp, errorInfo *info UNUSED){ /* Don't try dereferencing m! */ assert(m == (Method*)1); /* checkBufSize() done in caller. */ seekm(fp, len); return true;}booladdCheckedExceptions(Method* m, size_t len, classFile* fp, errorInfo *info UNUSED){ /* Don't try dereferencing m! */ assert(m == (Method*)1); /* checkBufSize() done in caller. */ seekm(fp, len); return true;}Hjava_lang_Class*setupClass(Hjava_lang_Class* this, u2 thisidx, u2 super, u2 access_flags, struct Hjava_lang_ClassLoader* loader, errorInfo* einfo UNUSED){ utf8ConstAssign(this->name, CLASS_CONST_UTF8(this, thisidx)); this->accflags = access_flags; this->loader = loader; this->this_index = thisidx; this->state = CSTATE_LOADED; /* XXX */ /* everything else is already zero'd. */ if (super != 0) { kaffeh_findClass(CLASS_CONST_UTF8(this, super)->data); if (include != NULL) { /* Put a blank line between fields for each (super)class. */ fprintf(include, "\n"); } } if (include != NULL) { if (strcmp(CLASS_CNAME(this), "java/lang/Object")) { fprintf(include, " /* Fields from %s: */\n", CLASS_CNAME(this)); } } return this;}voidaddInterfaces(Hjava_lang_Class* this UNUSED, u2 icount UNUSED, Hjava_lang_Class** ifaces UNUSED){}/* * Locate class specified and process it. */voidkaffeh_findClass(const char* nm){ int fd; ZZIP_DIR* jfile; ZZIP_FILE* jentry; char superName[512]; struct stat sbuf; char* start; char* end = (char*)1; errorInfo einfo; /* XXX initialize, and check! */ /* If classpath isn't set, get it from the environment */ if (realClassPath[0] == '\0') { start = getenv("KAFFE_CLASSPATH"); if (start == NULL) { start = getenv("CLASSPATH"); } if (start == NULL) { dprintf("CLASSPATH not set!\n"); exit(EXIT_FAILURE); } strcpy(realClassPath, start); } for (start = realClassPath; end != NULL; start = end + 1) { end = strchr(start, PATHSEP); if (end == NULL) { strcpy(superName, start); } else { strncpy(superName, start, (size_t)(end-start)); superName[end-start] = '\0'; } if (stat(superName, &sbuf) < 0) { /* Ignore */ } else if (S_ISDIR(sbuf.st_mode)) { Hjava_lang_Class tmpClass; classFile hand; unsigned char* buf; strcat(superName, "/"); strcat(superName, nm); strcat(superName, ".class"); fd = open(superName, O_RDONLY|O_BINARY, 0); if (fd < 0) { continue; } if (fstat(fd, &sbuf) < 0) { close(fd); continue; } buf = malloc((size_t) sbuf.st_size); if (buf == 0) { dprintf("kaffeh: Ran out of memory!"); close(fd); exit(EXIT_FAILURE); } /* XXX this is a bit weak. */ if (read(fd, buf, (size_t)sbuf.st_size) != sbuf.st_size) { free(buf); close(fd); continue; } classFileInit(&hand, buf, buf, (size_t)sbuf.st_size, CP_DIR); objectDepth++; /* savepool = constant_pool; */ memset(&tmpClass, 0, sizeof(tmpClass)); readClass(&tmpClass, &hand, NULL, &einfo); /* constant_pool = savepool; */ objectDepth--; hand.type = CP_INVALID; free(buf); close(fd); return; } else { unsigned char *buf; classFile hand; Hjava_lang_Class tmpClass; zzip_size_t length; /* JAR file */ jfile = zzip_opendir(superName); if (jfile == 0) { continue; } strcpy(superName, nm); strcat(superName, ".class"); jentry = zzip_file_open(jfile, superName, 0); if (jentry == 0) { zzip_closedir(jfile); continue; } length = getUncompressedSize(jentry); buf = getDataJarFile(jentry); zzip_file_close(jentry); if (buf == NULL) { zzip_closedir(jfile); continue; } classFileInit(&hand, buf, buf, length, CP_ZIPFILE); objectDepth++; /* savepool = constant_pool; */ memset(&tmpClass, 0, sizeof(tmpClass)); readClass(&tmpClass, &hand, NULL, &einfo); /* constant_pool = savepool; */ objectDepth--; hand.type = CP_INVALID; free(buf); zzip_closedir(jfile); return; } } dprintf("Failed to open object '%s'\n", nm); exit(EXIT_FAILURE);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -