#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;
}
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;
-- размеры типов не вычисляются (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
- нету счёта строк / столбцов
- любая ошибка фатальна
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)
{
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");
}
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
""
"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);"