diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/wasm-ast-checker.c | 29 | ||||
-rw-r--r-- | src/wasm-ast-writer.c | 10 | ||||
-rw-r--r-- | src/wasm-ast.c | 21 | ||||
-rw-r--r-- | src/wasm-ast.h | 8 | ||||
-rw-r--r-- | src/wasm-binary-reader-ast.c | 55 | ||||
-rw-r--r-- | src/wasm-binary-writer-spec.c | 3 | ||||
-rw-r--r-- | src/wasm-binary-writer.c | 87 | ||||
-rw-r--r-- | src/wasm-bison-parser.y | 7 |
8 files changed, 103 insertions, 117 deletions
diff --git a/src/wasm-ast-checker.c b/src/wasm-ast-checker.c index 4d391b9c..cc12f4c6 100644 --- a/src/wasm-ast-checker.c +++ b/src/wasm-ast-checker.c @@ -219,16 +219,29 @@ static WasmResult check_local_var(WasmContext* ctx, const WasmFunc* func, const WasmVar* var, WasmType* out_type) { - int index; - if (WASM_FAILED(check_var(ctx, &func->params_and_locals.bindings, - func->params_and_locals.types.size, var, "local", - &index))) { - return WASM_ERROR; + int max_index = wasm_get_num_params_and_locals(func); + int index = wasm_get_local_index_by_var(func, var); + if (index >= 0 && index < max_index) { + if (out_type) { + int num_params = func->params.types.size; + if (index < num_params) { + *out_type = func->params.types.data[index]; + } else { + *out_type = func->locals.types.data[index - num_params]; + } + } + return WASM_OK; } - if (out_type) - *out_type = func->params_and_locals.types.data[index]; - return WASM_OK; + if (var->type == WASM_VAR_TYPE_NAME) { + print_error(ctx, &var->loc, + "undefined local variable \"" PRIstringslice "\"", + WASM_PRINTF_STRING_SLICE_ARG(var->name)); + } else { + print_error(ctx, &var->loc, "local variable out of range (max %d)", + max_index); + } + return WASM_ERROR; } static void check_align(WasmContext* ctx, diff --git a/src/wasm-ast-writer.c b/src/wasm-ast-writer.c index ed492acc..72899217 100644 --- a/src/wasm-ast-writer.c +++ b/src/wasm-ast-writer.c @@ -614,11 +614,9 @@ static void write_exprs(WasmContext* ctx, const WasmExprPtrVector* exprs) { static void write_type_bindings(WasmContext* ctx, const char* prefix, const WasmFunc* func, - const WasmTypeBindings* type_bindings, - uint32_t index_offset) { + const WasmTypeBindings* type_bindings) { CHECK_ALLOC(ctx, wasm_make_type_binding_reverse_mapping( - ctx->allocator, type_bindings, index_offset, - &ctx->index_to_name)); + ctx->allocator, type_bindings, &ctx->index_to_name)); /* named params/locals must be specified by themselves, but nameless * params/locals can be compressed, e.g.: @@ -664,7 +662,7 @@ static void write_func(WasmContext* ctx, } if (func->flags & WASM_FUNC_FLAG_HAS_SIGNATURE) { num_params = func->params.types.size; - write_type_bindings(ctx, "param", func, &func->params, 0); + write_type_bindings(ctx, "param", func, &func->params); if (func->result_type != WASM_TYPE_VOID) { out_open_space(ctx, "result"); out_type(ctx, func->result_type, WASM_NEXT_CHAR_NONE); @@ -673,7 +671,7 @@ static void write_func(WasmContext* ctx, } out_newline(ctx, NO_FORCE_NEWLINE); if (func->locals.types.size) { - write_type_bindings(ctx, "local", func, &func->locals, -num_params); + write_type_bindings(ctx, "local", func, &func->locals); } out_newline(ctx, NO_FORCE_NEWLINE); write_exprs(ctx, &func->exprs); diff --git a/src/wasm-ast.c b/src/wasm-ast.c index 604e9af6..917c4a06 100644 --- a/src/wasm-ast.c +++ b/src/wasm-ast.c @@ -200,7 +200,19 @@ int wasm_get_import_index_by_var(const WasmModule* module, const WasmVar* var) { } int wasm_get_local_index_by_var(const WasmFunc* func, const WasmVar* var) { - return wasm_get_index_from_var(&func->params_and_locals.bindings, var); + if (var->type == WASM_VAR_TYPE_INDEX) + return var->index; + + int result = find_binding_index_by_name(&func->params.bindings, &var->name); + if (result != -1) + return result; + /* the locals start after all the params */ + return func->params.types.size + + find_binding_index_by_name(&func->locals.bindings, &var->name); +} + +size_t wasm_get_num_params_and_locals(const WasmFunc* func) { + return func->params.types.size + func->locals.types.size; } WasmFuncPtr wasm_get_func_by_var(const WasmModule* module, const WasmVar* var) { @@ -253,7 +265,6 @@ WasmResult wasm_extend_type_bindings(WasmAllocator* allocator, WasmResult wasm_make_type_binding_reverse_mapping( struct WasmAllocator* allocator, const WasmTypeBindings* type_bindings, - uint32_t index_offset, WasmStringSliceVector* out_reverse_mapping) { uint32_t num_names = type_bindings->types.size; if (WASM_FAILED(wasm_reserve_string_slices(allocator, out_reverse_mapping, @@ -271,7 +282,7 @@ WasmResult wasm_make_type_binding_reverse_mapping( if (wasm_hash_entry_is_free(entry)) continue; - uint32_t index = entry->binding.index + index_offset; + uint32_t index = entry->binding.index; assert(index < out_reverse_mapping->size); out_reverse_mapping->data[index] = entry->binding.name; } @@ -490,10 +501,6 @@ void wasm_destroy_func(WasmAllocator* allocator, WasmFunc* func) { wasm_destroy_var(allocator, &func->type_var); wasm_destroy_type_bindings(allocator, &func->params); wasm_destroy_type_bindings(allocator, &func->locals); - /* params_and_locals shares binding data with params and locals */ - wasm_destroy_type_vector(allocator, &func->params_and_locals.types); - wasm_destroy_binding_hash_entry_vector( - allocator, &func->params_and_locals.bindings.entries); WASM_DESTROY_VECTOR_AND_ELEMENTS(allocator, func->exprs, expr_ptr); } diff --git a/src/wasm-ast.h b/src/wasm-ast.h index f822b357..7adf5e5c 100644 --- a/src/wasm-ast.h +++ b/src/wasm-ast.h @@ -208,10 +208,6 @@ typedef struct WasmFunc { WasmType result_type; WasmTypeBindings locals; WasmExprPtrVector exprs; - - /* combined from params and locals; the binding names share memory with the - originals */ - WasmTypeBindings params_and_locals; } WasmFunc; typedef WasmFunc* WasmFuncPtr; WASM_DEFINE_VECTOR(func_ptr, WasmFuncPtr); @@ -472,6 +468,7 @@ int wasm_get_func_type_index_by_var(const WasmModule* module, const WasmVar* var); int wasm_get_import_index_by_var(const WasmModule* module, const WasmVar* var); int wasm_get_local_index_by_var(const WasmFunc* func, const WasmVar* var); +size_t wasm_get_num_params_and_locals(const WasmFunc* func); WasmFuncPtr wasm_get_func_by_var(const WasmModule* module, const WasmVar* var); WasmFuncTypePtr wasm_get_func_type_by_var(const WasmModule* module, @@ -486,8 +483,7 @@ WasmResult wasm_extend_type_bindings(struct WasmAllocator*, WasmTypeBindings* src) WASM_WARN_UNUSED; WasmResult wasm_make_type_binding_reverse_mapping( struct WasmAllocator*, - const WasmTypeBindings* bindings, - uint32_t index_offset, + const WasmTypeBindings*, WasmStringSliceVector* out_reverse_mapping); WASM_EXTERN_C_END diff --git a/src/wasm-binary-reader-ast.c b/src/wasm-binary-reader-ast.c index 685c2006..feeab288 100644 --- a/src/wasm-binary-reader-ast.c +++ b/src/wasm-binary-reader-ast.c @@ -56,7 +56,7 @@ do { \ assert((ctx)->current_func->flags& WASM_FUNC_FLAG_HAS_FUNC_TYPE); \ uint32_t max_local_index = \ - get_num_func_params_and_locals((ctx)->module, (ctx)->current_func); \ + wasm_get_num_params_and_locals((ctx)->current_func); \ if ((local_index) >= max_local_index) { \ print_error((ctx), "invalid local_index: %d (max %d)", (local_index), \ max_local_index); \ @@ -107,22 +107,6 @@ static void print_error(WasmContext* ctx, const char* format, ...) { on_error(UNKNOWN_OFFSET, buffer, ctx); } -static WasmFuncSignature* get_func_sig(WasmModule* module, WasmFunc* func) { - return &module->func_types.data[func->type_var.index]->sig; -} - -static uint32_t get_num_func_params(WasmModule* module, WasmFunc* func) { - WasmFuncSignature* sig = get_func_sig(module, func); - return sig->param_types.size; -} - -static uint32_t get_num_func_params_and_locals(WasmModule* module, - WasmFunc* func) { - uint32_t num_params = get_num_func_params(module, func); - uint32_t num_locals = func->locals.types.size; - return num_params + num_locals; -} - /* TODO(binji): remove all this if-block stuff when we switch to postorder */ static WasmResult push_depth(WasmContext* ctx) { uint32_t* depth = wasm_append_uint32(ctx->allocator, &ctx->depth_stack); @@ -319,11 +303,20 @@ static WasmResult on_function_signature(uint32_t index, WasmFunc* func = &field->func; WASM_ZERO_MEMORY(*func); - func->flags = WASM_FUNC_FLAG_HAS_FUNC_TYPE; + func->flags = WASM_FUNC_FLAG_HAS_FUNC_TYPE | WASM_FUNC_FLAG_HAS_SIGNATURE; func->type_var.type = WASM_VAR_TYPE_INDEX; assert(sig_index < ctx->module->func_types.size); func->type_var.index = sig_index; + /* copy the signature from the function type */ + WasmFuncSignature* sig = &ctx->module->func_types.data[sig_index]->sig; + size_t i; + for (i = 0; i < sig->param_types.size; ++i) { + CHECK_ALLOC(ctx, wasm_append_type_value(ctx->allocator, &func->params.types, + &sig->param_types.data[i])); + } + func->result_type = sig->result_type; + assert(index < ctx->module->funcs.capacity); WasmFuncPtr* func_ptr = wasm_append_func_ptr(ctx->allocator, &ctx->module->funcs); @@ -1034,21 +1027,12 @@ static WasmResult on_local_names_count(uint32_t index, WasmModule* module = ctx->module; assert(index < module->funcs.size); WasmFunc* func = module->funcs.data[index]; - uint32_t num_params_and_locals = get_num_func_params_and_locals(module, func); + uint32_t num_params_and_locals = wasm_get_num_params_and_locals(func); if (count > num_params_and_locals) { print_error(ctx, "expected local name count (%d) <= local count (%d)", count, num_params_and_locals); return WASM_ERROR; } - /* copy the signature from the function type */ - WasmFuncSignature* sig = get_func_sig(module, func); - size_t i; - for (i = 0; i < sig->param_types.size; ++i) { - CHECK_ALLOC(ctx, wasm_append_type_value(ctx->allocator, &func->params.types, - &sig->param_types.data[i])); - } - func->result_type = sig->result_type; - func->flags |= WASM_FUNC_FLAG_HAS_SIGNATURE; return WASM_OK; } @@ -1059,22 +1043,25 @@ static WasmResult on_local_name(uint32_t func_index, WasmContext* ctx = user_data; WasmModule* module = ctx->module; WasmFunc* func = module->funcs.data[func_index]; - uint32_t num_params = get_num_func_params(module, func); + uint32_t num_params = func->params.types.size; WasmStringSlice dup_name; CHECK_ALLOC_NULL_STR(ctx, dup_name = wasm_dup_string_slice(ctx->allocator, name)); + WasmBindingHash* bindings; WasmBinding* binding; + uint32_t index; if (local_index < num_params) { /* param name */ - binding = - wasm_insert_binding(ctx->allocator, &func->params.bindings, &dup_name); + bindings = &func->params.bindings; + index = local_index; } else { /* local name */ - binding = - wasm_insert_binding(ctx->allocator, &func->locals.bindings, &dup_name); + bindings = &func->locals.bindings; + index = local_index - num_params; } + binding = wasm_insert_binding(ctx->allocator, bindings, &dup_name); CHECK_ALLOC_NULL(ctx, binding); - binding->index = local_index; + binding->index = index; /* TODO(binji): We could update the get_local/set_local expressions to use * the name instead of the index */ return WASM_OK; diff --git a/src/wasm-binary-writer-spec.c b/src/wasm-binary-writer-spec.c index b68e953b..003decc7 100644 --- a/src/wasm-binary-writer-spec.c +++ b/src/wasm-binary-writer-spec.c @@ -470,9 +470,6 @@ static void write_commands(WasmWriteSpecContext* ctx, WasmScript* script) { CHECK_ALLOC_NULL(caller); CHECK_ALLOC(wasm_append_type_value( script->allocator, &caller->locals.types, &result_type)); - CHECK_ALLOC(wasm_append_type_value(script->allocator, - &caller->params_and_locals.types, - &result_type)); expr_ptr = wasm_append_expr_ptr(script->allocator, &caller->exprs); CHECK_ALLOC_NULL(expr_ptr); *expr_ptr = create_set_local_expr( diff --git a/src/wasm-binary-writer.c b/src/wasm-binary-writer.c index 2958af7c..022b08de 100644 --- a/src/wasm-binary-writer.c +++ b/src/wasm-binary-writer.c @@ -84,10 +84,8 @@ typedef struct WasmContext { int* import_sig_indexes; int* func_sig_indexes; - uint32_t* remapped_locals; /* from unpacked -> packed index, has params */ - uint32_t* - reverse_remapped_locals; /* from packed -> unpacked index, no params */ - const WasmStringSlice** local_type_names; /* from packed -> local name */ + uint32_t* remapped_locals; /* from unpacked -> packed index */ + uint32_t* reverse_remapped_locals; /* from packed -> unpacked index */ } WasmContext; WASM_DEFINE_VECTOR(func_signature, WasmFuncSignature); @@ -488,9 +486,9 @@ static void remap_locals(WasmContext* ctx, const WasmFunc* func) { if (num_params_and_locals) CHECK_ALLOC_NULL(ctx->remapped_locals); - ctx->reverse_remapped_locals = - wasm_realloc(ctx->allocator, ctx->reverse_remapped_locals, - num_locals * sizeof(uint32_t), WASM_DEFAULT_ALIGN); + ctx->reverse_remapped_locals = wasm_realloc( + ctx->allocator, ctx->reverse_remapped_locals, + num_params_and_locals * sizeof(uint32_t), WASM_DEFAULT_ALIGN); if (num_locals) CHECK_ALLOC_NULL(ctx->reverse_remapped_locals); @@ -498,7 +496,7 @@ static void remap_locals(WasmContext* ctx, const WasmFunc* func) { /* just pass the index straight through */ for (i = 0; i < num_params_and_locals; ++i) ctx->remapped_locals[i] = i; - for (i = 0; i < num_locals; ++i) + for (i = 0; i < num_params_and_locals; ++i) ctx->reverse_remapped_locals[i] = i; return; } @@ -511,8 +509,10 @@ static void remap_locals(WasmContext* ctx, const WasmFunc* func) { } /* params don't need remapping */ - for (i = 0; i < num_params; ++i) + for (i = 0; i < num_params; ++i) { ctx->remapped_locals[i] = i; + ctx->reverse_remapped_locals[i] = i; + } uint32_t start[WASM_NUM_TYPES]; start[WASM_TYPE_I32] = num_params; @@ -527,7 +527,7 @@ static void remap_locals(WasmContext* ctx, const WasmFunc* func) { uint32_t unpacked_index = num_params + i; uint32_t packed_index = start[type] + seen[type]++; ctx->remapped_locals[unpacked_index] = packed_index; - ctx->reverse_remapped_locals[packed_index - num_params] = i; + ctx->reverse_remapped_locals[packed_index] = unpacked_index; } } @@ -642,7 +642,6 @@ static void write_expr(WasmContext* ctx, break; case WASM_EXPR_TYPE_GET_LOCAL: { int index = wasm_get_local_index_by_var(func, &expr->get_local.var); - assert(index >= 0 && (size_t)index < func->params_and_locals.types.size); out_opcode(ctx, WASM_OPCODE_GET_LOCAL); out_u32_leb128(ctx, ctx->remapped_locals[index], "remapped local index"); break; @@ -796,10 +795,12 @@ static void write_func_locals(WasmContext* ctx, return; } -/* remapped_locals includes the parameter list, so skip those */ -#define FIRST_LOCAL_INDEX (0) -#define LAST_LOCAL_INDEX (local_types->size) -#define GET_LOCAL_TYPE(x) (local_types->data[ctx->reverse_remapped_locals[x]]) + uint32_t num_params = func->params.types.size; + +#define FIRST_LOCAL_INDEX (num_params) +#define LAST_LOCAL_INDEX (num_params + local_types->size) +#define GET_LOCAL_TYPE(x) \ + (local_types->data[ctx->reverse_remapped_locals[x] - num_params]) /* loop through once to count the number of local declaration runs */ WasmType current_type = GET_LOCAL_TYPE(FIRST_LOCAL_INDEX); @@ -972,54 +973,49 @@ static void write_module(WasmContext* ctx, const WasmModule* module) { } if (ctx->options->write_debug_names) { + WasmStringSliceVector index_to_name; + WASM_ZERO_MEMORY(index_to_name); + char desc[100]; begin_section(ctx, WASM_SECTION_NAME_NAMES, leb_size_guess); out_u32_leb128(ctx, module->funcs.size, "num functions"); for (i = 0; i < module->funcs.size; ++i) { const WasmFunc* func = module->funcs.data[i]; + uint32_t num_params = func->params.types.size; + uint32_t num_locals = func->locals.types.size; + uint32_t num_params_and_locals = wasm_get_num_params_and_locals(func); + wasm_snprintf(desc, sizeof(desc), "func name %" PRIzd, i); out_str(ctx, func->name.start, func->name.length, WASM_PRINT_CHARS, desc); - out_u32_leb128(ctx, func->params_and_locals.types.size, "num locals"); + out_u32_leb128(ctx, num_params_and_locals, "num locals"); - if (func->params_and_locals.types.size) { + if (num_params_and_locals) { remap_locals(ctx, func); - /* create mapping from packed index to its name (if any) */ - size_t local_type_names_size = - func->params_and_locals.types.size * sizeof(WasmStringSlice*); - ctx->local_type_names = - wasm_realloc(ctx->allocator, ctx->local_type_names, - local_type_names_size, WASM_DEFAULT_ALIGN); - CHECK_ALLOC_NULL(ctx->local_type_names); - memset(ctx->local_type_names, 0, local_type_names_size); - + CHECK_ALLOC(wasm_make_type_binding_reverse_mapping( + ctx->allocator, &func->params, &index_to_name)); size_t j; - for (j = 0; j < func->params_and_locals.bindings.entries.capacity; - ++j) { - const WasmBindingHashEntry* entry = - &func->params_and_locals.bindings.entries.data[j]; - if (wasm_hash_entry_is_free(entry)) - continue; - - ctx->local_type_names[ctx->remapped_locals[entry->binding.index]] = - &entry->binding.name; + for (j = 0; j < num_params; ++j) { + WasmStringSlice name = index_to_name.data[j]; + wasm_snprintf(desc, sizeof(desc), "remapped local name %" PRIzd, j); + out_str(ctx, name.start, name.length, WASM_PRINT_CHARS, desc); } - for (j = 0; j < func->params_and_locals.types.size; ++j) { - WasmStringSlice name; - if (ctx->local_type_names[j]) { - name = *ctx->local_type_names[j]; - } else { - name.start = ""; - name.length = 0; - } - - wasm_snprintf(desc, sizeof(desc), "remapped local name %" PRIzd, j); + CHECK_ALLOC(wasm_make_type_binding_reverse_mapping( + ctx->allocator, &func->locals, &index_to_name)); + for (j = 0; j < num_locals; ++j) { + WasmStringSlice name = + index_to_name.data[ctx->reverse_remapped_locals[num_params + j] - + num_params]; + wasm_snprintf(desc, sizeof(desc), "remapped local name %" PRIzd, + num_params + j); out_str(ctx, name.start, name.length, WASM_PRINT_CHARS, desc); } } } end_section(ctx); + + wasm_destroy_string_slice_vector(ctx->allocator, &index_to_name); } destroy_func_signature_vector_and_elements(ctx->allocator, &sigs); } @@ -1049,7 +1045,6 @@ static void cleanup_context(WasmContext* ctx) { wasm_free(ctx->allocator, ctx->func_sig_indexes); wasm_free(ctx->allocator, ctx->remapped_locals); wasm_free(ctx->allocator, ctx->reverse_remapped_locals); - wasm_free(ctx->allocator, ctx->local_type_names); } WasmResult wasm_write_binary_module(WasmAllocator* allocator, diff --git a/src/wasm-bison-parser.y b/src/wasm-bison-parser.y index 5f5806b3..c8d7ba46 100644 --- a/src/wasm-bison-parser.y +++ b/src/wasm-bison-parser.y @@ -957,13 +957,6 @@ module : &func_type->sig.param_types)); } } - - /* now that func->params is set, we can easily create params_and_locals - * as well */ - CHECK_ALLOC(wasm_extend_type_bindings( - parser->allocator, &func->params_and_locals, &func->params)); - CHECK_ALLOC(wasm_extend_type_bindings( - parser->allocator, &func->params_and_locals, &func->locals)); } } ; |