From 300f85db72227ce3928569a240c35cda022feded Mon Sep 17 00:00:00 2001 From: Nunuhara Cabbage Date: Fri, 28 Aug 2020 19:28:06 -0700 Subject: [PATCH] Clean up ain_get/ain_add functions These functions should NEVER return a pointer into the ain object, since its storage can be realloc'd. Now all get/add functions return an index which can safely be stored for later use. --- include/system4/ain.h | 23 ++++++------ src/ain.c | 49 ++++++++----------------- src/debugger.c | 5 ++- src/tools/ainedit/asm.c | 12 +++--- src/tools/ainedit/jaf_compile.c | 2 +- src/tools/ainedit/jaf_parser.y | 2 +- src/tools/ainedit/jaf_static_analysis.c | 24 ++++++------ src/tools/ainedit/jaf_types.c | 4 +- 8 files changed, 52 insertions(+), 69 deletions(-) diff --git a/include/system4/ain.h b/include/system4/ain.h index 361170d..33819c2 100644 --- a/include/system4/ain.h +++ b/include/system4/ain.h @@ -338,23 +338,22 @@ struct ain *ain_new(int version); void ain_decrypt(uint8_t *buf, size_t len); void ain_init_member_functions(struct ain *ain, char *(*to_ascii)(const char*)); -struct ain_function *ain_get_function(struct ain *ain, char *name); -int ain_get_function_no(struct ain *ain, char *name); + +int ain_get_function(struct ain *ain, char *name); int ain_get_function_index(struct ain *ain, struct ain_function *f); -struct ain_struct *ain_get_struct(struct ain *ain, char *name); -int ain_get_struct_no(struct ain *ain, char *name); -int ain_add_struct(struct ain *ain, char *name); -struct ain_variable *ain_add_global(struct ain *ain, char *name); -struct ain_variable *ain_get_global(struct ain *ain, const char *name); -int ain_get_global_no(struct ain *ain, const char *name); -void ain_add_initval(struct ain *ain, struct ain_initval *init); -int ain_add_function(struct ain *ain, struct ain_function *fun); -int ain_add_functype(struct ain *ain, struct ain_function_type *fun); +int ain_get_global(struct ain *ain, const char *name); +int ain_get_struct(struct ain *ain, char *name); int ain_get_functype(struct ain *ain, const char *name); + +int ain_add_function(struct ain *ain, struct ain_function *fun); +int ain_add_global(struct ain *ain, struct ain_variable *var); +int ain_add_initval(struct ain *ain, struct ain_initval *init); +int ain_add_struct(struct ain *ain, struct ain_struct *struc); +int ain_add_library(struct ain *ain, struct ain_library *lib); +int ain_add_functype(struct ain *ain, struct ain_function_type *fun); int ain_add_string(struct ain *ain, const char *str); int ain_add_message(struct ain *ain, const char *str); int ain_add_file(struct ain *ain, const char *filename); -int ain_add_library(struct ain *ain, struct ain_library *lib); void ain_free(struct ain *ain); void ain_free_functions(struct ain *ain); diff --git a/src/ain.c b/src/ain.c index 9d0cf9d..5dbce09 100644 --- a/src/ain.c +++ b/src/ain.c @@ -172,7 +172,7 @@ static struct func_list *get_function(struct ain *ain, const char *name) return ht_get(ain->_func_ht, name, NULL); } -struct ain_function *ain_get_function(struct ain *ain, char *name) +int ain_get_function(struct ain *ain, char *name) { size_t len; long n = 0; @@ -191,14 +191,8 @@ struct ain_function *ain_get_function(struct ain *ain, char *name) struct func_list *funs = get_function(ain, name); if (!funs || n >= funs->nr_slots) - return NULL; - return &ain->functions[funs->slots[n]]; -} - -int ain_get_function_no(struct ain *ain, char *name) -{ - struct ain_function *f = ain_get_function(ain, name); - return f ? f - ain->functions : -1; + return -1; + return funs->slots[n]; } int ain_get_function_index(struct ain *ain, struct ain_function *f) @@ -215,61 +209,48 @@ err: ERROR("Invalid function: '%s'", f->name); } -struct ain_struct *ain_get_struct(struct ain *ain, char *name) +int ain_get_struct(struct ain *ain, char *name) { - return ht_get(ain->_struct_ht, name, NULL); -} - -int ain_get_struct_no(struct ain *ain, char *name) -{ - struct ain_struct *s = ain_get_struct(ain, name); + struct ain_struct *s = ht_get(ain->_struct_ht, name, NULL); return s ? s - ain->structures : -1; } -int ain_add_struct(struct ain *ain, char *name) +int ain_add_struct(struct ain *ain, struct ain_struct *struc) { ain->structures = xrealloc_array(ain->structures, ain->nr_structures, ain->nr_structures+1, sizeof(struct ain_struct)); - ain->structures[ain->nr_structures].name = strdup(name); - ain->structures[ain->nr_structures].constructor = -1; - ain->structures[ain->nr_structures].destructor = -1; + ain->structures[ain->nr_structures] = *struc; struct_ht_add(ain, &ain->structures[ain->nr_structures]); ain->nr_structures++; return ain->nr_structures - 1; } -struct ain_variable *ain_add_global(struct ain *ain, char *name) +int ain_add_global(struct ain *ain, struct ain_variable *var) { int no = ain->nr_globals; ain->globals = xrealloc_array(ain->globals, ain->nr_globals, ain->nr_globals+1, sizeof(struct ain_variable)); - ain->globals[no].name = strdup(name); + ain->globals[no] = *var; if (AIN_VERSION_GTE(ain, 12, 0)) ain->globals[no].name2 = strdup(""); ain->globals[no].var_type = AIN_VAR_GLOBAL; ain->nr_globals++; - return &ain->globals[no]; + return no; } -struct ain_variable *ain_get_global(struct ain *ain, const char *name) +int ain_get_global(struct ain *ain, const char *name) { - // TODO: use hash table for faster lookup for (int i = 0; i < ain->nr_globals; i++) { if (!strcmp(ain->globals[i].name, name)) - return &ain->globals[i]; + return i; } - return NULL; + return -1; } -int ain_get_global_no(struct ain *ain, const char *name) -{ - struct ain_variable *v = ain_get_global(ain, name); - return v ? v - ain->globals : -1; -} - -void ain_add_initval(struct ain *ain, struct ain_initval *init) +int ain_add_initval(struct ain *ain, struct ain_initval *init) { ain->global_initvals = xrealloc_array(ain->global_initvals, ain->nr_initvals, ain->nr_initvals+1, sizeof(struct ain_initval)); ain->global_initvals[ain->nr_initvals++] = *init; + return ain->nr_initvals - 1; } int ain_add_function(struct ain *ain, struct ain_function *fun) diff --git a/src/debugger.c b/src/debugger.c index d66e2b8..3928037 100644 --- a/src/debugger.c +++ b/src/debugger.c @@ -148,14 +148,15 @@ static void set_function_breakpoint(const char *_name, sexp handler) } char *name = utf2sjis(_name, 0); - struct ain_function *f = ain_get_function(ain, name); + int fno = ain_get_function(ain, name); free(name); - if (!f) { + if (fno < 0) { SCM_ERROR("No function with name '%s'", _name); return; } + struct ain_function *f = &ain->functions[fno]; breakpoints = xrealloc_array(breakpoints, nr_breakpoints, nr_breakpoints+1, sizeof(struct breakpoint)); breakpoints[nr_breakpoints].restore_op = LittleEndian_getW(ain->code, f->address); breakpoints[nr_breakpoints].handler = handler; diff --git a/src/tools/ainedit/asm.c b/src/tools/ainedit/asm.c index ef5ca91..077806c 100644 --- a/src/tools/ainedit/asm.c +++ b/src/tools/ainedit/asm.c @@ -279,11 +279,11 @@ static uint32_t asm_resolve_arg(struct asm_state *state, enum opcode opcode, enu } case T_FUNC: { char *u = encode_text(arg); - struct ain_function *f = ain_get_function(ain, u); + int fno = ain_get_function(ain, u); free(u); - if (!f) + if (fno < 0) ASM_ERROR(state, "Unable to resolve function: '%s'", arg); - return f - ain->functions; + return fno; } case T_STRING: { return asm_add_string(state, arg); @@ -324,11 +324,11 @@ static uint32_t asm_resolve_arg(struct asm_state *state, enum opcode opcode, enu } case T_STRUCT: { char *u = encode_text(arg); - struct ain_struct *s = ain_get_struct(state->ain, u); + int sno = ain_get_struct(state->ain, u); free(u); - if (!s) + if (sno < 0) ASM_ERROR(state, "Unable to resolve struct: '%s'", arg); - return s - state->ain->structures; + return sno; } case T_SYSCALL: { for (int i = 0; i < NR_SYSCALLS; i++) { diff --git a/src/tools/ainedit/jaf_compile.c b/src/tools/ainedit/jaf_compile.c index adba979..523d241 100644 --- a/src/tools/ainedit/jaf_compile.c +++ b/src/tools/ainedit/jaf_compile.c @@ -998,7 +998,7 @@ static void compile_declaration(struct compiler_state *state, struct jaf_block_i static void compile_global_init_function(struct compiler_state *state) { - if (ain_get_function(state->ain, "0")) + if (ain_get_function(state->ain, "0") >= 0) return; struct ain_function f = {0}; diff --git a/src/tools/ainedit/jaf_parser.y b/src/tools/ainedit/jaf_parser.y index 7d742c5..41a9e5a 100644 --- a/src/tools/ainedit/jaf_parser.y +++ b/src/tools/ainedit/jaf_parser.y @@ -92,7 +92,7 @@ struct jaf_block *jaf_parse(struct ain *ain, const char **files, unsigned nr_fil int sym_type(char *name) { char *u = encode_text(name); - if (ain_get_struct(jaf_ain_out, u)) { + if (ain_get_struct(jaf_ain_out, u) >= 0) { free(u); return TYPEDEF_NAME; } diff --git a/src/tools/ainedit/jaf_static_analysis.c b/src/tools/ainedit/jaf_static_analysis.c index 63d724f..9ff686e 100644 --- a/src/tools/ainedit/jaf_static_analysis.c +++ b/src/tools/ainedit/jaf_static_analysis.c @@ -33,11 +33,14 @@ void jaf_define_struct(struct ain *ain, struct jaf_block_item *def) if (!def->struc.name) ERROR("Anonymous structs not supported"); - char *u = encode_text(def->struc.name->text); - if (ain_get_struct(ain, u)) + struct ain_struct s = { + .name = encode_text(def->struc.name->text), + .constructor = -1, + .destructor = -1, + }; + if (ain_get_struct(ain, s.name) >= 0) ERROR("Redefining structs not supported"); - def->struc.struct_no = ain_add_struct(ain, u); - free(u); + def->struc.struct_no = ain_add_struct(ain, &s); } void jaf_define_functype(struct ain *ain, struct jaf_fundecl *decl) @@ -116,7 +119,7 @@ static void resolve_typedef(struct ain *ain, struct jaf_type_specifier *type) { int no; char *u = encode_text(type->name->text); - if ((no = ain_get_struct_no(ain, u)) >= 0) { + if ((no = ain_get_struct(ain, u)) >= 0) { type->type = JAF_STRUCT; type->struct_no = no; } else if ((no = ain_get_functype(ain, u)) >= 0) { @@ -231,7 +234,7 @@ static void analyze_message(struct jaf_env *env, struct jaf_block_item *item) } char *u = encode_text(item->msg.func->text); - if ((item->msg.func_no = ain_get_function_no(env->ain, u)) < 0) + if ((item->msg.func_no = ain_get_function(env->ain, u)) < 0) ERROR("Undefined function: %s", item->msg.func->text); free(u); } @@ -565,11 +568,10 @@ static void add_functype(struct ain *ain, struct jaf_fundecl *decl) static void add_global(struct ain *ain, struct jaf_vardecl *decl) { - char *u = encode_text(decl->name->text); - struct ain_variable *v = ain_add_global(ain, u); - jaf_to_ain_type(ain, &v->type, decl->type); - decl->var_no = v - ain->globals; - free(u); + struct ain_variable v = {0}; + v.name = encode_text(decl->name->text); + jaf_to_ain_type(ain, &v.type, decl->type); + ain_add_global(ain, &v); } static void jaf_process_declarations(struct ain *ain, struct jaf_block *block) diff --git a/src/tools/ainedit/jaf_types.c b/src/tools/ainedit/jaf_types.c index 1f229c4..a4cf769 100644 --- a/src/tools/ainedit/jaf_types.c +++ b/src/tools/ainedit/jaf_types.c @@ -311,7 +311,7 @@ struct ain_variable *jaf_env_lookup(struct jaf_env *env, const char *name, int * scope = scope->parent; } - int no = ain_get_global_no(env->ain, name); + int no = ain_get_global(env->ain, name); if (no >= 0) { *var_no = no; return &env->ain->globals[no]; @@ -329,7 +329,7 @@ static void jaf_check_types_identifier(struct jaf_env *env, struct jaf_expressio expr->valuetype = v->type; expr->ident.var_type = v->var_type; expr->ident.var_no = no; - } else if ((no = ain_get_function_no(env->ain, u)) >= 0) { + } else if ((no = ain_get_function(env->ain, u)) >= 0) { expr->valuetype.data = AIN_FUNCTION; expr->valuetype.struc = no; } else {