From: Brendan Hansen Date: Fri, 24 Jun 2022 04:06:44 +0000 (-0500) Subject: much progress on converting a WASM binary X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=81338e58040338df248a9ce16542e0a1f8f30397;p=onyx-embedder.git much progress on converting a WASM binary --- diff --git a/src/wasm/module_parsing.c.incl b/src/wasm/module_parsing.c.incl index 8906334..e885d5b 100644 --- a/src/wasm/module_parsing.c.incl +++ b/src/wasm/module_parsing.c.incl @@ -372,21 +372,216 @@ static void parse_expression(build_context *ctx); static void parse_instruction(build_context *ctx) { char instr_byte; switch (instr_byte = CONSUME_BYTE(ctx)) { - case 0x00: return; - case 0x01: return; + case 0x00: break; + case 0x01: break; case 0x02: { // Currently, only "void" block types are valid. assert(CONSUME_BYTE(ctx) == 0x40); push_label_target(ctx, label_kind_block); - parse_expression(ctx); + break; + } + + case 0x03: { + // Currently, only "void" block types are valid. + assert(CONSUME_BYTE(ctx) == 0x40); + push_label_target(ctx, label_kind_loop); + break; + } + + case 0x04: { + // Currently, only "void" block types are valid. + assert(CONSUME_BYTE(ctx) == 0x40); + push_label_target(ctx, label_kind_block); + // TODO: Ifs + break; + } + + case 0x05: { + // TODO: If-elses + break; + } + + case 0x0B: { pop_label_target(ctx); - return; + break; + } + + case 0x0C: { + int label_idx = uleb128_to_uint(ctx->binary.data, &ctx->offset); + ovm_code_builder_add_branch(&ctx->builder, label_idx); + break; } + + case 0x0D: { + int label_idx = uleb128_to_uint(ctx->binary.data, &ctx->offset); + ovm_code_builder_add_cond_branch(&ctx->builder, label_idx); + break; + } + + case 0x0E: assert(0); { + // TODO: Branch tables + break; + } + + case 0x0F: { + ovm_code_builder_add_return(&ctx->builder); + break; + } + + case 0x10: { + int func_idx = uleb128_to_uint(ctx->binary.data, &ctx->offset); + int param_count = ctx->program->funcs[func_idx].param_count; + ovm_code_builder_add_call(&ctx->builder, param_count); + break; + } + + case 0x11: { + int type_idx = uleb128_to_uint(ctx->binary.data, &ctx->offset); + int table_idx = uleb128_to_uint(ctx->binary.data, &ctx->offset); + assert(table_idx == 0); + + int param_count = ctx->module->type_section.data[type_idx]->type.func.params.size; + ovm_code_builder_add_indirect_call(&ctx->builder, param_count); + break; + } + + case 0x1A: { + ovm_code_builder_drop_value(&ctx->builder); + break; + } + + case 0x1B: assert(0); + + case 0x20: { + int local_idx = uleb128_to_uint(ctx->binary.data, &ctx->offset); + ovm_code_builder_add_local_get(&ctx->builder, local_idx); + break; + } + + case 0x21: { + int local_idx = uleb128_to_uint(ctx->binary.data, &ctx->offset); + ovm_code_builder_add_local_set(&ctx->builder, local_idx); + break; + } + + case 0x22: { + int local_idx = uleb128_to_uint(ctx->binary.data, &ctx->offset); + ovm_code_builder_add_local_set(&ctx->builder, local_idx); + ovm_code_builder_add_local_get(&ctx->builder, local_idx); + break; + } + + case 0x23: { + int global_idx = uleb128_to_uint(ctx->binary.data, &ctx->offset); + ovm_code_builder_add_register_get(&ctx->builder, global_idx); + break; + } + + case 0x24: { + int global_idx = uleb128_to_uint(ctx->binary.data, &ctx->offset); + ovm_code_builder_add_register_set(&ctx->builder, global_idx); + break; + } + + case 0x28: { + int alignment = uleb128_to_uint(ctx->binary.data, &ctx->offset); + int offset = uleb128_to_uint(ctx->binary.data, &ctx->offset); + ovm_code_builder_add_load(&ctx->builder, OVM_TYPE_I32, offset); + break; + } + + case 0x29: { + int alignment = uleb128_to_uint(ctx->binary.data, &ctx->offset); + int offset = uleb128_to_uint(ctx->binary.data, &ctx->offset); + ovm_code_builder_add_load(&ctx->builder, OVM_TYPE_I64, offset); + break; + } + + case 0x2A: { + int alignment = uleb128_to_uint(ctx->binary.data, &ctx->offset); + int offset = uleb128_to_uint(ctx->binary.data, &ctx->offset); + ovm_code_builder_add_load(&ctx->builder, OVM_TYPE_F32, offset); + break; + } + + case 0x2B: { + int alignment = uleb128_to_uint(ctx->binary.data, &ctx->offset); + int offset = uleb128_to_uint(ctx->binary.data, &ctx->offset); + ovm_code_builder_add_load(&ctx->builder, OVM_TYPE_F64, offset); + break; + } + + // ... More loading and storing instruction here ... + + case 0x41: { + int value = uleb128_to_uint(ctx->binary.data, &ctx->offset); + ovm_code_builder_add_imm(&ctx->builder, OVM_TYPE_I32, &value); + break; + } + + case 0x42: { + long long value = uleb128_to_uint(ctx->binary.data, &ctx->offset); + ovm_code_builder_add_imm(&ctx->builder, OVM_TYPE_I64, &value); + break; + } + + case 0x43: { + float value = * (f32 *) &ctx->binary.data[ctx->offset]; + ctx->offset += 4; + ovm_code_builder_add_imm(&ctx->builder, OVM_TYPE_F32, &value); + break; + } + + case 0x44: { + double value = * (f64 *) &ctx->binary.data[ctx->offset]; + ctx->offset += 4; + ovm_code_builder_add_imm(&ctx->builder, OVM_TYPE_F64, &value); + break; + } + + case 0x46: ovm_code_builder_add_binop(&ctx->builder, OVM_TYPED_INSTR(OVMI_EQ, OVM_TYPE_I32)); break; + case 0x47: ovm_code_builder_add_binop(&ctx->builder, OVM_TYPED_INSTR(OVMI_NE, OVM_TYPE_I32)); break; + case 0x48: ovm_code_builder_add_binop(&ctx->builder, OVM_TYPED_INSTR(OVMI_LT_S, OVM_TYPE_I32)); break; + case 0x49: ovm_code_builder_add_binop(&ctx->builder, OVM_TYPED_INSTR(OVMI_LT, OVM_TYPE_I32)); break; + case 0x4A: ovm_code_builder_add_binop(&ctx->builder, OVM_TYPED_INSTR(OVMI_GT_S, OVM_TYPE_I32)); break; + case 0x4B: ovm_code_builder_add_binop(&ctx->builder, OVM_TYPED_INSTR(OVMI_GT, OVM_TYPE_I32)); break; + case 0x4C: ovm_code_builder_add_binop(&ctx->builder, OVM_TYPED_INSTR(OVMI_LE_S, OVM_TYPE_I32)); break; + case 0x4D: ovm_code_builder_add_binop(&ctx->builder, OVM_TYPED_INSTR(OVMI_LE, OVM_TYPE_I32)); break; + case 0x4E: ovm_code_builder_add_binop(&ctx->builder, OVM_TYPED_INSTR(OVMI_GE_S, OVM_TYPE_I32)); break; + case 0x4F: ovm_code_builder_add_binop(&ctx->builder, OVM_TYPED_INSTR(OVMI_GE, OVM_TYPE_I32)); break; + + case 0x51: ovm_code_builder_add_binop(&ctx->builder, OVM_TYPED_INSTR(OVMI_EQ, OVM_TYPE_I64)); break; + case 0x52: ovm_code_builder_add_binop(&ctx->builder, OVM_TYPED_INSTR(OVMI_NE, OVM_TYPE_I64)); break; + case 0x53: ovm_code_builder_add_binop(&ctx->builder, OVM_TYPED_INSTR(OVMI_LT_S, OVM_TYPE_I64)); break; + case 0x54: ovm_code_builder_add_binop(&ctx->builder, OVM_TYPED_INSTR(OVMI_LT, OVM_TYPE_I64)); break; + case 0x55: ovm_code_builder_add_binop(&ctx->builder, OVM_TYPED_INSTR(OVMI_GT_S, OVM_TYPE_I64)); break; + case 0x56: ovm_code_builder_add_binop(&ctx->builder, OVM_TYPED_INSTR(OVMI_GT, OVM_TYPE_I64)); break; + case 0x57: ovm_code_builder_add_binop(&ctx->builder, OVM_TYPED_INSTR(OVMI_LE_S, OVM_TYPE_I64)); break; + case 0x58: ovm_code_builder_add_binop(&ctx->builder, OVM_TYPED_INSTR(OVMI_LE, OVM_TYPE_I64)); break; + case 0x59: ovm_code_builder_add_binop(&ctx->builder, OVM_TYPED_INSTR(OVMI_GE_S, OVM_TYPE_I64)); break; + case 0x5A: ovm_code_builder_add_binop(&ctx->builder, OVM_TYPED_INSTR(OVMI_GE, OVM_TYPE_I64)); break; + + case 0x5B: ovm_code_builder_add_binop(&ctx->builder, OVM_TYPED_INSTR(OVMI_EQ, OVM_TYPE_F32)); break; + case 0x5C: ovm_code_builder_add_binop(&ctx->builder, OVM_TYPED_INSTR(OVMI_NE, OVM_TYPE_F32)); break; + case 0x5D: ovm_code_builder_add_binop(&ctx->builder, OVM_TYPED_INSTR(OVMI_LT, OVM_TYPE_F32)); break; + case 0x5E: ovm_code_builder_add_binop(&ctx->builder, OVM_TYPED_INSTR(OVMI_GT, OVM_TYPE_F32)); break; + case 0x5F: ovm_code_builder_add_binop(&ctx->builder, OVM_TYPED_INSTR(OVMI_LE, OVM_TYPE_F32)); break; + case 0x60: ovm_code_builder_add_binop(&ctx->builder, OVM_TYPED_INSTR(OVMI_GE, OVM_TYPE_F32)); break; + + case 0x61: ovm_code_builder_add_binop(&ctx->builder, OVM_TYPED_INSTR(OVMI_EQ, OVM_TYPE_F64)); break; + case 0x62: ovm_code_builder_add_binop(&ctx->builder, OVM_TYPED_INSTR(OVMI_NE, OVM_TYPE_F64)); break; + case 0x63: ovm_code_builder_add_binop(&ctx->builder, OVM_TYPED_INSTR(OVMI_LT, OVM_TYPE_F64)); break; + case 0x64: ovm_code_builder_add_binop(&ctx->builder, OVM_TYPED_INSTR(OVMI_GT, OVM_TYPE_F64)); break; + case 0x65: ovm_code_builder_add_binop(&ctx->builder, OVM_TYPED_INSTR(OVMI_LE, OVM_TYPE_F64)); break; + case 0x66: ovm_code_builder_add_binop(&ctx->builder, OVM_TYPED_INSTR(OVMI_GE, OVM_TYPE_F64)); break; + + + default: assert(("UNHANDLED INSTRUCTION", 0)); } } static void parse_expression(build_context *ctx) { - while (PEEK_BYTE(ctx) != 0x0B) { + while (bh_arr_length(ctx->builder.label_stack) > 0) { parse_instruction(ctx); } }