DEADSOFTWARE

JVM: исправлен конфлик имён локальных и глобальных процедур
[dsw-obn.git] / src / backends / jvm / generator-jvm-basic.c
index d092f8e799aa1d38af2f368cb0d5840026fb1329..2088559c7e7089b6609e4857179125f70cda025e 100644 (file)
@@ -7,7 +7,6 @@
 
 #include <gc.h>
 
-#include "../../../include/oberon.h"
 #include "../../oberon-internals.h"
 #include "generator-jvm.h"
 #include "generator-jvm-basic.h"
@@ -53,10 +52,11 @@ jvm_get_descriptor(oberon_type_t * type)
 
        switch(type -> class)
        {
-               case OBERON_TYPE_VOID:
+               case OBERON_TYPE_NOTYPE:
                        return new_string("V");
                        break;
                case OBERON_TYPE_INTEGER:
+               case OBERON_TYPE_SET:
                        switch(type -> size)
                        {
                                case 1:
@@ -76,6 +76,9 @@ jvm_get_descriptor(oberon_type_t * type)
                                        break;
                        }
                        break;
+               case OBERON_TYPE_SYSTEM_BYTE:
+                       return new_string("B");
+                       break;
                case OBERON_TYPE_REAL:
                        switch(type -> size)
                        {
@@ -90,6 +93,26 @@ jvm_get_descriptor(oberon_type_t * type)
                                        break;
                        }
                        break;
+               case OBERON_TYPE_CHAR:
+                       switch(type -> size)
+                       {
+                               case 1:
+                                       return new_string("B");
+                                       break;
+                               case 2:
+                                       return new_string("C");
+                                       break;
+                               case 4:
+                                       return new_string("I");
+                                       break;
+                               case 8:
+                                       return new_string("J");
+                                       break;
+                               default:
+                                       gen_error("jvm_get_descriptor: unsupported char size %i", type -> size);
+                                       break;
+                       }
+                       break;
                case OBERON_TYPE_BOOLEAN:
                        return new_string("Z");
                        break;
@@ -105,6 +128,29 @@ jvm_get_descriptor(oberon_type_t * type)
                        desc = jvm_get_descriptor(type -> base);
                        return new_string("[%s", desc);
                        break;
+               case OBERON_TYPE_STRING:
+                       switch(type -> size)
+                       {
+                               case 1:
+                                       return new_string("[B");
+                                       break;
+                               case 2:
+                                       return new_string("[C");
+                                       break;
+                               case 4:
+                                       return new_string("[I");
+                                       break;
+                               case 8:
+                                       return new_string("[J");
+                                       break;
+                               default:
+                                       gen_error("jvm_get_descriptor: unsupported string size %i", type -> size);
+                                       break;
+                       }
+                       break;
+               case OBERON_TYPE_SYSTEM_PTR:
+                       return new_string("Ljava/lang/Object;");
+                       break;
                default:
                        gen_error("jvm_get_descriptor: unsupported type class %i", type -> class);
                        break;
@@ -113,29 +159,65 @@ jvm_get_descriptor(oberon_type_t * type)
        return NULL;
 }
 
+char *
+jvm_get_descriptor_safe(oberon_type_t * type)
+{
+       switch(type -> class)
+       {
+               case OBERON_TYPE_POINTER:
+                       return new_string("PTR%s", jvm_get_descriptor_safe(type -> base));
+                       break;
+               case OBERON_TYPE_PROCEDURE:
+               case OBERON_TYPE_RECORD:
+                       return jvm_get_class_full_name(type);
+                       break;
+               case OBERON_TYPE_ARRAY:
+                       return new_string("A%s", jvm_get_descriptor_safe(type -> base));
+                       break;
+               case OBERON_TYPE_SYSTEM_PTR:
+                       return new_string("SYSPTR");
+                       break;
+               default:
+                       return jvm_get_descriptor(type);
+                       break;
+       }
+
+       return NULL;
+}
+
 char
 jvm_get_prefix(oberon_type_t * type)
 {
        int size = type -> size;
        switch(type -> class)
        {
+               case OBERON_TYPE_NOTYPE:
+                       return ' ';
+                       break;
                case OBERON_TYPE_BOOLEAN:
                case OBERON_TYPE_INTEGER:
+               case OBERON_TYPE_CHAR:
+               case OBERON_TYPE_SET:
+               case OBERON_TYPE_SYSTEM_BYTE:
                        return (size <= 4) ? ('i') : ('l');
                        break;
                case OBERON_TYPE_PROCEDURE:
                case OBERON_TYPE_ARRAY:
                case OBERON_TYPE_RECORD:
                case OBERON_TYPE_POINTER:
+               case OBERON_TYPE_STRING:
+               case OBERON_TYPE_NIL:
+               case OBERON_TYPE_SYSTEM_PTR:
                        return 'a';
                        break;
                case OBERON_TYPE_REAL:
                        return (size <= 4) ? ('f') : ('d');
                        break;
+               default:
+                       gen_error("jvm_get_prefix: wat %i", type -> class);
+                       return '!';
+                       break;
        }
-
-       gen_error("jvm_get_prefix: wat");
-       return '!';
 }
 
 char
