summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: afdfb61)
raw | patch | inline | side by side (parent: afdfb61)
author | DeaDDooMER <deaddoomer@deadsoftware.ru> | |
Fri, 15 Sep 2017 11:06:50 +0000 (14:06 +0300) | ||
committer | DeaDDooMER <deaddoomer@deadsoftware.ru> | |
Fri, 15 Sep 2017 11:06:50 +0000 (14:06 +0300) |
diff --git a/Test.obn b/Test.obn
index 6fae5299c4ceb508ddf3708622d39e419e562a12..8aea2558a93efbec45e4a9117831ef6c41a9542a 100644 (file)
--- a/Test.obn
+++ b/Test.obn
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.
index 353ce21e88af205130ec950698296c57b013323f..48b3951ac5ea30d296263ee7f14338ee23561b9a 100644 (file)
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
index 48db18000ba1a65e2c651d59f7f0f0afe0482f53..91b82bf8c0465f99626d544d4f787421a15d0e23 100644 (file)
}
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);
}
}
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:
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)
}
}
+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)
{
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
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)
{
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);
+}
+
index 5e10df4be2e1616ad4b801973eb088a1bbb2f091..f769a1e6ce58e6022424ba6fdc05194f4cb527e4 100644 (file)
bool wide;
char prefix;
char postfix;
+ char * full_name;
char * desc;
int cell_size;
};
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 5617e79796ac450128ab6536c7f9c35b7448ad9b..2618ec77e09b856c78a33a094effdc8306c7dd01 100644 (file)
--- a/src/generator.h
+++ b/src/generator.h
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 1b7f5d9b19315aa614ef96e1665f21c11054da9b..58823246bde98fb0e9ebedd171d7fe24e85659c4 100644 (file)
--- a/src/oberon.c
+++ b/src/oberon.c
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