From d8bb323b09a5773d00e428ad5aeb27377b76a911 Mon Sep 17 00:00:00 2001 From: Orangerot Date: Thu, 15 May 2025 21:58:29 +0200 Subject: [PATCH] feat: local function variables on stack --- wai.c | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/wai.c b/wai.c index 06235c2..9a5ed3a 100644 --- a/wai.c +++ b/wai.c @@ -78,7 +78,7 @@ struct func_type_t { struct func_t { size_t func_type_index; size_t num_local_vars; - u_char *func_start_addr; + u_char *addr; }; enum export_desc { @@ -96,9 +96,8 @@ struct export_t { }; struct module { - struct func_type_t func_types[MAX_FUNCTIONS]; // TYPE SECTION - u_char *code[MAX_FUNCTIONS]; // CODE SECTION - size_t func_to_func_type[MAX_FUNCTIONS]; // FUNCTION SECTION + struct func_type_t func_types[MAX_FUNCTIONS]; + struct func_t func[MAX_FUNCTIONS]; struct table_t *tables; struct mem_t *mems; struct global_t *globals; @@ -110,7 +109,6 @@ struct module { u_char *binary; struct stack stack; size_t num_exports; - int scope; }; enum INSTRUCTION { @@ -314,10 +312,10 @@ int parse_instruction(struct module *module, u_char *binary, size_t func_i, size } case INSTR_LOCAL_GET: { int local_index = binary[i]; - size_t func_type_i = module->func_to_func_type[func_i]; + size_t func_type_i = module->func[func_i].func_type_index; struct func_type_t *func_type = &module->func_types[func_type_i]; - // TODO: take local variables into account in addition to parameters - int num_locals = func_type->num_params; + int num_locals = func_type->num_params + module->func[func_i].num_local_vars; + printf("num locals %d, %d\n", num_locals, num_locals - 1 - local_index); stack_peak(&module->stack, &result, num_locals - 1 - local_index, func_stack_begin); incr(i, len); @@ -333,8 +331,9 @@ int parse_instruction(struct module *module, u_char *binary, size_t func_i, size int parse_function(struct module *module, size_t func_i, int len) { int i = 0; - u_char *binary = module->code[func_i]; - size_t func_type_i = module->func_to_func_type[func_i]; + struct func_t *func = &module->func[func_i]; + u_char *binary = func->addr; + size_t func_type_i = func->func_type_index; struct func_type_t *func_type = &module->func_types[func_type_i]; int body_size = binary[i]; size_t func_stack_begin = module->stack.bytes; @@ -342,9 +341,12 @@ int parse_function(struct module *module, size_t func_i, int len) { struct value_t result = {0}; incr(i, len); - // int local_decl_cound = binary[i]; + func->num_local_vars = binary[i]; incr(i, len); - module->scope = 1; + for (int local_var_i = 0; local_var_i < func->num_local_vars; local_var_i++) { + stack_push(&module->stack, &(struct value_t) {.type = binary[i], .value = 0}); + incr(i, len); + } while (binary[i] != INSTR_END) { i += parse_instruction(module, &binary[i], func_i, func_stack_begin, len); } @@ -352,7 +354,7 @@ int parse_function(struct module *module, size_t func_i, int len) { func_stack_end = module->stack.bytes; module->stack.bytes = func_stack_begin; - for (size_t param_i = 0; param_i < func_type->num_params; param_i++) { + for (size_t local_i = 0; local_i < func_type->num_params + func->num_local_vars; local_i++) { stack_pop(&module->stack, &result); } for (size_t result_i = 0; result_i < func_type->num_results; result_i++) { @@ -406,7 +408,7 @@ int parse_section(struct module *module, u_char *binary, int len) { size_t num_functions = binary[i]; incr(i, len); for (size_t function_i = 0; function_i < num_functions; function_i++) { - module->func_to_func_type[function_i] = binary[i]; + module->func[function_i].func_type_index = binary[i]; incr(i, len); } break; @@ -442,7 +444,7 @@ int parse_section(struct module *module, u_char *binary, int len) { printf("export name: %s of type %d\n", export->name, export->description); if (export->description == Export_Func) { printf("exported function %s(", export->name); - size_t func_type_index = module->func_to_func_type[export->func_index]; + size_t func_type_index = module->func[export->func_index].func_type_index; struct func_type_t *func_type = &module->func_types[func_type_index]; for (size_t param_i = 0; param_i < func_type->num_params; param_i++) { printf("%s", TYPE_NAME[func_type->param[param_i]]); @@ -472,7 +474,7 @@ int parse_section(struct module *module, u_char *binary, int len) { int num_functions2 = binary[i]; incr(i, len); for (int function_i = 0; function_i < num_functions2; function_i++) { - module->code[function_i] = &binary[i]; + module->func[function_i].addr = &binary[i]; stack_push(&module->stack, &(struct value_t) {.type = TYPE_F64, .value.f64 = 1}); i += parse_function(module, function_i, len); stack_pop(&module->stack, &(struct value_t) {0}); @@ -521,8 +523,9 @@ int main(int argc, char **argv) { struct stat st; struct module module = {0}; - if (argc != 2) { + if (argc < 3) { printf("Usage: %s [file] [function name] [function arguments ...]\n", argv[0]); + exit(1); }; file = fopen(argv[1], "r"); if (file == NULL) { @@ -552,7 +555,8 @@ int main(int argc, char **argv) { exit(1); } size_t function_search_i = module.exports[export_search_i].func_index; - struct func_type_t *func_type_search = &module.func_types[module.func_to_func_type[function_search_i]]; + size_t function_search_type_index = module.func[function_search_i].func_type_index; + struct func_type_t *func_type_search = &module.func_types[function_search_type_index]; if (func_type_search->num_params != argc - 3) { printf("Not enough function arguments provided. Got %d expected %zu. \n", argc - 3, func_type_search->num_params); exit(1);