+added a memory pool to interpreter shell in main.c.

This commit is contained in:
tony 2015-08-26 21:21:19 +08:00
parent 78fe066a29
commit 0b7d939fe1
6 changed files with 281 additions and 63 deletions

View File

@ -1,3 +1,6 @@
Aug. 26 2015
Added a memory pool to interpreter shell in main.c
Aug. 25 2015
Allowed a user to define the memory tag data type, unsigned short as default
Added an mb_set_memory_manager function, allows user defined memory management

View File

@ -78,7 +78,7 @@ extern "C" {
/** Macros */
#define _VER_MAJOR 1
#define _VER_MINOR 1
#define _VER_REVISION 63
#define _VER_REVISION 64
#define _MB_VERSION ((_VER_MAJOR * 0x01000000) + (_VER_MINOR * 0x00010000) + (_VER_REVISION))
/* Uncomment this line to treat warnings as error */
@ -299,8 +299,7 @@ typedef struct _object_t {
#endif /* MB_ENABLE_SOURCE_TRACE */
} _object_t;
typedef unsigned short _mem_tag_t;
#define _MB_MEM_TAG_SIZE (sizeof(_mem_tag_t))
#define _MB_MEM_TAG_SIZE (sizeof(mb_mem_tag_t))
#ifdef MB_ENABLE_ALLOC_STAT
const size_t MB_SIZEOF_INT = _MB_MEM_TAG_SIZE + sizeof(int);
@ -631,9 +630,9 @@ static void _ht_clear(_ht_node_t* ht);
static void _ht_destroy(_ht_node_t* ht);
/** Memory operations */
#define _MB_CHECK_MEM_TAG_SIZE(y, s) do { _mem_tag_t _tmp = (_mem_tag_t)s; if((y)_tmp != s) { mb_assert(0 && "\"_mem_tag_t\" is too small."); printf("The type \"_mem_tag_t\" is not precise enough to hold the given data, please redefine it!"); } } while(0)
#define _MB_WRITE_MEM_TAG_SIZE(t, s) (*((_mem_tag_t*)((char*)(t) - _MB_MEM_TAG_SIZE)) = (_mem_tag_t)s)
#define _MB_READ_MEM_TAG_SIZE(t) (*((_mem_tag_t*)((char*)(t) - _MB_MEM_TAG_SIZE)))
#define _MB_CHECK_MEM_TAG_SIZE(y, s) do { mb_mem_tag_t _tmp = (mb_mem_tag_t)s; if((y)_tmp != s) { mb_assert(0 && "\"mb_mem_tag_t\" is too small."); printf("The type \"mb_mem_tag_t\" is not precise enough to hold the given data, please redefine it!"); } } while(0)
#define _MB_WRITE_MEM_TAG_SIZE(t, s) (*((mb_mem_tag_t*)((char*)(t) - _MB_MEM_TAG_SIZE)) = (mb_mem_tag_t)s)
#define _MB_READ_MEM_TAG_SIZE(t) (*((mb_mem_tag_t*)((char*)(t) - _MB_MEM_TAG_SIZE)))
#ifdef MB_ENABLE_ALLOC_STAT
static volatile size_t _mb_allocated = 0;

View File

@ -243,6 +243,8 @@ typedef struct mb_value_t {
mb_value_u value;
} mb_value_t;
typedef unsigned short mb_mem_tag_t;
typedef int (* mb_func_t)(struct mb_interpreter_t*, void**);
typedef void (* mb_debug_stepped_handler_t)(struct mb_interpreter_t*, int, unsigned short, unsigned short);
typedef void (* mb_error_handler_t)(struct mb_interpreter_t*, enum mb_error_e, char*, int, unsigned short, unsigned short, int);

Binary file not shown.

View File

@ -36,8 +36,8 @@
IDI_ICON_MAIN ICON "icon.ico"
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,1,63,0
PRODUCTVERSION 1,1,63,0
FILEVERSION 1,1,64,0
PRODUCTVERSION 1,1,64,0
FILEFLAGSMASK 0x17L
# ifdef _DEBUG
FILEFLAGS 0x1L
@ -55,13 +55,13 @@
VALUE "Comments", "MY-BASIC"
VALUE "CompanyName", "Wang Renxin"
VALUE "FileDescription", "MY-BASIC Interpreter for Windows"
VALUE "FileVersion", "1, 1, 63, 0"
VALUE "FileVersion", "1, 1, 64, 0"
VALUE "InternalName", "my_basic"
VALUE "LegalCopyright", "Copyright (C) 2011 - 2015 Wang Renxin"
VALUE "LegalTrademarks", "MY-BASIC"
VALUE "OriginalFilename", "my_basic.exe"
VALUE "ProductName", "MY-BASIC"
VALUE "ProductVersion", "1, 1, 63, 0"
VALUE "ProductVersion", "1, 1, 64, 0"
END
END
BLOCK "VarFileInfo"

View File

@ -57,6 +57,13 @@
# define strdup _strdup
#endif /* __POCC__ */
/*
** {========================================================
** Common declarations
*/
#define _USE_MEM_POOL /* Comment this macro to disable memory pool */
#define _MAX_LINE_LENGTH 256
#define _str_eq(__str1, __str2) (_strcmpi(__str1, __str2) == 0)
@ -64,14 +71,174 @@
#define _NO_END(s) (MB_FUNC_OK == s || MB_FUNC_SUSPEND == s || MB_FUNC_WARNING == s || MB_FUNC_ERR == s || MB_FUNC_END == s)
static struct mb_interpreter_t* bas = 0;
/* ========================================================} */
/*
** {========================================================
** Memory manipulation
*/
#ifdef _USE_MEM_POOL
extern const size_t MB_SIZEOF_INT;
extern const size_t MB_SIZEOF_PTR;
extern const size_t MB_SIZEOF_LSN;
extern const size_t MB_SIZEOF_HTN;
extern const size_t MB_SIZEOF_OBJ;
extern const size_t MB_SIZEOF_FUN;
extern const size_t MB_SIZEOF_ARR;
extern const size_t MB_SIZEOF_VAR;
extern const size_t MB_SIZEOF_LBL;
typedef unsigned _pool_chunk_size_t;
typedef union _pool_tag_t {
_pool_chunk_size_t size;
void* ptr;
} _pool_tag_t;
typedef struct _pool_t {
size_t size;
char* stack;
} _pool_t;
static int pool_count = 0;
static _pool_t* pool = 0;
#define _POOL_NODE_ALLOC(size) (((char*)malloc(sizeof(_pool_tag_t) + size)) + sizeof(_pool_tag_t))
#define _POOL_NODE_PTR(s) (s - sizeof(_pool_tag_t))
#define _POOL_NODE_NEXT(s) (*((void**)(s - sizeof(_pool_tag_t))))
#define _POOL_NODE_SIZE(s) (*((_pool_chunk_size_t*)(s - sizeof(_pool_tag_t))))
#define _POOL_NODE_FREE(s) free(_POOL_NODE_PTR(s))
static void _open_mem_pool(void) {
#define N 9
size_t szs[N];
size_t lst[N] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
int i = 0;
int j = 0;
size_t s = 0;
pool_count = 0;
szs[0] = MB_SIZEOF_INT;
szs[1] = MB_SIZEOF_PTR;
szs[2] = MB_SIZEOF_LSN;
szs[3] = MB_SIZEOF_HTN;
szs[4] = MB_SIZEOF_OBJ;
szs[5] = MB_SIZEOF_FUN;
szs[6] = MB_SIZEOF_ARR;
szs[7] = MB_SIZEOF_VAR;
szs[8] = MB_SIZEOF_LBL;
for(i = 0; i < N; i++) {
s = szs[i];
for(j = 0; j < N; j++) {
if(!lst[j]) {
lst[j] = s;
pool_count++;
break;
} else if(lst[j] == s) {
break;
}
}
}
pool = (_pool_t*)malloc(sizeof(_pool_t) * pool_count);
for(i = 0; i < pool_count; i++) {
pool[i].size = lst[i];
pool[i].stack = 0;
}
#undef N
}
static void _close_mem_pool(void) {
int i = 0;
char* s = 0;
if(!pool_count)
return;
for(i = 0; i < pool_count; i++) {
while((s = pool[i].stack)) {
pool[i].stack = _POOL_NODE_NEXT(s);
free(_POOL_NODE_PTR(s));
}
}
free((void*)pool);
pool = 0;
pool_count = 0;
}
static char* _memory_allocate(unsigned s) {
int i = 0;
_pool_t* pl = 0;
char* result = 0;
if(pool_count) {
for(i = 0; i < pool_count; i++) {
pl = &pool[i];
if(s == pl->size) {
if(pl->stack) {
result = pl->stack;
pl->stack = _POOL_NODE_NEXT(result);
_POOL_NODE_SIZE(result) = (_pool_chunk_size_t)s;
return result;
} else {
result = _POOL_NODE_ALLOC(s);
_POOL_NODE_SIZE(result) = (_pool_chunk_size_t)s;
return result;
}
}
}
}
result = _POOL_NODE_ALLOC(s);
_POOL_NODE_SIZE(result) = (_pool_chunk_size_t)0;
return result;
}
static void _memory_free(char* p) {
int i = 0;
_pool_t* pl = 0;
if(pool_count) {
for(i = 0; i < pool_count; i++) {
pl = &pool[i];
if(_POOL_NODE_SIZE(p) == pl->size) {
_POOL_NODE_NEXT(p) = pl->stack;
pl->stack = p;
return;
}
}
}
_POOL_NODE_FREE(p);
}
#endif /* _USE_MEM_POOL */
/* ========================================================} */
/*
** {========================================================
** Code manipulation
*/
typedef struct _code_line_t {
char** lines;
int count;
int size;
} _code_line_t;
static struct mb_interpreter_t* bas = 0;
static _code_line_t* c = 0;
static _code_line_t* _create_code(void) {
@ -191,58 +358,12 @@ static int _save_file(const char* path, const char* txt) {
return 0;
}
static int beep(struct mb_interpreter_t* s, void** l) {
int result = MB_FUNC_OK;
/* ========================================================} */
mb_assert(s && l);
mb_check(mb_attempt_func_begin(s, l));
mb_check(mb_attempt_func_end(s, l));
putchar('\a');
return result;
}
static void _on_stepped(struct mb_interpreter_t* s, int p, unsigned short row, unsigned short col) {
mb_unrefvar(s);
mb_unrefvar(p);
mb_unrefvar(row);
mb_unrefvar(col);
}
static void _on_error(struct mb_interpreter_t* s, mb_error_e e, char* m, int p, unsigned short row, unsigned short col, int abort_code) {
mb_unrefvar(s);
mb_unrefvar(p);
if(SE_NO_ERR != e) {
printf("Error:\n [LINE] %d, [COL] %d,\n [CODE] %d, [MESSAGE] %s, [ABORT CODE] %d\n", row, col, e, m, abort_code);
}
}
static void _on_startup(void) {
c = _create_code();
mb_init();
mb_open(&bas);
mb_debug_set_stepped_handler(bas, _on_stepped);
mb_set_error_handler(bas, _on_error);
mb_reg_fun(bas, beep);
}
static void _on_exit(void) {
mb_close(&bas);
mb_dispose();
_destroy_code(c);
c = 0;
#if defined _MSC_VER && !defined _WIN64
if(0 != _CrtDumpMemoryLeaks()) { _asm { int 3 } }
#endif /* _MSC_VER && !_WIN64 */
}
/*
** {========================================================
** Interactive commands
*/
static void _clear_screen(void) {
#ifdef _MSC_VER
@ -484,6 +605,97 @@ static int _do_line(void) {
return result;
}
/* ========================================================} */
/*
** {========================================================
** Scripting interfaces
*/
static int beep(struct mb_interpreter_t* s, void** l) {
int result = MB_FUNC_OK;
mb_assert(s && l);
mb_check(mb_attempt_func_begin(s, l));
mb_check(mb_attempt_func_end(s, l));
putchar('\a');
return result;
}
/* ========================================================} */
/*
** {========================================================
** Callbacks and handlers
*/
static void _on_stepped(struct mb_interpreter_t* s, int p, unsigned short row, unsigned short col) {
mb_unrefvar(s);
mb_unrefvar(p);
mb_unrefvar(row);
mb_unrefvar(col);
}
static void _on_error(struct mb_interpreter_t* s, mb_error_e e, char* m, int p, unsigned short row, unsigned short col, int abort_code) {
mb_unrefvar(s);
mb_unrefvar(p);
if(SE_NO_ERR != e) {
printf("Error:\n [LINE] %d, [COL] %d,\n [CODE] %d, [MESSAGE] %s, [ABORT CODE] %d\n", row, col, e, m, abort_code);
}
}
/* ========================================================} */
/*
** {========================================================
** Initialization and disposing
*/
static void _on_startup(void) {
#ifdef _USE_MEM_POOL
_open_mem_pool();
mb_set_memory_manager(_memory_allocate, _memory_free);
#endif /* _USE_MEM_POOL */
c = _create_code();
mb_init();
mb_open(&bas);
mb_debug_set_stepped_handler(bas, _on_stepped);
mb_set_error_handler(bas, _on_error);
mb_reg_fun(bas, beep);
}
static void _on_exit(void) {
mb_close(&bas);
mb_dispose();
_destroy_code(c);
c = 0;
#ifdef _USE_MEM_POOL
_close_mem_pool();
#endif /* _USE_MEM_POOL */
#if defined _MSC_VER && !defined _WIN64
if(0 != _CrtDumpMemoryLeaks()) { _asm { int 3 } }
#endif /* _MSC_VER && !_WIN64 */
}
/* ========================================================} */
/*
** {========================================================
** Entry
*/
int main(int argc, char* argv[]) {
int status = 0;
@ -510,3 +722,5 @@ int main(int argc, char* argv[]) {
return 0;
}
/* ========================================================} */