summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/wasm-apply-names.c98
-rw-r--r--src/wasm-ast-writer.c29
-rw-r--r--src/wasm-binary-reader-ast.c28
-rw-r--r--src/wasm-generate-names.c85
4 files changed, 201 insertions, 39 deletions
diff --git a/src/wasm-apply-names.c b/src/wasm-apply-names.c
index b940efdf..ee18a477 100644
--- a/src/wasm-apply-names.c
+++ b/src/wasm-apply-names.c
@@ -43,6 +43,10 @@
typedef uint32_t WasmUint32;
WASM_DEFINE_VECTOR(uint32, WasmUint32);
+typedef WasmLabel* WasmLabelPtr;
+WASM_DEFINE_VECTOR(label_ptr, WasmLabelPtr);
+
+
typedef struct WasmContext {
WasmAllocator* allocator;
WasmModule* module;
@@ -51,8 +55,36 @@ typedef struct WasmContext {
/* mapping from param index to its name, if any, for the current func */
WasmStringSliceVector param_index_to_name;
WasmStringSliceVector local_index_to_name;
+ WasmLabelPtrVector labels;
} WasmContext;
+static WasmResult push_label(WasmContext* ctx, WasmLabel* label) {
+ CHECK_ALLOC(
+ wasm_append_label_ptr_value(ctx->allocator, &ctx->labels, &label));
+ return WASM_OK;
+}
+
+static void pop_label(WasmContext* ctx) {
+ assert(ctx->labels.size > 0);
+ ctx->labels.size--;
+}
+
+static WasmLabel* find_label_by_var(WasmContext* ctx, WasmVar* var) {
+ if (var->type == WASM_VAR_TYPE_NAME) {
+ int i;
+ for (i = ctx->labels.size - 1; i >= 0; --i) {
+ WasmLabel* label = ctx->labels.data[i];
+ if (wasm_string_slices_are_equal(label, &var->name))
+ return label;
+ }
+ return NULL;
+ } else {
+ if (var->index < 0 || (size_t)var->index >= ctx->labels.size)
+ return NULL;
+ return ctx->labels.data[ctx->labels.size - 1 - var->index];
+ }
+}
+
static WasmResult use_name_for_var(WasmAllocator* allocator,
WasmStringSlice* name,
WasmVar* var) {
@@ -61,7 +93,7 @@ static WasmResult use_name_for_var(WasmAllocator* allocator,
return WASM_OK;
}
- if (name->start) {
+ if (name && name->start) {
var->type = WASM_VAR_TYPE_NAME;
var->name = wasm_dup_string_slice(allocator, *name);
return var->name.start != NULL ? WASM_OK : WASM_ERROR;
@@ -132,6 +164,62 @@ static WasmResult use_name_for_param_and_local_var(WasmContext* ctx,
return WASM_OK;
}
+WasmResult begin_block_expr(WasmExpr* expr, void* user_data) {
+ WasmContext* ctx = user_data;
+ CHECK_RESULT(push_label(ctx, &expr->block.label));
+ return WASM_OK;
+}
+
+WasmResult end_block_expr(WasmExpr* expr, void* user_data) {
+ WasmContext* ctx = user_data;
+ pop_label(ctx);
+ return WASM_OK;
+}
+
+WasmResult begin_loop_expr(WasmExpr* expr, void* user_data) {
+ WasmContext* ctx = user_data;
+ CHECK_RESULT(push_label(ctx, &expr->loop.outer));
+ CHECK_RESULT(push_label(ctx, &expr->loop.inner));
+ return WASM_OK;
+}
+
+WasmResult end_loop_expr(WasmExpr* expr, void* user_data) {
+ WasmContext* ctx = user_data;
+ pop_label(ctx);
+ pop_label(ctx);
+ return WASM_OK;
+}
+
+WasmResult begin_br_expr(WasmExpr* expr, void* user_data) {
+ WasmContext* ctx = user_data;
+ WasmLabel* label = find_label_by_var(ctx, &expr->br.var);
+ CHECK_RESULT(use_name_for_var(ctx->allocator, label, &expr->br.var));
+ return WASM_OK;
+}
+
+WasmResult begin_br_if_expr(WasmExpr* expr, void* user_data) {
+ WasmContext* ctx = user_data;
+ WasmLabel* label = find_label_by_var(ctx, &expr->br.var);
+ CHECK_RESULT(use_name_for_var(ctx->allocator, label, &expr->br.var));
+ return WASM_OK;
+}
+
+WasmResult begin_br_table_expr(WasmExpr* expr, void* user_data) {
+ WasmContext* ctx = user_data;
+ size_t i;
+ WasmVarVector* targets = &expr->br_table.targets;
+ for (i = 0; i < targets->size; ++i) {
+ WasmVar* target = &targets->data[i];
+ WasmLabel* label = find_label_by_var(ctx, target);
+ CHECK_RESULT(use_name_for_var(ctx->allocator, label, target));
+ }
+
+ WasmLabel* label = find_label_by_var(ctx, &expr->br_table.default_target);
+ CHECK_RESULT(
+ use_name_for_var(ctx->allocator, label, &expr->br_table.default_target));
+ return WASM_OK;
+}
+
static WasmResult begin_call_expr(WasmExpr* expr, void* user_data) {
WasmContext* ctx = user_data;
CHECK_RESULT(use_name_for_func_var(ctx->allocator, ctx->module,
@@ -232,6 +320,13 @@ WasmResult wasm_apply_names(WasmAllocator* allocator, WasmModule* module) {
ctx.allocator = allocator;
ctx.module = module;
ctx.visitor.user_data = &ctx;
+ ctx.visitor.begin_block_expr = begin_block_expr;
+ ctx.visitor.end_block_expr = end_block_expr;
+ ctx.visitor.begin_loop_expr = begin_loop_expr;
+ ctx.visitor.end_loop_expr = end_loop_expr;
+ ctx.visitor.begin_br_expr = begin_br_expr;
+ ctx.visitor.begin_br_if_expr = begin_br_if_expr;
+ ctx.visitor.begin_br_table_expr = begin_br_table_expr;
ctx.visitor.begin_call_expr = begin_call_expr;
ctx.visitor.begin_call_import_expr = begin_call_import_expr;
ctx.visitor.begin_call_indirect_expr = begin_call_indirect_expr;
@@ -240,5 +335,6 @@ WasmResult wasm_apply_names(WasmAllocator* allocator, WasmModule* module) {
WasmResult result = visit_module(&ctx, module);
wasm_destroy_string_slice_vector(allocator, &ctx.param_index_to_name);
wasm_destroy_string_slice_vector(allocator, &ctx.local_index_to_name);
+ wasm_destroy_label_ptr_vector(allocator, &ctx.labels);
return result;
}
diff --git a/src/wasm-ast-writer.c b/src/wasm-ast-writer.c
index 7d6cb75a..495c0377 100644
--- a/src/wasm-ast-writer.c
+++ b/src/wasm-ast-writer.c
@@ -211,11 +211,12 @@ static void out_string_slice(WasmContext* ctx,
ctx->next_char = next_char;
}
-static void out_string_slice_opt(WasmContext* ctx,
- const WasmStringSlice* str,
- WasmNextChar next_char) {
+static WasmBool out_string_slice_opt(WasmContext* ctx,
+ const WasmStringSlice* str,
+ WasmNextChar next_char) {
if (str->start)
out_string_slice(ctx, str, next_char);
+ return str->start ? WASM_TRUE : WASM_FALSE;
}
static void out_string_slice_or_index(WasmContext* ctx,
@@ -308,8 +309,8 @@ static void write_block(WasmContext* ctx,
const WasmBlock* block,
const char* text) {
out_open_space(ctx, text);
- out_string_slice_opt(ctx, &block->label, WASM_NEXT_CHAR_SPACE);
- out_printf(ctx, " ;; exit = @%d", ctx->depth);
+ if (!out_string_slice_opt(ctx, &block->label, WASM_NEXT_CHAR_SPACE))
+ out_printf(ctx, " ;; exit = @%d", ctx->depth);
out_newline(ctx, FORCE_NEWLINE);
ctx->depth++;
write_exprs(ctx, &block->exprs);
@@ -541,17 +542,27 @@ static void write_expr(WasmContext* ctx, const WasmExpr* expr) {
out_close_newline(ctx);
break;
- case WASM_EXPR_TYPE_LOOP:
+ case WASM_EXPR_TYPE_LOOP: {
out_open_space(ctx, s_opcode_name[WASM_OPCODE_LOOP]);
- out_string_slice_opt(ctx, &expr->loop.inner, WASM_NEXT_CHAR_SPACE);
- out_string_slice_opt(ctx, &expr->loop.outer, WASM_NEXT_CHAR_SPACE);
- out_printf(ctx, " ;; exit = @%d, cont = @%d", ctx->depth, ctx->depth + 1);
+ WasmBool has_outer_name =
+ out_string_slice_opt(ctx, &expr->loop.outer, WASM_NEXT_CHAR_SPACE);
+ WasmBool has_inner_name =
+ out_string_slice_opt(ctx, &expr->loop.inner, WASM_NEXT_CHAR_SPACE);
+ if (!has_outer_name || !has_inner_name) {
+ out_printf(ctx, " ;;");
+ if (!has_outer_name)
+ out_printf(ctx, "exit = @%d", ctx->depth);
+ if (!has_inner_name) {
+ out_printf(ctx, "cont = @%d", ctx->depth + 1);
+ }
+ }
out_newline(ctx, FORCE_NEWLINE);
ctx->depth += 2;
write_exprs(ctx, &expr->loop.exprs);
ctx->depth -= 2;
out_close_newline(ctx);
break;
+ }
case WASM_EXPR_TYPE_MEMORY_SIZE:
out_open_space(ctx, s_opcode_name[WASM_OPCODE_MEMORY_SIZE]);
diff --git a/src/wasm-binary-reader-ast.c b/src/wasm-binary-reader-ast.c
index f0e6abae..acbe2422 100644
--- a/src/wasm-binary-reader-ast.c
+++ b/src/wasm-binary-reader-ast.c
@@ -107,6 +107,18 @@ static void print_error(WasmContext* ctx, const char* format, ...) {
on_error(UNKNOWN_OFFSET, buffer, ctx);
}
+static WasmResult dup_name(WasmContext* ctx,
+ WasmStringSlice* name,
+ WasmStringSlice* out_name) {
+ if (name->length > 0) {
+ *out_name = wasm_dup_string_slice(ctx->allocator, *name);
+ CHECK_ALLOC_NULL_STR(ctx, *out_name);
+ } else {
+ WASM_ZERO_MEMORY(*out_name);
+ }
+ return WASM_OK;
+}
+
/* 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);
@@ -1006,17 +1018,16 @@ static WasmResult on_function_name(uint32_t index,
void* user_data) {
WasmContext* ctx = user_data;
- WasmStringSlice dup_name;
- CHECK_ALLOC_NULL_STR(ctx,
- dup_name = wasm_dup_string_slice(ctx->allocator, name));
+ WasmStringSlice new_name;
+ CHECK_RESULT(dup_name(ctx, &name, &new_name));
WasmBinding* binding = wasm_insert_binding(
- ctx->allocator, &ctx->module->func_bindings, &dup_name);
+ ctx->allocator, &ctx->module->func_bindings, &new_name);
CHECK_ALLOC_NULL(ctx, binding);
binding->index = index;
WasmFunc* func = ctx->module->funcs.data[index];
- func->name = dup_name;
+ func->name = new_name;
return WASM_OK;
}
@@ -1044,9 +1055,8 @@ static WasmResult on_local_name(uint32_t func_index,
WasmModule* module = ctx->module;
WasmFunc* func = module->funcs.data[func_index];
uint32_t num_params = wasm_get_num_params(func);
- WasmStringSlice dup_name;
- CHECK_ALLOC_NULL_STR(ctx,
- dup_name = wasm_dup_string_slice(ctx->allocator, name));
+ WasmStringSlice new_name;
+ CHECK_RESULT(dup_name(ctx, &name, &new_name));
WasmBindingHash* bindings;
WasmBinding* binding;
uint32_t index;
@@ -1059,7 +1069,7 @@ static WasmResult on_local_name(uint32_t func_index,
bindings = &func->local_bindings;
index = local_index - num_params;
}
- binding = wasm_insert_binding(ctx->allocator, bindings, &dup_name);
+ binding = wasm_insert_binding(ctx->allocator, bindings, &new_name);
CHECK_ALLOC_NULL(ctx, binding);
binding->index = index;
return WASM_OK;
diff --git a/src/wasm-generate-names.c b/src/wasm-generate-names.c
index 43c50a94..e41519ee 100644
--- a/src/wasm-generate-names.c
+++ b/src/wasm-generate-names.c
@@ -46,7 +46,9 @@ WASM_DEFINE_VECTOR(uint32, WasmUint32);
typedef struct WasmContext {
WasmAllocator* allocator;
WasmModule* module;
+ WasmExprVisitor visitor;
WasmStringSliceVector index_to_name;
+ uint32_t label_count;
} WasmContext;
static WasmBool has_name(WasmStringSlice* str) {
@@ -54,7 +56,6 @@ static WasmBool has_name(WasmStringSlice* str) {
}
static WasmResult generate_name(WasmAllocator* allocator,
- WasmBindingHash* bindings,
const char* prefix,
uint32_t index,
WasmStringSlice* str) {
@@ -67,26 +68,46 @@ static WasmResult generate_name(WasmAllocator* allocator,
buf.length = actual_len;
buf.start = buffer;
CHECK_ALLOC_NULL_STR(*str = wasm_dup_string_slice(allocator, buf));
- WasmBinding* binding;
- CHECK_ALLOC_NULL(binding = wasm_insert_binding(allocator, bindings, str));
- binding->index = index;
return WASM_OK;
}
static WasmResult maybe_generate_name(WasmAllocator* allocator,
- WasmBindingHash* bindings,
const char* prefix,
uint32_t index,
WasmStringSlice* str) {
if (has_name(str))
return WASM_OK;
- return generate_name(allocator, bindings, prefix, index, str);
+ return generate_name(allocator, prefix, index, str);
+}
+
+
+static WasmResult generate_and_bind_name(WasmAllocator* allocator,
+ WasmBindingHash* bindings,
+ const char* prefix,
+ uint32_t index,
+ WasmStringSlice* str) {
+ CHECK_RESULT(generate_name(allocator, prefix, index, str));
+ WasmBinding* binding;
+ CHECK_ALLOC_NULL(binding = wasm_insert_binding(allocator, bindings, str));
+ binding->index = index;
+ return WASM_OK;
+}
+
+static WasmResult maybe_generate_and_bind_name(WasmAllocator* allocator,
+ WasmBindingHash* bindings,
+ const char* prefix,
+ uint32_t index,
+ WasmStringSlice* str) {
+ if (has_name(str))
+ return WASM_OK;
+ return generate_and_bind_name(allocator, bindings, prefix, index, str);
}
-static WasmResult generate_local_names(WasmAllocator* allocator,
- WasmStringSliceVector* index_to_name,
- WasmBindingHash* bindings,
- const char* prefix) {
+static WasmResult generate_and_bind_local_names(
+ WasmAllocator* allocator,
+ WasmStringSliceVector* index_to_name,
+ WasmBindingHash* bindings,
+ const char* prefix) {
size_t i;
for (i = 0; i < index_to_name->size; ++i) {
WasmStringSlice* old_name = &index_to_name->data[i];
@@ -94,37 +115,57 @@ static WasmResult generate_local_names(WasmAllocator* allocator,
continue;
WasmStringSlice new_name;
- CHECK_RESULT(generate_name(allocator, bindings, prefix, i, &new_name));
+ CHECK_RESULT(
+ generate_and_bind_name(allocator, bindings, prefix, i, &new_name));
index_to_name->data[i] = new_name;
}
return WASM_OK;
}
+static WasmResult begin_block_expr(WasmExpr* expr, void* user_data) {
+ WasmContext* ctx = user_data;
+ CHECK_ALLOC(maybe_generate_name(ctx->allocator, "$B", ctx->label_count++,
+ &expr->block.label));
+ return WASM_OK;
+}
+
+static WasmResult begin_loop_expr(WasmExpr* expr, void* user_data) {
+ WasmContext* ctx = user_data;
+ CHECK_ALLOC(maybe_generate_name(ctx->allocator, "$L", ctx->label_count++,
+ &expr->loop.outer));
+ CHECK_ALLOC(maybe_generate_name(ctx->allocator, "$L", ctx->label_count++,
+ &expr->loop.inner));
+ return WASM_OK;
+}
+
static WasmResult visit_func(WasmContext* ctx,
uint32_t func_index,
WasmFunc* func) {
- CHECK_ALLOC(maybe_generate_name(ctx->allocator, &ctx->module->func_bindings,
- "$f", func_index, &func->name));
+ CHECK_ALLOC(maybe_generate_and_bind_name(ctx->allocator,
+ &ctx->module->func_bindings, "$f",
+ func_index, &func->name));
CHECK_ALLOC(wasm_make_type_binding_reverse_mapping(
ctx->allocator, &func->decl.sig.param_types, &func->param_bindings,
&ctx->index_to_name));
- CHECK_RESULT(generate_local_names(ctx->allocator, &ctx->index_to_name,
- &func->param_bindings, "$p"));
+ CHECK_RESULT(generate_and_bind_local_names(
+ ctx->allocator, &ctx->index_to_name, &func->param_bindings, "$p"));
CHECK_ALLOC(wasm_make_type_binding_reverse_mapping(
ctx->allocator, &func->local_types, &func->local_bindings,
&ctx->index_to_name));
- CHECK_RESULT(generate_local_names(ctx->allocator, &ctx->index_to_name,
- &func->local_bindings, "$l"));
+ CHECK_RESULT(generate_and_bind_local_names(
+ ctx->allocator, &ctx->index_to_name, &func->local_bindings, "$l"));
+ ctx->label_count = 0;
+ CHECK_RESULT(wasm_visit_func(func, &ctx->visitor));
return WASM_OK;
}
static WasmResult visit_func_type(WasmContext* ctx,
uint32_t func_type_index,
WasmFuncType* func_type) {
- CHECK_ALLOC(maybe_generate_name(ctx->allocator,
+ CHECK_ALLOC(maybe_generate_and_bind_name(ctx->allocator,
&ctx->module->func_type_bindings, "$t",
func_type_index, &func_type->name));
return WASM_OK;
@@ -133,8 +174,9 @@ static WasmResult visit_func_type(WasmContext* ctx,
static WasmResult visit_import(WasmContext* ctx,
uint32_t import_index,
WasmImport* import) {
- CHECK_ALLOC(maybe_generate_name(ctx->allocator, &ctx->module->import_bindings,
- "$i", import_index, &import->name));
+ CHECK_ALLOC(maybe_generate_and_bind_name(ctx->allocator,
+ &ctx->module->import_bindings, "$i",
+ import_index, &import->name));
return WASM_OK;
}
@@ -153,6 +195,9 @@ WasmResult wasm_generate_names(WasmAllocator* allocator, WasmModule* module) {
WasmContext ctx;
WASM_ZERO_MEMORY(ctx);
ctx.allocator = allocator;
+ ctx.visitor.user_data = &ctx;
+ ctx.visitor.begin_block_expr = begin_block_expr;
+ ctx.visitor.begin_loop_expr = begin_loop_expr;
ctx.module = module;
WasmResult result = visit_module(&ctx, module);
wasm_destroy_string_slice_vector(allocator, &ctx.index_to_name);