summaryrefslogtreecommitdiff
path: root/src/wasm-interpreter.h
diff options
context:
space:
mode:
authorBen Smith <binji@chromium.org>2016-03-25 23:47:26 -0700
committerBen Smith <binji@chromium.org>2016-04-02 22:32:14 -0700
commit2e4639e97f03c306374a02c4e8097add36f31aa7 (patch)
tree21e5c7bc7288da93c8dd6a6b4b3ee748ea3932c0 /src/wasm-interpreter.h
parentda5e6ec567a41f6d21b9477d67b5d1960bf1dcfa (diff)
downloadwabt-2e4639e97f03c306374a02c4e8097add36f31aa7.tar.gz
wabt-2e4639e97f03c306374a02c4e8097add36f31aa7.tar.bz2
wabt-2e4639e97f03c306374a02c4e8097add36f31aa7.zip
wasm interpreter
Works by generating an instruction stream for a simple stack machine.
Diffstat (limited to 'src/wasm-interpreter.h')
-rw-r--r--src/wasm-interpreter.h181
1 files changed, 181 insertions, 0 deletions
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h
new file mode 100644
index 00000000..91101d4a
--- /dev/null
+++ b/src/wasm-interpreter.h
@@ -0,0 +1,181 @@
+/*
+ * 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_INTERPRETER_H_
+#define WASM_INTERPRETER_H_
+
+#include <stdint.h>
+
+#include "wasm-array.h"
+#include "wasm-vector.h"
+#include "wasm-writer.h"
+
+#define FOREACH_INTERPRETER_RESULT(V) \
+ V(OK, "ok") \
+ /* returned from the top-most function */ \
+ V(RETURNED, "returned") \
+ /* memory access is out of bounds */ \
+ V(TRAP_MEMORY_ACCESS_OUT_OF_BOUNDS, "out of bounds memory access") \
+ /* converting from float -> int would overflow int */ \
+ V(TRAP_INTEGER_OVERFLOW, "integer overflow") \
+ /* dividend is zero in integer divide */ \
+ V(TRAP_INTEGER_DIVIDE_BY_ZERO, "integer divide by zero") \
+ /* converting from float -> int where float is nan */ \
+ V(TRAP_INVALID_CONVERSION_TO_INTEGER, "invalid conversion to integer") \
+ /* function table index is out of bounds */ \
+ V(TRAP_UNDEFINED_TABLE_INDEX, "undefined table index") \
+ /* unreachable instruction executed */ \
+ V(TRAP_UNREACHABLE, "unreachable executed") \
+ /* call indirect signature doesn't match function table signature */ \
+ V(TRAP_INDIRECT_CALL_SIGNATURE_MISMATCH, "indirect call signature mismatch") \
+ /* growing the memory would overflow the memory size type */ \
+ V(TRAP_MEMORY_SIZE_OVERFLOW, "memory size overflow") \
+ /* out of memory */ \
+ V(TRAP_OUT_OF_MEMORY, "memory size exceeds implementation limit") \
+ /* ran out of call stack frames (probably infinite recursion) */ \
+ V(TRAP_CALL_STACK_EXHAUSTED, "call stack exhausted") \
+ /* ran out of value stack space */ \
+ V(TRAP_VALUE_STACK_EXHAUSTED, "value stack exhausted") \
+ /* we called an import function, but the return value didn't match the */ \
+ /* expected type */ \
+ V(TRAP_IMPORT_RESULT_TYPE_MISMATCH, "import result type mismatch")
+
+typedef enum WasmInterpreterResult {
+#define V(name, str) WASM_INTERPRETER_##name,
+ FOREACH_INTERPRETER_RESULT(V)
+#undef V
+} WasmInterpreterResult;
+
+#define WASM_INVALID_OFFSET ((uint32_t)~0)
+
+enum {
+ /* push space on the value stack for N entries */
+ WASM_OPCODE_ALLOCA = WASM_LAST_OPCODE,
+ WASM_OPCODE_DISCARD,
+ WASM_OPCODE_DISCARD_KEEP,
+ WASM_LAST_INTERPRETER_OPCODE,
+};
+WASM_STATIC_ASSERT(WASM_LAST_INTERPRETER_OPCODE <= 256);
+
+typedef uint8_t WasmUint8;
+WASM_DEFINE_VECTOR(uint8, WasmUint8);
+WASM_DEFINE_VECTOR(type, WasmType);
+
+/* TODO(binji): identical to WasmFuncSignature. Share? */
+typedef struct WasmInterpreterFuncSignature {
+ WasmType result_type;
+ WasmTypeVector param_types;
+} WasmInterpreterFuncSignature;
+WASM_DEFINE_ARRAY(interpreter_func_signature, WasmInterpreterFuncSignature);
+
+typedef struct WasmInterpreterMemory {
+ WasmAllocator* allocator;
+ void* data;
+ uint32_t page_size;
+ uint32_t byte_size;
+} WasmInterpreterMemory;
+
+typedef struct WasmInterpreterFuncTableEntry {
+ uint32_t sig_index;
+ uint32_t func_offset;
+} WasmInterpreterFuncTableEntry;
+WASM_DEFINE_ARRAY(interpreter_func_table_entry, WasmInterpreterFuncTableEntry);
+
+typedef union WasmInterpreterValue {
+ uint32_t i32;
+ uint64_t i64;
+ uint32_t f32_bits;
+ uint64_t f64_bits;
+} WasmInterpreterValue;
+WASM_DEFINE_ARRAY(interpreter_value, WasmInterpreterValue);
+
+typedef struct WasmInterpreterTypedValue {
+ WasmType type;
+ WasmInterpreterValue value;
+} WasmInterpreterTypedValue;
+WASM_DEFINE_ARRAY(interpreter_typed_value, WasmInterpreterTypedValue);
+
+struct WasmInterpreterModule;
+struct WasmInterpreterImport;
+
+typedef WasmInterpreterTypedValue (*WasmInterpreterImportCallback)(
+ struct WasmInterpreterModule* module,
+ struct WasmInterpreterImport* import,
+ uint32_t num_args,
+ WasmInterpreterTypedValue* args,
+ void* user_data);
+
+typedef struct WasmInterpreterImport {
+ WasmStringSlice module_name;
+ WasmStringSlice func_name;
+ uint32_t sig_index;
+ WasmInterpreterImportCallback callback;
+ void* user_data;
+} WasmInterpreterImport;
+WASM_DEFINE_ARRAY(interpreter_import, WasmInterpreterImport);
+
+typedef struct WasmInterpreterExport {
+ WasmStringSlice name;
+ uint32_t func_offset;
+ uint32_t sig_index;
+} WasmInterpreterExport;
+WASM_DEFINE_ARRAY(interpreter_export, WasmInterpreterExport);
+
+typedef struct WasmInterpreterModule {
+ WasmInterpreterMemory memory;
+ WasmInterpreterFuncSignatureArray sigs;
+ WasmInterpreterFuncTableEntryArray func_table;
+ WasmInterpreterImportArray imports;
+ WasmInterpreterExportArray exports;
+ WasmOutputBuffer istream;
+ uint32_t start_func_offset; /* == WASM_INVALID_OFFSET if not defined */
+} WasmInterpreterModule;
+
+typedef uint32_t WasmUint32;
+WASM_DEFINE_ARRAY(uint32, WasmUint32);
+
+typedef struct WasmInterpreterThread {
+ WasmInterpreterValueArray value_stack;
+ WasmUint32Array call_stack;
+ uint32_t value_stack_top;
+ uint32_t call_stack_top;
+ uint32_t pc;
+
+ /* a temporary buffer that is for passing args to import functions */
+ WasmInterpreterTypedValueArray import_args;
+} WasmInterpreterThread;
+
+typedef struct WasmInterpreterThreadOptions {
+ uint32_t value_stack_size;
+ uint32_t call_stack_size;
+ uint32_t pc;
+} WasmInterpreterThreadOptions;
+
+WASM_EXTERN_C_BEGIN
+WasmResult wasm_init_interpreter_thread(WasmAllocator* allocator,
+ WasmInterpreterModule* module,
+ WasmInterpreterThread* thread,
+ WasmInterpreterThreadOptions* options);
+void wasm_destroy_interpreter_thread(WasmAllocator* allocator,
+ WasmInterpreterThread* thread);
+WasmInterpreterResult wasm_run_interpreter(WasmInterpreterModule* module,
+ WasmInterpreterThread* thread,
+ uint32_t num_instructions);
+void wasm_trace_pc(WasmInterpreterModule* module,
+ WasmInterpreterThread* thread);
+WASM_EXTERN_C_END
+
+#endif /* WASM_INTERPRETER_H_ */