@@ -144,10 +226,14 @@ jvm_get_postfix(oberon_type_t * type)
        int size = type -> size;
        switch(type -> class)
        {
+               case OBERON_TYPE_NOTYPE:
+                       return ' ';
+                       break;
                case OBERON_TYPE_BOOLEAN:
                        return 'b';
                        break;
                case OBERON_TYPE_INTEGER:
+               case OBERON_TYPE_SET:
                        switch(size)
                        {
                                case 1:
@@ -167,10 +253,36 @@ jvm_get_postfix(oberon_type_t * type)
                                        break;
                        }
                        break;
+               case OBERON_TYPE_SYSTEM_BYTE:
+                       return 'b';
+                       break;
+               case OBERON_TYPE_CHAR:
+                       switch(size)
+                       {
+                               case 1:
+                                       return 'b';
+                                       break;
+                               case 2:
+                                       return 'c';
+                                       break;
+                               case 4:
+                                       return 'i';
+                                       break;
+                               case 8:
+                                       return 'l';
+                                       break;
+                               default:
+                                       gen_error("jvm_get_postfix: char wat");
+                                       break;
+                       }
+                       break;
                case OBERON_TYPE_PROCEDURE:
                case OBERON_TYPE_ARRAY:
                case OBERON_TYPE_RECORD:
                case OBERON_TYPE_POINTER:
+               case OBERON_TYPE_STRING:
+               case OBERON_TYPE_NIL:
+               case OBERON_TYPE_SYSTEM_PTR:
                        return 'a';
                        break;
                case OBERON_TYPE_REAL:
@@ -184,19 +296,77 @@ jvm_get_postfix(oberon_type_t * type)
        return '!';
 }
 
