summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/wasm-apply-names.c244
-rw-r--r--src/wasm-apply-names.h44
-rw-r--r--src/wasm-ast-writer.c26
-rw-r--r--src/wasm-binary-reader-ast.c4
-rw-r--r--src/wasm-binary-reader.h2
-rw-r--r--src/wasm-generate-names.c160
-rw-r--r--src/wasm-generate-names.h29
-rw-r--r--src/wasm-vector.h3
-rw-r--r--src/wasm-wast.c48
9 files changed, 531 insertions, 29 deletions
diff --git a/src/wasm-apply-names.c b/src/wasm-apply-names.c
new file mode 100644
index 00000000..b940efdf
--- /dev/null
+++ b/src/wasm-apply-names.c
@@ -0,0 +1,244 @@
+/*
+ * Copyright 2016 WebAssembly Community Group participants
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "wasm-apply-names.h"
+
+#include <assert.h>
+#include <stdio.h>
+
+#include "wasm-allocator.h"
+#include "wasm-ast.h"
+
+#define CHECK_ALLOC_(cond) \
+ do { \
+ if (!(cond)) { \
+ fprintf(stderr, "%s:%d: allocation failed", __FILE__, __LINE__); \
+ return WASM_ERROR; \
+ } \
+ } while (0)
+
+#define CHECK_ALLOC(e) CHECK_ALLOC_(WASM_SUCCEEDED(e))
+#define CHECK_ALLOC_NULL(v) CHECK_ALLOC_((v) != NULL)
+#define CHECK_ALLOC_NULL_STR(v) CHECK_ALLOC_((v).start)
+
+#define CHECK_RESULT(expr) \
+ do { \
+ if (WASM_FAILED(expr)) \
+ return WASM_ERROR; \
+ } while (0)
+
+typedef uint32_t WasmUint32;
+WASM_DEFINE_VECTOR(uint32, WasmUint32);
+
+typedef struct WasmContext {
+ WasmAllocator* allocator;
+ WasmModule* module;
+ WasmFunc* current_func;
+ WasmExprVisitor visitor;
+ /* mapping from param index to its name, if any, for the current func */
+ WasmStringSliceVector param_index_to_name;
+ WasmStringSliceVector local_index_to_name;
+} WasmContext;
+
+static WasmResult use_name_for_var(WasmAllocator* allocator,
+ WasmStringSlice* name,
+ WasmVar* var) {
+ if (var->type == WASM_VAR_TYPE_NAME) {
+ assert(wasm_string_slices_are_equal(name, &var->name));
+ return WASM_OK;
+ }
+
+ if (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;
+ }
+ return WASM_OK;
+}
+
+static WasmResult use_name_for_func_type_var(WasmAllocator* allocator,
+ WasmModule* module,
+ WasmVar* var) {
+ WasmFuncType* func_type = wasm_get_func_type_by_var(module, var);
+ if (func_type == NULL)
+ return WASM_ERROR;
+ CHECK_ALLOC(use_name_for_var(allocator, &func_type->name, var));
+ return WASM_OK;
+}
+
+static WasmResult use_name_for_func_var(WasmAllocator* allocator,
+ WasmModule* module,
+ WasmVar* var) {
+ WasmFunc* func = wasm_get_func_by_var(module, var);
+ if (func == NULL)
+ return WASM_ERROR;
+ CHECK_ALLOC(use_name_for_var(allocator, &func->name, var));
+ return WASM_OK;
+}
+
+static WasmResult use_name_for_import_var(WasmAllocator* allocator,
+ WasmModule* module,
+ WasmVar* var) {
+ WasmImport* import = wasm_get_import_by_var(module, var);
+ if (import == NULL)
+ return WASM_ERROR;
+ CHECK_ALLOC(use_name_for_var(allocator, &import->name, var));
+ return WASM_OK;
+}
+
+static WasmResult use_name_for_param_and_local_var(WasmContext* ctx,
+ WasmFunc* func,
+ WasmVar* var) {
+ int local_index = wasm_get_local_index_by_var(func, var);
+ assert(local_index >= 0 &&
+ (size_t)local_index < wasm_get_num_params_and_locals(func));
+
+ uint32_t num_params = wasm_get_num_params(func);
+ WasmStringSlice* name;
+ if ((uint32_t)local_index < num_params) {
+ /* param */
+ assert((size_t)local_index < ctx->param_index_to_name.size);
+ name = &ctx->param_index_to_name.data[local_index];
+ } else {
+ /* local */
+ local_index -= num_params;
+ assert((size_t)local_index < ctx->local_index_to_name.size);
+ name = &ctx->local_index_to_name.data[local_index];
+ }
+
+ if (var->type == WASM_VAR_TYPE_NAME) {
+ assert(wasm_string_slices_are_equal(name, &var->name));
+ return WASM_OK;
+ }
+
+ if (name->start) {
+ var->type = WASM_VAR_TYPE_NAME;
+ var->name = wasm_dup_string_slice(ctx->allocator, *name);
+ return var->name.start != NULL ? WASM_OK : WASM_ERROR;
+ }
+ 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,
+ &expr->call.var));
+ return WASM_OK;
+}
+
+static WasmResult begin_call_import_expr(WasmExpr* expr, void* user_data) {
+ WasmContext* ctx = user_data;
+ CHECK_RESULT(
+ use_name_for_import_var(ctx->allocator, ctx->module, &expr->call.var));
+ return WASM_OK;
+}
+
+static WasmResult begin_call_indirect_expr(WasmExpr* expr, void* user_data) {
+ WasmContext* ctx = user_data;
+ CHECK_RESULT(use_name_for_func_type_var(ctx->allocator, ctx->module,
+ &expr->call_indirect.var));
+ return WASM_OK;
+}
+
+static WasmResult on_get_local_expr(WasmExpr* expr, void* user_data) {
+ WasmContext* ctx = user_data;
+ CHECK_RESULT(use_name_for_param_and_local_var(ctx, ctx->current_func,
+ &expr->get_local.var));
+ return WASM_OK;
+}
+
+static WasmResult begin_set_local_expr(WasmExpr* expr, void* user_data) {
+ WasmContext* ctx = user_data;
+ CHECK_RESULT(use_name_for_param_and_local_var(ctx, ctx->current_func,
+ &expr->set_local.var));
+ return WASM_OK;
+}
+
+static WasmResult visit_func(WasmContext* ctx,
+ uint32_t func_index,
+ WasmFunc* func) {
+ ctx->current_func = func;
+ if (wasm_decl_has_func_type(&func->decl)) {
+ CHECK_RESULT(use_name_for_func_type_var(ctx->allocator, ctx->module,
+ &func->decl.type_var));
+ }
+
+ assert(wasm_decl_has_signature(&func->decl));
+
+ CHECK_ALLOC(wasm_make_type_binding_reverse_mapping(
+ ctx->allocator, &func->decl.sig.param_types, &func->param_bindings,
+ &ctx->param_index_to_name));
+
+ CHECK_ALLOC(wasm_make_type_binding_reverse_mapping(
+ ctx->allocator, &func->local_types, &func->local_bindings,
+ &ctx->local_index_to_name));
+
+ CHECK_RESULT(wasm_visit_func(func, &ctx->visitor));
+ ctx->current_func = NULL;
+ return WASM_OK;
+}
+
+static WasmResult visit_import(WasmContext* ctx,
+ uint32_t import_index,
+ WasmImport* import) {
+ if (wasm_decl_has_func_type(&import->decl)) {
+ CHECK_RESULT(use_name_for_func_type_var(ctx->allocator, ctx->module,
+ &import->decl.type_var));
+ }
+ return WASM_OK;
+}
+
+static WasmResult visit_export(WasmContext* ctx,
+ uint32_t export_index,
+ WasmExport* export) {
+ CHECK_ALLOC(use_name_for_func_var(ctx->allocator, ctx->module, &export->var));
+ return WASM_OK;
+}
+
+static WasmResult visit_module(WasmContext* ctx, WasmModule* module) {
+ size_t i;
+ for (i = 0; i < module->imports.size; ++i)
+ CHECK_RESULT(visit_import(ctx, i, module->imports.data[i]));
+ for (i = 0; i < module->funcs.size; ++i)
+ CHECK_RESULT(visit_func(ctx, i, module->funcs.data[i]));
+ for (i = 0; i < module->exports.size; ++i)
+ CHECK_RESULT(visit_export(ctx, i, module->exports.data[i]));
+ if (module->table) {
+ for (i = 0; i < module->table->size; ++i) {
+ CHECK_RESULT(use_name_for_func_var(ctx->allocator, ctx->module,
+ &module->table->data[i]));
+ }
+ }
+ return WASM_OK;
+}
+
+
+WasmResult wasm_apply_names(WasmAllocator* allocator, WasmModule* module) {
+ WasmContext ctx;
+ WASM_ZERO_MEMORY(ctx);
+ ctx.allocator = allocator;
+ ctx.module = module;
+ ctx.visitor.user_data = &ctx;
+ 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;
+ ctx.visitor.on_get_local_expr = on_get_local_expr;
+ ctx.visitor.begin_set_local_expr = begin_set_local_expr;
+ 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);
+ return result;
+}
diff --git a/src/wasm-apply-names.h b/src/wasm-apply-names.h
new file mode 100644
index 00000000..88999b25
--- /dev/null
+++ b/src/wasm-apply-names.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2016 WebAssembly Community Group participants
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef WASM_APPLY_NAMES_H_
+#define WASM_APPLY_NAMES_H_
+
+#include "wasm-common.h"
+
+struct WasmAllocator;
+struct WasmModule;
+
+/* Use function, import, function type, parameter and local names in WasmVars
+ * that reference them.
+ *
+ * e.g. transform this:
+ *
+ * (func $foo ...)
+ * ...
+ * (call 0 ...)
+ *
+ * to this:
+ *
+ * (func $foo ...)
+ * ...
+ * (call $foo ...)
+ */
+WASM_EXTERN_C_BEGIN
+WasmResult wasm_apply_names(struct WasmAllocator*, struct WasmModule*);
+WASM_EXTERN_C_END
+
+#endif /* WASM_APPLY_NAMES_H_ */
diff --git a/src/wasm-ast-writer.c b/src/wasm-ast-writer.c
index 00c5d59b..7d6cb75a 100644
--- a/src/wasm-ast-writer.c
+++ b/src/wasm-ast-writer.c
@@ -218,6 +218,16 @@ static void out_string_slice_opt(WasmContext* ctx,
out_string_slice(ctx, str, next_char);
}
+static void out_string_slice_or_index(WasmContext* ctx,
+ const WasmStringSlice* str,
+ uint32_t index,
+ WasmNextChar next_char) {
+ if (str->start)
+ out_string_slice(ctx, str, next_char);
+ else
+ out_printf(ctx, "(;%u;)", index);
+}
+
static void out_quoted_data(WasmContext* ctx, const void* data, size_t length) {
const uint8_t* u8_data = data;
static const char s_hexdigits[] = "0123456789abcdef";
@@ -260,7 +270,7 @@ static void out_br_var(WasmContext* ctx,
const WasmVar* var,
WasmNextChar next_char) {
if (var->type == WASM_VAR_TYPE_INDEX) {
- out_printf(ctx, "%d (; @%d ;)", var->index, ctx->depth - var->index - 1);
+ out_printf(ctx, "%d (;@%d;)", var->index, ctx->depth - var->index - 1);
ctx->next_char = next_char;
} else {
out_string_slice(ctx, &var->name, next_char);
@@ -651,8 +661,7 @@ static void write_func(WasmContext* ctx,
int func_index,
const WasmFunc* func) {
out_open_space(ctx, "func");
- out_printf(ctx, "(; %d ;)", func_index);
- out_string_slice_opt(ctx, &func->name, WASM_NEXT_CHAR_SPACE);
+ out_string_slice_or_index(ctx, &func->name, func_index, WASM_NEXT_CHAR_SPACE);
if (wasm_decl_has_func_type(&func->decl)) {
out_open_space(ctx, "type");
out_var(ctx, &func->decl.type_var, WASM_NEXT_CHAR_NONE);
@@ -681,8 +690,8 @@ static void write_import(WasmContext* ctx,
int import_index,
const WasmImport* import) {
out_open_space(ctx, "import");
- out_printf(ctx, "(; %d ;)", import_index);
- out_string_slice_opt(ctx, &import->name, WASM_NEXT_CHAR_SPACE);
+ out_string_slice_or_index(ctx, &import->name, import_index,
+ WASM_NEXT_CHAR_SPACE);
out_quoted_string_slice(ctx, &import->module_name, WASM_NEXT_CHAR_SPACE);
out_quoted_string_slice(ctx, &import->func_name, WASM_NEXT_CHAR_SPACE);
if (wasm_decl_has_func_type(&import->decl)) {
@@ -699,9 +708,8 @@ static void write_export(WasmContext* ctx,
int export_index,
const WasmExport* export) {
out_open_space(ctx, "export");
- out_printf(ctx, "(; %d ;)", export_index);
out_quoted_string_slice(ctx, &export->name, WASM_NEXT_CHAR_SPACE);
- out_var(ctx, &export->var, WASM_NEXT_CHAR_NONE);
+ out_var(ctx, &export->var, WASM_NEXT_CHAR_SPACE);
out_close_newline(ctx);
}
@@ -746,8 +754,8 @@ static void write_func_type(WasmContext* ctx,
int func_type_index,
const WasmFuncType* func_type) {
out_open_space(ctx, "type");
- out_printf(ctx, "(; %d ;)", func_type_index);
- out_string_slice_opt(ctx, &func_type->name, WASM_NEXT_CHAR_SPACE);
+ out_string_slice_or_index(ctx, &func_type->name, func_type_index,
+ WASM_NEXT_CHAR_SPACE);
out_open_space(ctx, "func");
out_func_sig_space(ctx, &func_type->sig);
out_close_space(ctx);
diff --git a/src/wasm-binary-reader-ast.c b/src/wasm-binary-reader-ast.c
index 3e37f81e..f0e6abae 100644
--- a/src/wasm-binary-reader-ast.c
+++ b/src/wasm-binary-reader-ast.c
@@ -1017,8 +1017,6 @@ static WasmResult on_function_name(uint32_t index,
WasmFunc* func = ctx->module->funcs.data[index];
func->name = dup_name;
- /* TODO(binji): We could update the call expressions to use the function name
- * instead of the index */
return WASM_OK;
}
@@ -1064,8 +1062,6 @@ static WasmResult on_local_name(uint32_t func_index,
binding = wasm_insert_binding(ctx->allocator, bindings, &dup_name);
CHECK_ALLOC_NULL(ctx, binding);
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-reader.h b/src/wasm-binary-reader.h
index c1012432..470f0a56 100644
--- a/src/wasm-binary-reader.h
+++ b/src/wasm-binary-reader.h
@@ -26,7 +26,7 @@
struct WasmAllocator;
#define WASM_READ_BINARY_OPTIONS_DEFAULT \
- { 0 }
+ { WASM_FALSE }
typedef struct WasmReadBinaryOptions {
WasmBool read_debug_names;
diff --git a/src/wasm-generate-names.c b/src/wasm-generate-names.c
new file mode 100644
index 00000000..43c50a94
--- /dev/null
+++ b/src/wasm-generate-names.c
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2016 WebAssembly Community Group participants
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "wasm-generate-names.h"
+
+#include <assert.h>
+#include <stdio.h>
+
+#include "wasm-allocator.h"
+#include "wasm-ast.h"
+
+#define CHECK_ALLOC_(cond) \
+ do { \
+ if (!(cond)) { \
+ fprintf(stderr, "%s:%d: allocation failed", __FILE__, __LINE__); \
+ return WASM_ERROR; \
+ } \
+ } while (0)
+
+#define CHECK_ALLOC(e) CHECK_ALLOC_(WASM_SUCCEEDED(e))
+#define CHECK_ALLOC_NULL(v) CHECK_ALLOC_((v) != NULL)
+#define CHECK_ALLOC_NULL_STR(v) CHECK_ALLOC_((v).start)
+
+#define CHECK_RESULT(expr) \
+ do { \
+ if (WASM_FAILED(expr)) \
+ return WASM_ERROR; \
+ } while (0)
+
+typedef uint32_t WasmUint32;
+WASM_DEFINE_VECTOR(uint32, WasmUint32);
+
+typedef struct WasmContext {
+ WasmAllocator* allocator;
+ WasmModule* module;
+ WasmStringSliceVector index_to_name;
+} WasmContext;
+
+static WasmBool has_name(WasmStringSlice* str) {
+ return str->length > 0;
+}
+
+static WasmResult generate_name(WasmAllocator* allocator,
+ WasmBindingHash* bindings,
+ const char* prefix,
+ uint32_t index,
+ WasmStringSlice* str) {
+ size_t prefix_len = strlen(prefix);
+ size_t buffer_len = prefix_len + 20; /* add space for the number */
+ char* buffer = alloca(buffer_len);
+ int actual_len = wasm_snprintf(buffer, buffer_len, "%s%u", prefix, index);
+
+ WasmStringSlice buf;
+ 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);
+}
+
+static WasmResult generate_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];
+ if (has_name(old_name))
+ continue;
+
+ WasmStringSlice new_name;
+ CHECK_RESULT(generate_name(allocator, bindings, prefix, i, &new_name));
+ index_to_name->data[i] = new_name;
+ }
+ 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(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_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"));
+
+ 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,
+ &ctx->module->func_type_bindings, "$t",
+ func_type_index, &func_type->name));
+ return WASM_OK;
+}
+
+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));
+ return WASM_OK;
+}
+
+static WasmResult visit_module(WasmContext* ctx, WasmModule* module) {
+ size_t i;
+ for (i = 0; i < module->func_types.size; ++i)
+ CHECK_RESULT(visit_func_type(ctx, i, module->func_types.data[i]));
+ for (i = 0; i < module->imports.size; ++i)
+ CHECK_RESULT(visit_import(ctx, i, module->imports.data[i]));
+ for (i = 0; i < module->funcs.size; ++i)
+ CHECK_RESULT(visit_func(ctx, i, module->funcs.data[i]));
+ return WASM_OK;
+}
+
+WasmResult wasm_generate_names(WasmAllocator* allocator, WasmModule* module) {
+ WasmContext ctx;
+ WASM_ZERO_MEMORY(ctx);
+ ctx.allocator = allocator;
+ ctx.module = module;
+ WasmResult result = visit_module(&ctx, module);
+ wasm_destroy_string_slice_vector(allocator, &ctx.index_to_name);
+ return result;
+}
diff --git a/src/wasm-generate-names.h b/src/wasm-generate-names.h
new file mode 100644
index 00000000..4fa6acfa
--- /dev/null
+++ b/src/wasm-generate-names.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2016 WebAssembly Community Group participants
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef WASM_GENERATE_NAMES_H_
+#define WASM_GENERATE_NAMES_H_
+
+#include "wasm-common.h"
+
+struct WasmAllocator;
+struct WasmModule;
+
+WASM_EXTERN_C_BEGIN
+WasmResult wasm_generate_names(struct WasmAllocator*, struct WasmModule*);
+WASM_EXTERN_C_END
+
+#endif /* WASM_GENERATE_NAMES_H_ */
diff --git a/src/wasm-vector.h b/src/wasm-vector.h
index d67175cd..7a508138 100644
--- a/src/wasm-vector.h
+++ b/src/wasm-vector.h
@@ -74,6 +74,9 @@
void wasm_destroy_##name##_vector(struct WasmAllocator* allocator, \
type##Vector* vec) { \
wasm_free(allocator, vec->data); \
+ vec->data = NULL; \
+ vec->size = 0; \
+ vec->capacity = 0; \
} \
WasmResult wasm_resize_##name##_vector(struct WasmAllocator* allocator, \
type##Vector* vec, size_t size) { \
diff --git a/src/wasm-wast.c b/src/wasm-wast.c
index 01ad58b1..d4686772 100644
--- a/src/wasm-wast.c
+++ b/src/wasm-wast.c
@@ -20,10 +20,12 @@
#include <stdlib.h>
#include "wasm-allocator.h"
+#include "wasm-apply-names.h"
#include "wasm-ast.h"
#include "wasm-ast-writer.h"
#include "wasm-binary-reader.h"
#include "wasm-binary-reader-ast.h"
+#include "wasm-generate-names.h"
#include "wasm-option-parser.h"
#include "wasm-stack-allocator.h"
#include "wasm-writer.h"
@@ -33,7 +35,8 @@ static const char* s_infile;
static const char* s_outfile;
static WasmReadBinaryOptions s_read_binary_options =
WASM_READ_BINARY_OPTIONS_DEFAULT;
-static int s_use_libc_allocator;
+static WasmBool s_use_libc_allocator;
+static WasmBool s_generate_names;
#define NOPE WASM_OPTION_NO_ARGUMENT
#define YEP WASM_OPTION_HAS_ARGUMENT
@@ -44,6 +47,7 @@ enum {
FLAG_OUTPUT,
FLAG_USE_LIBC_ALLOCATOR,
FLAG_DEBUG_NAMES,
+ FLAG_GENERATE_NAMES,
NUM_FLAGS
};
@@ -57,6 +61,8 @@ static WasmOption s_options[] = {
"use malloc, free, etc. instead of stack allocator"},
{FLAG_DEBUG_NAMES, 0, "debug-names", NULL, NOPE,
"Read debug names from the binary file"},
+ {FLAG_GENERATE_NAMES, 0, "generate-names", NULL, NOPE,
+ "Give auto-generated names to non-named functions, types, etc."},
};
WASM_STATIC_ASSERT(NUM_FLAGS == WASM_ARRAY_SIZE(s_options));
@@ -84,6 +90,10 @@ static void on_option(struct WasmOptionParser* parser,
case FLAG_DEBUG_NAMES:
s_read_binary_options.read_debug_names = WASM_TRUE;
break;
+
+ case FLAG_GENERATE_NAMES:
+ s_generate_names = WASM_TRUE;
+ break;
}
}
@@ -129,22 +139,30 @@ int main(int argc, char** argv) {
void* data;
size_t size;
result = wasm_read_file(allocator, s_infile, &data, &size);
- if (result == WASM_OK) {
+ if (WASM_SUCCEEDED(result)) {
WasmModule module;
WASM_ZERO_MEMORY(module);
- result = wasm_read_binary_ast(allocator, data, size,
- &s_read_binary_options, &module);
- if (result == WASM_OK) {
- WasmFileWriter file_writer;
- if (s_outfile) {
- result = wasm_init_file_writer(&file_writer, s_outfile);
- } else {
- result = wasm_init_file_writer_existing(&file_writer, stdout);
- }
-
- if (result == WASM_OK) {
- result = wasm_write_ast(allocator, &file_writer.base, &module);
- wasm_close_file_writer(&file_writer);
+ result = wasm_read_binary_ast(allocator, data, size, &s_read_binary_options,
+ &module);
+ if (WASM_SUCCEEDED(result)) {
+ if (s_generate_names)
+ result = wasm_generate_names(allocator, &module);
+
+ if (WASM_SUCCEEDED(result))
+ result = wasm_apply_names(allocator, &module);
+
+ if (WASM_SUCCEEDED(result)) {
+ WasmFileWriter file_writer;
+ if (s_outfile) {
+ result = wasm_init_file_writer(&file_writer, s_outfile);
+ } else {
+ result = wasm_init_file_writer_existing(&file_writer, stdout);
+ }
+
+ if (WASM_SUCCEEDED(result)) {
+ result = wasm_write_ast(allocator, &file_writer.base, &module);
+ wasm_close_file_writer(&file_writer);
+ }
}
}