From 8db9b6a5f0d565ae2994cefeb081712ce917f67f Mon Sep 17 00:00:00 2001 From: DeaDDooMER Date: Fri, 15 Sep 2017 14:06:50 +0300 Subject: [PATCH] =?utf8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D0=B5?= =?utf8?q?=D0=BD=D0=BE=20=D0=B4=D0=B5=D0=B9=D1=81=D1=82=D0=B2=D0=B8=D0=B5?= =?utf8?q?=20=D0=BA=D0=BE=D0=BD=D1=81=D1=82=D1=80=D1=83=D0=BA=D1=86=D0=B8?= =?utf8?q?=D0=B8=20WITH?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- Test.obn | 14 +++++++++ src/backends/jvm/generator-jvm-abi.c | 5 ++++ src/backends/jvm/generator-jvm.c | 44 ++++++++++++++++++++-------- src/backends/jvm/generator-jvm.h | 4 +++ src/generator.h | 2 ++ src/oberon.c | 40 +++++++++++-------------- 6 files changed, 73 insertions(+), 36 deletions(-) diff --git a/Test.obn b/Test.obn index 6fae529..8aea255 100644 --- a/Test.obn +++ b/Test.obn @@ -1,3 +1,17 @@ MODULE Test; +TYPE + Elem = POINTER TO ElemDesc; + ElemDesc = RECORD END; + + ElemMsg = RECORD END; + CopyMsg = RECORD (ElemMsg) a : Elem; END; + + Alien = POINTER TO RECORD (ElemDesc) END; + +PROCEDURE HandleAlien (VAR msg: ElemMsg); +BEGIN + WITH msg: CopyMsg DO msg.a := NIL END +END HandleAlien; + END Test. diff --git a/src/backends/jvm/generator-jvm-abi.c b/src/backends/jvm/generator-jvm-abi.c index 353ce21..48b3951 100644 --- a/src/backends/jvm/generator-jvm-abi.c +++ b/src/backends/jvm/generator-jvm-abi.c @@ -105,6 +105,11 @@ jvm_generate_load(gen_proc_t * p, gen_var_t * src) gen_error("jvm_generate_load: unknow storage type %i", src -> storage); break; } + + if(src -> typecheck) + { + jvm_generate(p, 1, 1, "checkcast %s", src -> forcetype -> full_name); + } } void diff --git a/src/backends/jvm/generator-jvm.c b/src/backends/jvm/generator-jvm.c index 48db180..91b82bf 100644 --- a/src/backends/jvm/generator-jvm.c +++ b/src/backends/jvm/generator-jvm.c @@ -78,7 +78,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 +587,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 +605,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 -> 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 +777,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 +806,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 +851,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) { @@ -1940,3 +1950,11 @@ 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); +} + diff --git a/src/backends/jvm/generator-jvm.h b/src/backends/jvm/generator-jvm.h index 5e10df4..f769a1e 100644 --- a/src/backends/jvm/generator-jvm.h +++ b/src/backends/jvm/generator-jvm.h @@ -71,6 +71,7 @@ struct gen_type_t bool wide; char prefix; char postfix; + char * full_name; char * desc; int cell_size; }; @@ -82,6 +83,9 @@ struct gen_var_t int reg; int level; + bool typecheck; + gen_type_t * forcetype; + char * name; char * full_name; gen_proc_t * p; diff --git a/src/generator.h b/src/generator.h index 5617e79..2618ec7 100644 --- a/src/generator.h +++ b/src/generator.h @@ -13,6 +13,8 @@ void oberon_generator_destroy_context(oberon_context_t * ctx); void oberon_generator_init_module(oberon_context_t * ctx, oberon_module_t * mod); void oberon_generator_fini_module(oberon_module_t * mod); +void oberon_set_typecheck(oberon_object_t * var, bool enable); + /* * Функции генерации тела модуля */ diff --git a/src/oberon.c b/src/oberon.c index 1b7f5d9..5882324 100644 --- a/src/oberon.c +++ b/src/oberon.c @@ -3322,44 +3322,38 @@ oberon_case_statement(oberon_context_t * ctx) static void oberon_with_guard_do(oberon_context_t * ctx, gen_label_t * end) { - oberon_expr_t * val; - oberon_expr_t * var; - oberon_expr_t * type; + oberon_object_t * var; + oberon_expr_t * var_expr; + oberon_expr_t * type_expr; oberon_expr_t * cond; - oberon_expr_t * cast; + oberon_type_t * type; oberon_type_t * old_type; - gen_var_t * old_var; gen_label_t * this_end; this_end = oberon_generator_reserve_label(ctx); - var = oberon_qualident_expr(ctx); + var_expr = oberon_qualident_expr(ctx); oberon_assert_token(ctx, COLON); - type = oberon_qualident_expr(ctx); - cond = oberon_make_bin_op(ctx, IS, var, type); + type_expr = oberon_qualident_expr(ctx); + cond = oberon_make_bin_op(ctx, IS, var_expr, type_expr); + + var = var_expr -> item.var; + type = type_expr -> result; + old_type = var -> type; oberon_assert_token(ctx, DO); oberon_generate_branch(ctx, cond, false, this_end); - /* Сохраняем ссылку во временной переменной */ - val = oberon_make_temp_var_item(ctx, type -> result); - //cast = oberno_make_record_cast(ctx, var, type -> result); - cast = oberon_cast_expr(ctx, var, type -> result); - oberon_assign(ctx, cast, val); - /* Подменяем тип у оригинальной переменной */ - old_type = var -> item.var -> type; - var -> item.var -> type = type -> result; - /* Подменяем ссылку на переменную */ - old_var = var -> item.var -> gen_var; - var -> item.var -> gen_var = val -> item.var -> gen_var; + var -> type = type; + oberon_set_typecheck(var, true); oberon_statement_seq(ctx); + + var -> type = old_type; + oberon_set_typecheck(var, false); + oberon_generate_goto(ctx, end); oberon_generate_label(ctx, this_end); - - /* Возвращаем исходное состояние */ - var -> item.var -> gen_var = old_var; - var -> item.var -> type = old_type; } static void -- 2.29.2