+char *
+jvm_get_name(oberon_object_t * x)
+{
+       switch(x -> class)
+       {
+               case OBERON_CLASS_VAR:
+               case OBERON_CLASS_VAR_PARAM:
+               case OBERON_CLASS_PARAM:
+               case OBERON_CLASS_FIELD:
+                       return new_string(x -> name);
+               case OBERON_CLASS_PROC:
+                       if(x -> parent)
+                       {
+                               return new_string("%s$%s", jvm_get_name(x -> parent), x -> name);
+                       }
+                       else
+                       {
+                               return new_string(x -> name);
+                       }
+               default:
+                       gen_error("jvm_get_name: wat");
+       }
+
+       return NULL;
+}
+
 char *
 jvm_get_field_full_name(oberon_object_t * x)
 {
+       char * parent;
        switch(x -> class)
        {
                case OBERON_CLASS_VAR:
+                       return new_string("%s/%s", x -> module -> name, jvm_get_name(x));
+                       break;
                case OBERON_CLASS_PROC:
-                       return new_string("%s/%s", x -> module -> name, x -> name);
+                       return new_string("%s/%s", x -> module -> name, jvm_get_name(x));
+                       break;
+               case OBERON_CLASS_FIELD:
+                       parent = jvm_get_class_full_name(x -> parent_type);
+                       return new_string("%s/%s", parent, jvm_get_name(x));
+                       break;
+               case OBERON_CLASS_MODULE:
+                       return new_string(x -> module -> name);
+                       break;
+               default:
+                       gen_error("jvm_get_field_full_name: wat");
+                       break;
+       }
+
+       return NULL;
+}
+
+char *
+jvm_get_field_full_name_safe(oberon_object_t * x)
+{
+       switch(x -> class)
+       {
+               case OBERON_CLASS_VAR:
+                       return new_string("%s$%s", x -> module -> name, x -> name);
+                       break;
+               case OBERON_CLASS_PROC:
+                       return new_string("%s$%s", x -> module -> name, jvm_get_name(x));
+                       break;
                case OBERON_CLASS_FIELD:;
                        char * rec_name = jvm_get_class_full_name(x -> parent_type);
-                       return new_string("%s/%s", rec_name, x -> name);
+                       return new_string("%s$%s", rec_name, x -> name);
+                       break;
                case OBERON_CLASS_MODULE:
                        return new_string(x -> module -> name);
+                       break;
                default:
                        gen_error("jvm_get_field_full_name: wat");
                        break;
@@ -213,19 +383,29 @@ jvm_get_class_full_name(oberon_type_t * type)
 
        switch(type -> class)
        {
+               case OBERON_TYPE_POINTER:
+                       name = jvm_get_class_full_name(type -> base);
+                       break;
                case OBERON_TYPE_PROCEDURE:
                        name = new_string("SYSTEM$PROCEDURE");
 
                        char * desc;
-                       desc = jvm_get_descriptor(type -> base);
+                       char * spec;
+                       desc = jvm_get_descriptor_safe(type -> base);
                        name = new_string("%s$%s", name, desc);
 
                        int num = type -> num_decl;
                        oberon_object_t * arg = type -> decl;
+
                        for(int i = 0; i < num; i++)
                        {
-                               desc = jvm_get_descriptor(arg -> type);
-                               name = new_string("%s%s", name, desc);
+                               spec = "";
+                               if(arg -> class == OBERON_CLASS_VAR_PARAM)
+                               {
+                                       spec = "VAR";
+                               }
+                               desc = jvm_get_descriptor_safe(arg -> type);
+                               name = new_string("%s%s%s", name, spec, desc);
                                arg = arg -> next;
                        }
 
@@ -234,6 +414,9 @@ jvm_get_class_full_name(oberon_type_t * type)
                        rec_id = type -> gen_type -> rec_id;
                        name = new_string("%s$RECORD%i", type -> module -> name, rec_id);
                        break;
+               case OBERON_TYPE_SYSTEM_PTR:
+                       name = new_string("java/lang/Object");
+                       break;
                default:
                        gen_error("jvm_get_class_full_name: unk type class %i", type -> class);
                        break;
@@ -242,40 +425,23 @@ jvm_get_class_full_name(oberon_type_t * type)
        return name;
 }
 
-char *
-jvm_get_procedure_signature(oberon_type_t * proc)
-{
-       char * signature;
-       char * desc;
-
-       signature = new_string("(");
-
-       int num = proc -> num_decl;
-       oberon_object_t * arg = proc -> decl;
-       for(int i = 0; i < num; i++)
-       {
-               desc = jvm_get_descriptor(arg -> type);
-               signature = new_string("%s%s", signature, desc);
-               arg = arg -> next;
-       }
-
-       desc = jvm_get_descriptor(proc -> base);
-       signature = new_string("%s)%s", signature, desc);
-
-       return signature;
-}
-
 int
 jvm_cell_size_for_type(oberon_type_t * type)
 {
        if(type -> class == OBERON_TYPE_INTEGER
-               || type -> class == OBERON_TYPE_REAL)
+               || type -> class == OBERON_TYPE_REAL
+               || type -> class == OBERON_TYPE_CHAR
+               || type -> class == OBERON_TYPE_SET)
        {
                if(type -> size > 4)
                {
                        return 2;
                }
        }
+       else if(type -> class == OBERON_TYPE_NOTYPE)
+       {
+               return 0;
+       }
 
        return 1;
 }
@@ -285,6 +451,8 @@ jvm_cell_size_for_postfix(char postfix)
 {
        switch(postfix)
        {
+               case ' ':
+                       return 0;
                case 'a':
                case 'b':
                case 's':
@@ -295,7 +463,7 @@ jvm_cell_size_for_postfix(char postfix)
                case 'd':
                        return 2;
                default:
-                       gen_error("jvm_cell_size_for_postfix: unk postfix %c", postfix);
+                       gen_error("jvm_cell_size_for_postfix: unk postfix %c (%i)", postfix, postfix);
        }
 
        return -666;
@@ -372,6 +540,8 @@ jvm_get_type_of_prefix(char prefix)
 {
        switch(prefix)
        {
+               case ' ':
+                       return 'V';
                case 'b':
                        return 'B';
                case 'c':