summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: c4d4a26)
raw | patch | inline | side by side (parent: c4d4a26)
author | DeaDDooMER <deaddoomer@deadsoftware.ru> | |
Mon, 24 Jul 2017 20:04:11 +0000 (23:04 +0300) | ||
committer | DeaDDooMER <deaddoomer@deadsoftware.ru> | |
Mon, 24 Jul 2017 20:04:11 +0000 (23:04 +0300) |
generator.c | patch | blob | history | |
notes | patch | blob | history | |
oberon.c | patch | blob | history | |
oberon.h | patch | blob | history | |
test.c | patch | blob | history |
diff --git a/generator.c b/generator.c
index 94bc1696a8f54f281e8868cfa02d7a51f1800cb0..179320aef7df8ffb4cf1aa4a6ecc3b4df4250f17 100644 (file)
--- a/generator.c
+++ b/generator.c
#include <ctype.h>
#include <string.h>
#include <assert.h>
+#include <stdbool.h>
#include <gc.h>
{
void * p = GC_MALLOC(bytes);
memset(p, 0, bytes);
+ printf("allocated %lu bytes\n", bytes);
return p;
}
@@ -323,10 +325,50 @@ static gcc_jit_rvalue * rvalue_from_item(oberon_context_t * ctx, oberon_item_t *
static gcc_jit_rvalue * rvalue_from_expr(oberon_context_t * ctx, oberon_expr_t * expr);
static int
-oberon_generator_get_type_size(oberon_type_t * type)
+oberon_generator_get_type_size(oberon_context_t * ctx, oberon_type_t * type)
{
- printf("TODO: oberon_generator_get_type_size\n");
- return 128;
+ int size = 0;
+ switch(type -> class)
+ {
+ case OBERON_TYPE_INTEGER:
+ size = type -> size;
+ printf("int size: %i\n", size);
+ break;
+ case OBERON_TYPE_BOOLEAN:
+ size = sizeof(bool);
+ printf("bool size: %i\n", size);
+ break;
+ case OBERON_TYPE_PROCEDURE:
+ case OBERON_TYPE_POINTER:
+ size = sizeof(void*);
+ printf("ptr size: %i\n", size);
+ break;
+ case OBERON_TYPE_ARRAY:
+ size = type -> size;
+ type = type -> base;
+ size *= oberon_generator_get_type_size(ctx, type);
+ printf("array size: %i\n", size);
+ break;
+ case OBERON_TYPE_RECORD:
+ {
+ int num = type -> num_decl;
+ oberon_object_t * arg = type -> decl;
+ for(int i = 0; i < num; i++)
+ {
+ oberon_type_t * x;
+ x = arg -> type;
+ size += oberon_generator_get_type_size(ctx, x);
+ arg = arg -> next;
+ }
+ }
+ printf("struct size: %i\n", size);
+ break;
+ default:
+ oberon_error(ctx, "oberon_generator_get_type_size: wat");
+ break;
+ }
+
+ return size;
}
void
gcc_jit_type * type = gcc_jit_context_get_type(gcc_context, GCC_JIT_TYPE_VOID_PTR);
right = gcc_jit_context_null(gcc_context, type);
}
- else if(item -> mode == MODE_NEWARR)
+ else if(item -> mode == MODE_NEW)
{
- int type_size = oberon_generator_get_type_size(item -> type);
+ assert(item -> result -> class == OBERON_TYPE_POINTER);
+
+ oberon_type_t * type = item -> result -> base;
+ int type_size = oberon_generator_get_type_size(ctx, type);
int array_size = type_size;
int num = item -> num_args;
index 977d7cd3e9966f7e5280050849215b3eae712114..d8331b14584b22f479cb511a9a1c786bcab1f6e8 100644 (file)
--- a/notes
+++ b/notes
-- размеры типов не вычисляются (oberon_generator_get_type_size)
- в libgccjit нет средств получения размера типов, в т.ч. структур
- Придётся гадать.
-- процедура NEW создаёт массивы только статической размерности (и не создаёт структуры).
+- нету типа real, оператор / должен возвращать дробный результат
- нету открытых массивов
+- нет символов и строк
- нету операторов if, while и т.д.
-- нет символов и строк
- импортируемые модули не инициализируются (секция begin)
-- нету типа real, оператор / должен возвращать дробный результат
- нету типа set
- не реализована свёртка констант
- не протестированы типы разнных размеров
+- не реализовано расширение типа record:
+ libgccjit не умеет в классы. Проверки в рантайме надо делать вручную.
+- нет проверок границ массивов в рантайме:
+ Потому что как минимум нет дескрипторов типа.
+ Возможно можно заюзать это:
+ https://gcc.gnu.org/onlinedocs/gcc/Pointer-Bounds-Checker-builtins.html
+- При вычислении размера структур не учитывается вравнивание.
+ в libgccjit нет средств получения размера типов, в т.ч. структур
+ Как происходит выравнивание и есть ли оно вообще по дефолту - не понятно:
+ Нужно ли для получения выровненных структур использовать gcc_jit_type_get_aligned?
+ Пересекается с этим:
+ https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html
+ Требуемые выравнивания для типов можно получить через встроинную функцию __alignof__(T)
+ https://gcc.gnu.org/onlinedocs/gcc/Alignment.html
+ Возможный алгоритм выравнивания:
+ https://stackoverflow.com/questions/6963998/how-does-gcc-calculate-the-required-space-for-a-structure
+ http://www.rendoc.tech/questions/834444/how-does-gcc-calculate-the-required-space-for-a-structure
+ Есть ещё что-то для проверки границ объектов:
+ https://gcc.gnu.org/onlinedocs/gcc/Object-Size-Checking.html
+- не понятен результат присваивания статических/разыменованных структур и массивов
+ (* reca := recb; *) - побайтовое копирование?
- не реализовано присваивание процедур к переменным-процедурам:
в libgccjit нет средств получения указателя на функцию.
Как решение-костыль - получение указателя в основной программе и сохранение в переменной.
-- не реализовано расширение типа record:
- libgccjit не умеет в классы. Проверки в рантайме надо делать вручную.
- не реализован автокаст:
Не критично: libgccjit сам разруливает типы разных размеров.
- не реализованы локальные процедуры:
libgccjit не умеет в локальные функции.
Обойти можно костылём как в jvm.
-- не понятен результат присваивания статических/разыменованных структур (* reca := recb; *)
-- не понятен результат присваивания статических/разыменованных массивов (* arr1 := arr2; *)
+- нет проверок переполнения как в рантайме, так и в компилтайме.
+ Возможно можно заюзать это:
+ https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html
- нету счёта строк / столбцов
- любая ошибка фатальна
diff --git a/oberon.c b/oberon.c
index 931d948c57bc15c0faf906e0a6f23b52f991a122..dab60b0bb151dce64579a099f2aa59f5722a2eb6 100644 (file)
--- a/oberon.c
+++ b/oberon.c
@@ -2602,16 +2602,19 @@ oberon_make_new_call(oberon_context_t * ctx, int num_args, oberon_expr_t * list_
type = type -> base;
oberon_expr_t * src;
+ src = oberon_new_item(MODE_NEW, dst -> result, 0);
+ src -> item.num_args = 0;
+ src -> item.args = NULL;
+
if(type -> class == OBERON_TYPE_ARRAY)
{
+ // Пригодится при работе с открытыми массивами
+ /*
int dim = 1;
-
oberon_expr_t * sizes = NULL;
oberon_expr_t * last_size = NULL;
-
sizes = last_size = oberon_new_item(MODE_INTEGER, ctx -> int_type, 1);
sizes -> item.integer = type -> size;
-
oberon_type_t * base = type -> base;
while(base -> class == OBERON_TYPE_ARRAY)
{
@@ -2624,13 +2627,12 @@ oberon_make_new_call(oberon_context_t * ctx, int num_args, oberon_expr_t * list_
base = base -> base;
dim += 1;
}
+ */
- src = oberon_new_item(MODE_NEWARR, dst -> result, 0);
- src -> item.num_args = dim;
- src -> item.args = sizes;
- src -> item.type = base;
+ src -> item.num_args = 0;
+ src -> item.args = NULL;
}
- else
+ else if(type -> class != OBERON_TYPE_RECORD)
{
oberon_error(ctx, "oberon_make_new_call: wat");
}
diff --git a/oberon.h b/oberon.h
index 4b785453befda47bbdcfe1ccf9c7b9a67ccfd1cc..53693a79629e8b772c38497cfc0c00046891cbed 100644 (file)
--- a/oberon.h
+++ b/oberon.h
MODE_FIELD,
MODE_DEREF,
MODE_NIL,
- MODE_NEWARR
+ MODE_NEW
};
enum
int num_args;
oberon_expr_t * args;
- oberon_type_t * type;
};
struct oberon_oper_s
index fc0033339d03fff36dbd6f52ba6989c3df777c0c..1f440779e411b51f514c9409fddf97b033019685 100644 (file)
--- a/test.c
+++ b/test.c
""
"VAR"
" nx- : INTEGER;"
- " p : POINTER TO ARRAY 3 OF INTEGER;"
+ " p : POINTER TO ARRAY 3 OF RECORD i, j, k : INTEGER END;"
+ " q : POINTER TO RECORD x, y, z : INTEGER END;"
""
"PROCEDURE ChParam(VAR i : INTEGER);"
"BEGIN"
""
"BEGIN;"
" NEW(p);"
- " p[0] := 1;"
+ " p[2].k := 1;"
+ " NEW(q);"
" "
" Out.Open;"
" ChParam(nx);"