summaryrefslogtreecommitdiff
path: root/src/tools/wasm-interp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/wasm-interp.c')
-rw-r--r--src/tools/wasm-interp.c236
1 files changed, 129 insertions, 107 deletions
diff --git a/src/tools/wasm-interp.c b/src/tools/wasm-interp.c
index 85abc7e4..5e99a345 100644
--- a/src/tools/wasm-interp.c
+++ b/src/tools/wasm-interp.c
@@ -231,41 +231,7 @@ static void print_typed_value(WasmInterpreterTypedValue* tv) {
}
}
-static void print_typed_values(WasmInterpreterTypedValue* values,
- size_t num_values) {
- uint32_t i;
- for (i = 0; i < num_values; ++i) {
- print_typed_value(&values[i]);
- if (i != num_values - 1)
- printf(", ");
- }
-}
-
-static WasmResult default_host_callback(const WasmInterpreterFuncSignature* sig,
- const WasmStringSlice* module_name,
- const WasmStringSlice* field_name,
- uint32_t num_args,
- WasmInterpreterTypedValue* args,
- uint32_t num_results,
- WasmInterpreterTypedValue* out_results,
- void* user_data) {
- memset(out_results, 0, sizeof(WasmInterpreterTypedValue) * num_results);
- uint32_t i;
- for (i = 0; i < num_results; ++i)
- out_results[i].type = sig->result_types.data[i];
-
- printf("called host " PRIstringslice "." PRIstringslice "(",
- WASM_PRINTF_STRING_SLICE_ARG(*module_name),
- WASM_PRINTF_STRING_SLICE_ARG(*field_name));
- print_typed_values(args, num_args);
- printf(") => (");
- print_typed_values(out_results, num_results);
- printf(")\n");
- return WASM_OK;
-}
-
-static WasmInterpreterResult run_defined_function(WasmInterpreterModule* module,
- WasmInterpreterThread* thread,
+static WasmInterpreterResult run_defined_function(WasmInterpreterThread* thread,
uint32_t offset) {
thread->pc = offset;
WasmInterpreterResult iresult = WASM_INTERPRETER_OK;
@@ -273,9 +239,8 @@ static WasmInterpreterResult run_defined_function(WasmInterpreterModule* module,
uint32_t* call_stack_return_top = thread->call_stack_top;
while (iresult == WASM_INTERPRETER_OK) {
if (s_trace)
- wasm_trace_pc(module, thread, s_stdout_stream);
- iresult =
- wasm_run_interpreter(module, thread, quantum, call_stack_return_top);
+ wasm_trace_pc(thread, s_stdout_stream);
+ iresult = wasm_run_interpreter(thread, quantum, call_stack_return_top);
}
if (iresult != WASM_INTERPRETER_RETURNED) {
if (s_trace)
@@ -286,27 +251,23 @@ static WasmInterpreterResult run_defined_function(WasmInterpreterModule* module,
return WASM_INTERPRETER_OK;
}
-static WasmInterpreterResult run_function(WasmInterpreterModule* module,
- WasmInterpreterThread* thread,
+static WasmInterpreterResult run_function(WasmInterpreterThread* thread,
uint32_t func_index) {
- assert(func_index < module->funcs.size);
- WasmInterpreterFunc* func = &module->funcs.data[func_index];
- if (func->is_host) {
- WasmInterpreterImport* import = &module->imports.data[func->import_index];
- return wasm_call_host(module, thread, import);
- } else {
- return run_defined_function(module, thread, func->offset);
- }
+ assert(func_index < thread->env->funcs.size);
+ WasmInterpreterFunc* func = &thread->env->funcs.data[func_index];
+ if (func->is_host)
+ return wasm_call_host(thread, func);
+ else
+ return run_defined_function(thread, func->defined.offset);
}
-static WasmResult run_start_function(WasmInterpreterModule* module,
- WasmInterpreterThread* thread) {
+static WasmResult run_start_function(WasmInterpreterThread* thread) {
WasmResult result = WASM_OK;
- if (module->start_func_index != WASM_INVALID_FUNC_INDEX) {
+ if (thread->module->defined.start_func_index != WASM_INVALID_INDEX) {
if (s_trace)
printf(">>> running start function:\n");
WasmInterpreterResult iresult =
- run_function(module, thread, module->start_func_index);
+ run_function(thread, thread->module->defined.start_func_index);
if (iresult != WASM_INTERPRETER_OK) {
/* trap */
fprintf(stderr, "error: %s\n", s_trap_strings[iresult]);
@@ -317,22 +278,22 @@ static WasmResult run_start_function(WasmInterpreterModule* module,
}
static WasmInterpreterFuncSignature* get_export_signature(
- WasmInterpreterModule* module,
+ WasmInterpreterEnvironment* env,
WasmInterpreterExport* export) {
+ assert(export->kind == WASM_EXTERNAL_KIND_FUNC);
uint32_t func_index = export->index;
- uint32_t sig_index = module->funcs.data[func_index].sig_index;
- assert(sig_index < module->sigs.size);
- return &module->sigs.data[sig_index];
+ uint32_t sig_index = env->funcs.data[func_index].sig_index;
+ assert(sig_index < env->sigs.size);
+ return &env->sigs.data[sig_index];
}
static WasmInterpreterResult run_export(
WasmAllocator* allocator,
- WasmInterpreterModule* module,
WasmInterpreterThread* thread,
WasmInterpreterExport* export,
- WasmInterpreterFuncSignature* sig,
WasmInterpreterTypedValueVector* out_results) {
assert(export->kind == WASM_EXTERNAL_KIND_FUNC);
+ WasmInterpreterFuncSignature* sig = get_export_signature(thread->env, export);
/* push all 0 values as arguments */
assert(sig->param_types.size < thread->value_stack.size);
@@ -340,7 +301,7 @@ static WasmInterpreterResult run_export(
thread->value_stack_top = &thread->value_stack.data[num_args];
memset(thread->value_stack.data, 0, num_args * sizeof(WasmInterpreterValue));
- WasmInterpreterResult result = run_function(module, thread, export->index);
+ WasmInterpreterResult result = run_function(thread, export->index);
if (result == WASM_INTERPRETER_OK) {
size_t expected_results = sig->result_types.size;
@@ -374,7 +335,6 @@ static WasmInterpreterResult run_export(
static WasmInterpreterResult run_export_wrapper(
WasmAllocator* allocator,
- WasmInterpreterModule* module,
WasmInterpreterThread* thread,
WasmInterpreterExport* export,
WasmInterpreterTypedValueVector* out_results,
@@ -384,11 +344,12 @@ static WasmInterpreterResult run_export_wrapper(
WASM_PRINTF_STRING_SLICE_ARG(export->name));
}
- WasmInterpreterFuncSignature* sig = get_export_signature(module, export);
WasmInterpreterResult result =
- run_export(allocator, module, thread, export, sig, out_results);
+ run_export(allocator, thread, export, out_results);
if (verbose) {
+ WasmInterpreterFuncSignature* sig =
+ get_export_signature(thread->env, export);
printf(PRIstringslice "(", WASM_PRINTF_STRING_SLICE_ARG(export->name));
size_t i;
for (i = 0; i < sig->param_types.size; ++i) {
@@ -416,19 +377,18 @@ static WasmInterpreterResult run_export_wrapper(
static WasmResult run_export_by_name(
WasmAllocator* allocator,
- WasmInterpreterModule* module,
WasmInterpreterThread* thread,
WasmStringSlice* name,
WasmInterpreterResult* out_iresult,
WasmInterpreterTypedValueVector* out_results,
RunVerbosity verbose) {
WasmInterpreterExport* export =
- wasm_get_interpreter_export_by_name(module, name);
+ wasm_get_interpreter_export_by_name(thread->module, name);
if (!export)
return WASM_ERROR;
- *out_iresult = run_export_wrapper(allocator, module, thread, export,
- out_results, verbose);
+ *out_iresult =
+ run_export_wrapper(allocator, thread, export, out_results, verbose);
return WASM_OK;
}
@@ -441,86 +401,148 @@ static void run_all_exports(WasmAllocator* allocator,
uint32_t i;
for (i = 0; i < module->exports.size; ++i) {
WasmInterpreterExport* export = &module->exports.data[i];
- run_export_wrapper(allocator, module, thread, export, &results, verbose);
+ run_export_wrapper(allocator, thread, export, &results, verbose);
}
wasm_destroy_interpreter_typed_value_vector(allocator, &results);
}
static WasmResult read_module(WasmAllocator* allocator,
const char* module_filename,
- WasmInterpreterModule* out_module,
+ WasmInterpreterEnvironment* env,
+ WasmInterpreterModule** out_module,
WasmInterpreterThread* out_thread) {
WasmResult result;
void* data;
size_t size;
- WASM_ZERO_MEMORY(*out_module);
WASM_ZERO_MEMORY(*out_thread);
result = wasm_read_file(allocator, module_filename, &data, &size);
if (WASM_SUCCEEDED(result)) {
WasmAllocator* memory_allocator = &g_wasm_libc_allocator;
- result = wasm_read_binary_interpreter(allocator, memory_allocator, data,
- size, &s_read_binary_options,
+ result = wasm_read_binary_interpreter(allocator, memory_allocator, env,
+ data, size, &s_read_binary_options,
&s_error_handler, out_module);
if (WASM_SUCCEEDED(result)) {
- if (s_verbose) {
- wasm_disassemble_module(out_module, s_stdout_stream, 0,
- out_module->istream.size);
- }
+ if (s_verbose)
+ wasm_disassemble_module(env, s_stdout_stream, *out_module);
- result = wasm_init_interpreter_thread(allocator, out_module, out_thread,
- &s_thread_options);
- out_thread->host_func.callback = default_host_callback;
- out_thread->host_func.user_data = NULL;
+ result = wasm_init_interpreter_thread(allocator, env, *out_module,
+ out_thread, &s_thread_options);
}
wasm_free(allocator, data);
}
return result;
}
-static void destroy_module_and_thread(WasmAllocator* allocator,
- WasmInterpreterModule* module,
- WasmInterpreterThread* thread) {
- wasm_destroy_interpreter_thread(allocator, thread);
- wasm_destroy_interpreter_module(allocator, module);
+static void print_typed_values(WasmInterpreterTypedValue* values,
+ size_t num_values) {
+ uint32_t i;
+ for (i = 0; i < num_values; ++i) {
+ print_typed_value(&values[i]);
+ if (i != num_values - 1)
+ printf(", ");
+ }
+}
+
+static WasmResult default_host_callback(const WasmInterpreterFunc* func,
+ const WasmInterpreterFuncSignature* sig,
+ uint32_t num_args,
+ WasmInterpreterTypedValue* args,
+ uint32_t num_results,
+ WasmInterpreterTypedValue* out_results,
+ void* user_data) {
+ memset(out_results, 0, sizeof(WasmInterpreterTypedValue) * num_results);
+ uint32_t i;
+ for (i = 0; i < num_results; ++i)
+ out_results[i].type = sig->result_types.data[i];
+
+ printf("called host " PRIstringslice "." PRIstringslice "(",
+ WASM_PRINTF_STRING_SLICE_ARG(func->host.module_name),
+ WASM_PRINTF_STRING_SLICE_ARG(func->host.field_name));
+ print_typed_values(args, num_args);
+ printf(") => (");
+ print_typed_values(out_results, num_results);
+ printf(")\n");
+ return WASM_OK;
+}
+
+static WasmResult spectest_import_func(WasmInterpreterImport* import,
+ WasmInterpreterFunc* func,
+ WasmInterpreterFuncSignature* sig,
+ void* user_data) {
+ func->host.callback = default_host_callback;
+ return WASM_OK;
+}
+
+static WasmResult spectest_import_table(WasmInterpreterImport* import,
+ WasmInterpreterTable* table,
+ void* user_data) {
+ return WASM_ERROR;
+}
+
+static WasmResult spectest_import_memory(WasmInterpreterImport* import,
+ WasmInterpreterMemory* memory,
+ void* user_data) {
+ return WASM_ERROR;
+}
+
+static WasmResult spectest_import_global(WasmInterpreterImport* import,
+ WasmInterpreterGlobal* global,
+ void* user_data) {
+ return WASM_ERROR;
+}
+
+static void init_environment(WasmAllocator* allocator,
+ WasmInterpreterEnvironment* env) {
+ wasm_init_interpreter_environment(allocator, env);
+ WasmInterpreterModule* host_module = wasm_append_host_module(
+ allocator, env, wasm_string_slice_from_cstr("spectest"));
+ host_module->host.import_delegate.import_func = spectest_import_func;
+ host_module->host.import_delegate.import_table = spectest_import_table;
+ host_module->host.import_delegate.import_memory = spectest_import_memory;
+ host_module->host.import_delegate.import_global = spectest_import_global;
}
static WasmResult read_and_run_module(WasmAllocator* allocator,
const char* module_filename) {
WasmResult result;
- WasmInterpreterModule module;
+ WasmInterpreterEnvironment env;
+ WasmInterpreterModule* module = NULL;
WasmInterpreterThread thread;
- result = read_module(allocator, module_filename, &module, &thread);
- if (WASM_SUCCEEDED(result))
- result = run_start_function(&module, &thread);
- if (WASM_SUCCEEDED(result) && s_run_all_exports)
- run_all_exports(allocator, &module, &thread, RUN_VERBOSE);
- destroy_module_and_thread(allocator, &module, &thread);
+ init_environment(allocator, &env);
+ result = read_module(allocator, module_filename, &env, &module, &thread);
+ if (WASM_SUCCEEDED(result)) {
+ result = run_start_function(&thread);
+ if (s_run_all_exports)
+ run_all_exports(allocator, module, &thread, RUN_VERBOSE);
+ }
+ wasm_destroy_interpreter_thread(allocator, &thread);
+ wasm_destroy_interpreter_environment(allocator, &env);
return result;
}
static WasmResult read_and_run_spec_json(WasmAllocator* allocator,
const char* spec_json_filename) {
WasmResult result = WASM_OK;
- WasmInterpreterModule module;
+ WasmInterpreterEnvironment env;
+ WasmInterpreterModule* module = NULL;
WasmInterpreterThread thread;
WasmStringSlice command_file;
WasmStringSlice command_name;
- WasmAllocatorMark module_mark;
WasmInterpreterTypedValueVector result_values;
uint32_t command_line_no;
- WasmBool has_module = WASM_FALSE;
+ WasmBool has_thread = WASM_FALSE;
uint32_t passed = 0;
uint32_t failed = 0;
- WASM_ZERO_MEMORY(module);
WASM_ZERO_MEMORY(thread);
WASM_ZERO_MEMORY(command_file);
WASM_ZERO_MEMORY(command_name);
- WASM_ZERO_MEMORY(module_mark);
WASM_ZERO_MEMORY(result_values);
+ init_environment(allocator, &env);
+
void* data;
size_t size;
result = wasm_read_file(allocator, spec_json_filename, &data, &size);
@@ -653,9 +675,9 @@ static WasmResult read_and_run_spec_json(WasmAllocator* allocator,
case END_MODULE_OBJECT:
EXPECT('}');
MAYBE_CONTINUE(MODULES_ARRAY);
- destroy_module_and_thread(allocator, &module, &thread);
- wasm_reset_to_mark(allocator, module_mark);
- has_module = WASM_FALSE;
+ assert(has_thread);
+ wasm_destroy_interpreter_thread(allocator, &thread);
+ has_thread = WASM_FALSE;
break;
case MODULE_FILENAME: {
@@ -673,14 +695,13 @@ static WasmResult read_and_run_spec_json(WasmAllocator* allocator,
WASM_PRINTF_STRING_SLICE_ARG(module_filename));
}
- module_mark = wasm_mark(allocator);
- result = read_module(allocator, path, &module, &thread);
+ result = read_module(allocator, path, &env, &module, &thread);
if (WASM_FAILED(result))
goto fail;
- has_module = WASM_TRUE;
+ has_thread = WASM_TRUE;
- result = run_start_function(&module, &thread);
+ result = run_start_function(&thread);
if (WASM_FAILED(result))
goto fail;
@@ -727,8 +748,8 @@ static WasmResult read_and_run_spec_json(WasmAllocator* allocator,
WasmInterpreterResult iresult;
EXPECT('}');
RunVerbosity verbose = command_type == ACTION ? RUN_VERBOSE : RUN_QUIET;
- result = run_export_by_name(allocator, &module, &thread, &command_name,
- &iresult, &result_values, verbose);
+ result = run_export_by_name(allocator, &thread, &command_name, &iresult,
+ &result_values, verbose);
if (WASM_FAILED(result)) {
FAILED("unknown export");
failed++;
@@ -837,8 +858,9 @@ fail:
result = WASM_ERROR;
done:
- if (has_module)
- destroy_module_and_thread(allocator, &module, &thread);
+ if (has_thread)
+ wasm_destroy_interpreter_thread(allocator, &thread);
+ wasm_destroy_interpreter_environment(allocator, &env);
wasm_destroy_interpreter_typed_value_vector(allocator, &result_values);
wasm_free(allocator, data);
return result;