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   
C/C++ Source or Header  |  1996-09-28  |  8KB  |  403 lines

  1. /*
  2.  * support.c
  3.  * ...
  4.  *
  5.  * Copyright (c) 1996 Systems Architecture Research Centre,
  6.  *           City University, London, UK.
  7.  *
  8.  * See the file "license.terms" for information on usage and redistribution
  9.  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  10.  *
  11.  * Written by Tim Wilkinson <tim@sarc.city.ac.uk>, July 1996.
  12.  */
  13.  
  14. #include "config.h"
  15. #include <stdio.h>
  16. #include <string.h>
  17. #include <assert.h>
  18. #include <sys/stat.h>
  19. #if defined(HAVE_UNISTD_H)
  20. #include <unistd.h>
  21. #endif
  22. #include "gtypes.h"
  23. #include "constants.h"
  24. #include "file.h"
  25. #include "access.h"
  26. #include "readClassConfig.h"
  27. #include "readClass.h"
  28. #include "zipfile.h"
  29.  
  30. #if !defined(S_ISDIR)
  31. #define    S_ISDIR(m)    ((m) & S_IFDIR)
  32. #endif
  33.  
  34. #if defined(__WIN32__)
  35. #define    PATHSEP    ';'
  36. #else
  37. #define    PATHSEP    ':'
  38. #endif
  39.  
  40. void findClass(char*);
  41.  
  42. extern char realClassPath[];
  43. extern char className[];
  44. extern constants* constant_pool;
  45. extern FILE* include;
  46. extern FILE* stub;
  47.  
  48. extern char* translateSig(char*, char**, int*);
  49. extern char* translateSigType(char*, char*);
  50. extern char* getenv(char*);
  51.  
  52. static int objectDepth = -1;
  53. static int argpos = 0;
  54.  
  55. /*
  56.  * Start stub file.
  57.  */
  58. void
  59. startStub(void)
  60. {
  61.     if (stub != 0) {
  62.         fprintf(stub,"/* DO NOT EDIT THIS FILE - it is machine generated */\n");
  63.         fprintf(stub,"#include <stubPreamble.h>\n");
  64.         fprintf(stub,"/* Stubs for class %s */\n", className);
  65.     }
  66. }
  67.  
  68. /*
  69.  * Start include file.
  70.  */
  71. void
  72. startInclude(void)
  73. {
  74.     argpos = 0;
  75.  
  76.     if (include != 0) {
  77.         fprintf(include, "/* DO NOT EDIT THIS FILE - it is machine generated */\n");
  78.         fprintf(include, "#include <native.h>\n");
  79.         fprintf(include, "/* Header for class %s */\n", className);
  80.         fprintf(include, "\n"); 
  81.         fprintf(include, "#ifndef _Included_%s\n", className);
  82.         fprintf(include, "#define _Included_%s\n", className);
  83.         fprintf(include, "\n"); 
  84.         fprintf(include, "#ifdef __cplusplus\n"); 
  85.         fprintf(include, "extern \"C\" {\n"); 
  86.         fprintf(include, "#endif\n"); 
  87.         fprintf(include, "\n"); 
  88.         fprintf(include, "typedef struct Class%s {\n", className); 
  89.     }
  90. }
  91.  
  92. /*
  93.  * End include file. 
  94.  */
  95. void
  96. endInclude(void)
  97. {
  98.     if (include != 0) {
  99.         fprintf(include, "\n");
  100.         fprintf(include, "#ifdef __cplusplus\n"); 
  101.         fprintf(include, "}\n"); 
  102.         fprintf(include, "#endif\n"); 
  103.         fprintf(include, "\n");
  104.         fprintf(include, "#endif\n");
  105.     }
  106. }
  107.  
  108. /*
  109.  * Add a class.
  110.  */
  111. void
  112. addClass(u2 this, u2 super, u2 access, constants* cpool)
  113. {
  114.     if (super != 0) {
  115.         findClass((char*)cpool->data[cpool->data[super]]);
  116.     }
  117. }
  118.  
  119. /*
  120.  * Finish processing a class's fields.
  121.  */
  122. void
  123. readFieldEnd(void)
  124. {
  125.     if (include != 0) {
  126.         if (objectDepth == 0) {
  127.             if (argpos == 0) {
  128.                 fprintf(include, "\tint __DUMMY__;\n");
  129.             }
  130.             fprintf(include, "} Class%s;\n", className);
  131.             fprintf(include, "HandleTo(%s);\n\n", className);
  132.         }
  133.     }
  134. }
  135.  
  136. /*
  137.  * Read and process a class field.
  138.  */
  139. void
  140. readField(FILE* fp, classes* this, constants* cpool)
  141. {
  142.     field_info f;
  143.     int argsize = 0;
  144.     char* arg;
  145.  
  146.     readu2(&f.access_flags, fp);
  147.     readu2(&f.name_index, fp);
  148.     readu2(&f.signature_index, fp);
  149.  
  150.     if (include != 0) {
  151.  
  152.         /* Ignore statics */
  153.         if (f.access_flags & ACC_STATIC) {
  154.             return;
  155.         }
  156.         arg = translateSig((char*)cpool->data[f.signature_index], 0, &argsize);
  157.         if (argpos % argsize == 1) {
  158.             fprintf(include, "  int __dummy%d;\n", argpos);
  159.             argpos++;
  160.         }
  161.         argpos += argsize;
  162.         fprintf(include, "  %s", translateSig((char*)cpool->data[f.signature_index], 0, &argsize));
  163.         fprintf(include, " %s;\n", (char*)cpool->data[f.name_index]);
  164.     }
  165. }
  166.  
  167. /*
  168.  * Read and process a method.
  169.  */
  170. void
  171. readMethod(FILE* fp, methods* this, constants* cpool)
  172. {
  173.     method_info m;
  174.     char* name;
  175.     char* sig;
  176.     char* str;
  177.     char* ret;
  178.     char* tsig;
  179.     char type;
  180.     int j;
  181.     char rtype;
  182.     int args;
  183.  
  184.     readu2(&m.access_flags, fp);
  185.     readu2(&m.name_index, fp);
  186.     readu2(&m.signature_index, fp);
  187.  
  188.     /* If we shouldn't generate method prototypes, quit now */
  189.     if (objectDepth > 0) {
  190.         return;
  191.     }
  192.  
  193.     /* Only generate stubs for native methods */
  194.     if (!(m.access_flags & ACC_NATIVE)) {
  195.         return;
  196.     }
  197.     args = 0;
  198.  
  199.     /* Generate method prototype */
  200.     name = (char*)cpool->data[m.name_index];
  201.     sig = (char*)cpool->data[m.signature_index];
  202.     ret = strchr(sig,')');
  203.     ret++;
  204.  
  205.     if (include != 0) {
  206.         fprintf(include, "extern %s", translateSig(ret, 0, 0));
  207.         fprintf(include, " %s_%s(", className, name);
  208.         fprintf(include, "struct H%s*", className);
  209.         if (sig[1] != ')') {
  210.             fprintf(include, ", ");
  211.         }
  212.     }
  213.     str = sig + 1;
  214.     args++;
  215.     while (str[0] != ')') {
  216.         tsig = translateSig(str, &str, &args);
  217.         if (include != 0) {
  218.             fprintf(include, "%s", tsig);
  219.             if (str[0] != ')') {
  220.                 fprintf(include, ", ");
  221.             }
  222.         }
  223.     }
  224.     if (include != 0) {
  225.         fprintf(include, ");\n");
  226.     }
  227.  
  228.     if (stub != 0) {
  229.         /* Generate method stub */
  230.         fprintf(stub, "\n/* SYMBOL: %s %s%s */\n", className, name, sig);
  231.         translateSigType(ret, &rtype);
  232.         fprintf(stub, "EXPORT(void)\n");
  233.         fprintf(stub, "Kaffe_%s_%s_stub(stack_item* _P_)\n", className, name);
  234.         fprintf(stub, "{\n");
  235.         fprintf(stub, "\textern %s", translateSig(ret, 0, 0));
  236.         fprintf(stub, " %s_%s(", className, name);
  237.         str = sig + 1;
  238.         fprintf(stub, "void*");
  239.         if (str[0] != ')') {
  240.             fprintf(stub, ", ");
  241.         }
  242.         while (str[0] != ')') {
  243.             tsig = translateSig(str, &str, 0);
  244.             if (strncmp(tsig, "struct H", 8) == 0) {
  245.                 fprintf(stub, "void*");
  246.             }
  247.             else {
  248.                 fprintf(stub, "%s", tsig);
  249.             }
  250.             if (str[0] != ')') {
  251.                 fprintf(stub, ", ");
  252.             }
  253.         }
  254.         fprintf(stub, ");\n");
  255.         fprintf(stub, "\t");
  256.         if (rtype != 'v') {
  257.             fprintf(stub, "%s ret = ", translateSig(ret, 0, 0));
  258.         }
  259.         fprintf(stub, "%s_%s(", className, name);
  260.         str = sig + 1;
  261.         j = args - 1;
  262.         /* Statics have a dummy null argument */
  263.         if (m.access_flags & ACC_STATIC) {
  264.             fprintf(stub, "0");
  265.         }
  266.         else {
  267.             fprintf(stub, "_P_[%d].p", j);
  268.         }
  269.         if (str[0] != ')') {
  270.             fprintf(stub, ", ");
  271.         }
  272.         j--;
  273.         for (; str[0] != ')'; j--) {
  274.             str = translateSigType(str, &type);
  275.             /* This is horrid - but basically just copy */
  276.             /* the data one-for-one.            */
  277.             switch(type) {
  278.             case 'f':
  279.                 fprintf(stub, "_P_[%d].f", j);
  280.                 break;
  281.             case 'd':
  282.                 j--;
  283.                 fprintf(stub, "_P_[%d].d", j);
  284.                 break;
  285.             case 'l':
  286.                 j--;
  287.                 fprintf(stub, "_P_[%d].l", j);
  288.                 break;
  289.             case 'i':
  290.                 fprintf(stub, "_P_[%d].i", j);
  291.                 break;
  292.             case 'p':
  293.                 fprintf(stub, "_P_[%d].p", j);
  294.                 break;
  295.             case 'v':
  296.                 break;
  297.             }
  298.             if (str[0] != ')') {
  299.                 fprintf(stub, ", ");
  300.             }
  301.         }
  302.         fprintf(stub, ");\n");
  303.         switch (rtype) {
  304.         case 'f':
  305.             fprintf(stub, "\treturn_float(ret);\n");
  306.             break;
  307.         case 'd':
  308.             fprintf(stub, "\treturn_double(ret);\n");
  309.             break;
  310.         case 'l':
  311.             fprintf(stub, "\treturn_long(ret);\n");
  312.             break;
  313.         case 'i':
  314.             fprintf(stub, "\treturn_int(ret);\n");
  315.             break;
  316.         case 'p':
  317.             fprintf(stub, "\treturn_ref(ret);\n");
  318.             break;
  319.         case 'v':
  320.             break;
  321.         }
  322.         fprintf(stub, "}\n");
  323.     }
  324. }
  325.  
  326. /*
  327.  * Locate class specified and process it.
  328.  */
  329. void
  330. findClass(char* nm)
  331. {
  332.     FILE* fp;
  333.     ZipFile zipf;
  334.     ZipDirectory* zipd;
  335.     char superName[100];
  336.     struct stat sbuf;
  337.     char* start;
  338.     char* end = (char*)1;
  339.     int j;
  340.  
  341.     /* If classpath isn't set, get it from the environment */
  342.     if (realClassPath[0] == 0) {
  343.         start = getenv("CLASSPATH");
  344.         if (start == 0) {
  345.             fprintf(stderr, "CLASSPATH not set!\n");
  346.             exit(1);
  347.         }
  348.         strcpy(realClassPath, start);
  349.     }
  350.  
  351.     for (start = realClassPath; end != 0; start = end + 1) {
  352.         end = strchr(start, PATHSEP);
  353.         if (end == 0) {
  354.             strcpy(superName, start);
  355.         }
  356.         else {
  357.             strncpy(superName, start, end-start);
  358.             superName[end-start] = 0;
  359.         }
  360.  
  361.         if (stat(superName, &sbuf) < 0) {
  362.             /* Ignore */
  363.         }
  364.         else if (S_ISDIR(sbuf.st_mode)) {
  365.             strcat(superName, "/");
  366.             strcat(superName, nm);
  367.             strcat(superName, ".class");
  368.             fp = fopen(superName, "rb");
  369.             if (fp == 0) {
  370.                 continue;
  371.             }
  372.         }
  373.         else {
  374.             /* Zip file */
  375.             fp = fopen(superName, "rb");
  376.             zipf.fd = fileno(fp);
  377.             if (fp == 0 || read_zip_archive(&zipf) != 0) {
  378.                 continue;
  379.             }
  380.  
  381.             strcpy(superName, nm);
  382.             strcat(superName, ".class");
  383.  
  384.             zipd = (ZipDirectory*)zipf.central_directory;
  385.             for (j = 0; j < zipf.count; j++, zipd = ZIPDIR_NEXT(zipd)) {
  386.                 if (strcmp(superName, ZIPDIR_FILENAME(zipd)) == 0) {
  387.                     fseek(fp, zipd->filestart, SEEK_SET);
  388.                     goto found;
  389.                 }
  390.             }
  391.             continue;
  392.         }
  393.         found:
  394.         objectDepth++;
  395.         readClass(fp);
  396.         objectDepth--;
  397.         fclose(fp);
  398.         return;
  399.     }
  400.     fprintf(stderr, "Failed to open object '%s'\n", nm);
  401.     exit(1);
  402. }
  403.