X-Git-Url: http://deadsoftware.ru/gitweb?p=dsw-obn.git;a=blobdiff_plain;f=src%2Fbackends%2Fjvm%2Fgenerator-jvm.c;h=f26c9513e000ca18cc3203fc0e67155b3111398c;hp=79da2b9f68fac681b5624a512508c7228702eeb1;hb=HEAD;hpb=9ae75f92f805e23b0b151cf8be18a3fe96935c3b diff --git a/src/backends/jvm/generator-jvm.c b/src/backends/jvm/generator-jvm.c index 79da2b9..f26c951 100644 --- a/src/backends/jvm/generator-jvm.c +++ b/src/backends/jvm/generator-jvm.c @@ -9,6 +9,7 @@ #include #include "../../oberon-internals.h" +#include "../../oberon-type-compat.h" #include "../../generator.h" #include "generator-jvm.h" #include "generator-jvm-abi.h" @@ -78,7 +79,7 @@ jvm_generate_hard_cast_type(gen_proc_t * p, oberon_type_t * from, oberon_type_t } else { - jvm_generate(p, 2, 2, "invokestatic java/lang/Double/doubleToRawIntBits(D)J"); + jvm_generate(p, 2, 2, "invokestatic java/lang/Double/doubleToRawLongBits(D)J"); jvm_generate_cast_prefix(p, 'l', postfix); } } @@ -587,6 +588,7 @@ oberon_generator_init_type(oberon_context_t * ctx, oberon_type_t * type) break; case OBERON_TYPE_RECORD: m = type -> module -> gen_mod; + t -> full_name = jvm_get_class_full_name(type); oberon_generate_record_class(c -> dir, m, type); break; case OBERON_TYPE_PROCEDURE: @@ -604,6 +606,14 @@ oberon_generator_init_type(oberon_context_t * ctx, oberon_type_t * type) t -> postfix = jvm_get_postfix(type); } + if((type -> class == OBERON_TYPE_POINTER && type -> base -> class == OBERON_TYPE_RECORD) || + type -> class == OBERON_TYPE_PROCEDURE || + type -> class == OBERON_TYPE_RECORD || + type -> class == OBERON_TYPE_SYSTEM_PTR) + { + t -> full_name = jvm_get_class_full_name(type); + } + t -> cell_size = jvm_cell_size_for_type(type); if(type -> class != OBERON_TYPE_NIL) @@ -768,6 +778,18 @@ oberon_generator_init_var(oberon_context_t * ctx, oberon_object_t * var) } } +static void +oberon_generate_static_initialization(gen_proc_t * p, oberon_object_t * x) +{ + if(x -> type -> class == OBERON_TYPE_ARRAY + || x -> type -> class == OBERON_TYPE_RECORD) + { + jvm_generate_ldst_prepare(p, x -> gen_var); + jvm_generate_new(p, x -> type, 0); + jvm_generate_store(p, x -> gen_var); + } +} + void oberon_generator_init_temp_var(oberon_context_t * ctx, oberon_object_t * var) { @@ -785,6 +807,7 @@ oberon_generator_init_temp_var(oberon_context_t * ctx, oberon_object_t * var) var -> gen_var = jvm_create_function_temp_var(p, t); jvm_generate_var(var -> gen_var); jvm_generate_var_initialization(p, var -> gen_var); + oberon_generate_static_initialization(p, var); } void @@ -829,18 +852,6 @@ oberon_generator_fini_module(oberon_module_t * mod) static void push_expr(gen_proc_t * p, oberon_expr_t * expr); -static void -oberon_generate_static_initialization(gen_proc_t * p, oberon_object_t * x) -{ - if(x -> type -> class == OBERON_TYPE_ARRAY - || x -> type -> class == OBERON_TYPE_RECORD) - { - jvm_generate_ldst_prepare(p, x -> gen_var); - jvm_generate_new(p, x -> type, 0); - jvm_generate_store(p, x -> gen_var); - } -} - void oberon_generate_begin_module(oberon_context_t * ctx) { @@ -1049,6 +1060,7 @@ oberon_generate_begin_proc(oberon_context_t * ctx, oberon_object_t * proc) } name = jvm_get_name(proc); + p -> ret_prefix = jvm_get_prefix(proc -> type -> base); jvm_generate_function_header(p, "public static", name, signature); if(proc -> local) @@ -1087,6 +1099,35 @@ oberon_generate_end_proc(oberon_context_t * ctx) p = m -> class -> p; oberon_generate_trap(ctx, -4); + + if(p -> ret_prefix == ' ') + { + jvm_generate(p, 0, 0, "return"); + } + else + { + int sz = jvm_cell_size_for_postfix(p -> ret_prefix); + switch(p -> ret_prefix) + { + case 'a': + jvm_generate(p, 0, 1, "aconst_null"); + break; + case 'l': + jvm_generate_push_int_size(p, 0, 8); + break; + case 'f': + jvm_generate_push_float(p, 0, 4); + break; + case 'd': + jvm_generate_push_float(p, 0, 8); + break; + default: + jvm_generate_push_int(p, 0); + break; + } + jvm_generate(p, sz, 0, "%creturn", p -> ret_prefix); + } + jvm_generate_function_end(p); } @@ -1351,6 +1392,10 @@ push_item(gen_proc_t * p, oberon_item_t * item) jvm_generate_array_len(p, item -> integer); jvm_generate_cast_prefix(p, 'i', jvm_get_postfix(item -> result)); break; + case MODE_AS: + push_item(p, item -> parent); + jvm_generate_cast_type(p, item -> parent -> result, item -> result); + break; default: gen_error("push_item: unk mode %i", item -> mode); break; @@ -1440,8 +1485,7 @@ jvm_generate_compare_op(gen_proc_t * p, oberon_type_t * t, int op) } else if(prefix == 'a') { - if(t -> class == OBERON_TYPE_STRING - || (t -> class == OBERON_TYPE_POINTER && t -> base -> class == OBERON_TYPE_CHAR)) + if(oberon_is_array_of_char_type(t) || oberon_is_string_type(t)) { jvm_generate(p, 2, 1, "invokestatic SYSTEM/STRCMP([B[B)I"); jvm_generate(p, 1, 0, "if%s L%i", cmpop, label_true); @@ -1936,3 +1980,29 @@ oberon_set_out_directory(oberon_context_t * ctx, const char * path) c -> dir = new_string(path); } + +void +oberon_set_typecheck(oberon_object_t * var, bool enable) +{ + var -> gen_var -> typecheck = enable; + var -> gen_var -> forcetype = (enable) ? (var -> type -> gen_type) : (NULL); +} + +void oberon_set_line(oberon_context_t * ctx, int line) +{ + gen_module_t * m; + gen_proc_t * p; + + m = ctx -> mod -> gen_mod; + if(m != NULL) + { + p = m -> class -> p; + + if(p != NULL) + { + jvm_generate(p, 0, 0, ".line %i", line); + } + + m -> line = line; + } +}