summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOrangerot <purple@orangerot.dev>2025-05-15 21:58:29 +0200
committerOrangerot <purple@orangerot.dev>2025-05-15 21:58:29 +0200
commitd8bb323b09a5773d00e428ad5aeb27377b76a911 (patch)
tree09ed13734aadb97f3100a04607c4a2df53ae468e
parente13c2aac40279d420faac6527964303bb62ab7b4 (diff)
feat: local function variables on stack
-rw-r--r--wai.c40
1 files 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);