diff options
author | Ben Smith <binjimin@gmail.com> | 2016-08-04 20:15:18 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-08-04 20:15:18 -0700 |
commit | 2d375e8d502327e814d62a08f22da9d9b6b675dc (patch) | |
tree | fbac644d0498c0fdf368935593f4894d3817ab2d /src/wasm-binary-writer.c | |
parent | 31dcad7ff987455bae219b31e4d6c76d78634315 (diff) | |
download | wabt-2d375e8d502327e814d62a08f22da9d9b6b675dc.tar.gz wabt-2d375e8d502327e814d62a08f22da9d9b6b675dc.tar.bz2 wabt-2d375e8d502327e814d62a08f22da9d9b6b675dc.zip |
update testsuite, handle implicit func types (#96)
Change 7c482b1a of the spec repo now requires that implicit function
types are created when creating a new func or import, but only when the
type is not explicitly specified, and the have not been specified. For
example:
```
(func (param i32))
(import "foo" "bar" (result i32)
```
This was previously done in sexpr-wasm when writing the binary, but now
these types can be referenced by `call_import`, so it has to be handled
earlier.
Since all signatures are now defined in the module, I made it so the
function signature is shared with the module function types. The tricky
part here is when a function type and an explicit signature are both
specified:
```
(func (type $t) (param f32) ...)
```
In this case, we need to keep the explicit signature around long enough
to be checked against the function type, so it must be owned by the
function. The WASM_FUNC_DECLARATION_FLAG_SHARED_SIGNATURE flag specifies
this case.
To simplify code that uses the AST, I reverted many of the
changes introduced in 73e5bc7d. Now the function declaration's signature
is always valid to access, and will have been resolved if it was
specified with a func type instead of an explicit signature.
Some other changes:
* There was a bug in the interpreter's `f32.demote/f64` rounding when
given a value that is very close to positive or negative F32_MAX
* Added `update-spec-tests.py` to more easily update the spec tests in
`test/interp/spec/*.txt` from the files in
`third_party/testsuite/*.wast`. Previously I would just do it
manually.
Diffstat (limited to 'src/wasm-binary-writer.c')
-rw-r--r-- | src/wasm-binary-writer.c | 125 |
1 files changed, 12 insertions, 113 deletions
diff --git a/src/wasm-binary-writer.c b/src/wasm-binary-writer.c index 5019d6f5..8b699089 100644 --- a/src/wasm-binary-writer.c +++ b/src/wasm-binary-writer.c @@ -70,20 +70,10 @@ typedef struct Context { size_t last_section_offset; size_t last_section_leb_size_guess; - int* import_sig_indexes; - int* func_sig_indexes; uint32_t* remapped_locals; /* from unpacked -> packed index */ uint32_t* reverse_remapped_locals; /* from packed -> unpacked index */ } Context; -WASM_DEFINE_VECTOR(func_signature, WasmFuncSignature); - -static void destroy_func_signature_vector_and_elements( - WasmAllocator* allocator, - WasmFuncSignatureVector* sigs) { - WASM_DESTROY_VECTOR_AND_ELEMENTS(allocator, *sigs, func_signature); -} - static void write_header(Context* ctx, const char* name, int index) { if (ctx->log_stream) { if (index == PRINT_HEADER_NO_INDEX) { @@ -305,93 +295,6 @@ static void pop_label(Context* ctx, const WasmLabel* label) { pop_unused_label(ctx, label); } -static int find_func_signature(const WasmFuncSignatureVector* sigs, - const WasmType result_type, - const WasmTypeVector* param_types) { - size_t i; - for (i = 0; i < sigs->size; ++i) { - const WasmFuncSignature* sig2 = &sigs->data[i]; - if (sig2->result_type != result_type) - continue; - if (sig2->param_types.size != param_types->size) - continue; - size_t j; - for (j = 0; j < param_types->size; ++j) { - if (sig2->param_types.data[j] != param_types->data[j]) - break; - } - if (j == param_types->size) - return i; - } - return -1; -} - -static void get_or_create_func_signature(Context* ctx, - WasmFuncSignatureVector* sigs, - WasmType result_type, - const WasmTypeVector* param_types, - int* out_index) { - int index = find_func_signature(sigs, result_type, param_types); - if (index == -1) { - index = sigs->size; - WasmFuncSignature* sig = wasm_append_func_signature(ctx->allocator, sigs); - sig->result_type = result_type; - WASM_ZERO_MEMORY(sig->param_types); - wasm_extend_types(ctx->allocator, &sig->param_types, param_types); - } - *out_index = index; -} - -static int get_signature_index(Context* ctx, - const WasmModule* module, - WasmFuncSignatureVector* sigs, - const WasmFuncDeclaration* decl) { - int index = -1; - if (wasm_decl_has_signature(decl)) { - get_or_create_func_signature(ctx, sigs, decl->sig.result_type, - &decl->sig.param_types, &index); - } else { - assert(wasm_decl_has_func_type(decl)); - index = wasm_get_func_type_index_by_var(module, &decl->type_var); - assert(index != -1); - } - return index; -} - -static void get_func_signatures(Context* ctx, - const WasmModule* module, - WasmFuncSignatureVector* sigs) { - /* function types are not deduped; we don't want the signature index to match - if they were specified separately in the source */ - size_t i; - for (i = 0; i < module->func_types.size; ++i) { - const WasmFuncType* func_type = module->func_types.data[i]; - WasmFuncSignature* sig = wasm_append_func_signature(ctx->allocator, sigs); - sig->result_type = func_type->sig.result_type; - WASM_ZERO_MEMORY(sig->param_types); - wasm_extend_types(ctx->allocator, &sig->param_types, - &func_type->sig.param_types); - } - - ctx->import_sig_indexes = - wasm_realloc(ctx->allocator, ctx->import_sig_indexes, - module->imports.size * sizeof(int), WASM_DEFAULT_ALIGN); - for (i = 0; i < module->imports.size; ++i) { - const WasmImport* import = module->imports.data[i]; - ctx->import_sig_indexes[i] = - get_signature_index(ctx, module, sigs, &import->decl); - } - - ctx->func_sig_indexes = - wasm_realloc(ctx->allocator, ctx->func_sig_indexes, - module->funcs.size * sizeof(int), WASM_DEFAULT_ALIGN); - for (i = 0; i < module->funcs.size; ++i) { - const WasmFunc* func = module->funcs.data[i]; - ctx->func_sig_indexes[i] = - get_signature_index(ctx, module, sigs, &func->decl); - } -} - static void remap_locals(Context* ctx, const WasmModule* module, const WasmFunc* func) { @@ -779,14 +682,12 @@ static void write_module(Context* ctx, const WasmModule* module) { wasm_write_u32(&ctx->stream, WASM_BINARY_MAGIC, "WASM_BINARY_MAGIC"); wasm_write_u32(&ctx->stream, WASM_BINARY_VERSION, "WASM_BINARY_VERSION"); - WasmFuncSignatureVector sigs; - WASM_ZERO_MEMORY(sigs); - get_func_signatures(ctx, module, &sigs); - if (sigs.size) { + if (module->func_types.size) { begin_section(ctx, WASM_SECTION_NAME_TYPE, leb_size_guess); - write_u32_leb128(&ctx->stream, sigs.size, "num types"); - for (i = 0; i < sigs.size; ++i) { - const WasmFuncSignature* sig = &sigs.data[i]; + 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); wasm_write_u8(&ctx->stream, WASM_BINARY_TYPE_FORM_FUNCTION, "function form"); @@ -812,7 +713,8 @@ static void write_module(Context* ctx, const WasmModule* module) { for (i = 0; i < module->imports.size; ++i) { const WasmImport* import = module->imports.data[i]; write_header(ctx, "import header", i); - write_u32_leb128(&ctx->stream, ctx->import_sig_indexes[i], + write_u32_leb128(&ctx->stream, + wasm_get_func_type_index_by_decl(module, &import->decl), "import signature index"); write_str(&ctx->stream, import->module_name.start, import->module_name.length, WASM_PRINT_CHARS, @@ -828,10 +730,13 @@ static void write_module(Context* ctx, const WasmModule* module) { 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]; char desc[100]; wasm_snprintf(desc, sizeof(desc), "function %" PRIzd " signature index", i); - write_u32_leb128(&ctx->stream, ctx->func_sig_indexes[i], desc); + write_u32_leb128(&ctx->stream, + wasm_get_func_type_index_by_decl(module, &func->decl), + desc); } end_section(ctx); } @@ -938,12 +843,9 @@ static void write_module(Context* ctx, const WasmModule* module) { write_u32_leb128(&ctx->stream, num_params_and_locals, "num locals"); if (num_params_and_locals) { - const WasmFuncSignature* sig = - wasm_decl_get_signature(module, &func->decl); remap_locals(ctx, module, func); - wasm_make_type_binding_reverse_mapping( - ctx->allocator, &sig->param_types, &func->param_bindings, + ctx->allocator, &func->decl.sig.param_types, &func->param_bindings, &index_to_name); size_t j; for (j = 0; j < num_params; ++j) { @@ -971,7 +873,6 @@ static void write_module(Context* ctx, const WasmModule* module) { wasm_destroy_string_slice_vector(ctx->allocator, &index_to_name); } - destroy_func_signature_vector_and_elements(ctx->allocator, &sigs); } static void write_commands(Context* ctx, const WasmScript* script) { @@ -995,8 +896,6 @@ static void write_commands(Context* ctx, const WasmScript* script) { } static void cleanup_context(Context* ctx) { - wasm_free(ctx->allocator, ctx->import_sig_indexes); - wasm_free(ctx->allocator, ctx->func_sig_indexes); wasm_free(ctx->allocator, ctx->remapped_locals); wasm_free(ctx->allocator, ctx->reverse_remapped_locals); } |