style: formatting

This commit is contained in:
Orangerot 2025-05-13 03:40:22 +02:00
parent bce3e3bf25
commit 906b2d03e3

439
wai.c
View file

@ -24,12 +24,12 @@
*/ */
#include <endian.h> #include <endian.h>
#include <inttypes.h>
#include <stddef.h> #include <stddef.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <inttypes.h>
enum section { enum section {
Section_Custom, Section_Custom,
@ -101,20 +101,14 @@ enum TYPE {
TYPE_I64 = 0x7E, TYPE_I64 = 0x7E,
TYPE_F32 = 0x7D, TYPE_F32 = 0x7D,
TYPE_F64 = 0x7C, TYPE_F64 = 0x7C,
TYPE_V128= 0x7B, TYPE_V128 = 0x7B,
TYPE_FUNCREF = 0x70, TYPE_FUNCREF = 0x70,
TYPE_EXTERNREF = 0x6F TYPE_EXTERNREF = 0x6F
}; };
static const int TYPE_SIZE[] = { static const int TYPE_SIZE[] = {
[TYPE_I32] = 4, [TYPE_I32] = 4, [TYPE_I64] = 8, [TYPE_F32] = 4, [TYPE_F64] = 8,
[TYPE_I64] = 8, [TYPE_V128] = 16, [TYPE_FUNCREF] = 16, [TYPE_EXTERNREF] = 16};
[TYPE_F32] = 4,
[TYPE_F64] = 8,
[TYPE_V128] = 16,
[TYPE_FUNCREF] = 16,
[TYPE_EXTERNREF] = 16
};
struct value_t { struct value_t {
enum TYPE type; enum TYPE type;
@ -129,7 +123,11 @@ struct value_t {
} value; } value;
}; };
#define incr(i, len) i++; if (i >= len) {return -1;} #define incr(i, len) \
i++; \
if (i >= len) { \
return -1; \
}
void stack_push(struct stack *s, const struct value_t *value) { void stack_push(struct stack *s, const struct value_t *value) {
size_t type_size = TYPE_SIZE[value->type]; size_t type_size = TYPE_SIZE[value->type];
@ -144,27 +142,27 @@ void stack_push(struct stack *s, const struct value_t *value) {
void *value = &s->items[i - type_size]; void *value = &s->items[i - type_size];
switch (t) { switch (t) {
case TYPE_I32: case TYPE_I32:
printf("%d (I32)", *(int32_t*)value); printf("%d (I32)", *(int32_t *)value);
break; break;
case TYPE_I64: case TYPE_I64:
printf("%ld (I32)", *(int64_t*)value); printf("%ld (I32)", *(int64_t *)value);
break; break;
case TYPE_F32: case TYPE_F32:
printf("%f (F32)", *(float*)value); printf("%f (F32)", *(float *)value);
break; break;
case TYPE_F64: case TYPE_F64:
printf("%f (F64)", *(double*)value); printf("%f (F64)", *(double *)value);
break; break;
case TYPE_V128: case TYPE_V128:
printf("%ld (V128)", *(__int128*)value); printf("%ld (V128)", *(__int128 *)value);
break; break;
case TYPE_FUNCREF: case TYPE_FUNCREF:
printf("%ld (EREF)", *(int64_t*)value); printf("%ld (EREF)", *(int64_t *)value);
break; break;
case TYPE_EXTERNREF: case TYPE_EXTERNREF:
printf("%ld (EREF)", *(int64_t*)value); printf("%ld (EREF)", *(int64_t *)value);
break; break;
} }
printf(", "); printf(", ");
} }
@ -172,8 +170,9 @@ void stack_push(struct stack *s, const struct value_t *value) {
} }
void stack_top(struct stack *s, struct value_t *value) { void stack_top(struct stack *s, struct value_t *value) {
value->type = s->items[s->bytes-1]; value->type = s->items[s->bytes - 1];
memcpy(&value->value, &(s->items[s->bytes - 1 - TYPE_SIZE[value->type]]), TYPE_SIZE[value->type]); memcpy(&value->value, &(s->items[s->bytes - 1 - TYPE_SIZE[value->type]]),
TYPE_SIZE[value->type]);
} }
void stack_pop(struct stack *s, struct value_t *value) { void stack_pop(struct stack *s, struct value_t *value) {
@ -187,24 +186,26 @@ int parse_type(u_char *binary, int len) {
printf("type %x\n", param); printf("type %x\n", param);
incr(i, len); incr(i, len);
switch (param) { switch (param) {
case TYPE_I32: case TYPE_I32:
case TYPE_I64: case TYPE_I64:
case TYPE_F32: case TYPE_F32:
case TYPE_F64: case TYPE_F64:
case TYPE_V128: case TYPE_V128:
case TYPE_FUNCREF: case TYPE_FUNCREF:
case TYPE_EXTERNREF: case TYPE_EXTERNREF:
break; break;
default: default:
return -1; return -1;
} }
return i; return i;
} }
int parse_function(struct module *module, u_char *binary, double param, int len); int parse_function(struct module *module, u_char *binary, double param,
int parse_instruction(struct module *module, u_char *binary, double param, int len) { int len);
int parse_instruction(struct module *module, u_char *binary, double param,
int len) {
int i = 0; int i = 0;
enum INSTRUCTION instr = (u_char) binary[i]; enum INSTRUCTION instr = (u_char)binary[i];
u_char *instr_addr = &binary[i]; u_char *instr_addr = &binary[i];
struct value_t a = {0}; struct value_t a = {0};
struct value_t b = {0}; struct value_t b = {0};
@ -213,94 +214,97 @@ int parse_instruction(struct module *module, u_char *binary, double param, int l
incr(i, len); incr(i, len);
switch (instr) { switch (instr) {
case INSTR_CALL: { case INSTR_CALL: {
int func_index = binary[i]; int func_index = binary[i];
incr(i, len); incr(i, len);
stack_pop(&module->stack, &a); stack_pop(&module->stack, &a);
parse_function(module, module->funcs[func_index], a.value.f64, len); parse_function(module, module->funcs[func_index], a.value.f64, len);
break; break;
} }
case INSTR_ELSE: case INSTR_ELSE:
printf("reached else instruction: impossible!\n"); printf("reached else instruction: impossible!\n");
case INSTR_END: case INSTR_END:
break; break;
case INSTR_F64_CONST: case INSTR_F64_CONST:
result.type = TYPE_F64; result.type = TYPE_F64;
result.value.f64 = *(double*)&binary[i]; result.value.f64 = *(double *)&binary[i];
i += 8; i += 8;
stack_push(&module->stack, &result); stack_push(&module->stack, &result);
break; break;
case INSTR_F64_LT: { case INSTR_F64_LT: {
stack_pop(&module->stack, &a); stack_pop(&module->stack, &a);
stack_pop(&module->stack, &b); stack_pop(&module->stack, &b);
if (a.type != TYPE_F64 || b.type != TYPE_F64) if (a.type != TYPE_F64 || b.type != TYPE_F64)
printf("Wrong types!\n"); printf("Wrong types!\n");
result.type = TYPE_F64; result.type = TYPE_F64;
result.value.f64 = b.value.f64 < a.value.f64; result.value.f64 = b.value.f64 < a.value.f64;
stack_push(&module->stack, &result); stack_push(&module->stack, &result);
break; break;
} }
case INSTR_F64_MUL: { case INSTR_F64_MUL: {
stack_pop(&module->stack, &a); stack_pop(&module->stack, &a);
stack_pop(&module->stack, &b); stack_pop(&module->stack, &b);
if (a.type != TYPE_F64 || b.type != TYPE_F64) if (a.type != TYPE_F64 || b.type != TYPE_F64)
printf("Wrong types!\n"); printf("Wrong types!\n");
result.type = TYPE_F64; result.type = TYPE_F64;
result.value.f64 = a.value.f64 * b.value.f64; result.value.f64 = a.value.f64 * b.value.f64;
stack_push(&module->stack, &result); stack_push(&module->stack, &result);
break; break;
} }
case INSTR_F64_SUB: { case INSTR_F64_SUB: {
stack_pop(&module->stack, &a); stack_pop(&module->stack, &a);
stack_pop(&module->stack, &b); stack_pop(&module->stack, &b);
if (a.type != TYPE_F64 || b.type != TYPE_F64) if (a.type != TYPE_F64 || b.type != TYPE_F64)
printf("Wrong types!\n"); printf("Wrong types!\n");
result.type = TYPE_F64; result.type = TYPE_F64;
result.value.f64 = b.value.f64 - a.value.f64; result.value.f64 = b.value.f64 - a.value.f64;
stack_push(&module->stack, &result); stack_push(&module->stack, &result);
break; break;
} }
case INSTR_IF: { case INSTR_IF: {
stack_pop(&module->stack, &a); stack_pop(&module->stack, &a);
enum TYPE condition_type = binary[i]; enum TYPE condition_type = binary[i];
incr(i, len); incr(i, len);
if (a.type != condition_type) if (a.type != condition_type)
printf("Wrong types!\n"); printf("Wrong types!\n");
while (binary[i] != INSTR_ELSE) { while (binary[i] != INSTR_ELSE) {
// TODO test condition with correct type. // TODO test condition with correct type.
// This might not matter since all types are false with 0x0 // This might not matter since all types are false with 0x0
if (a.value.i64) { if (a.value.i64) {
i += parse_instruction(module, &binary[i], param, len); i += parse_instruction(module, &binary[i], param, len);
} else { } else {
incr(i, len); incr(i, len);
}
} }
incr(i, len); }
while (binary[i] != INSTR_END) { incr(i, len);
if (a.value.i64) { while (binary[i] != INSTR_END) {
incr(i, len); if (a.value.i64) {
} else { incr(i, len);
i += parse_instruction(module, &binary[i], param, len); } else {
} i += parse_instruction(module, &binary[i], param, len);
} }
incr(i, len); }
break; incr(i, len);
} break;
case INSTR_LOCAL_GET: { }
int local_index = binary[i]; case INSTR_LOCAL_GET: {
incr(i, len); int local_index = binary[i];
stack_push(&module->stack, &(struct value_t) {.value.f64 = param, .type = TYPE_F64}); incr(i, len);
break; stack_push(&module->stack,
} &(struct value_t){.value.f64 = param, .type = TYPE_F64});
default: break;
printf("unknown instruction! %x at %lx\n", instr, instr_addr - module->binary); }
exit(1); default:
printf("unknown instruction! %x at %lx\n", instr,
instr_addr - module->binary);
exit(1);
} }
return i; return i;
} }
int parse_function(struct module *module, u_char *binary, double param, int len) { int parse_function(struct module *module, u_char *binary, double param,
int len) {
int i = 0; int i = 0;
int body_size = binary[i]; int body_size = binary[i];
incr(i, len); incr(i, len);
@ -322,98 +326,102 @@ int parse_section(struct module *module, u_char *binary, int len) {
incr(i, len); incr(i, len);
printf("section %x with size %d\n", type, size); printf("section %x with size %d\n", type, size);
switch ((enum section) type) { switch ((enum section)type) {
case Section_Custom: case Section_Custom:
break; break;
case Section_Type: case Section_Type:
printf("section: type\n"); printf("section: type\n");
int num_types = binary[i]; int num_types = binary[i];
incr(i, len); incr(i, len);
for (int type_i = 0; type_i < num_types; type_i++) { for (int type_i = 0; type_i < num_types; type_i++) {
if (binary[i] != 0x60) { if (binary[i] != 0x60) {
printf("expected function type, found %x\n", binary[i]); printf("expected function type, found %x\n", binary[i]);
return -1; return -1;
} }
incr(i, len);
int num_params = binary[i];
incr(i, len);
for (int params_i = 0; params_i < num_params; params_i++) {
i += (parse_type(&binary[i], len));
}
int num_results = binary[i];
incr(i, len);
for (int results_i = 0; results_i < num_results; results_i++) {
i += (parse_type(&binary[i], len));
}
}
break;
case Section_Import:
break;
case Section_Function:
printf("section: function\n");
int num_functions = binary[i];
incr(i, len); incr(i, len);
for (int function_i = 0; function_i < num_functions; function_i++) { int num_params = binary[i];
incr(i, len);
}
break;
case Section_Table:
break;
case Section_Memory:
break;
case Section_Global:
break;
case Section_Export:
printf("section: exports\n");
int num_exports = binary[i];
if(num_exports > MAX_FUNCTIONS) {
printf("Number of exports exceeds maximum number of functions in a module (%d)", MAX_FUNCTIONS);
return -1;
}
incr(i, len); incr(i, len);
for (int exports_i = 0; exports_i < num_exports; exports_i++) { for (int params_i = 0; params_i < num_params; params_i++) {
struct export_t *export = &module->exports[i]; i += (parse_type(&binary[i], len));
export->name_length = binary[i];
incr(i, len);
for (int si = 0; si < export->name_length; si++) {
export->name[si] = binary[i];
incr(i, len);
}
export->description = (int) binary[i];
incr(i, len);
export->index = (uint32_t) binary[i];
printf("export name: %s of type %d\n", export->name, export->description);
incr(i, len);
} }
break; int num_results = binary[i];
case Section_Start:
break;
case Section_Element:
break;
case Section_Code:
printf("section: code\n");
int num_functions2 = binary[i];
incr(i, len); incr(i, len);
for (int function_i = 0; function_i < num_functions2; function_i++) { for (int results_i = 0; results_i < num_results; results_i++) {
module->funcs[function_i] = &binary[i]; i += (parse_type(&binary[i], len));
i += parse_function(module, &binary[i], 4, len);
} }
// printf("result: %f\n", module->stack.items[0]); }
break; break;
case Section_Data: case Section_Import:
break; break;
case Section_Data_Count: case Section_Function:
break; printf("section: function\n");
default: int num_functions = binary[i];
fprintf(stderr, "expectet section\n"); incr(i, len);
exit(1); for (int function_i = 0; function_i < num_functions; function_i++) {
incr(i, len);
}
break;
case Section_Table:
break;
case Section_Memory:
break;
case Section_Global:
break;
case Section_Export:
printf("section: exports\n");
int num_exports = binary[i];
if (num_exports > MAX_FUNCTIONS) {
printf("Number of exports exceeds maximum number of functions in a "
"module (%d)",
MAX_FUNCTIONS);
return -1;
}
incr(i, len);
for (int exports_i = 0; exports_i < num_exports; exports_i++) {
struct export_t *export = &module->exports[i];
export->name_length = binary[i];
incr(i, len);
for (size_t si = 0; si < export->name_length; si++) {
export->name[si] = binary[i];
incr(i, len);
}
export->description = (int)binary[i];
incr(i, len);
export->index = (uint32_t)binary[i];
printf("export name: %s of type %d\n", export->name, export->description);
incr(i, len);
}
break;
case Section_Start:
break;
case Section_Element:
break;
case Section_Code:
printf("section: code\n");
int num_functions2 = binary[i];
incr(i, len);
for (int function_i = 0; function_i < num_functions2; function_i++) {
module->funcs[function_i] = &binary[i];
i += parse_function(module, &binary[i], 4, len);
}
// printf("result: %f\n", module->stack.items[0]);
break;
case Section_Data:
break;
case Section_Data_Count:
break;
default:
fprintf(stderr, "expectet section\n");
exit(1);
} }
if (size == 0x0) {incr(i, len);} if (size == 0x0) {
incr(i, len);
}
return i; return i;
} }
@ -421,14 +429,14 @@ int parse_module(u_char *binary, size_t len) {
int i = 0; int i = 0;
char *magic = "\0asm"; char *magic = "\0asm";
while (i < 4) { while (i < 4) {
if ((char) binary[i] != magic[i]) { if ((char)binary[i] != magic[i]) {
fprintf(stderr, "no wasm magic\n"); fprintf(stderr, "no wasm magic\n");
return 0; return 0;
} }
incr(i, len); incr(i, len);
} }
printf("magic found\n"); printf("magic found\n");
printf("wasm version: %d\n", le32toh(*(int*)&binary[i])); printf("wasm version: %d\n", le32toh(*(int *)&binary[i]));
i += 4; i += 4;
printf("addr %d\n", i); printf("addr %d\n", i);
@ -468,4 +476,3 @@ int main(int argc, char **argv) {
fclose(file); fclose(file);
return 0; return 0;
} }