lccrt/include/internal/lccrt_ctx.h

294 lines
12 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_ctx.h - пользовательский интерфейс (динамической) компиляции.
*/
#ifndef LCCRT_CTX_H
#define LCCRT_CTX_H
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#include <stdlib.h>
#include <string.h>
#include "lccrt.h"
#include "internal/lccrt_ilist.h"
#include "internal/lccrt_hash.h"
#define LCCRT_MAX( a, b) (((a) >= (b)) ? (a) : (b))
#define LCCRT_MIN( a, b) (((a) <= (b)) ? (a) : (b))
#ifndef NDEBUG
/**
* Макрос задающий тип сборки в отладочном режиме.
*/
#define LCCRT_DEBUG
#endif /* !NDEBUG */
/**
* Преобразование значения в строку.
*/
#define LCCRT_TO_STR_OPERATOR( x) #x
#define LCCRT_TO_STR( x) LCCRT_TO_STR_OPERATOR( x)
#define LCCRT_ASM_SFUNC_COMPILE LCCRT_TO_STR( LCCRT_ASM_FUNC_COMPILE)
#define LCCRT_ASM_SFUNC_GETTOOL LCCRT_TO_STR( LCCRT_ASM_FUNC_GETTOOL)
#define LCCRT_PLUGIN_LIBRARY_NAME_S LCCRT_TO_STR( LCCRT_PLUGIN_LIBRARY_NAME)
#define LCCRT_PLUGIN_LCCRT_VERSION_S LCCRT_TO_STR( LCCRT_PLUGIN_LCCRT_VERSION)
#define LCCRT_PLUGIN_TARGETS_S LCCRT_TO_STR( LCCRT_PLUGIN_TARGETS)
/**
* Проверка двух строк на равенство.
*/
#define lccrt_str_eq( s, p) (strcmp( s, p) == 0)
#define lccrt_str_eqz( p, q) (!(p) || !(q) || lccrt_str_eq( p, q))
#define lccrt_min( a, b) ((a) < (b) ? (a) : (b))
#define lccrt_max( a, b) ((a) > (b) ? (a) : (b))
/**
* Присвоение под условием.
*/
#define lccrt_assign( p, v) ((p) ? ((*(p) = (v)), 0) : 0)
/**
* Исполнить выражение при нулевом значении флаговой переменной с сохранением во
* флаговую переменную результата выполнения выражения.
*/
#define lccrt_test0( flag, expr) ((flag) = ((expr) != 0) || (flag))
#define lccrt_test1( flag, expr) ((flag) = (!(expr) != 0) || (flag))
/**
* Чтение числа из строки с продвижкой указателя (возвращается 1 при возможности чтения
* символов из строки s).
*/
#define lccrt_strtoll( s, se, base, p) \
( \
((s) && (s)[0]) \
? (((p)[0] = strtoll( s, se, base)), 1) \
: 0 \
)
/**
* Интерефейс динамической проверки типов структур.
*/
#ifdef LCCRT_DEBUG
int lccrt_assert_var __attribute__((weak));
#define lccrt_assert( p) \
( \
lccrt_assert_var = ((p) \
? 0 \
: (printf( "ERROR: %s: %s:%d\n", __FUNCTION__, __FILE__, __LINE__), \
abort(), 0)) \
)
//#define lccrt_assert( p) assert( p)
#define lccrt_check_type_name( type) lccrt_check_var__##type
#define lccrt_check_type_declare( type) extern void *lccrt_check_type_name( type)
#define lccrt_check_type_define( type) void *lccrt_check_type_name( type)
#define lccrt_check_type_assert( d, t) \
( \
lccrt_assert( !(d) \
|| (((t *)(d))->type_check.ptr == (void *)&lccrt_check_type_name( t))) \
)
#define lccrt_check_type_init( d, t) \
( \
((t *)(d))->type_check.ptr = (void *)&lccrt_check_type_name( t) \
)
#define lccrt_check_type_done( d, t) \
( \
lccrt_check_type_assert( d, t), ((t *)(d))->type_check.ptr = 0 \
)
#else /* !LCCRT_DEBUG */
#define lccrt_assert( p)
#define lccrt_check_type_assert( d, t)
#define lccrt_check_type_declare( type)
#define lccrt_check_type_define( type)
#define lccrt_check_type_init( d, t)
#define lccrt_check_type_done( d, t)
#endif /* LCCRT_DEBUG */
/**
* Структура для динамического контроля типа структур.
*/
typedef struct
{
#ifdef LCCRT_DEBUG
void *ptr;
#endif /* LCCRT_DEBUG */
} lccrt_check_type_t;
/**
* Типы плагинов.
*/
typedef enum
{
LCCRT_PLUGIN_TYPE_ASM,
LCCRT_PLUGIN_TYPE_LAST
} lccrt_plugin_type_t;
/**
* Типы функций в ассемблере.
*/
typedef enum
{
LCCRT_PLUGIN_ASM_FUNC_COMP,
LCCRT_PLUGIN_ASM_FUNC_TOOL,
LCCRT_PLUGIN_ASM_FUNC_LAST
} lccrt_plugin_asm_func_name_t;
/**
* Структура внешнего плагина.
*/
typedef struct lccrt_plugin_r
{
lccrt_context_ptr ctx;
lccrt_plugin_type_t type; /* тип плагина */
void *lib; /* плагин */
const char *lib_name; /* название плагина */
const char *lccrt_ver; /* версия lccrt-библиотеки, с которой был собран плагин */
int num_targs; /* количество, поддерживаемых целей */
const char **targs; /* массив целей */
int num_funcs; /* количество методов в плагине */
void **funcs; /* методы плагина */
const char **lccrt_s; /* пути установки нативных (!) библиотек liblccrt_s */
const char **include_s; /* пути установки нативных заголовочных файлов */
lccrt_check_type_t type_check;
} lccrt_plugin_t;
/**
* Штатные пути для поиска компонент.
*/
typedef struct
{
char *home; /* корневая директория */
char *plugin; /* директория поиска плагинов */
char *plugins[LCCRT_PLUGIN_TYPE_LAST]; /* директория поиска плагинов по типу */
} lccrt_context_paths_t;
/**
* Данные по типам отладочных печатей.
*/
typedef struct
{
int8_t is_base; /* информация о переменных окружения, плагинах и т.п. */
int8_t is_ir; /* создание новых операций */
} lccrt_context_verbose_t;
/**
* \defgroup tyCtx lccrt_context_t
* Для работы с библиотекой в начале необходимо создать структуру контекста lccrt_context_t.
* В основном структура данных lccrt_context_t выполняет технические функции,
* в частности, можно одновременно создать несколько контекстов. Далее можно работать с разными контекстами
* независимым образом, причем все последующие данные создаются только в рамках одного из контекстов.
* При удалении контекста также (автоматически) удаляются все данные, созданные в рамках данного контекста.
*
* При создании контекста:
* - задается \ref lccrt_mem_t "менеджер памяти", с помощью которого должна выделяться память под структуры данных
* (при использовании внешних библиотек менеджер памяти не пропагируется), причем по умолчанию используются
* стандартные функции <b><tt> malloc/free </tt></b>
* - задается \ref lccrt_err_t "менеджер вывода сообщений об ошибках", причем по умолчанию используются
* стандартные функции <b><tt> printf/abort </tt></b>
* - происходит загрузка плагинов по штатным путям (см. \ref pgPlg "Загрузка плагинов")
*
*/
/**
* \class lccrt_context_t
* \copydoc tyCtx
*
* \copydoc tyCtxFns
*
* \ref tyCtxFns
*/
typedef struct lccrt_context_r
{
lccrt_mem_t mem; /*!< интерфейс менеджера памяти */
lccrt_err_t err; /*!< интерфейс менеджера ошибок */
lccrt_hash_ptr modules; /* хеш-таблица модулей */
uint64_t module_max; /* счетчик модулей */
int num_plgs[LCCRT_PLUGIN_TYPE_LAST]; /* количество штатных плагинов */
lccrt_plugin_t *plgs[LCCRT_PLUGIN_TYPE_LAST]; /* штатные плагины */
lccrt_context_paths_t paths; /* пути поиска компонент */
lccrt_context_verbose_t verbose; /* флаги отладочных печатетей */
lccrt_check_type_t type_check;
} lccrt_context_t;
/**
* Стандартный менеджер памяти и поток вывода ошибок.
*/
extern lccrt_mem_t lccrt_std_mem;
extern lccrt_err_t lccrt_std_err;
/**
* Перечисление типов структур с динамической проверкой типа.
*/
lccrt_check_type_declare( lccrt_type_t);
lccrt_check_type_declare( lccrt_varinit_t);
lccrt_check_type_declare( lccrt_var_t);
lccrt_check_type_declare( lccrt_oper_t);
lccrt_check_type_declare( lccrt_oper_iterator_t);
lccrt_check_type_declare( lccrt_einfo_block_t);
lccrt_check_type_declare( lccrt_einfo_tydescr_t);
lccrt_check_type_declare( lccrt_einfo_link_t);
lccrt_check_type_declare( lccrt_function_t);
lccrt_check_type_declare( lccrt_function_jit_info_t);
lccrt_check_type_declare( lccrt_module_t);
lccrt_check_type_declare( lccrt_context_t);
lccrt_check_type_declare( lccrt_plugin_t);
lccrt_check_type_declare( lccrt_fs_t);
lccrt_check_type_declare( lccrt_jit_t);
extern void *lccrt_ctx_malloc_func( lccrt_ctx_ptr ctx, uint64_t size);
extern void *lccrt_ctx_realloc_func( lccrt_ctx_ptr ctx, void *ptr, uint64_t size);
extern void *lccrt_ctx_free_func( lccrt_ctx_ptr ctx, void *ptr);
extern void *lccrt_ctx_memdup_func( lccrt_ctx_ptr ctx, void *ptr, uint64_t len);
extern void **lccrt_ctx_copy_arr_func( lccrt_ctx_ptr ctx, void **ptr, uint64_t size, uint64_t len);
extern char *lccrt_ctx_copy_str( lccrt_context_ptr ctx, const char *str);
extern char *lccrt_ctx_cat_strs( lccrt_context_ptr ctx, const char *str1, const char *str2);
extern char *lccrt_ctx_catby_strs( lccrt_context_ptr ctx, const char *str1, const char *str2);
#define lccrt_ctx_malloc( ctx, type) (type *)lccrt_ctx_malloc_func( ctx, sizeof( type))
#define lccrt_ctx_mallocn( ctx, type, n) ((type *)lccrt_ctx_malloc_func( ctx, (n) * sizeof( type)))
#define lccrt_ctx_realloc( ctx, ptr, len) lccrt_ctx_realloc_func( ctx, (void *)ptr, len)
#define lccrt_ctx_free( ctx, ptr) lccrt_ctx_free_func( ctx, (void *)ptr)
#define lccrt_ctx_memdup( ctx, ptr, len) lccrt_ctx_memdup_func( ctx, (void *)ptr, len)
#define lccrt_ctx_copy_arr( ctx, ptr, type, n) \
( \
(type *)lccrt_ctx_copy_arr_func( ctx, (void **)(ptr), sizeof( type), n) \
)
#define lccrt_ctx_error( ctx, eid, fmt, ...) \
( \
(ctx)->err.error_func \
? ((ctx)->err.error_func( (ctx)->err.data, eid, "Error:%s:%d: " fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__), 0) \
: 0 \
)
#define lccrt_ctx_warning( ctx, wid, fmt, ...) \
( \
(ctx)->err.warning_func \
? ((ctx)->err.warning_func( (ctx)->err.data, wid, "Warning:%s:%d: " fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__), 0) \
: 0 \
)
extern void *lccrt_ctx_plugin_get_func( lccrt_plg_ptr plg, int func_num);
extern lccrt_fs_ptr lccrt_fs_new_file( lccrt_context_ptr ctx, FILE *file);
extern lccrt_fs_ptr lccrt_fs_open_file( lccrt_context_ptr ctx, const char *name, int is_load);
extern lccrt_fs_ptr lccrt_fs_new_buffer( lccrt_context_ptr ctx, char *buff, uint64_t buff_size);
extern int lccrt_fs_delete( lccrt_fs_ptr f);
extern int lccrt_fs_is_error( lccrt_fs_ptr f);
extern uint64_t lccrt_fs_get_syms_count( lccrt_fs_ptr f);
extern char *lccrt_fs_get_buffer( lccrt_fs_ptr f);
extern int lccrt_fs_get_sym( lccrt_fs_ptr f);
extern int lccrt_fs_printf( lccrt_fs_ptr f, const char *fmt, ...);
extern int lccrt_fs_print_name_str( lccrt_fs_ptr f, const char *name);
#if defined(__cplusplus)
}
#endif
#endif /* LCCRT_CTX_H */