lccrt/lib/irv/lccrt_module.c

453 lines
13 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 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 */