lccrt/lib/irv/lccrt_module.c

453 lines
13 KiB
C
Raw Normal View History

/**
* Part of the Lccrt Project, under the Apache License v2.0
* See http://www.apache.org/licenses/LICENSE-2.0.txt for license information.
* SPDX-License-Identifier: Apache-2.0
*
* lccrt_module.c - реализация пользовательский интерфейс (динамической) компиляции.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdarg.h>
#include "lccrt_real.h"
/**
* Инициализация контекста (стандартные типы).
*/
static void
lccrt_module_init_types_std( lccrt_module_ptr m)
{
lccrt_types_std_t *ts = &(m->types_std);
lccrt_check_type_assert( m, lccrt_module_t);
ts->ptr_bytesize = m->is_ptr32 ? 4 : 8;
ts->bool_type = lccrt_type_make_simple( m, LCCRT_TYPE_BOOL, "bool", 0, 1, 1);
//ts->bool_type = lccrt_type_make_simple( m, LCCRT_TYPE_INT, "u8", 0, 1);
ts->void_type = lccrt_type_make_simple( m, LCCRT_TYPE_VOID, "void", 0, 1, 0);
ts->int_types[0][0] = lccrt_type_make_simple( m, LCCRT_TYPE_INT, "u8", 0, 1, 1);
ts->int_types[0][1] = lccrt_type_make_simple( m, LCCRT_TYPE_INT, "u16", 0, 2, 2);
ts->int_types[0][2] = lccrt_type_make_simple( m, LCCRT_TYPE_INT, "u32", 0, 4, 4);
ts->int_types[0][3] = lccrt_type_make_simple( m, LCCRT_TYPE_INT, "u64", 0, 8, 8);
ts->int_types[0][4] = lccrt_type_make_simple( m, LCCRT_TYPE_INT, "u128", 0, 16, 16);
ts->int_types[0][5] = 0;
ts->int_types[1][0] = lccrt_type_make_simple( m, LCCRT_TYPE_INT, "i8", 1, 1, 1);
ts->int_types[1][1] = lccrt_type_make_simple( m, LCCRT_TYPE_INT, "i16", 1, 2, 2);
ts->int_types[1][2] = lccrt_type_make_simple( m, LCCRT_TYPE_INT, "i32", 1, 4, 4);
ts->int_types[1][3] = lccrt_type_make_simple( m, LCCRT_TYPE_INT, "i64", 1, 8, 8);
ts->int_types[1][4] = lccrt_type_make_simple( m, LCCRT_TYPE_INT, "i128", 1, 16, 16);
ts->int_types[1][5] = 0;
ts->float_types[0] = lccrt_type_make_simple( m, LCCRT_TYPE_FLOAT, "f32", 0, 4, 4);
ts->float_types[1] = lccrt_type_make_simple( m, LCCRT_TYPE_FLOAT, "f64", 0, 8, 8);
ts->float_types[2] = lccrt_type_make_simple( m, LCCRT_TYPE_FLOAT, "f80", 0, 16, 10);
ts->float_types[3] = lccrt_type_make_simple( m, LCCRT_TYPE_FLOAT, "f128", 0, 16, 16);
ts->float_types[4] = 0;
ts->ellipsis = lccrt_type_make_simple( m, LCCRT_TYPE_ELLIPSIS, "...", 0, 1, 0);
ts->intptr = ts->int_types[0][m->is_ptr32 ? LCCRT_INT_SUBTYPE_32 : LCCRT_INT_SUBTYPE_64];
ts->ptr_byte = lccrt_type_make_ptr_type( ts->int_types[0][LCCRT_INT_SUBTYPE_8]);
ts->ptr_char = lccrt_type_make_ptr_type( ts->int_types[1][LCCRT_INT_SUBTYPE_8]);
ts->ptr_intptr = lccrt_type_make_ptr_type( ts->intptr);
return;
} /* lccrt_module_init_types_std */
/**
* Создание нового модуля.
*/
lccrt_module_ptr
lccrt_module_new( lccrt_context_ptr ctx, const char *name, int is_m32)
{
lccrt_module_ptr m = lccrt_ctx_malloc( ctx, lccrt_module_t);
lccrt_check_type_assert( ctx, lccrt_context_t);
memset( m, 0, sizeof( m[0]));
lccrt_check_type_init( m, lccrt_module_t);
m->ctx = ctx;
m->name = lccrt_ctx_copy_str( ctx, name);
m->is_ptr32 = is_m32;
m->types = lccrt_hash_new( ctx, LCCRT_HASH_KEY_STRING);
m->type_usr_names = lccrt_hash_new( ctx, LCCRT_HASH_KEY_STRING);
m->type_max = 0;
m->gvars = lccrt_hash_new( ctx, LCCRT_HASH_KEY_STRING);
m->funcs = lccrt_hash_new( ctx, LCCRT_HASH_KEY_STRING);
m->einfo_cats = lccrt_hash_new( ctx, LCCRT_HASH_KEY_STRING);
m->einfo_tyarrs = lccrt_hash_new( ctx, LCCRT_HASH_KEY_INTPTR);
m->einfo_tysts = lccrt_hash_new( ctx, LCCRT_HASH_KEY_STRING);
lccrt_ilist_head_init( &(m->types_head));
lccrt_ilist_head_init( &(m->gvars_head));
lccrt_ilist_head_init( &(m->funcs_head));
lccrt_ilist_head_init( &(m->varinits_head));
ctx->module_max++;
m->ident_num = ctx->module_max;
m->gvars_num = 0;
m->funcs_num = 0;
m->cargs_name_id = 0;
m->global_name_id = 0;
lccrt_hash_push( ctx->modules, (uintptr_t)m, 0);
lccrt_module_init_types_std( m);
return (m);
} /* lccrt_module_new */
/**
* Удаление модуля.
*/
void
lccrt_module_delete_data( lccrt_m_ptr m)
{
lccrt_varinit_ptr vi_unit;
lccrt_einfo_block_ptr eib_unit, eib_next;
lccrt_einfo_tydescr_ptr eitd_unit, eitd_next;
lccrt_hash_entry_ptr e = 0;
lccrt_context_ptr ctx = m->ctx;
lccrt_check_type_assert( m, lccrt_module_t);
lccrt_ctx_free( ctx, m->name);
lccrt_ctx_free( ctx, m->asm_text);
/* Удаляем все ранее созданные типы и сопутствующие структуры данных. */
for ( e = lccrt_hash_first( m->funcs); e; e = lccrt_hash_next( e) )
{
lccrt_function_delete( (lccrt_f_ptr)lccrt_hash_get( e));
}
lccrt_hash_delete( m->funcs);
for ( e = lccrt_hash_first( m->gvars); e; e = lccrt_hash_next( e) )
{
lccrt_var_delete( (lccrt_v_ptr)lccrt_hash_get( e));
}
lccrt_hash_delete( m->gvars);
for ( vi_unit = m->varinits_head.first; vi_unit; vi_unit = m->varinits_head.first )
{
lccrt_varinit_delete( vi_unit);
}
/* Удаляем цепочку привязку к модулю собственных мета-данных. */
m->einfo = lccrt_einfo_link_delete_chain( m->einfo);
/* Удаляем все категории мета-данных. */
lccrt_hash_delete( m->einfo_cats);
/* Удаляем все мета-данные. */
for ( eib_unit = m->eblocks_head; eib_unit; eib_unit = eib_next )
{
eib_next = eib_unit->next;
lccrt_einfo_block_delete( eib_unit);
}
/* Удаляем все описания типов мета-данных. */
for ( eitd_unit = m->etydescrs_head; eitd_unit; eitd_unit = eitd_next )
{
eitd_next = eitd_unit->next;
lccrt_einfo_tydescr_delete( eitd_unit);
}
/* Удаляем таблицы хеширования описания мета-данных. */
lccrt_hash_delete( m->einfo_tyarrs);
lccrt_hash_delete( m->einfo_tysts);
for ( e = lccrt_hash_first( m->types); e; e = lccrt_hash_next( e) )
{
lccrt_type_delete( (lccrt_t_ptr)lccrt_hash_get( e));
}
lccrt_hash_delete( m->types);
lccrt_hash_delete( m->type_usr_names);
lccrt_check_type_done( m, lccrt_module_t);
lccrt_ctx_free( ctx, m);
return;
} /* lccrt_module_delete_data */
/**
* Удаление модуля.
*/
void
lccrt_module_delete( lccrt_module_ptr m)
{
lccrt_context_ptr ctx = m->ctx;
lccrt_hash_entry_ptr he = lccrt_hash_find( ctx->modules, (uintptr_t)m);
lccrt_check_type_assert( m, lccrt_module_t);
lccrt_check_type_assert( ctx, lccrt_context_t);
lccrt_module_delete_data( m);
if ( he )
{
lccrt_hash_remove( he);
}
return;
} /* lccrt_module_delete */
/**
* Прочитать поле.
*/
lccrt_context_ptr
lccrt_module_get_context( lccrt_module_ptr m)
{
lccrt_context_ptr r = m->ctx;
lccrt_check_type_assert( m, lccrt_module_t);
return (r);
} /* lccrt_module_get_context */
/**
* Прочитать поле.
*/
const char *
lccrt_module_get_inline_asm( lccrt_m_ptr m)
{
const char *r = m->asm_text;
lccrt_check_type_assert( m, lccrt_module_t);
return (r);
} /* lccrt_module_get_inline_asm */
/**
* Прочитать поле.
*/
void
lccrt_module_set_inline_asm( lccrt_m_ptr m, const char *asm_text)
{
lccrt_ctx_ptr ctx = m->ctx;
lccrt_check_type_assert( m, lccrt_module_t);
lccrt_ctx_free( ctx, m->asm_text);
m->asm_text = lccrt_ctx_copy_str( ctx, asm_text);
return;
} /* lccrt_module_set_inline_asm */
/**
* Прочитать поле.
*/
uint64_t
lccrt_module_get_type_max( lccrt_module_ptr m)
{
uint64_t r = m->type_max;
lccrt_check_type_assert( m, lccrt_module_t);
return (r);
} /* lccrt_module_get_type_max */
/**
* Прочитать поле.
*/
uint64_t
lccrt_module_get_func_max( lccrt_module_ptr m)
{
uint64_t r = m->funcs_num;
lccrt_check_type_assert( m, lccrt_module_t);
return (r);
} /* lccrt_module_get_func_max */
/**
* Прочитать поле.
*/
const char*
lccrt_module_get_name( lccrt_module_ptr m)
{
const char *r = m->name;
lccrt_check_type_assert( m, lccrt_module_t);
return (r);
} /* lccrt_module_get_name */
/**
* Формирование нового имени для глобальной переменной.
*/
char *
lccrt_module_name_new_global( lccrt_m_ptr module, const char *name)
{
char str[1024];
const char *q = name;
char *result = 0;
lccrt_check_type_assert( module, lccrt_module_t);
if ( !name )
{
snprintf( str, 1024, "__lccrt_g%jd", module->global_name_id);
module->global_name_id++;
q = str;
}
result = lccrt_ctx_copy_str( module->ctx, q);
return (result);
} /* lccrt_module_name_new_global */
/**
* Прочитать поле.
*/
int
lccrt_module_is_ptr32( lccrt_module_ptr m)
{
int r = m->is_ptr32;
lccrt_check_type_assert( m, lccrt_module_t);
return (r);
} /* lccrt_module_is_ptr32 */
/**
* Прочитать поле.
*/
lccrt_hash_ptr
lccrt_module_get_types( lccrt_module_ptr m)
{
lccrt_check_type_assert( m, lccrt_module_t);
return (m->types);
} /* lccrt_module_get_types */
/**
* Прочитать поле.
*/
lccrt_hash_ptr
lccrt_module_get_gvars( lccrt_module_ptr m)
{
lccrt_check_type_assert( m, lccrt_module_t);
return (m->gvars);
} /* lccrt_module_get_gvars */
/**
* Прочитать поле.
*/
lccrt_hash_ptr
lccrt_module_get_funcs( lccrt_module_ptr m)
{
lccrt_check_type_assert( m, lccrt_module_t);
return (m->funcs);
} /* lccrt_module_get_funcs */
/**
* Получить первый тип модуля.
*/
lccrt_type_ptr
lccrt_module_get_first_type( lccrt_module_ptr m)
{
lccrt_type_ptr r;
lccrt_check_type_assert( m, lccrt_module_t);
r = m->types_head.first;
lccrt_check_type_assert( r, lccrt_type_t);
return (r);
} /* lccrt_module_get_first_type */
/**
* Получить первую глобальную переменную модуля.
*/
lccrt_var_ptr
lccrt_module_get_first_var( lccrt_module_ptr m)
{
lccrt_var_ptr r;
lccrt_check_type_assert( m, lccrt_module_t);
r = m->gvars_head.first;
lccrt_assert( !r || lccrt_var_is_global( r));
return (r);
} /* lccrt_module_get_first_var */
/**
* Получить первую глобальную переменную модуля.
*/
lccrt_function_ptr
lccrt_module_get_first_func( lccrt_module_ptr m)
{
lccrt_function_ptr r;
lccrt_check_type_assert( m, lccrt_module_t);
r = m->funcs_head.first;
return (r);
} /* lccrt_module_get_first_func */
/**
* Поиск функции по имени.
*/
lccrt_function_ptr
lccrt_module_find_function( lccrt_module_ptr m, const char *name)
{
lccrt_hash_entry_ptr e = lccrt_hash_find( m->funcs, (uintptr_t)name);
lccrt_function_ptr r = e ? (lccrt_f_ptr)lccrt_hash_get( e) : 0;
lccrt_check_type_assert( m, lccrt_module_t);
return (r);
} /* lccrt_module_find_function */
/**
* Добавить в модуль новые мета-данные, либо изменить значение старых.
*/
void
lccrt_module_set_einfo( lccrt_module_ptr m, lccrt_einfo_category_t ecat, lccrt_eir_t value)
{
lccrt_check_type_assert( m, lccrt_module_t);
lccrt_assert( !lccrt_einfo_is_scalar( value));
m->einfo = lccrt_einfo_link_push_value( m, m->einfo, ecat, value);
return;
} /* lccrt_module_set_einfo */
/**
* Получить значение мета-данных с заданным именем или 0, если таких данных нет.
*/
lccrt_einfo_reference_t
lccrt_module_get_einfo( lccrt_module_ptr m, lccrt_einfo_category_t ecat)
{
lccrt_einfo_link_ptr unit = lccrt_einfo_link_find( m->einfo, ecat);
lccrt_einfo_reference_t r = lccrt_einfo_link_get_value( unit);
lccrt_check_type_assert( m, lccrt_module_t);
return (r);
} /* lccrt_module_get_einfo */
/**
* Получить первую глобальную переменную модуля.
*/
void
lccrt_module_rename( lccrt_module_ptr m, const char *new_name)
{
lccrt_check_type_assert( m, lccrt_module_t);
lccrt_assert( 0);
return;
} /* lccrt_module_rename */
/**
* Всем типам, у которых не задано пользовательское имя, назначить пользовательское имя.
*/
void
lccrt_module_init_types_usr_names( lccrt_module_ptr m)
{
lccrt_hash_entry_ptr e;
for ( e = lccrt_hash_first( m->types); e; e = lccrt_hash_next( e) )
{
lccrt_type_ptr t = (lccrt_type_ptr)(uintptr_t)lccrt_hash_get( e);
if ( t->usr_name )
{
}
}
return;
} /* lccrt_module_init_types_usr_names */