home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Geek Gadgets 1
/
ADE-1.bin
/
ade-dist
/
kaffe-0.5p4-src.tgz
/
tar.out
/
contrib
/
kaffe
/
kaffeh
/
support.c
< prev
Wrap
C/C++ Source or Header
|
1996-09-28
|
8KB
|
403 lines
/*
* support.c
* ...
*
* Copyright (c) 1996 Systems Architecture Research Centre,
* City University, London, UK.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* Written by Tim Wilkinson <tim@sarc.city.ac.uk>, July 1996.
*/
#include "config.h"
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <sys/stat.h>
#if defined(HAVE_UNISTD_H)
#include <unistd.h>
#endif
#include "gtypes.h"
#include "constants.h"
#include "file.h"
#include "access.h"
#include "readClassConfig.h"
#include "readClass.h"
#include "zipfile.h"
#if !defined(S_ISDIR)
#define S_ISDIR(m) ((m) & S_IFDIR)
#endif
#if defined(__WIN32__)
#define PATHSEP ';'
#else
#define PATHSEP ':'
#endif
void findClass(char*);
extern char realClassPath[];
extern char className[];
extern constants* constant_pool;
extern FILE* include;
extern FILE* stub;
extern char* translateSig(char*, char**, int*);
extern char* translateSigType(char*, char*);
extern char* getenv(char*);
static int objectDepth = -1;
static int argpos = 0;
/*
* Start stub file.
*/
void
startStub(void)
{
if (stub != 0) {
fprintf(stub,"/* DO NOT EDIT THIS FILE - it is machine generated */\n");
fprintf(stub,"#include <stubPreamble.h>\n");
fprintf(stub,"/* Stubs for class %s */\n", className);
}
}
/*
* Start include file.
*/
void
startInclude(void)
{
argpos = 0;
if (include != 0) {
fprintf(include, "/* DO NOT EDIT THIS FILE - it is machine generated */\n");
fprintf(include, "#include <native.h>\n");
fprintf(include, "/* Header for class %s */\n", className);
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");
fprintf(include, "\n");
fprintf(include, "typedef struct Class%s {\n", className);
}
}
/*
* End include file.
*/
void
endInclude(void)
{
if (include != 0) {
fprintf(include, "\n");
fprintf(include, "#ifdef __cplusplus\n");
fprintf(include, "}\n");
fprintf(include, "#endif\n");
fprintf(include, "\n");
fprintf(include, "#endif\n");
}
}
/*
* Add a class.
*/
void
addClass(u2 this, u2 super, u2 access, constants* cpool)
{
if (super != 0) {
findClass((char*)cpool->data[cpool->data[super]]);
}
}
/*
* Finish processing a class's fields.
*/
void
readFieldEnd(void)
{
if (include != 0) {
if (objectDepth == 0) {
if (argpos == 0) {
fprintf(include, "\tint __DUMMY__;\n");
}
fprintf(include, "} Class%s;\n", className);
fprintf(include, "HandleTo(%s);\n\n", className);
}
}
}
/*
* Read and process a class field.
*/
void
readField(FILE* fp, classes* this, constants* cpool)
{
field_info f;
int argsize = 0;
char* arg;
readu2(&f.access_flags, fp);
readu2(&f.name_index, fp);
readu2(&f.signature_index, fp);
if (include != 0) {
/* Ignore statics */
if (f.access_flags & ACC_STATIC) {
return;
}
arg = translateSig((char*)cpool->data[f.signature_index], 0, &argsize);
if (argpos % argsize == 1) {
fprintf(include, " int __dummy%d;\n", argpos);
argpos++;
}
argpos += argsize;
fprintf(include, " %s", translateSig((char*)cpool->data[f.signature_index], 0, &argsize));
fprintf(include, " %s;\n", (char*)cpool->data[f.name_index]);
}
}
/*
* Read and process a method.
*/
void
readMethod(FILE* fp, methods* this, constants* cpool)
{
method_info m;
char* name;
char* sig;
char* str;
char* ret;
char* tsig;
char type;
int j;
char rtype;
int args;
readu2(&m.access_flags, fp);
readu2(&m.name_index, fp);
readu2(&m.signature_index, fp);
/* If we shouldn't generate method prototypes, quit now */
if (objectDepth > 0) {
return;
}
/* Only generate stubs for native methods */
if (!(m.access_flags & ACC_NATIVE)) {
return;
}
args = 0;
/* Generate method prototype */
name = (char*)cpool->data[m.name_index];
sig = (char*)cpool->data[m.signature_index];
ret = strchr(sig,')');
ret++;
if (include != 0) {
fprintf(include, "extern %s", translateSig(ret, 0, 0));
fprintf(include, " %s_%s(", className, name);
fprintf(include, "struct H%s*", className);
if (sig[1] != ')') {
fprintf(include, ", ");
}
}
str = sig + 1;
args++;
while (str[0] != ')') {
tsig = translateSig(str, &str, &args);
if (include != 0) {
fprintf(include, "%s", tsig);
if (str[0] != ')') {
fprintf(include, ", ");
}
}
}
if (include != 0) {
fprintf(include, ");\n");
}
if (stub != 0) {
/* Generate method stub */
fprintf(stub, "\n/* SYMBOL: %s %s%s */\n", className, name, sig);
translateSigType(ret, &rtype);
fprintf(stub, "EXPORT(void)\n");
fprintf(stub, "Kaffe_%s_%s_stub(stack_item* _P_)\n", className, name);
fprintf(stub, "{\n");
fprintf(stub, "\textern %s", translateSig(ret, 0, 0));
fprintf(stub, " %s_%s(", className, name);
str = sig + 1;
fprintf(stub, "void*");
if (str[0] != ')') {
fprintf(stub, ", ");
}
while (str[0] != ')') {
tsig = translateSig(str, &str, 0);
if (strncmp(tsig, "struct H", 8) == 0) {
fprintf(stub, "void*");
}
else {
fprintf(stub, "%s", tsig);
}
if (str[0] != ')') {
fprintf(stub, ", ");
}
}
fprintf(stub, ");\n");
fprintf(stub, "\t");
if (rtype != 'v') {
fprintf(stub, "%s ret = ", translateSig(ret, 0, 0));
}
fprintf(stub, "%s_%s(", className, name);
str = sig + 1;
j = args - 1;
/* Statics have a dummy null argument */
if (m.access_flags & ACC_STATIC) {
fprintf(stub, "0");
}
else {
fprintf(stub, "_P_[%d].p", j);
}
if (str[0] != ')') {
fprintf(stub, ", ");
}
j--;
for (; str[0] != ')'; j--) {
str = translateSigType(str, &type);
/* This is horrid - but basically just copy */
/* the data one-for-one. */
switch(type) {
case 'f':
fprintf(stub, "_P_[%d].f", j);
break;
case 'd':
j--;
fprintf(stub, "_P_[%d].d", j);
break;
case 'l':
j--;
fprintf(stub, "_P_[%d].l", j);
break;
case 'i':
fprintf(stub, "_P_[%d].i", j);
break;
case 'p':
fprintf(stub, "_P_[%d].p", j);
break;
case 'v':
break;
}
if (str[0] != ')') {
fprintf(stub, ", ");
}
}
fprintf(stub, ");\n");
switch (rtype) {
case 'f':
fprintf(stub, "\treturn_float(ret);\n");
break;
case 'd':
fprintf(stub, "\treturn_double(ret);\n");
break;
case 'l':
fprintf(stub, "\treturn_long(ret);\n");
break;
case 'i':
fprintf(stub, "\treturn_int(ret);\n");
break;
case 'p':
fprintf(stub, "\treturn_ref(ret);\n");
break;
case 'v':
break;
}
fprintf(stub, "}\n");
}
}
/*
* Locate class specified and process it.
*/
void
findClass(char* nm)
{
FILE* fp;
ZipFile zipf;
ZipDirectory* zipd;
char superName[100];
struct stat sbuf;
char* start;
char* end = (char*)1;
int j;
/* If classpath isn't set, get it from the environment */
if (realClassPath[0] == 0) {
start = getenv("CLASSPATH");
if (start == 0) {
fprintf(stderr, "CLASSPATH not set!\n");
exit(1);
}
strcpy(realClassPath, start);
}
for (start = realClassPath; end != 0; start = end + 1) {
end = strchr(start, PATHSEP);
if (end == 0) {
strcpy(superName, start);
}
else {
strncpy(superName, start, end-start);
superName[end-start] = 0;
}
if (stat(superName, &sbuf) < 0) {
/* Ignore */
}
else if (S_ISDIR(sbuf.st_mode)) {
strcat(superName, "/");
strcat(superName, nm);
strcat(superName, ".class");
fp = fopen(superName, "rb");
if (fp == 0) {
continue;
}
}
else {
/* Zip file */
fp = fopen(superName, "rb");
zipf.fd = fileno(fp);
if (fp == 0 || read_zip_archive(&zipf) != 0) {
continue;
}
strcpy(superName, nm);
strcat(superName, ".class");
zipd = (ZipDirectory*)zipf.central_directory;
for (j = 0; j < zipf.count; j++, zipd = ZIPDIR_NEXT(zipd)) {
if (strcmp(superName, ZIPDIR_FILENAME(zipd)) == 0) {
fseek(fp, zipd->filestart, SEEK_SET);
goto found;
}
}
continue;
}
found:
objectDepth++;
readClass(fp);
objectDepth--;
fclose(fp);
return;
}
fprintf(stderr, "Failed to open object '%s'\n", nm);
exit(1);
}