diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/binary-reader-ast.c | 9 | ||||
-rw-r--r-- | src/binary-reader-objdump.c | 50 | ||||
-rw-r--r-- | src/binary-reader.c | 71 | ||||
-rw-r--r-- | src/binary-reader.h | 19 | ||||
-rw-r--r-- | src/binary-writer.c | 337 | ||||
-rw-r--r-- | src/binary-writer.h | 34 |
6 files changed, 295 insertions, 225 deletions
diff --git a/src/binary-reader-ast.c b/src/binary-reader-ast.c index 01c092b1..e82b82c2 100644 --- a/src/binary-reader-ast.c +++ b/src/binary-reader-ast.c @@ -837,10 +837,11 @@ static WasmResult end_elem_segment_init_expr(uint32_t index, void* user_data) { return WASM_OK; } -static WasmResult on_elem_segment_function_index_count(uint32_t index, - uint32_t count, - void* user_data) { - Context* ctx = user_data; +static WasmResult on_elem_segment_function_index_count( + WasmBinaryReaderContext* context, + uint32_t index, + uint32_t count) { + Context* ctx = context->user_data; assert(index == ctx->module->elem_segments.size - 1); WasmElemSegment* segment = ctx->module->elem_segments.data[index]; wasm_reserve_vars(ctx->allocator, &segment->vars, count); diff --git a/src/binary-reader-objdump.c b/src/binary-reader-objdump.c index 7665f25f..4633410a 100644 --- a/src/binary-reader-objdump.c +++ b/src/binary-reader-objdump.c @@ -61,16 +61,10 @@ static void WASM_PRINTF_FORMAT(2, 3) va_end(args); } -#define SEGSTART(segname, name) \ - static WasmResult begin_##segname##_section(WasmBinaryReaderContext* ctx, \ - uint32_t size) { \ - return begin_section(ctx->user_data, name, ctx->offset, size); \ - } - -static WasmResult begin_section(Context* ctx, - const char* name, - size_t offset, - size_t size) { +static WasmResult do_begin_section(Context* ctx, + const char* name, + size_t offset, + size_t size) { switch (ctx->options->mode) { case WASM_DUMP_HEADERS: printf("%9s start=%#010" PRIzx " end=%#010" PRIzx " (size=%#010" PRIzx @@ -97,12 +91,17 @@ static WasmResult begin_section(Context* ctx, return WASM_OK; } +static WasmResult begin_section(WasmBinaryReaderContext* ctx, + WasmBinarySection type, + uint32_t size) { + return do_begin_section(ctx->user_data, wasm_get_section_name(type), + ctx->offset, size); +} + static WasmResult begin_custom_section(WasmBinaryReaderContext* ctx, uint32_t size, WasmStringSlice section_name) { Context* context = ctx->user_data; - if (begin_section(context, "CUSTOM", ctx->offset, size)) - return WASM_ERROR; print_details(context, " - name: \"" PRIstringslice "\"\n", WASM_PRINTF_STRING_SLICE_ARG(section_name)); if (context->options->mode == WASM_DUMP_HEADERS) @@ -110,18 +109,6 @@ static WasmResult begin_custom_section(WasmBinaryReaderContext* ctx, return WASM_OK; } -SEGSTART(signature, "TYPE") -SEGSTART(import, "IMPORT") -SEGSTART(function_signatures, "FUNCTION") -SEGSTART(table, "TABLE") -SEGSTART(memory, "MEMORY") -SEGSTART(global, "GLOBAL") -SEGSTART(export, "EXPORT") -SEGSTART(start, "START") -SEGSTART(function_bodies, "CODE") -SEGSTART(elem, "ELEM") -SEGSTART(data, "DATA") - static WasmResult on_count(uint32_t count, void* user_data) { Context* ctx = user_data; if (ctx->options->mode == WASM_DUMP_HEADERS) { @@ -608,16 +595,16 @@ static WasmBinaryReader s_binary_reader = { .end_module = end_module, .on_error = on_error, + .begin_section = begin_section, + // User section .begin_custom_section = begin_custom_section, // Signature section - .begin_signature_section = begin_signature_section, .on_signature_count = on_count, .on_signature = on_signature, // Import section - .begin_import_section = begin_import_section, .on_import_count = on_count, .on_import = on_import, .on_import_func = on_import_func, @@ -626,46 +613,35 @@ static WasmBinaryReader s_binary_reader = { .on_import_global = on_import_global, // Function sigs section - .begin_function_signatures_section = begin_function_signatures_section, .on_function_signatures_count = on_count, .on_function_signature = on_function_signature, // Table section - .begin_table_section = begin_table_section, .on_table_count = on_count, .on_table = on_table, // Memory section - .begin_memory_section = begin_memory_section, .on_memory_count = on_count, .on_memory = on_memory, // Globl seciont - .begin_global_section = begin_global_section, .begin_global = begin_global, .on_global_count = on_count, // Export section - .begin_export_section = begin_export_section, .on_export_count = on_count, .on_export = on_export, - // Start section - .begin_start_section = begin_start_section, - // Body section - .begin_function_bodies_section = begin_function_bodies_section, .on_function_bodies_count = on_count, .begin_function_body = begin_function_body, // Elems section - .begin_elem_section = begin_elem_section, .begin_elem_segment = begin_elem_segment, .on_elem_segment_count = on_count, .on_elem_segment_function_index = on_elem_segment_function_index, // Data section - .begin_data_section = begin_data_section, .begin_data_segment = begin_data_segment, .on_data_segment_data = on_data_segment_data, .on_data_segment_count = on_count, diff --git a/src/binary-reader.c b/src/binary-reader.c index 5fe7977a..a8bc2fd6 100644 --- a/src/binary-reader.c +++ b/src/binary-reader.c @@ -200,72 +200,88 @@ static void in_f64(Context* ctx, uint64_t* out_value, const char* desc) { ((type)((value) << SHIFT_AMOUNT(type, sign_bit)) >> \ SHIFT_AMOUNT(type, sign_bit)) -static void in_u32_leb128(Context* ctx, uint32_t* out_value, const char* desc) { - const uint8_t* p = ctx->data + ctx->offset; - const uint8_t* end = ctx->data + ctx->section_end; - +size_t wasm_read_u32_leb128(const uint8_t* p, + const uint8_t* end, + uint32_t* out_value) { if (p < end && (p[0] & 0x80) == 0) { *out_value = LEB128_1(uint32_t); - ctx->offset += 1; + return 1; } else if (p + 1 < end && (p[1] & 0x80) == 0) { *out_value = LEB128_2(uint32_t); - ctx->offset += 2; + return 2; } else if (p + 2 < end && (p[2] & 0x80) == 0) { *out_value = LEB128_3(uint32_t); - ctx->offset += 3; + return 3; } else if (p + 3 < end && (p[3] & 0x80) == 0) { *out_value = LEB128_4(uint32_t); - ctx->offset += 4; + return 4; } else if (p + 4 < end && (p[4] & 0x80) == 0) { /* the top bits set represent values > 32 bits */ if (p[4] & 0xf0) - RAISE_ERROR("invalid u32 leb128: %s", desc); + return 0; *out_value = LEB128_5(uint32_t); - ctx->offset += 5; + return 5; } else { /* past the end */ *out_value = 0; - RAISE_ERROR("unable to read u32 leb128: %s", desc); + return 0; } } -static void in_i32_leb128(Context* ctx, uint32_t* out_value, const char* desc) { +static void in_u32_leb128(Context* ctx, uint32_t* out_value, const char* desc) { const uint8_t* p = ctx->data + ctx->offset; const uint8_t* end = ctx->data + ctx->section_end; + size_t bytes_read = wasm_read_u32_leb128(p, end, out_value); + if (!bytes_read) + RAISE_ERROR("unable to read u32 leb128: %s", desc); + ctx->offset += bytes_read; +} +size_t wasm_read_i32_leb128(const uint8_t* p, + const uint8_t* end, + uint32_t* out_value) { if (p < end && (p[0] & 0x80) == 0) { uint32_t result = LEB128_1(uint32_t); *out_value = SIGN_EXTEND(int32_t, result, 6); - ctx->offset += 1; + return 1; } else if (p + 1 < end && (p[1] & 0x80) == 0) { uint32_t result = LEB128_2(uint32_t); *out_value = SIGN_EXTEND(int32_t, result, 13); - ctx->offset += 2; + return 2; } else if (p + 2 < end && (p[2] & 0x80) == 0) { uint32_t result = LEB128_3(uint32_t); *out_value = SIGN_EXTEND(int32_t, result, 20); - ctx->offset += 3; + return 3; } else if (p + 3 < end && (p[3] & 0x80) == 0) { uint32_t result = LEB128_4(uint32_t); *out_value = SIGN_EXTEND(int32_t, result, 27); - ctx->offset += 4; + return 4; } else if (p + 4 < end && (p[4] & 0x80) == 0) { /* the top bits should be a sign-extension of the sign bit */ WasmBool sign_bit_set = (p[4] & 0x8); int top_bits = p[4] & 0xf0; if ((sign_bit_set && top_bits != 0x70) || (!sign_bit_set && top_bits != 0)) { - RAISE_ERROR("invalid i32 leb128: %s", desc); + return 0; } uint32_t result = LEB128_5(uint32_t); *out_value = result; - ctx->offset += 5; + return 5; } else { /* past the end */ - RAISE_ERROR("unable to read i32 leb128: %s", desc); + return 0; } } +static void in_i32_leb128(Context* ctx, uint32_t* out_value, const char* desc) { + const uint8_t* p = ctx->data + ctx->offset; + const uint8_t* end = ctx->data + ctx->section_end; + size_t bytes_read = wasm_read_i32_leb128(p, end, out_value); + if (!bytes_read) + RAISE_ERROR("unable to read i32 leb128: %s", desc); + ctx->offset += bytes_read; +} + static void in_i64_leb128(Context* ctx, uint64_t* out_value, const char* desc) { const uint8_t* p = ctx->data + ctx->offset; const uint8_t* end = ctx->data + ctx->section_end; @@ -465,6 +481,7 @@ static WasmBool skip_until_section(Context* ctx, RAISE_ERROR("invalid section size: extends past end"); if (section_code == WASM_BINARY_SECTION_CUSTOM) { + CALLBACK_CTX(begin_section, section_code, *section_size); WasmStringSlice section_name; in_str(ctx, §ion_name, "section name"); handle_custom_section(ctx, §ion_name, *section_size); @@ -478,6 +495,7 @@ static WasmBool skip_until_section(Context* ctx, } if (section_code == expected_code) { + CALLBACK_CTX(begin_section, section_code, *section_size); return WASM_TRUE; } else if (section_code < expected_code) { RAISE_ERROR("section %s out of order", s_section_name[section_code]); @@ -588,6 +606,14 @@ static WasmResult logging_begin_custom_section(WasmBinaryReaderContext* context, FORWARD(name, value0, value1); \ } +#define LOGGING_UINT32_UINT32_CTX(name, desc0, desc1) \ + static WasmResult logging_##name(WasmBinaryReaderContext* context, \ + uint32_t value0, uint32_t value1) { \ + LoggingContext* ctx = context->user_data; \ + LOGF(#name "(" desc0 ": %u, " desc1 ": %u)\n", value0, value1); \ + FORWARD_CTX(name, value0, value1); \ + } + #define LOGGING_OPCODE(name) \ static WasmResult logging_##name(WasmOpcode opcode, void* user_data) { \ LoggingContext* ctx = user_data; \ @@ -666,7 +692,9 @@ LOGGING_UINT32(on_elem_segment_count) LOGGING_UINT32_UINT32(begin_elem_segment, "index", "table_index") LOGGING_UINT32(begin_elem_segment_init_expr) LOGGING_UINT32(end_elem_segment_init_expr) -LOGGING_UINT32_UINT32(on_elem_segment_function_index_count, "index", "count") +LOGGING_UINT32_UINT32_CTX(on_elem_segment_function_index_count, + "index", + "count") LOGGING_UINT32_UINT32(on_elem_segment_function_index, "index", "func_index") LOGGING_UINT32(end_elem_segment) LOGGING_END(elem_section) @@ -1982,7 +2010,8 @@ WasmResult wasm_read_binary(WasmAllocator* allocator, uint32_t j, num_function_indexes; in_u32_leb128(ctx, &num_function_indexes, "elem segment function index count"); - CALLBACK(on_elem_segment_function_index_count, i, num_function_indexes); + CALLBACK_CTX(on_elem_segment_function_index_count, i, + num_function_indexes); for (j = 0; j < num_function_indexes; ++j) { uint32_t func_index; in_u32_leb128(ctx, &func_index, "elem segment function index"); diff --git a/src/binary-reader.h b/src/binary-reader.h index e51c0f01..93ffe1cc 100644 --- a/src/binary-reader.h +++ b/src/binary-reader.h @@ -49,6 +49,10 @@ typedef struct WasmBinaryReader { WasmResult (*begin_module)(uint32_t version, void* user_data); WasmResult (*end_module)(void* user_data); + WasmResult (*begin_section)(WasmBinaryReaderContext* ctx, + WasmBinarySection section_type, + uint32_t size); + /* custom section */ WasmResult (*begin_custom_section)(WasmBinaryReaderContext* ctx, uint32_t size, @@ -242,9 +246,10 @@ typedef struct WasmBinaryReader { void* user_data); WasmResult (*begin_elem_segment_init_expr)(uint32_t index, void* user_data); WasmResult (*end_elem_segment_init_expr)(uint32_t index, void* user_data); - WasmResult (*on_elem_segment_function_index_count)(uint32_t index, - uint32_t count, - void* user_data); + WasmResult (*on_elem_segment_function_index_count)( + WasmBinaryReaderContext* ctx, + uint32_t index, + uint32_t count); WasmResult (*on_elem_segment_function_index)(uint32_t index, uint32_t func_index, void* user_data); @@ -308,6 +313,14 @@ WasmResult wasm_read_binary(struct WasmAllocator* allocator, WasmBinaryReader* reader, uint32_t num_function_passes, const WasmReadBinaryOptions* options); + +size_t wasm_read_u32_leb128(const uint8_t* ptr, + const uint8_t* end, + uint32_t* out_value); + +size_t wasm_read_i32_leb128(const uint8_t* ptr, + const uint8_t* end, + uint32_t* out_value); WASM_EXTERN_C_END #endif /* WASM_BINARY_READER_H_ */ diff --git a/src/binary-writer.c b/src/binary-writer.c index 9e87799b..10d8ee29 100644 --- a/src/binary-writer.c +++ b/src/binary-writer.c @@ -78,10 +78,10 @@ static void write_header(Context* ctx, const char* name, int index) { } while (1) /* returns the length of the leb128 */ -static uint32_t write_u32_leb128_at(WasmStream* stream, - uint32_t offset, - uint32_t value, - const char* desc) { +uint32_t wasm_write_u32_leb128_at(WasmStream* stream, + uint32_t offset, + uint32_t value, + const char* desc) { uint8_t data[MAX_U32_LEB128_BYTES]; uint32_t i = 0; LEB128_LOOP_UNTIL(value == 0); @@ -90,31 +90,49 @@ static uint32_t write_u32_leb128_at(WasmStream* stream, return length; } -static uint32_t write_fixed_u32_leb128_at(WasmStream* stream, - uint32_t offset, - uint32_t value, - const char* desc) { - uint8_t data[MAX_U32_LEB128_BYTES]; +uint32_t wasm_write_fixed_u32_leb128_raw(uint8_t* data, + uint8_t* end, + uint32_t value) { + if (end - data < MAX_U32_LEB128_BYTES) + return 0; data[0] = (value & 0x7f) | 0x80; data[1] = ((value >> 7) & 0x7f) | 0x80; data[2] = ((value >> 14) & 0x7f) | 0x80; data[3] = ((value >> 21) & 0x7f) | 0x80; data[4] = ((value >> 28) & 0x0f); - wasm_write_data_at(stream, offset, data, MAX_U32_LEB128_BYTES, - WASM_DONT_PRINT_CHARS, desc); return MAX_U32_LEB128_BYTES; } -static void write_u32_leb128(WasmStream* stream, - uint32_t value, - const char* desc) { - uint32_t length = write_u32_leb128_at(stream, stream->offset, value, desc); +uint32_t wasm_write_fixed_u32_leb128_at(WasmStream* stream, + uint32_t offset, + uint32_t value, + const char* desc) { + uint8_t data[MAX_U32_LEB128_BYTES]; + uint32_t length = + wasm_write_fixed_u32_leb128_raw(data, data + MAX_U32_LEB128_BYTES, value); + wasm_write_data_at(stream, offset, data, length, WASM_DONT_PRINT_CHARS, desc); + return length; +} + +void wasm_write_u32_leb128(WasmStream* stream, + uint32_t value, + const char* desc) { + uint32_t length = + wasm_write_u32_leb128_at(stream, stream->offset, value, desc); stream->offset += length; } -static void write_i32_leb128(WasmStream* stream, - int32_t value, - const char* desc) { +void wasm_write_fixed_u32_leb128(WasmStream* stream, + uint32_t value, + const char* desc) { + uint32_t length = + wasm_write_fixed_u32_leb128_at(stream, stream->offset, value, desc); + stream->offset += length; +} + +void wasm_write_i32_leb128(WasmStream* stream, + int32_t value, + const char* desc) { uint8_t data[MAX_U32_LEB128_BYTES]; uint32_t i = 0; if (value < 0) @@ -180,38 +198,38 @@ static void write_fixup_u32_leb128_size(Context* ctx, uint32_t dst_offset = offset + leb_size; wasm_move_data(&ctx->stream, dst_offset, src_offset, size); } - write_u32_leb128_at(&ctx->stream, offset, size, desc); + wasm_write_u32_leb128_at(&ctx->stream, offset, size, desc); ctx->stream.offset += leb_size - leb_size_guess; } else { uint32_t size = ctx->stream.offset - offset - MAX_U32_LEB128_BYTES; - write_fixed_u32_leb128_at(&ctx->stream, offset, size, desc); + wasm_write_fixed_u32_leb128_at(&ctx->stream, offset, size, desc); } } -static void write_str(WasmStream* stream, - const char* s, - size_t length, - WasmPrintChars print_chars, - const char* desc) { - write_u32_leb128(stream, length, "string length"); +void wasm_write_str(WasmStream* stream, + const char* s, + size_t length, + WasmPrintChars print_chars, + const char* desc) { + wasm_write_u32_leb128(stream, length, "string length"); wasm_write_data_at(stream, stream->offset, s, length, print_chars, desc); stream->offset += length; } -static void write_opcode(WasmStream* stream, uint8_t opcode) { +void wasm_write_opcode(WasmStream* stream, uint8_t opcode) { wasm_write_u8(stream, opcode, wasm_get_opcode_name(opcode)); } -static void write_type(WasmStream* stream, WasmType type) { - write_i32_leb128(stream, type, wasm_get_type_name(type)); +void wasm_write_type(WasmStream* stream, WasmType type) { + wasm_write_i32_leb128(stream, type, wasm_get_type_name(type)); } static void write_inline_signature_type(WasmStream* stream, const WasmBlockSignature* sig) { if (sig->size == 0) { - write_type(stream, WASM_TYPE_VOID); + wasm_write_type(stream, WASM_TYPE_VOID); } else if (sig->size == 1) { - write_type(stream, sig->data[0]); + wasm_write_type(stream, sig->data[0]); } else { /* this is currently unrepresentable */ wasm_write_u8(stream, 0xff, "INVALID INLINE SIGNATURE"); @@ -244,8 +262,8 @@ static void begin_custom_section(Context* ctx, ctx->last_section_leb_size_guess = leb_size_guess; ctx->last_section_offset = write_u32_leb128_space(ctx, leb_size_guess, "section size (guess)"); - write_str(&ctx->stream, name, strlen(name), WASM_PRINT_CHARS, - "custom section name"); + wasm_write_str(&ctx->stream, name, strlen(name), WASM_PRINT_CHARS, + "custom section name"); } static void end_section(Context* ctx) { @@ -272,44 +290,45 @@ static void write_expr(Context* ctx, const WasmExpr* expr) { switch (expr->type) { case WASM_EXPR_TYPE_BINARY: - write_opcode(&ctx->stream, expr->binary.opcode); + wasm_write_opcode(&ctx->stream, expr->binary.opcode); break; case WASM_EXPR_TYPE_BLOCK: - write_opcode(&ctx->stream, WASM_OPCODE_BLOCK); + wasm_write_opcode(&ctx->stream, WASM_OPCODE_BLOCK); write_inline_signature_type(&ctx->stream, &expr->block.sig); write_expr_list(ctx, module, func, expr->block.first); - write_opcode(&ctx->stream, WASM_OPCODE_END); + wasm_write_opcode(&ctx->stream, WASM_OPCODE_END); break; case WASM_EXPR_TYPE_BR: - write_opcode(&ctx->stream, WASM_OPCODE_BR); - write_u32_leb128(&ctx->stream, get_label_var_depth(ctx, &expr->br.var), - "break depth"); + wasm_write_opcode(&ctx->stream, WASM_OPCODE_BR); + wasm_write_u32_leb128( + &ctx->stream, get_label_var_depth(ctx, &expr->br.var), "break depth"); break; case WASM_EXPR_TYPE_BR_IF: - write_opcode(&ctx->stream, WASM_OPCODE_BR_IF); - write_u32_leb128(&ctx->stream, get_label_var_depth(ctx, &expr->br_if.var), - "break depth"); + wasm_write_opcode(&ctx->stream, WASM_OPCODE_BR_IF); + wasm_write_u32_leb128(&ctx->stream, + get_label_var_depth(ctx, &expr->br_if.var), + "break depth"); break; case WASM_EXPR_TYPE_BR_TABLE: { - write_opcode(&ctx->stream, WASM_OPCODE_BR_TABLE); - write_u32_leb128(&ctx->stream, expr->br_table.targets.size, - "num targets"); + wasm_write_opcode(&ctx->stream, WASM_OPCODE_BR_TABLE); + wasm_write_u32_leb128(&ctx->stream, expr->br_table.targets.size, + "num targets"); size_t i; uint32_t depth; for (i = 0; i < expr->br_table.targets.size; ++i) { depth = get_label_var_depth(ctx, &expr->br_table.targets.data[i]); - write_u32_leb128(&ctx->stream, depth, "break depth"); + wasm_write_u32_leb128(&ctx->stream, depth, "break depth"); } depth = get_label_var_depth(ctx, &expr->br_table.default_target); - write_u32_leb128(&ctx->stream, depth, "break depth for default"); + wasm_write_u32_leb128(&ctx->stream, depth, "break depth for default"); break; } case WASM_EXPR_TYPE_CALL: { int index = wasm_get_func_index_by_var(module, &expr->call.var); assert(ctx->options->is_invalid || (index >= 0 && (size_t)index < module->funcs.size)); - write_opcode(&ctx->stream, WASM_OPCODE_CALL); - write_u32_leb128(&ctx->stream, index, "func index"); + wasm_write_opcode(&ctx->stream, WASM_OPCODE_CALL); + wasm_write_u32_leb128(&ctx->stream, index, "function index"); break; } case WASM_EXPR_TYPE_CALL_INDIRECT: { @@ -317,33 +336,33 @@ static void write_expr(Context* ctx, wasm_get_func_type_index_by_var(module, &expr->call_indirect.var); assert(ctx->options->is_invalid || (index >= 0 && (size_t)index < module->func_types.size)); - write_opcode(&ctx->stream, WASM_OPCODE_CALL_INDIRECT); - write_u32_leb128(&ctx->stream, index, "signature index"); - write_u32_leb128(&ctx->stream, 0, "call_indirect reserved"); + wasm_write_opcode(&ctx->stream, WASM_OPCODE_CALL_INDIRECT); + wasm_write_u32_leb128(&ctx->stream, index, "signature index"); + wasm_write_u32_leb128(&ctx->stream, 0, "call_indirect reserved"); break; } case WASM_EXPR_TYPE_COMPARE: - write_opcode(&ctx->stream, expr->compare.opcode); + wasm_write_opcode(&ctx->stream, expr->compare.opcode); break; case WASM_EXPR_TYPE_CONST: switch (expr->const_.type) { case WASM_TYPE_I32: { - write_opcode(&ctx->stream, WASM_OPCODE_I32_CONST); - write_i32_leb128(&ctx->stream, (int32_t)expr->const_.u32, - "i32 literal"); + wasm_write_opcode(&ctx->stream, WASM_OPCODE_I32_CONST); + wasm_write_i32_leb128(&ctx->stream, (int32_t)expr->const_.u32, + "i32 literal"); break; } case WASM_TYPE_I64: - write_opcode(&ctx->stream, WASM_OPCODE_I64_CONST); + wasm_write_opcode(&ctx->stream, WASM_OPCODE_I64_CONST); write_i64_leb128(&ctx->stream, (int64_t)expr->const_.u64, "i64 literal"); break; case WASM_TYPE_F32: - write_opcode(&ctx->stream, WASM_OPCODE_F32_CONST); + wasm_write_opcode(&ctx->stream, WASM_OPCODE_F32_CONST); wasm_write_u32(&ctx->stream, expr->const_.f32_bits, "f32 literal"); break; case WASM_TYPE_F64: - write_opcode(&ctx->stream, WASM_OPCODE_F64_CONST); + wasm_write_opcode(&ctx->stream, WASM_OPCODE_F64_CONST); wasm_write_u64(&ctx->stream, expr->const_.f64_bits, "f64 literal"); break; default: @@ -351,97 +370,97 @@ static void write_expr(Context* ctx, } break; case WASM_EXPR_TYPE_CONVERT: - write_opcode(&ctx->stream, expr->convert.opcode); + wasm_write_opcode(&ctx->stream, expr->convert.opcode); break; case WASM_EXPR_TYPE_CURRENT_MEMORY: - write_opcode(&ctx->stream, WASM_OPCODE_CURRENT_MEMORY); - write_u32_leb128(&ctx->stream, 0, "current_memory reserved"); + wasm_write_opcode(&ctx->stream, WASM_OPCODE_CURRENT_MEMORY); + wasm_write_u32_leb128(&ctx->stream, 0, "current_memory reserved"); break; case WASM_EXPR_TYPE_DROP: - write_opcode(&ctx->stream, WASM_OPCODE_DROP); + wasm_write_opcode(&ctx->stream, WASM_OPCODE_DROP); break; case WASM_EXPR_TYPE_GET_GLOBAL: { int index = wasm_get_global_index_by_var(module, &expr->get_global.var); - write_opcode(&ctx->stream, WASM_OPCODE_GET_GLOBAL); - write_u32_leb128(&ctx->stream, index, "global index"); + wasm_write_opcode(&ctx->stream, WASM_OPCODE_GET_GLOBAL); + wasm_write_u32_leb128(&ctx->stream, index, "global index"); break; } case WASM_EXPR_TYPE_GET_LOCAL: { int index = wasm_get_local_index_by_var(func, &expr->get_local.var); - write_opcode(&ctx->stream, WASM_OPCODE_GET_LOCAL); - write_u32_leb128(&ctx->stream, index, "local index"); + wasm_write_opcode(&ctx->stream, WASM_OPCODE_GET_LOCAL); + wasm_write_u32_leb128(&ctx->stream, index, "local index"); break; } case WASM_EXPR_TYPE_GROW_MEMORY: - write_opcode(&ctx->stream, WASM_OPCODE_GROW_MEMORY); - write_u32_leb128(&ctx->stream, 0, "grow_memory reserved"); + wasm_write_opcode(&ctx->stream, WASM_OPCODE_GROW_MEMORY); + wasm_write_u32_leb128(&ctx->stream, 0, "grow_memory reserved"); break; case WASM_EXPR_TYPE_IF: - write_opcode(&ctx->stream, WASM_OPCODE_IF); + wasm_write_opcode(&ctx->stream, WASM_OPCODE_IF); write_inline_signature_type(&ctx->stream, &expr->if_.true_.sig); write_expr_list(ctx, module, func, expr->if_.true_.first); if (expr->if_.false_) { - write_opcode(&ctx->stream, WASM_OPCODE_ELSE); + wasm_write_opcode(&ctx->stream, WASM_OPCODE_ELSE); write_expr_list(ctx, module, func, expr->if_.false_); } - write_opcode(&ctx->stream, WASM_OPCODE_END); + wasm_write_opcode(&ctx->stream, WASM_OPCODE_END); break; case WASM_EXPR_TYPE_LOAD: { - write_opcode(&ctx->stream, expr->load.opcode); + wasm_write_opcode(&ctx->stream, expr->load.opcode); uint32_t align = wasm_get_opcode_alignment(expr->load.opcode, expr->load.align); wasm_write_u8(&ctx->stream, log2_u32(align), "alignment"); - write_u32_leb128(&ctx->stream, (uint32_t)expr->load.offset, - "load offset"); + wasm_write_u32_leb128(&ctx->stream, (uint32_t)expr->load.offset, + "load offset"); break; } case WASM_EXPR_TYPE_LOOP: - write_opcode(&ctx->stream, WASM_OPCODE_LOOP); + wasm_write_opcode(&ctx->stream, WASM_OPCODE_LOOP); write_inline_signature_type(&ctx->stream, &expr->loop.sig); write_expr_list(ctx, module, func, expr->loop.first); - write_opcode(&ctx->stream, WASM_OPCODE_END); + wasm_write_opcode(&ctx->stream, WASM_OPCODE_END); break; case WASM_EXPR_TYPE_NOP: - write_opcode(&ctx->stream, WASM_OPCODE_NOP); + wasm_write_opcode(&ctx->stream, WASM_OPCODE_NOP); break; case WASM_EXPR_TYPE_RETURN: - write_opcode(&ctx->stream, WASM_OPCODE_RETURN); + wasm_write_opcode(&ctx->stream, WASM_OPCODE_RETURN); break; case WASM_EXPR_TYPE_SELECT: - write_opcode(&ctx->stream, WASM_OPCODE_SELECT); + wasm_write_opcode(&ctx->stream, WASM_OPCODE_SELECT); break; case WASM_EXPR_TYPE_SET_GLOBAL: { int index = wasm_get_global_index_by_var(module, &expr->get_global.var); - write_opcode(&ctx->stream, WASM_OPCODE_SET_GLOBAL); - write_u32_leb128(&ctx->stream, index, "global index"); + wasm_write_opcode(&ctx->stream, WASM_OPCODE_SET_GLOBAL); + wasm_write_u32_leb128(&ctx->stream, index, "global index"); break; } case WASM_EXPR_TYPE_SET_LOCAL: { int index = wasm_get_local_index_by_var(func, &expr->get_local.var); - write_opcode(&ctx->stream, WASM_OPCODE_SET_LOCAL); - write_u32_leb128(&ctx->stream, index, "local index"); + wasm_write_opcode(&ctx->stream, WASM_OPCODE_SET_LOCAL); + wasm_write_u32_leb128(&ctx->stream, index, "local index"); break; } case WASM_EXPR_TYPE_STORE: { - write_opcode(&ctx->stream, expr->store.opcode); + wasm_write_opcode(&ctx->stream, expr->store.opcode); uint32_t align = wasm_get_opcode_alignment(expr->store.opcode, expr->store.align); wasm_write_u8(&ctx->stream, log2_u32(align), "alignment"); - write_u32_leb128(&ctx->stream, (uint32_t)expr->store.offset, - "store offset"); + wasm_write_u32_leb128(&ctx->stream, (uint32_t)expr->store.offset, + "store offset"); break; } case WASM_EXPR_TYPE_TEE_LOCAL: { int index = wasm_get_local_index_by_var(func, &expr->get_local.var); - write_opcode(&ctx->stream, WASM_OPCODE_TEE_LOCAL); - write_u32_leb128(&ctx->stream, index, "local index"); + wasm_write_opcode(&ctx->stream, WASM_OPCODE_TEE_LOCAL); + wasm_write_u32_leb128(&ctx->stream, index, "local index"); break; } case WASM_EXPR_TYPE_UNARY: - write_opcode(&ctx->stream, expr->unary.opcode); + wasm_write_opcode(&ctx->stream, expr->unary.opcode); break; case WASM_EXPR_TYPE_UNREACHABLE: - write_opcode(&ctx->stream, WASM_OPCODE_UNREACHABLE); + wasm_write_opcode(&ctx->stream, WASM_OPCODE_UNREACHABLE); break; } } @@ -460,7 +479,7 @@ static void write_init_expr(Context* ctx, const WasmExpr* expr) { if (expr) write_expr(ctx, module, NULL, expr); - write_opcode(&ctx->stream, WASM_OPCODE_END); + wasm_write_opcode(&ctx->stream, WASM_OPCODE_END); } static void write_func_locals(Context* ctx, @@ -468,7 +487,7 @@ static void write_func_locals(Context* ctx, const WasmFunc* func, const WasmTypeVector* local_types) { if (local_types->size == 0) { - write_u32_leb128(&ctx->stream, 0, "local decl count"); + wasm_write_u32_leb128(&ctx->stream, 0, "local decl count"); return; } @@ -491,7 +510,7 @@ static void write_func_locals(Context* ctx, } /* loop through again to write everything out */ - write_u32_leb128(&ctx->stream, local_decl_count, "local decl count"); + wasm_write_u32_leb128(&ctx->stream, local_decl_count, "local decl count"); current_type = GET_LOCAL_TYPE(FIRST_LOCAL_INDEX); uint32_t local_type_count = 1; for (i = FIRST_LOCAL_INDEX + 1; i <= LAST_LOCAL_INDEX; ++i) { @@ -500,8 +519,8 @@ static void write_func_locals(Context* ctx, if (current_type == type) { local_type_count++; } else { - write_u32_leb128(&ctx->stream, local_type_count, "local type count"); - write_type(&ctx->stream, current_type); + wasm_write_u32_leb128(&ctx->stream, local_type_count, "local type count"); + wasm_write_type(&ctx->stream, current_type); local_type_count = 1; current_type = type; } @@ -513,30 +532,28 @@ static void write_func(Context* ctx, const WasmFunc* func) { write_func_locals(ctx, module, func, &func->local_types); write_expr_list(ctx, module, func, func->first_expr); - write_opcode(&ctx->stream, WASM_OPCODE_END); + wasm_write_opcode(&ctx->stream, WASM_OPCODE_END); } -static void write_table(Context* ctx, const WasmTable* table) { - const WasmLimits* limits = &table->elem_limits; - write_type(&ctx->stream, WASM_TYPE_ANYFUNC); +void wasm_write_limits(WasmStream* stream, const WasmLimits* limits) { uint32_t flags = limits->has_max ? WASM_BINARY_LIMITS_HAS_MAX_FLAG : 0; - write_u32_leb128(&ctx->stream, flags, "table flags"); - write_u32_leb128(&ctx->stream, limits->initial, "table initial elems"); + wasm_write_u32_leb128(stream, flags, "limits: flags"); + wasm_write_u32_leb128(stream, limits->initial, "limits: initial"); if (limits->has_max) - write_u32_leb128(&ctx->stream, limits->max, "table max elems"); + wasm_write_u32_leb128(stream, limits->max, "limits: max"); +} + +static void write_table(Context* ctx, const WasmTable* table) { + wasm_write_type(&ctx->stream, WASM_TYPE_ANYFUNC); + wasm_write_limits(&ctx->stream, &table->elem_limits); } static void write_memory(Context* ctx, const WasmMemory* memory) { - const WasmLimits* limits = &memory->page_limits; - uint32_t flags = limits->has_max ? WASM_BINARY_LIMITS_HAS_MAX_FLAG : 0; - write_u32_leb128(&ctx->stream, flags, "memory flags"); - write_u32_leb128(&ctx->stream, limits->initial, "memory initial pages"); - if (limits->has_max) - write_u32_leb128(&ctx->stream, limits->max, "memory max pages"); + wasm_write_limits(&ctx->stream, &memory->page_limits); } static void write_global_header(Context* ctx, const WasmGlobal* global) { - write_type(&ctx->stream, global->type); + wasm_write_type(&ctx->stream, global->type); wasm_write_u8(&ctx->stream, global->mutable_, "global mutability"); } @@ -551,46 +568,46 @@ static void write_module(Context* ctx, const WasmModule* module) { if (module->func_types.size) { begin_known_section(ctx, WASM_BINARY_SECTION_TYPE, leb_size_guess); - write_u32_leb128(&ctx->stream, module->func_types.size, "num types"); + wasm_write_u32_leb128(&ctx->stream, module->func_types.size, "num types"); for (i = 0; i < module->func_types.size; ++i) { const WasmFuncType* func_type = module->func_types.data[i]; const WasmFuncSignature* sig = &func_type->sig; write_header(ctx, "type", i); - write_type(&ctx->stream, WASM_TYPE_FUNC); + wasm_write_type(&ctx->stream, WASM_TYPE_FUNC); size_t j; uint32_t num_params = sig->param_types.size; uint32_t num_results = sig->result_types.size; - write_u32_leb128(&ctx->stream, num_params, "num params"); + wasm_write_u32_leb128(&ctx->stream, num_params, "num params"); for (j = 0; j < num_params; ++j) - write_type(&ctx->stream, sig->param_types.data[j]); + wasm_write_type(&ctx->stream, sig->param_types.data[j]); - write_u32_leb128(&ctx->stream, num_results, "num results"); + wasm_write_u32_leb128(&ctx->stream, num_results, "num results"); for (j = 0; j < num_results; ++j) - write_type(&ctx->stream, sig->result_types.data[j]); + wasm_write_type(&ctx->stream, sig->result_types.data[j]); } end_section(ctx); } if (module->imports.size) { begin_known_section(ctx, WASM_BINARY_SECTION_IMPORT, leb_size_guess); - write_u32_leb128(&ctx->stream, module->imports.size, "num imports"); + wasm_write_u32_leb128(&ctx->stream, module->imports.size, "num imports"); for (i = 0; i < module->imports.size; ++i) { const WasmImport* import = module->imports.data[i]; write_header(ctx, "import header", i); - write_str(&ctx->stream, import->module_name.start, - import->module_name.length, WASM_PRINT_CHARS, - "import module name"); - write_str(&ctx->stream, import->field_name.start, - import->field_name.length, WASM_PRINT_CHARS, - "import field name"); + wasm_write_str(&ctx->stream, import->module_name.start, + import->module_name.length, WASM_PRINT_CHARS, + "import module name"); + wasm_write_str(&ctx->stream, import->field_name.start, + import->field_name.length, WASM_PRINT_CHARS, + "import field name"); wasm_write_u8(&ctx->stream, import->kind, "import kind"); switch (import->kind) { case WASM_EXTERNAL_KIND_FUNC: - write_u32_leb128(&ctx->stream, wasm_get_func_type_index_by_decl( - module, &import->func.decl), - "import signature index"); + wasm_write_u32_leb128(&ctx->stream, wasm_get_func_type_index_by_decl( + module, &import->func.decl), + "import signature index"); break; case WASM_EXTERNAL_KIND_TABLE: write_table(ctx, &import->table); @@ -613,16 +630,16 @@ static void write_module(Context* ctx, const WasmModule* module) { uint32_t num_funcs = module->funcs.size - module->num_func_imports; if (num_funcs) { begin_known_section(ctx, WASM_BINARY_SECTION_FUNCTION, leb_size_guess); - write_u32_leb128(&ctx->stream, num_funcs, "num functions"); + wasm_write_u32_leb128(&ctx->stream, num_funcs, "num functions"); for (i = 0; i < num_funcs; ++i) { const WasmFunc* func = module->funcs.data[i + module->num_func_imports]; char desc[100]; wasm_snprintf(desc, sizeof(desc), "function %" PRIzd " signature index", i); - write_u32_leb128(&ctx->stream, - wasm_get_func_type_index_by_decl(module, &func->decl), - desc); + wasm_write_u32_leb128( + &ctx->stream, wasm_get_func_type_index_by_decl(module, &func->decl), + desc); } end_section(ctx); } @@ -631,7 +648,7 @@ static void write_module(Context* ctx, const WasmModule* module) { uint32_t num_tables = module->tables.size - module->num_table_imports; if (num_tables) { begin_known_section(ctx, WASM_BINARY_SECTION_TABLE, leb_size_guess); - write_u32_leb128(&ctx->stream, num_tables, "num tables"); + wasm_write_u32_leb128(&ctx->stream, num_tables, "num tables"); for (i = 0; i < num_tables; ++i) { const WasmTable* table = module->tables.data[i + module->num_table_imports]; @@ -645,7 +662,7 @@ static void write_module(Context* ctx, const WasmModule* module) { uint32_t num_memories = module->memories.size - module->num_memory_imports; if (num_memories) { begin_known_section(ctx, WASM_BINARY_SECTION_MEMORY, leb_size_guess); - write_u32_leb128(&ctx->stream, num_memories, "num memories"); + wasm_write_u32_leb128(&ctx->stream, num_memories, "num memories"); for (i = 0; i < num_memories; ++i) { const WasmMemory* memory = module->memories.data[i + module->num_memory_imports]; @@ -659,7 +676,7 @@ static void write_module(Context* ctx, const WasmModule* module) { uint32_t num_globals = module->globals.size - module->num_global_imports; if (num_globals) { begin_known_section(ctx, WASM_BINARY_SECTION_GLOBAL, leb_size_guess); - write_u32_leb128(&ctx->stream, num_globals, "num globals"); + wasm_write_u32_leb128(&ctx->stream, num_globals, "num globals"); for (i = 0; i < num_globals; ++i) { const WasmGlobal* global = @@ -672,40 +689,40 @@ static void write_module(Context* ctx, const WasmModule* module) { if (module->exports.size) { begin_known_section(ctx, WASM_BINARY_SECTION_EXPORT, leb_size_guess); - write_u32_leb128(&ctx->stream, module->exports.size, "num exports"); + wasm_write_u32_leb128(&ctx->stream, module->exports.size, "num exports"); for (i = 0; i < module->exports.size; ++i) { const WasmExport* export = module->exports.data[i]; - write_str(&ctx->stream, export->name.start, export->name.length, - WASM_PRINT_CHARS, "export name"); + wasm_write_str(&ctx->stream, export->name.start, export->name.length, + WASM_PRINT_CHARS, "export name"); wasm_write_u8(&ctx->stream, export->kind, "export kind"); switch (export->kind) { case WASM_EXTERNAL_KIND_FUNC: { int index = wasm_get_func_index_by_var(module, &export->var); assert(ctx->options->is_invalid || (index >= 0 && (size_t)index < module->funcs.size)); - write_u32_leb128(&ctx->stream, index, "export func index"); + wasm_write_u32_leb128(&ctx->stream, index, "export func index"); break; } case WASM_EXTERNAL_KIND_TABLE: { int index = wasm_get_table_index_by_var(module, &export->var); assert(ctx->options->is_invalid || (index >= 0 && (size_t)index < module->tables.size)); - write_u32_leb128(&ctx->stream, index, "export table index"); + wasm_write_u32_leb128(&ctx->stream, index, "export table index"); break; } case WASM_EXTERNAL_KIND_MEMORY: { int index = wasm_get_memory_index_by_var(module, &export->var); assert(ctx->options->is_invalid || (index >= 0 && (size_t)index < module->memories.size)); - write_u32_leb128(&ctx->stream, index, "export memory index"); + wasm_write_u32_leb128(&ctx->stream, index, "export memory index"); break; } case WASM_EXTERNAL_KIND_GLOBAL: { int index = wasm_get_global_index_by_var(module, &export->var); assert(ctx->options->is_invalid || (index >= 0 && (size_t)index < module->globals.size)); - write_u32_leb128(&ctx->stream, index, "export global index"); + wasm_write_u32_leb128(&ctx->stream, index, "export global index"); break; } case WASM_NUM_EXTERNAL_KINDS: @@ -720,30 +737,30 @@ static void write_module(Context* ctx, const WasmModule* module) { int start_func_index = wasm_get_func_index_by_var(module, module->start); if (start_func_index != -1) { begin_known_section(ctx, WASM_BINARY_SECTION_START, leb_size_guess); - write_u32_leb128(&ctx->stream, start_func_index, "start func index"); + wasm_write_u32_leb128(&ctx->stream, start_func_index, "start func index"); end_section(ctx); } } if (module->tables.size && module->elem_segments.size) { begin_known_section(ctx, WASM_BINARY_SECTION_ELEM, leb_size_guess); - write_u32_leb128(&ctx->stream, module->elem_segments.size, - "num elem segments"); + wasm_write_u32_leb128(&ctx->stream, module->elem_segments.size, + "num elem segments"); for (i = 0; i < module->elem_segments.size; ++i) { WasmElemSegment* segment = module->elem_segments.data[i]; int table_index = wasm_get_table_index_by_var(module, &segment->table_var); write_header(ctx, "elem segment header", i); - write_u32_leb128(&ctx->stream, table_index, "table index"); + wasm_write_u32_leb128(&ctx->stream, table_index, "table index"); write_init_expr(ctx, module, segment->offset); - write_u32_leb128(&ctx->stream, segment->vars.size, - "num function indices"); + wasm_write_u32_leb128(&ctx->stream, segment->vars.size, + "num function indices"); size_t j; for (j = 0; j < segment->vars.size; ++j) { int index = wasm_get_func_index_by_var(module, &segment->vars.data[j]); assert(ctx->options->is_invalid || (index >= 0 && (size_t)index < module->funcs.size)); - write_u32_leb128(&ctx->stream, index, "function index"); + wasm_write_u32_leb128(&ctx->stream, index, "function index"); } } end_section(ctx); @@ -751,7 +768,7 @@ static void write_module(Context* ctx, const WasmModule* module) { if (num_funcs) { begin_known_section(ctx, WASM_BINARY_SECTION_CODE, leb_size_guess); - write_u32_leb128(&ctx->stream, num_funcs, "num functions"); + wasm_write_u32_leb128(&ctx->stream, num_funcs, "num functions"); for (i = 0; i < num_funcs; ++i) { write_header(ctx, "function body", i); @@ -770,16 +787,16 @@ static void write_module(Context* ctx, const WasmModule* module) { if (module->memories.size && module->data_segments.size) { begin_known_section(ctx, WASM_BINARY_SECTION_DATA, leb_size_guess); - write_u32_leb128(&ctx->stream, module->data_segments.size, - "num data segments"); + wasm_write_u32_leb128(&ctx->stream, module->data_segments.size, + "num data segments"); for (i = 0; i < module->data_segments.size; ++i) { const WasmDataSegment* segment = module->data_segments.data[i]; write_header(ctx, "data segment header", i); int memory_index = wasm_get_memory_index_by_var(module, &segment->memory_var); - write_u32_leb128(&ctx->stream, memory_index, "memory index"); + wasm_write_u32_leb128(&ctx->stream, memory_index, "memory index"); write_init_expr(ctx, module, segment->offset); - write_u32_leb128(&ctx->stream, segment->size, "data segment size"); + wasm_write_u32_leb128(&ctx->stream, segment->size, "data segment size"); write_header(ctx, "data segment data", i); wasm_write_data(&ctx->stream, segment->data, segment->size, "data segment data"); @@ -793,7 +810,7 @@ static void write_module(Context* ctx, const WasmModule* module) { char desc[100]; begin_custom_section(ctx, WASM_BINARY_SECTION_NAME, leb_size_guess); - write_u32_leb128(&ctx->stream, module->funcs.size, "num functions"); + wasm_write_u32_leb128(&ctx->stream, module->funcs.size, "num functions"); for (i = 0; i < module->funcs.size; ++i) { const WasmFunc* func = module->funcs.data[i]; uint32_t num_params = wasm_get_num_params(func); @@ -801,9 +818,9 @@ static void write_module(Context* ctx, const WasmModule* module) { uint32_t num_params_and_locals = wasm_get_num_params_and_locals(func); wasm_snprintf(desc, sizeof(desc), "func name %" PRIzd, i); - write_str(&ctx->stream, func->name.start, func->name.length, - WASM_PRINT_CHARS, desc); - write_u32_leb128(&ctx->stream, num_params_and_locals, "num locals"); + wasm_write_str(&ctx->stream, func->name.start, func->name.length, + WASM_PRINT_CHARS, desc); + wasm_write_u32_leb128(&ctx->stream, num_params_and_locals, "num locals"); if (num_params_and_locals) { wasm_make_type_binding_reverse_mapping( @@ -813,8 +830,8 @@ static void write_module(Context* ctx, const WasmModule* module) { for (j = 0; j < num_params; ++j) { WasmStringSlice name = index_to_name.data[j]; wasm_snprintf(desc, sizeof(desc), "local name %" PRIzd, j); - write_str(&ctx->stream, name.start, name.length, WASM_PRINT_CHARS, - desc); + wasm_write_str(&ctx->stream, name.start, name.length, + WASM_PRINT_CHARS, desc); } wasm_make_type_binding_reverse_mapping( @@ -824,8 +841,8 @@ static void write_module(Context* ctx, const WasmModule* module) { WasmStringSlice name = index_to_name.data[j]; wasm_snprintf(desc, sizeof(desc), "local name %" PRIzd, num_params + j); - write_str(&ctx->stream, name.start, name.length, WASM_PRINT_CHARS, - desc); + wasm_write_str(&ctx->stream, name.start, name.length, + WASM_PRINT_CHARS, desc); } } } diff --git a/src/binary-writer.h b/src/binary-writer.h index 37dff783..16a838ff 100644 --- a/src/binary-writer.h +++ b/src/binary-writer.h @@ -24,6 +24,7 @@ struct WasmModule; struct WasmScript; struct WasmWriter; struct WasmStream; +enum WasmPrintChars; #define WASM_WRITE_BINARY_OPTIONS_DEFAULT \ { NULL, WASM_TRUE, WASM_FALSE, WASM_FALSE } @@ -45,6 +46,39 @@ WasmResult wasm_write_binary_script(struct WasmAllocator*, struct WasmWriter*, const struct WasmScript*, const WasmWriteBinaryOptions*); + +void wasm_write_u32_leb128(struct WasmStream* stream, + uint32_t value, + const char* desc); + +void wasm_write_i32_leb128(struct WasmStream* stream, + int32_t value, + const char* desc); + +void wasm_write_fixed_u32_leb128(struct WasmStream* stream, + uint32_t value, + const char* desc); + +uint32_t wasm_write_fixed_u32_leb128_at(struct WasmStream* stream, + uint32_t offset, + uint32_t value, + const char* desc); + +uint32_t wasm_write_fixed_u32_leb128_raw(uint8_t* data, + uint8_t* end, + uint32_t value); + +void wasm_write_type(struct WasmStream* stream, WasmType type); + +void wasm_write_str(struct WasmStream* stream, + const char* s, + size_t length, + enum WasmPrintChars print_chars, + const char* desc); + +void wasm_write_opcode(struct WasmStream* stream, uint8_t opcode); + +void wasm_write_limits(struct WasmStream* stream, const WasmLimits* limits); WASM_EXTERN_C_END #endif /* WASM_BINARY_WRITER_H_ */ |