much progress on converting a WASM binary
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Fri, 24 Jun 2022 04:06:44 +0000 (23:06 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Fri, 24 Jun 2022 04:06:44 +0000 (23:06 -0500)
src/wasm/module_parsing.c.incl

index 890633478b971ae891b8ec85efc43c2834279b66..e885d5bdf27737321200df2f44629fad1e291a60 100644 (file)
@@ -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);
     }
 }