feat: local function variables on stack
This commit is contained in:
parent
e13c2aac40
commit
d8bb323b09
40
wai.c
40
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);
|
||||
|
|
Loading…
Reference in a new issue