summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/wasm-binary-reader.c765
1 files changed, 386 insertions, 379 deletions
diff --git a/src/wasm-binary-reader.c b/src/wasm-binary-reader.c
index 0529dda7..8b3ef7db 100644
--- a/src/wasm-binary-reader.c
+++ b/src/wasm-binary-reader.c
@@ -1194,6 +1194,390 @@ static void read_global_header(Context* ctx,
*out_mutable = mutable_;
}
+static void read_function_body(Context* ctx,
+ WasmAllocator* allocator,
+ uint32_t end_offset) {
+ WasmBool seen_end_opcode = WASM_FALSE;
+ while (ctx->offset < end_offset) {
+ uint8_t opcode;
+ in_u8(ctx, &opcode, "opcode");
+ CALLBACK(on_opcode, opcode);
+ switch (opcode) {
+ case WASM_OPCODE_UNREACHABLE:
+ CALLBACK0(on_unreachable_expr);
+ break;
+
+ case WASM_OPCODE_BLOCK: {
+ uint8_t sig_type;
+ in_u8(ctx, &sig_type, "block signature type");
+ RAISE_ERROR_UNLESS(is_inline_sig_type(sig_type),
+ "expected valid block signature type");
+ uint32_t num_types = sig_type == WASM_TYPE_VOID ? 0 : 1;
+ CALLBACK(on_block_expr, num_types, &sig_type);
+ break;
+ }
+
+ case WASM_OPCODE_LOOP: {
+ uint8_t sig_type;
+ in_u8(ctx, &sig_type, "loop signature type");
+ RAISE_ERROR_UNLESS(is_inline_sig_type(sig_type),
+ "expected valid block signature type");
+ uint32_t num_types = sig_type == WASM_TYPE_VOID ? 0 : 1;
+ CALLBACK(on_loop_expr, num_types, &sig_type);
+ break;
+ }
+
+ case WASM_OPCODE_IF: {
+ uint8_t sig_type;
+ in_u8(ctx, &sig_type, "if signature type");
+ RAISE_ERROR_UNLESS(is_inline_sig_type(sig_type),
+ "expected valid block signature type");
+ uint32_t num_types = sig_type == WASM_TYPE_VOID ? 0 : 1;
+ CALLBACK(on_if_expr, num_types, &sig_type);
+ break;
+ }
+
+ case WASM_OPCODE_ELSE:
+ CALLBACK0(on_else_expr);
+ break;
+
+ case WASM_OPCODE_SELECT:
+ CALLBACK0(on_select_expr);
+ break;
+
+ case WASM_OPCODE_BR: {
+ uint32_t depth;
+ in_u32_leb128(ctx, &depth, "br depth");
+ CALLBACK(on_br_expr, depth);
+ break;
+ }
+
+ case WASM_OPCODE_BR_IF: {
+ uint32_t depth;
+ in_u32_leb128(ctx, &depth, "br_if depth");
+ CALLBACK(on_br_if_expr, depth);
+ break;
+ }
+
+ case WASM_OPCODE_BR_TABLE: {
+ uint32_t num_targets;
+ in_u32_leb128(ctx, &num_targets, "br_table target count");
+ if (num_targets > ctx->target_depths.capacity) {
+ wasm_reserve_uint32s(allocator, &ctx->target_depths,
+ num_targets);
+ ctx->target_depths.size = num_targets;
+ }
+
+ uint32_t i;
+ for (i = 0; i < num_targets; ++i) {
+ uint32_t target_depth;
+ in_u32_leb128(ctx, &target_depth, "br_table target depth");
+ ctx->target_depths.data[i] = target_depth;
+ }
+
+ uint32_t default_target_depth;
+ in_u32_leb128(ctx, &default_target_depth,
+ "br_table default target depth");
+
+ CALLBACK(on_br_table_expr, num_targets, ctx->target_depths.data,
+ default_target_depth);
+ break;
+ }
+
+ case WASM_OPCODE_RETURN:
+ CALLBACK0(on_return_expr);
+ break;
+
+ case WASM_OPCODE_NOP:
+ CALLBACK0(on_nop_expr);
+ break;
+
+ case WASM_OPCODE_DROP:
+ CALLBACK0(on_drop_expr);
+ break;
+
+ case WASM_OPCODE_END:
+ if (ctx->offset == end_offset)
+ seen_end_opcode = WASM_TRUE;
+ else
+ CALLBACK0(on_end_expr);
+ break;
+
+ case WASM_OPCODE_I32_CONST: {
+ uint32_t value = 0;
+ in_i32_leb128(ctx, &value, "i32.const value");
+ CALLBACK(on_i32_const_expr, value);
+ break;
+ }
+
+ case WASM_OPCODE_I64_CONST: {
+ uint64_t value = 0;
+ in_i64_leb128(ctx, &value, "i64.const value");
+ CALLBACK(on_i64_const_expr, value);
+ break;
+ }
+
+ case WASM_OPCODE_F32_CONST: {
+ uint32_t value_bits = 0;
+ in_f32(ctx, &value_bits, "f32.const value");
+ CALLBACK(on_f32_const_expr, value_bits);
+ break;
+ }
+
+ case WASM_OPCODE_F64_CONST: {
+ uint64_t value_bits = 0;
+ in_f64(ctx, &value_bits, "f64.const value");
+ CALLBACK(on_f64_const_expr, value_bits);
+ break;
+ }
+
+ case WASM_OPCODE_GET_GLOBAL: {
+ uint32_t global_index;
+ in_u32_leb128(ctx, &global_index, "get_global global index");
+ CALLBACK(on_get_global_expr, global_index);
+ break;
+ }
+
+ case WASM_OPCODE_GET_LOCAL: {
+ uint32_t local_index;
+ in_u32_leb128(ctx, &local_index, "get_local local index");
+ CALLBACK(on_get_local_expr, local_index);
+ break;
+ }
+
+ case WASM_OPCODE_SET_GLOBAL: {
+ uint32_t global_index;
+ in_u32_leb128(ctx, &global_index, "set_global global index");
+ CALLBACK(on_set_global_expr, global_index);
+ break;
+ }
+
+ case WASM_OPCODE_SET_LOCAL: {
+ uint32_t local_index;
+ in_u32_leb128(ctx, &local_index, "set_local local index");
+ CALLBACK(on_set_local_expr, local_index);
+ break;
+ }
+
+ case WASM_OPCODE_CALL_FUNCTION: {
+ uint32_t func_index;
+ in_u32_leb128(ctx, &func_index, "call_function function index");
+ RAISE_ERROR_UNLESS(func_index < num_total_funcs(ctx),
+ "invalid call_function function index");
+ CALLBACK(on_call_expr, func_index);
+ break;
+ }
+
+ case WASM_OPCODE_CALL_INDIRECT: {
+ uint32_t sig_index;
+ in_u32_leb128(ctx, &sig_index, "call_indirect signature index");
+ RAISE_ERROR_UNLESS(sig_index < ctx->num_signatures,
+ "invalid call_indirect signature index");
+ CALLBACK(on_call_indirect_expr, sig_index);
+ break;
+ }
+
+ case WASM_OPCODE_TEE_LOCAL: {
+ uint32_t local_index;
+ in_u32_leb128(ctx, &local_index, "tee_local local index");
+ CALLBACK(on_tee_local_expr, local_index);
+ break;
+ }
+
+ case WASM_OPCODE_I32_LOAD8_S:
+ case WASM_OPCODE_I32_LOAD8_U:
+ case WASM_OPCODE_I32_LOAD16_S:
+ case WASM_OPCODE_I32_LOAD16_U:
+ case WASM_OPCODE_I64_LOAD8_S:
+ case WASM_OPCODE_I64_LOAD8_U:
+ case WASM_OPCODE_I64_LOAD16_S:
+ case WASM_OPCODE_I64_LOAD16_U:
+ case WASM_OPCODE_I64_LOAD32_S:
+ case WASM_OPCODE_I64_LOAD32_U:
+ case WASM_OPCODE_I32_LOAD:
+ case WASM_OPCODE_I64_LOAD:
+ case WASM_OPCODE_F32_LOAD:
+ case WASM_OPCODE_F64_LOAD: {
+ uint32_t alignment_log2;
+ in_u32_leb128(ctx, &alignment_log2, "load alignment");
+ uint32_t offset;
+ in_u32_leb128(ctx, &offset, "load offset");
+
+ CALLBACK(on_load_expr, opcode, alignment_log2, offset);
+ break;
+ }
+
+ case WASM_OPCODE_I32_STORE8:
+ case WASM_OPCODE_I32_STORE16:
+ case WASM_OPCODE_I64_STORE8:
+ case WASM_OPCODE_I64_STORE16:
+ case WASM_OPCODE_I64_STORE32:
+ case WASM_OPCODE_I32_STORE:
+ case WASM_OPCODE_I64_STORE:
+ case WASM_OPCODE_F32_STORE:
+ case WASM_OPCODE_F64_STORE: {
+ uint32_t alignment_log2;
+ in_u32_leb128(ctx, &alignment_log2, "store alignment");
+ uint32_t offset;
+ in_u32_leb128(ctx, &offset, "store offset");
+
+ CALLBACK(on_store_expr, opcode, alignment_log2, offset);
+ break;
+ }
+
+ case WASM_OPCODE_CURRENT_MEMORY:
+ CALLBACK0(on_current_memory_expr);
+ break;
+
+ case WASM_OPCODE_GROW_MEMORY:
+ CALLBACK0(on_grow_memory_expr);
+ break;
+
+ case WASM_OPCODE_I32_ADD:
+ case WASM_OPCODE_I32_SUB:
+ case WASM_OPCODE_I32_MUL:
+ case WASM_OPCODE_I32_DIV_S:
+ case WASM_OPCODE_I32_DIV_U:
+ case WASM_OPCODE_I32_REM_S:
+ case WASM_OPCODE_I32_REM_U:
+ case WASM_OPCODE_I32_AND:
+ case WASM_OPCODE_I32_OR:
+ case WASM_OPCODE_I32_XOR:
+ case WASM_OPCODE_I32_SHL:
+ case WASM_OPCODE_I32_SHR_U:
+ case WASM_OPCODE_I32_SHR_S:
+ case WASM_OPCODE_I32_ROTR:
+ case WASM_OPCODE_I32_ROTL:
+ case WASM_OPCODE_I64_ADD:
+ case WASM_OPCODE_I64_SUB:
+ case WASM_OPCODE_I64_MUL:
+ case WASM_OPCODE_I64_DIV_S:
+ case WASM_OPCODE_I64_DIV_U:
+ case WASM_OPCODE_I64_REM_S:
+ case WASM_OPCODE_I64_REM_U:
+ case WASM_OPCODE_I64_AND:
+ case WASM_OPCODE_I64_OR:
+ case WASM_OPCODE_I64_XOR:
+ case WASM_OPCODE_I64_SHL:
+ case WASM_OPCODE_I64_SHR_U:
+ case WASM_OPCODE_I64_SHR_S:
+ case WASM_OPCODE_I64_ROTR:
+ case WASM_OPCODE_I64_ROTL:
+ case WASM_OPCODE_F32_ADD:
+ case WASM_OPCODE_F32_SUB:
+ case WASM_OPCODE_F32_MUL:
+ case WASM_OPCODE_F32_DIV:
+ case WASM_OPCODE_F32_MIN:
+ case WASM_OPCODE_F32_MAX:
+ case WASM_OPCODE_F32_COPYSIGN:
+ case WASM_OPCODE_F64_ADD:
+ case WASM_OPCODE_F64_SUB:
+ case WASM_OPCODE_F64_MUL:
+ case WASM_OPCODE_F64_DIV:
+ case WASM_OPCODE_F64_MIN:
+ case WASM_OPCODE_F64_MAX:
+ case WASM_OPCODE_F64_COPYSIGN:
+ CALLBACK(on_binary_expr, opcode);
+ break;
+
+ case WASM_OPCODE_I32_EQ:
+ case WASM_OPCODE_I32_NE:
+ case WASM_OPCODE_I32_LT_S:
+ case WASM_OPCODE_I32_LE_S:
+ case WASM_OPCODE_I32_LT_U:
+ case WASM_OPCODE_I32_LE_U:
+ case WASM_OPCODE_I32_GT_S:
+ case WASM_OPCODE_I32_GE_S:
+ case WASM_OPCODE_I32_GT_U:
+ case WASM_OPCODE_I32_GE_U:
+ case WASM_OPCODE_I64_EQ:
+ case WASM_OPCODE_I64_NE:
+ case WASM_OPCODE_I64_LT_S:
+ case WASM_OPCODE_I64_LE_S:
+ case WASM_OPCODE_I64_LT_U:
+ case WASM_OPCODE_I64_LE_U:
+ case WASM_OPCODE_I64_GT_S:
+ case WASM_OPCODE_I64_GE_S:
+ case WASM_OPCODE_I64_GT_U:
+ case WASM_OPCODE_I64_GE_U:
+ case WASM_OPCODE_F32_EQ:
+ case WASM_OPCODE_F32_NE:
+ case WASM_OPCODE_F32_LT:
+ case WASM_OPCODE_F32_LE:
+ case WASM_OPCODE_F32_GT:
+ case WASM_OPCODE_F32_GE:
+ case WASM_OPCODE_F64_EQ:
+ case WASM_OPCODE_F64_NE:
+ case WASM_OPCODE_F64_LT:
+ case WASM_OPCODE_F64_LE:
+ case WASM_OPCODE_F64_GT:
+ case WASM_OPCODE_F64_GE:
+ CALLBACK(on_compare_expr, opcode);
+ break;
+
+ case WASM_OPCODE_I32_CLZ:
+ case WASM_OPCODE_I32_CTZ:
+ case WASM_OPCODE_I32_POPCNT:
+ case WASM_OPCODE_I64_CLZ:
+ case WASM_OPCODE_I64_CTZ:
+ case WASM_OPCODE_I64_POPCNT:
+ case WASM_OPCODE_F32_ABS:
+ case WASM_OPCODE_F32_NEG:
+ case WASM_OPCODE_F32_CEIL:
+ case WASM_OPCODE_F32_FLOOR:
+ case WASM_OPCODE_F32_TRUNC:
+ case WASM_OPCODE_F32_NEAREST:
+ case WASM_OPCODE_F32_SQRT:
+ case WASM_OPCODE_F64_ABS:
+ case WASM_OPCODE_F64_NEG:
+ case WASM_OPCODE_F64_CEIL:
+ case WASM_OPCODE_F64_FLOOR:
+ case WASM_OPCODE_F64_TRUNC:
+ case WASM_OPCODE_F64_NEAREST:
+ case WASM_OPCODE_F64_SQRT:
+ CALLBACK(on_unary_expr, opcode);
+ break;
+
+ case WASM_OPCODE_I32_TRUNC_S_F32:
+ case WASM_OPCODE_I32_TRUNC_S_F64:
+ case WASM_OPCODE_I32_TRUNC_U_F32:
+ case WASM_OPCODE_I32_TRUNC_U_F64:
+ case WASM_OPCODE_I32_WRAP_I64:
+ case WASM_OPCODE_I64_TRUNC_S_F32:
+ case WASM_OPCODE_I64_TRUNC_S_F64:
+ case WASM_OPCODE_I64_TRUNC_U_F32:
+ case WASM_OPCODE_I64_TRUNC_U_F64:
+ case WASM_OPCODE_I64_EXTEND_S_I32:
+ case WASM_OPCODE_I64_EXTEND_U_I32:
+ case WASM_OPCODE_F32_CONVERT_S_I32:
+ case WASM_OPCODE_F32_CONVERT_U_I32:
+ case WASM_OPCODE_F32_CONVERT_S_I64:
+ case WASM_OPCODE_F32_CONVERT_U_I64:
+ case WASM_OPCODE_F32_DEMOTE_F64:
+ case WASM_OPCODE_F32_REINTERPRET_I32:
+ case WASM_OPCODE_F64_CONVERT_S_I32:
+ case WASM_OPCODE_F64_CONVERT_U_I32:
+ case WASM_OPCODE_F64_CONVERT_S_I64:
+ case WASM_OPCODE_F64_CONVERT_U_I64:
+ case WASM_OPCODE_F64_PROMOTE_F32:
+ case WASM_OPCODE_F64_REINTERPRET_I64:
+ case WASM_OPCODE_I32_REINTERPRET_F32:
+ case WASM_OPCODE_I64_REINTERPRET_F64:
+ case WASM_OPCODE_I32_EQZ:
+ case WASM_OPCODE_I64_EQZ:
+ CALLBACK(on_convert_expr, opcode);
+ break;
+
+ default:
+ RAISE_ERROR("unexpected opcode: %d (0x%x)", opcode, opcode);
+ }
+ }
+ RAISE_ERROR_UNLESS(ctx->offset == end_offset,
+ "function body longer than given size");
+ RAISE_ERROR_UNLESS(seen_end_opcode,
+ "function body must end with END opcode");
+}
+
WasmResult wasm_read_binary(WasmAllocator* allocator,
const void* data,
size_t size,
@@ -1533,385 +1917,8 @@ WasmResult wasm_read_binary(WasmAllocator* allocator,
CALLBACK(on_local_decl, k, num_local_types, local_type);
}
- WasmBool seen_end_opcode = WASM_FALSE;
- while (ctx->offset < end_offset) {
- uint8_t opcode;
- in_u8(ctx, &opcode, "opcode");
- CALLBACK(on_opcode, opcode);
- switch (opcode) {
- case WASM_OPCODE_UNREACHABLE:
- CALLBACK0(on_unreachable_expr);
- break;
-
- case WASM_OPCODE_BLOCK: {
- uint8_t sig_type;
- in_u8(ctx, &sig_type, "block signature type");
- RAISE_ERROR_UNLESS(is_inline_sig_type(sig_type),
- "expected valid block signature type");
- uint32_t num_types = sig_type == WASM_TYPE_VOID ? 0 : 1;
- CALLBACK(on_block_expr, num_types, &sig_type);
- break;
- }
-
- case WASM_OPCODE_LOOP: {
- uint8_t sig_type;
- in_u8(ctx, &sig_type, "loop signature type");
- RAISE_ERROR_UNLESS(is_inline_sig_type(sig_type),
- "expected valid block signature type");
- uint32_t num_types = sig_type == WASM_TYPE_VOID ? 0 : 1;
- CALLBACK(on_loop_expr, num_types, &sig_type);
- break;
- }
-
- case WASM_OPCODE_IF: {
- uint8_t sig_type;
- in_u8(ctx, &sig_type, "if signature type");
- RAISE_ERROR_UNLESS(is_inline_sig_type(sig_type),
- "expected valid block signature type");
- uint32_t num_types = sig_type == WASM_TYPE_VOID ? 0 : 1;
- CALLBACK(on_if_expr, num_types, &sig_type);
- break;
- }
-
- case WASM_OPCODE_ELSE:
- CALLBACK0(on_else_expr);
- break;
-
- case WASM_OPCODE_SELECT:
- CALLBACK0(on_select_expr);
- break;
-
- case WASM_OPCODE_BR: {
- uint32_t depth;
- in_u32_leb128(ctx, &depth, "br depth");
- CALLBACK(on_br_expr, depth);
- break;
- }
-
- case WASM_OPCODE_BR_IF: {
- uint32_t depth;
- in_u32_leb128(ctx, &depth, "br_if depth");
- CALLBACK(on_br_if_expr, depth);
- break;
- }
-
- case WASM_OPCODE_BR_TABLE: {
- uint32_t num_targets;
- in_u32_leb128(ctx, &num_targets, "br_table target count");
- if (num_targets > ctx->target_depths.capacity) {
- wasm_reserve_uint32s(allocator, &ctx->target_depths,
- num_targets);
- ctx->target_depths.size = num_targets;
- }
-
- uint32_t i;
- for (i = 0; i < num_targets; ++i) {
- uint32_t target_depth;
- in_u32_leb128(ctx, &target_depth, "br_table target depth");
- ctx->target_depths.data[i] = target_depth;
- }
-
- uint32_t default_target_depth;
- in_u32_leb128(ctx, &default_target_depth,
- "br_table default target depth");
-
- CALLBACK(on_br_table_expr, num_targets, ctx->target_depths.data,
- default_target_depth);
- break;
- }
-
- case WASM_OPCODE_RETURN:
- CALLBACK0(on_return_expr);
- break;
-
- case WASM_OPCODE_NOP:
- CALLBACK0(on_nop_expr);
- break;
-
- case WASM_OPCODE_DROP:
- CALLBACK0(on_drop_expr);
- break;
-
- case WASM_OPCODE_END:
- if (ctx->offset == end_offset)
- seen_end_opcode = WASM_TRUE;
- else
- CALLBACK0(on_end_expr);
- break;
-
- case WASM_OPCODE_I32_CONST: {
- uint32_t value = 0;
- in_i32_leb128(ctx, &value, "i32.const value");
- CALLBACK(on_i32_const_expr, value);
- break;
- }
-
- case WASM_OPCODE_I64_CONST: {
- uint64_t value = 0;
- in_i64_leb128(ctx, &value, "i64.const value");
- CALLBACK(on_i64_const_expr, value);
- break;
- }
-
- case WASM_OPCODE_F32_CONST: {
- uint32_t value_bits = 0;
- in_f32(ctx, &value_bits, "f32.const value");
- CALLBACK(on_f32_const_expr, value_bits);
- break;
- }
-
- case WASM_OPCODE_F64_CONST: {
- uint64_t value_bits = 0;
- in_f64(ctx, &value_bits, "f64.const value");
- CALLBACK(on_f64_const_expr, value_bits);
- break;
- }
-
- case WASM_OPCODE_GET_GLOBAL: {
- uint32_t global_index;
- in_u32_leb128(ctx, &global_index, "get_global global index");
- CALLBACK(on_get_global_expr, global_index);
- break;
- }
-
- case WASM_OPCODE_GET_LOCAL: {
- uint32_t local_index;
- in_u32_leb128(ctx, &local_index, "get_local local index");
- CALLBACK(on_get_local_expr, local_index);
- break;
- }
-
- case WASM_OPCODE_SET_GLOBAL: {
- uint32_t global_index;
- in_u32_leb128(ctx, &global_index, "set_global global index");
- CALLBACK(on_set_global_expr, global_index);
- break;
- }
-
- case WASM_OPCODE_SET_LOCAL: {
- uint32_t local_index;
- in_u32_leb128(ctx, &local_index, "set_local local index");
- CALLBACK(on_set_local_expr, local_index);
- break;
- }
-
- case WASM_OPCODE_CALL_FUNCTION: {
- uint32_t func_index;
- in_u32_leb128(ctx, &func_index, "call_function function index");
- RAISE_ERROR_UNLESS(func_index < num_total_funcs(ctx),
- "invalid call_function function index");
- CALLBACK(on_call_expr, func_index);
- break;
- }
-
- case WASM_OPCODE_CALL_INDIRECT: {
- uint32_t sig_index;
- in_u32_leb128(ctx, &sig_index, "call_indirect signature index");
- RAISE_ERROR_UNLESS(sig_index < ctx->num_signatures,
- "invalid call_indirect signature index");
- CALLBACK(on_call_indirect_expr, sig_index);
- break;
- }
-
- case WASM_OPCODE_TEE_LOCAL: {
- uint32_t local_index;
- in_u32_leb128(ctx, &local_index, "tee_local local index");
- CALLBACK(on_tee_local_expr, local_index);
- break;
- }
-
- case WASM_OPCODE_I32_LOAD8_S:
- case WASM_OPCODE_I32_LOAD8_U:
- case WASM_OPCODE_I32_LOAD16_S:
- case WASM_OPCODE_I32_LOAD16_U:
- case WASM_OPCODE_I64_LOAD8_S:
- case WASM_OPCODE_I64_LOAD8_U:
- case WASM_OPCODE_I64_LOAD16_S:
- case WASM_OPCODE_I64_LOAD16_U:
- case WASM_OPCODE_I64_LOAD32_S:
- case WASM_OPCODE_I64_LOAD32_U:
- case WASM_OPCODE_I32_LOAD:
- case WASM_OPCODE_I64_LOAD:
- case WASM_OPCODE_F32_LOAD:
- case WASM_OPCODE_F64_LOAD: {
- uint32_t alignment_log2;
- in_u32_leb128(ctx, &alignment_log2, "load alignment");
- uint32_t offset;
- in_u32_leb128(ctx, &offset, "load offset");
-
- CALLBACK(on_load_expr, opcode, alignment_log2, offset);
- break;
- }
-
- case WASM_OPCODE_I32_STORE8:
- case WASM_OPCODE_I32_STORE16:
- case WASM_OPCODE_I64_STORE8:
- case WASM_OPCODE_I64_STORE16:
- case WASM_OPCODE_I64_STORE32:
- case WASM_OPCODE_I32_STORE:
- case WASM_OPCODE_I64_STORE:
- case WASM_OPCODE_F32_STORE:
- case WASM_OPCODE_F64_STORE: {
- uint32_t alignment_log2;
- in_u32_leb128(ctx, &alignment_log2, "store alignment");
- uint32_t offset;
- in_u32_leb128(ctx, &offset, "store offset");
-
- CALLBACK(on_store_expr, opcode, alignment_log2, offset);
- break;
- }
-
- case WASM_OPCODE_CURRENT_MEMORY:
- CALLBACK0(on_current_memory_expr);
- break;
-
- case WASM_OPCODE_GROW_MEMORY:
- CALLBACK0(on_grow_memory_expr);
- break;
-
- case WASM_OPCODE_I32_ADD:
- case WASM_OPCODE_I32_SUB:
- case WASM_OPCODE_I32_MUL:
- case WASM_OPCODE_I32_DIV_S:
- case WASM_OPCODE_I32_DIV_U:
- case WASM_OPCODE_I32_REM_S:
- case WASM_OPCODE_I32_REM_U:
- case WASM_OPCODE_I32_AND:
- case WASM_OPCODE_I32_OR:
- case WASM_OPCODE_I32_XOR:
- case WASM_OPCODE_I32_SHL:
- case WASM_OPCODE_I32_SHR_U:
- case WASM_OPCODE_I32_SHR_S:
- case WASM_OPCODE_I32_ROTR:
- case WASM_OPCODE_I32_ROTL:
- case WASM_OPCODE_I64_ADD:
- case WASM_OPCODE_I64_SUB:
- case WASM_OPCODE_I64_MUL:
- case WASM_OPCODE_I64_DIV_S:
- case WASM_OPCODE_I64_DIV_U:
- case WASM_OPCODE_I64_REM_S:
- case WASM_OPCODE_I64_REM_U:
- case WASM_OPCODE_I64_AND:
- case WASM_OPCODE_I64_OR:
- case WASM_OPCODE_I64_XOR:
- case WASM_OPCODE_I64_SHL:
- case WASM_OPCODE_I64_SHR_U:
- case WASM_OPCODE_I64_SHR_S:
- case WASM_OPCODE_I64_ROTR:
- case WASM_OPCODE_I64_ROTL:
- case WASM_OPCODE_F32_ADD:
- case WASM_OPCODE_F32_SUB:
- case WASM_OPCODE_F32_MUL:
- case WASM_OPCODE_F32_DIV:
- case WASM_OPCODE_F32_MIN:
- case WASM_OPCODE_F32_MAX:
- case WASM_OPCODE_F32_COPYSIGN:
- case WASM_OPCODE_F64_ADD:
- case WASM_OPCODE_F64_SUB:
- case WASM_OPCODE_F64_MUL:
- case WASM_OPCODE_F64_DIV:
- case WASM_OPCODE_F64_MIN:
- case WASM_OPCODE_F64_MAX:
- case WASM_OPCODE_F64_COPYSIGN:
- CALLBACK(on_binary_expr, opcode);
- break;
-
- case WASM_OPCODE_I32_EQ:
- case WASM_OPCODE_I32_NE:
- case WASM_OPCODE_I32_LT_S:
- case WASM_OPCODE_I32_LE_S:
- case WASM_OPCODE_I32_LT_U:
- case WASM_OPCODE_I32_LE_U:
- case WASM_OPCODE_I32_GT_S:
- case WASM_OPCODE_I32_GE_S:
- case WASM_OPCODE_I32_GT_U:
- case WASM_OPCODE_I32_GE_U:
- case WASM_OPCODE_I64_EQ:
- case WASM_OPCODE_I64_NE:
- case WASM_OPCODE_I64_LT_S:
- case WASM_OPCODE_I64_LE_S:
- case WASM_OPCODE_I64_LT_U:
- case WASM_OPCODE_I64_LE_U:
- case WASM_OPCODE_I64_GT_S:
- case WASM_OPCODE_I64_GE_S:
- case WASM_OPCODE_I64_GT_U:
- case WASM_OPCODE_I64_GE_U:
- case WASM_OPCODE_F32_EQ:
- case WASM_OPCODE_F32_NE:
- case WASM_OPCODE_F32_LT:
- case WASM_OPCODE_F32_LE:
- case WASM_OPCODE_F32_GT:
- case WASM_OPCODE_F32_GE:
- case WASM_OPCODE_F64_EQ:
- case WASM_OPCODE_F64_NE:
- case WASM_OPCODE_F64_LT:
- case WASM_OPCODE_F64_LE:
- case WASM_OPCODE_F64_GT:
- case WASM_OPCODE_F64_GE:
- CALLBACK(on_compare_expr, opcode);
- break;
-
- case WASM_OPCODE_I32_CLZ:
- case WASM_OPCODE_I32_CTZ:
- case WASM_OPCODE_I32_POPCNT:
- case WASM_OPCODE_I64_CLZ:
- case WASM_OPCODE_I64_CTZ:
- case WASM_OPCODE_I64_POPCNT:
- case WASM_OPCODE_F32_ABS:
- case WASM_OPCODE_F32_NEG:
- case WASM_OPCODE_F32_CEIL:
- case WASM_OPCODE_F32_FLOOR:
- case WASM_OPCODE_F32_TRUNC:
- case WASM_OPCODE_F32_NEAREST:
- case WASM_OPCODE_F32_SQRT:
- case WASM_OPCODE_F64_ABS:
- case WASM_OPCODE_F64_NEG:
- case WASM_OPCODE_F64_CEIL:
- case WASM_OPCODE_F64_FLOOR:
- case WASM_OPCODE_F64_TRUNC:
- case WASM_OPCODE_F64_NEAREST:
- case WASM_OPCODE_F64_SQRT:
- CALLBACK(on_unary_expr, opcode);
- break;
-
- case WASM_OPCODE_I32_TRUNC_S_F32:
- case WASM_OPCODE_I32_TRUNC_S_F64:
- case WASM_OPCODE_I32_TRUNC_U_F32:
- case WASM_OPCODE_I32_TRUNC_U_F64:
- case WASM_OPCODE_I32_WRAP_I64:
- case WASM_OPCODE_I64_TRUNC_S_F32:
- case WASM_OPCODE_I64_TRUNC_S_F64:
- case WASM_OPCODE_I64_TRUNC_U_F32:
- case WASM_OPCODE_I64_TRUNC_U_F64:
- case WASM_OPCODE_I64_EXTEND_S_I32:
- case WASM_OPCODE_I64_EXTEND_U_I32:
- case WASM_OPCODE_F32_CONVERT_S_I32:
- case WASM_OPCODE_F32_CONVERT_U_I32:
- case WASM_OPCODE_F32_CONVERT_S_I64:
- case WASM_OPCODE_F32_CONVERT_U_I64:
- case WASM_OPCODE_F32_DEMOTE_F64:
- case WASM_OPCODE_F32_REINTERPRET_I32:
- case WASM_OPCODE_F64_CONVERT_S_I32:
- case WASM_OPCODE_F64_CONVERT_U_I32:
- case WASM_OPCODE_F64_CONVERT_S_I64:
- case WASM_OPCODE_F64_CONVERT_U_I64:
- case WASM_OPCODE_F64_PROMOTE_F32:
- case WASM_OPCODE_F64_REINTERPRET_I64:
- case WASM_OPCODE_I32_REINTERPRET_F32:
- case WASM_OPCODE_I64_REINTERPRET_F64:
- case WASM_OPCODE_I32_EQZ:
- case WASM_OPCODE_I64_EQZ:
- CALLBACK(on_convert_expr, opcode);
- break;
-
- default:
- RAISE_ERROR("unexpected opcode: %d (0x%x)", opcode, opcode);
- }
- }
- RAISE_ERROR_UNLESS(ctx->offset == end_offset,
- "function body longer than given size");
- RAISE_ERROR_UNLESS(seen_end_opcode,
- "function body must end with END opcode");
+ read_function_body(ctx, allocator, end_offset);
+
CALLBACK(end_function_body, i);
CALLBACK(end_function_body_pass, i, j);
}