diff options
author | Ben Smith <binji@chromium.org> | 2016-03-25 23:47:26 -0700 |
---|---|---|
committer | Ben Smith <binji@chromium.org> | 2016-04-02 22:32:14 -0700 |
commit | 2e4639e97f03c306374a02c4e8097add36f31aa7 (patch) | |
tree | 21e5c7bc7288da93c8dd6a6b4b3ee748ea3932c0 /src/wasm-interpreter.h | |
parent | da5e6ec567a41f6d21b9477d67b5d1960bf1dcfa (diff) | |
download | wabt-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.h | 181 |
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_ */ |