From 1c4cbd0bf0320e1e7ed6101c52e182fdc7d2d954 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Sat, 18 Jul 2015 13:19:30 +0200 Subject: [PATCH 1/2] Using the wasm-module now for parsing --- .gitmodules | 3 + CMakeLists.txt | 65 +---- docs/BinaryFormat.md | 114 -------- docs/Instructions.md | 72 ----- src/ExceptionWithMessage.cpp | 3 - src/ExceptionWithMessage.h | 30 --- src/Function.cpp | 12 - src/Function.h | 37 --- src/FunctionContext.cpp | 3 - src/FunctionContext.h | 48 ---- src/FunctionSignature.cpp | 3 - src/FunctionSignature.h | 54 ---- src/FunctionTable.cpp | 3 - src/FunctionTable.h | 37 --- src/Global.cpp | 5 - src/Global.h | 29 --- src/GlobalTable.cpp | 5 - src/GlobalTable.h | 41 --- src/Module.cpp | 3 - src/Module.h | 67 ----- src/ModuleContext.cpp | 3 - src/ModuleContext.h | 49 ---- src/OpcodeTable.cpp | 3 - src/OpcodeTable.h | 37 --- src/Section.cpp | 19 -- src/Section.h | 55 ---- src/TypeTable.cpp | 23 -- src/TypeTable.h | 39 --- src/Variable.cpp | 16 -- src/Variable.h | 37 --- src/instructions/FunctionCall.cpp | 3 - src/instructions/FunctionCall.h | 48 ---- src/instructions/GetGlobal.cpp | 5 - src/instructions/GetGlobal.h | 42 --- src/instructions/GetLocal.cpp | 3 - src/instructions/GetLocal.h | 40 --- src/instructions/I32/I32Add.cpp | 3 - src/instructions/I32/I32Add.h | 48 ---- src/instructions/I32/I32Div.cpp | 3 - src/instructions/I32/I32Div.h | 51 ---- src/instructions/I32/I32Mul.cpp | 3 - src/instructions/I32/I32Mul.h | 46 ---- src/instructions/I32/I32Sub.cpp | 3 - src/instructions/I32/I32Sub.h | 46 ---- src/instructions/Instruction.cpp | 7 - src/instructions/Instruction.h | 47 ---- src/instructions/InstructionSet.cpp | 69 ----- src/instructions/InstructionSet.h | 19 -- src/instructions/Literal.cpp | 3 - src/instructions/Literal.h | 40 --- src/instructions/Print.cpp | 3 - src/instructions/Print.h | 38 --- src/instructions/SetGlobal.cpp | 5 - src/instructions/SetGlobal.h | 50 ---- src/instructions/SetLocal.cpp | 3 - src/instructions/SetLocal.h | 49 ---- src/instructions/controlflow/Block.cpp | 3 - src/instructions/controlflow/Block.h | 46 ---- src/instructions/controlflow/Break.cpp | 3 - src/instructions/controlflow/Break.h | 31 --- src/instructions/controlflow/Continue.cpp | 3 - src/instructions/controlflow/Continue.h | 31 --- src/instructions/controlflow/DoWhile.cpp | 3 - src/instructions/controlflow/DoWhile.h | 54 ---- src/instructions/controlflow/Forever.cpp | 3 - src/instructions/controlflow/Forever.h | 45 ---- src/instructions/controlflow/If.cpp | 3 - src/instructions/controlflow/If.h | 42 --- src/instructions/controlflow/Return.cpp | 3 - src/instructions/controlflow/Return.h | 43 --- src/instructions/heap/Int32Load.cpp | 3 - src/instructions/heap/Int32Load.h | 45 ---- src/instructions/heap/Int32Store.cpp | 3 - src/instructions/heap/Int32Store.h | 45 ---- src/interpreter/InstructionExecutor.cpp | 245 ++++++++++++++++++ src/interpreter/InstructionExecutor.h | 18 ++ src/interpreter/InstructionState.cpp | 6 +- src/interpreter/InstructionState.h | 2 +- src/interpreter/Thread.cpp | 1 + src/parsing/ByteStream.cpp | 3 - src/parsing/ByteStream.h | 91 ------- src/parsing/CodeSectionParser.cpp | 3 - src/parsing/CodeSectionParser.h | 67 ----- src/parsing/FunctionParser.cpp | 3 - src/parsing/FunctionParser.h | 89 ------- src/parsing/FunctionTableParser.cpp | 3 - src/parsing/FunctionTableParser.h | 38 --- src/parsing/GlobalTableParser.cpp | 5 - src/parsing/GlobalTableParser.h | 67 ----- src/parsing/ModuleParser.cpp | 3 - src/parsing/ModuleParser.h | 114 -------- src/parsing/OpcodeTableParser.cpp | 3 - src/parsing/OpcodeTableParser.h | 41 --- src/parsing/TypeTableParser.cpp | 3 - src/parsing/TypeTableParser.h | 39 --- src/types/Float32.cpp | 3 - src/types/Float32.h | 60 ----- src/types/Float64.cpp | 3 - src/types/Float64.h | 65 ----- src/types/Int32.cpp | 3 - src/types/Int32.h | 85 ------ src/types/Int64.cpp | 3 - src/types/Int64.h | 60 ----- src/types/Int8.cpp | 5 - src/types/Int8.h | 91 ------- src/types/Type.cpp | 3 - src/types/Type.h | 51 ---- src/types/Void.cpp | 3 - src/types/Void.h | 38 --- tests/ByteStreamTest.cpp | 34 --- tests/ForeverBreakTest.cpp | 1 + .../{ExampleModuleTest.cpp => GlobalTest.cpp} | 1 + tests/LoadStoreTest.cpp | 1 + tests/SimpleModuleTest.cpp | 1 + wasm-module | 1 + 115 files changed, 283 insertions(+), 3074 deletions(-) create mode 100644 .gitmodules delete mode 100644 docs/BinaryFormat.md delete mode 100644 docs/Instructions.md delete mode 100644 src/ExceptionWithMessage.cpp delete mode 100644 src/ExceptionWithMessage.h delete mode 100644 src/Function.cpp delete mode 100644 src/Function.h delete mode 100644 src/FunctionContext.cpp delete mode 100644 src/FunctionContext.h delete mode 100644 src/FunctionSignature.cpp delete mode 100644 src/FunctionSignature.h delete mode 100644 src/FunctionTable.cpp delete mode 100644 src/FunctionTable.h delete mode 100644 src/Global.cpp delete mode 100644 src/Global.h delete mode 100644 src/GlobalTable.cpp delete mode 100644 src/GlobalTable.h delete mode 100644 src/Module.cpp delete mode 100644 src/Module.h delete mode 100644 src/ModuleContext.cpp delete mode 100644 src/ModuleContext.h delete mode 100644 src/OpcodeTable.cpp delete mode 100644 src/OpcodeTable.h delete mode 100644 src/Section.cpp delete mode 100644 src/Section.h delete mode 100644 src/TypeTable.cpp delete mode 100644 src/TypeTable.h delete mode 100644 src/Variable.cpp delete mode 100644 src/Variable.h delete mode 100644 src/instructions/FunctionCall.cpp delete mode 100644 src/instructions/FunctionCall.h delete mode 100644 src/instructions/GetGlobal.cpp delete mode 100644 src/instructions/GetGlobal.h delete mode 100644 src/instructions/GetLocal.cpp delete mode 100644 src/instructions/GetLocal.h delete mode 100644 src/instructions/I32/I32Add.cpp delete mode 100644 src/instructions/I32/I32Add.h delete mode 100644 src/instructions/I32/I32Div.cpp delete mode 100644 src/instructions/I32/I32Div.h delete mode 100644 src/instructions/I32/I32Mul.cpp delete mode 100644 src/instructions/I32/I32Mul.h delete mode 100644 src/instructions/I32/I32Sub.cpp delete mode 100644 src/instructions/I32/I32Sub.h delete mode 100644 src/instructions/Instruction.cpp delete mode 100644 src/instructions/Instruction.h delete mode 100644 src/instructions/InstructionSet.cpp delete mode 100644 src/instructions/InstructionSet.h delete mode 100644 src/instructions/Literal.cpp delete mode 100644 src/instructions/Literal.h delete mode 100644 src/instructions/Print.cpp delete mode 100644 src/instructions/Print.h delete mode 100644 src/instructions/SetGlobal.cpp delete mode 100644 src/instructions/SetGlobal.h delete mode 100644 src/instructions/SetLocal.cpp delete mode 100644 src/instructions/SetLocal.h delete mode 100644 src/instructions/controlflow/Block.cpp delete mode 100644 src/instructions/controlflow/Block.h delete mode 100644 src/instructions/controlflow/Break.cpp delete mode 100644 src/instructions/controlflow/Break.h delete mode 100644 src/instructions/controlflow/Continue.cpp delete mode 100644 src/instructions/controlflow/Continue.h delete mode 100644 src/instructions/controlflow/DoWhile.cpp delete mode 100644 src/instructions/controlflow/DoWhile.h delete mode 100644 src/instructions/controlflow/Forever.cpp delete mode 100644 src/instructions/controlflow/Forever.h delete mode 100644 src/instructions/controlflow/If.cpp delete mode 100644 src/instructions/controlflow/If.h delete mode 100644 src/instructions/controlflow/Return.cpp delete mode 100644 src/instructions/controlflow/Return.h delete mode 100644 src/instructions/heap/Int32Load.cpp delete mode 100644 src/instructions/heap/Int32Load.h delete mode 100644 src/instructions/heap/Int32Store.cpp delete mode 100644 src/instructions/heap/Int32Store.h create mode 100644 src/interpreter/InstructionExecutor.cpp create mode 100644 src/interpreter/InstructionExecutor.h delete mode 100644 src/parsing/ByteStream.cpp delete mode 100644 src/parsing/ByteStream.h delete mode 100644 src/parsing/CodeSectionParser.cpp delete mode 100644 src/parsing/CodeSectionParser.h delete mode 100644 src/parsing/FunctionParser.cpp delete mode 100644 src/parsing/FunctionParser.h delete mode 100644 src/parsing/FunctionTableParser.cpp delete mode 100644 src/parsing/FunctionTableParser.h delete mode 100644 src/parsing/GlobalTableParser.cpp delete mode 100644 src/parsing/GlobalTableParser.h delete mode 100644 src/parsing/ModuleParser.cpp delete mode 100644 src/parsing/ModuleParser.h delete mode 100644 src/parsing/OpcodeTableParser.cpp delete mode 100644 src/parsing/OpcodeTableParser.h delete mode 100644 src/parsing/TypeTableParser.cpp delete mode 100644 src/parsing/TypeTableParser.h delete mode 100644 src/types/Float32.cpp delete mode 100644 src/types/Float32.h delete mode 100644 src/types/Float64.cpp delete mode 100644 src/types/Float64.h delete mode 100644 src/types/Int32.cpp delete mode 100644 src/types/Int32.h delete mode 100644 src/types/Int64.cpp delete mode 100644 src/types/Int64.h delete mode 100644 src/types/Int8.cpp delete mode 100644 src/types/Int8.h delete mode 100644 src/types/Type.cpp delete mode 100644 src/types/Type.h delete mode 100644 src/types/Void.cpp delete mode 100644 src/types/Void.h delete mode 100644 tests/ByteStreamTest.cpp rename tests/{ExampleModuleTest.cpp => GlobalTest.cpp} (99%) create mode 160000 wasm-module diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..bb5c250 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "wasm-module"] + path = wasm-module + url = https://github.com/Teemperor/wasm-module.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 543c083..6c5df87 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,77 +3,24 @@ project(wasmint) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") +add_subdirectory(wasm-module) + #################### # Common code # #################### +include_directories(wasm-module/src) include_directories (src) add_library(core - main.cpp - src/ExceptionWithMessage.cpp - src/instructions/InstructionSet.cpp - src/Module.cpp - src/Section.cpp - src/FunctionContext.cpp - src/FunctionSignature.cpp - src/FunctionTable.cpp - src/instructions/Instruction.cpp - src/OpcodeTable.cpp - src/Variable.cpp - src/Global.cpp - src/GlobalTable.cpp - src/Function.cpp - src/types/Type.cpp - src/TypeTable.cpp - src/ModuleContext.cpp - src/interpreter/Thread.cpp src/interpreter/FunctionState.cpp src/interpreter/InstructionState.cpp src/interpreter/RuntimeEnvironment.cpp + src/interpreter/InstructionExecutor.cpp src/interpreter/Heap.cpp - src/instructions/I32/I32Add.cpp - src/instructions/I32/I32Sub.cpp - src/instructions/I32/I32Mul.cpp - src/instructions/I32/I32Div.cpp - - src/instructions/heap/Int32Load.cpp - src/instructions/heap/Int32Store.cpp - - src/instructions/controlflow/Block.cpp - src/instructions/controlflow/Break.cpp - src/instructions/controlflow/Continue.cpp - src/instructions/controlflow/DoWhile.cpp - src/instructions/controlflow/Forever.cpp - src/instructions/controlflow/If.cpp - src/instructions/controlflow/Return.cpp - - src/instructions/Print.cpp - src/instructions/GetLocal.cpp - src/instructions/SetLocal.cpp - src/instructions/GetGlobal.cpp - src/instructions/SetGlobal.cpp - src/instructions/FunctionCall.cpp - src/instructions/Literal.cpp src/instructions/StepResult.cpp - - src/types/Int8.cpp - src/types/Int32.cpp - src/types/Int64.cpp - src/types/Void.cpp - src/types/Float32.cpp - src/types/Float64.cpp - - src/parsing/ByteStream.cpp - src/parsing/GlobalTableParser.cpp - src/parsing/FunctionParser.cpp - src/parsing/FunctionTableParser.cpp - src/parsing/TypeTableParser.cpp - src/parsing/ModuleParser.cpp - src/parsing/CodeSectionParser.cpp - src/parsing/OpcodeTableParser.cpp ) @@ -83,7 +30,7 @@ add_library(core add_executable(wasmint main.cpp) -target_link_libraries(wasmint core) +target_link_libraries(wasmint core wasm-module) #################### @@ -95,6 +42,6 @@ file(GLOB TEST_FILES "tests/*Test.cpp") foreach(TEST_FILE ${TEST_FILES}) get_filename_component(BASENAME ${TEST_FILE} NAME_WE) add_executable(${BASENAME} ${TEST_FILE}) - target_link_libraries(${BASENAME} core) + target_link_libraries(${BASENAME} core wasm-module) add_test(${BASENAME} ${BASENAME}) endforeach() \ No newline at end of file diff --git a/docs/BinaryFormat.md b/docs/BinaryFormat.md deleted file mode 100644 index 6f9f78b..0000000 --- a/docs/BinaryFormat.md +++ /dev/null @@ -1,114 +0,0 @@ -# Binary Format - -This is the documentation to the binary format that is used by wasmint. - -## Common types - -### uLEB128 - -A unsigned integer encoded in LEB128 - -### String - -A series of UTF-8 characters terminated by a zero byte ('\0'). - -## Module - -Each module file starts with a module header. This header contains as of now - -1. the local opcode table -2. the local type table -3. the function table for external functions -4. the section table - -in the order given above. - -The sections of the module are located directly behind the header. - -### Local opcode table - -The local opcode table provides functionality to translate opcodes (integers) -to the string names of the instructions. - -The opcode table starts with a uLEB128 (from now on called OT_LEN) -that specifies how many opcodes are used in this module. - -After that exactly OT_LEN strings follow that contain the names of the used opcodes. -The order of the strings define their local opcode. - -As an example, this opcode table would define 2 opcodes for the instruction `call` -and for the instruction `int32.add`: - -``` -2, // number of opcodes -'i', 'n', 't', '3', '2', '.', 'a', 'd', 'd', '\0', // opcode = 0x0 -'c', 'a', 'l', 'l', '\0', // opcode = 0x1 and so on -``` - -For information what instructions are available, see the (Instructions.md)[Instructions.md) - -### Local type table - -The local opcode table provides functionality to translate type indices (integers) -to the string names of the types. - -The local type table starts with a uLEB128 (from now on called LT_LEN) -that specifies how many types are used in this module. - -After that exactly LT_LEN strings follow that contain the names of the used types. -The order of the strings define their local type index. - -As an example, this type table would define indices for the types `int32` and `void`. - -``` -2, // number of types -'i', 'n', 't', '3', '2', '\0', // index = 0x0 -'v', 'o', 'i', 'd', '\0', // index = 0x1 and so on -``` - -### Function table for external functions - -This has to be empty right now and should only consist of a zero byte (0x0). - -### Section table - -The section table identifies the number, location and type of all sections in this module. - -It starts with a uLEB128 that identifies how many sections -are in this module. - -Then all sections are described in the order of appearance in this module (lowest offset first). - -Each section is described by a uLEB128 that identifies the type of the section. Currently -only the type 0x1 is supported which means code section. - -Afterwards a uLEB128 provides the offset of the section in this module (e.g. the index of the first byte -in this file. The first byte of the file has the index 0). - -Those two uLEB128 are repeated for each section. - -## Code section - -A code section contains multiple functions. It starts with the signatures of all functions and then the -serialized AST nodes of each function follows. - -### Function signatures - -First with a uLEB128 that identifies the number of functions this section contains. - -Now, for each function in this section, the signature of each function follows. - -Each signatures consists of those elements in the given order: - -1. A string that contains the name of this function -2. A uLEB128 which is the type index that identifies the return type of this function -3. A uLEB128 that identifies the number of parameters of this function -4. A uLEB128 the offset of the first byte of the serialized AST in the module - -Directly after the last signature, the serialized AST of the first function follows. -Then the serialized AST of the secondfunction and so on. - -### Serialized AST - -The serialized AST directly starts witht he first opcode. The end of the AST can only be identified -by parsing the whole AST. \ No newline at end of file diff --git a/docs/Instructions.md b/docs/Instructions.md deleted file mode 100644 index c6b0fbc..0000000 --- a/docs/Instructions.md +++ /dev/null @@ -1,72 +0,0 @@ -# Instructions - -This are the instructions that are provided by the wasmint interpreter. - -# Terminologie - -A **instruction** is AST node and it is identified by its opcode. -Each instruction can have several **arguments** which are additional parameters that -are located directly behind the opcode in the module. -Those additonal parameters need to have compile-time fixed values and -can not be instructions like `get_local`. - - -## `block` - -The block instruction defines a array of instructions in the AST. A block instruction requires an additional argument -that specifies the number of instructions in this block (encoded as a LEB128 unsigned integer) - -On execution the the children of this AST node will be executed in the order they appear in the module. - -A block has a void return value. - -#### Example: - -Code | Instruction ------|------------- -0x0 | `block` -0x1 | `set_local` - -``` -0x0 0x2 # Start a `block` with 2 instructions - 0x1 0x0 0x0 # `set_local` - will be executed first - 0x1 0x1 0x0 # `set_local` - will be executed last -``` - - -## `set_local` - -The `set_local` instruction sets the value of a local variable. It requires two arguments: - -1. The index of the local variable that is the target of this operation as a LEB128 encoded unsigned integer. -2. The value that should be copied to the local variable. The encoding of this value depends on the type of the local variable. - -`set_local` has a void return value. - -#### Example: - -Code | Instruction ------|------------- -0x0 | `set_local` - -``` -0x0 0x5 0x3 # Will assign the value 3 to the local variable with the index 5 -``` - -## `get_local` - -The `get_local` instruction gets the value of a local variable. It requires as an argument the index of the local variable -which is then returned by this instruction upon execution. - -The return type of `get_local` is the type of the local variable. - -#### Example: - -Code | Instruction ------|------------- -0x0 | `get_local` - -``` -0x0 0x1 # Returns the value of the local variable with the index 1 -``` - diff --git a/src/ExceptionWithMessage.cpp b/src/ExceptionWithMessage.cpp deleted file mode 100644 index 32aa1c2..0000000 --- a/src/ExceptionWithMessage.cpp +++ /dev/null @@ -1,3 +0,0 @@ - - -#include "ExceptionWithMessage.h" diff --git a/src/ExceptionWithMessage.h b/src/ExceptionWithMessage.h deleted file mode 100644 index cab0c86..0000000 --- a/src/ExceptionWithMessage.h +++ /dev/null @@ -1,30 +0,0 @@ - - -#ifndef WASMINT_EXCEPTIONWITHDATA_H -#define WASMINT_EXCEPTIONWITHDATA_H - - -#include -#include -#include - -class ExceptionWithMessage : public std::exception { - - std::string message_; - -public: - ExceptionWithMessage(std::string message) : message_(message) { - } - - virtual const char* what() const noexcept { - return message_.c_str(); - } - -}; - -#define ExceptionMessage(Name) class Name : public ExceptionWithMessage { \ - public: Name(std::string message) : ExceptionWithMessage(message) {} \ - }; - - -#endif //WASMINT_EXCEPTIONWITHDATA_H diff --git a/src/Function.cpp b/src/Function.cpp deleted file mode 100644 index 4c41647..0000000 --- a/src/Function.cpp +++ /dev/null @@ -1,12 +0,0 @@ - - -#include "Function.h" -#include - -Function::Function(FunctionContext& context, Instruction* mainInstruction) - : FunctionContext(context), mainInstruction_(mainInstruction) { -} - -Function::~Function() { - delete mainInstruction_; -} \ No newline at end of file diff --git a/src/Function.h b/src/Function.h deleted file mode 100644 index 31c0135..0000000 --- a/src/Function.h +++ /dev/null @@ -1,37 +0,0 @@ - - -#ifndef WASMINT_FUNCTION_H -#define WASMINT_FUNCTION_H - -#include -#include - -#include "types/Type.h" -#include "Variable.h" -#include "FunctionSignature.h" -#include "FunctionContext.h" -#include -#include -#include -#include - -class Instruction; - -class Function : public FunctionContext { - - /** - * The AST of this function which contains all instructions of this function. - */ - Instruction* mainInstruction_; - -public: - Function(FunctionContext& context, Instruction* mainInstruction); - virtual ~Function(); - - Instruction* mainInstruction() { - return mainInstruction_; - } -}; - - -#endif //WASMINT_FUNCTION_H diff --git a/src/FunctionContext.cpp b/src/FunctionContext.cpp deleted file mode 100644 index bc67126..0000000 --- a/src/FunctionContext.cpp +++ /dev/null @@ -1,3 +0,0 @@ - - -#include "FunctionContext.h" diff --git a/src/FunctionContext.h b/src/FunctionContext.h deleted file mode 100644 index e57644e..0000000 --- a/src/FunctionContext.h +++ /dev/null @@ -1,48 +0,0 @@ - - -#ifndef WASMINT_FUNCTIONCONTEXT_H -#define WASMINT_FUNCTIONCONTEXT_H - - -#include "types/Type.h" -#include "FunctionSignature.h" -#include - -/** - * The context of a function. This contains all information that are needed to - * create the instructions in the AST of the related function. - */ -class FunctionContext : public FunctionSignature { - - std::vector locals_; - -public: - FunctionContext() { - } - - FunctionContext(std::string name, Type* returnType, std::vector parameterTypes, - std::vector locals, bool exported) - : locals_(locals), FunctionSignature(name, returnType, parameterTypes, exported) { - - } - - std::vector pureLocals() { - return locals_; - } - - std::vector locals() { - std::vector result; - - for(Type* type : parameters()) { - result.push_back(type); - } - - for(Type* type : pureLocals()) { - result.push_back(type); - } - return result; - } -}; - - -#endif //WASMINT_FUNCTIONCONTEXT_H diff --git a/src/FunctionSignature.cpp b/src/FunctionSignature.cpp deleted file mode 100644 index a962182..0000000 --- a/src/FunctionSignature.cpp +++ /dev/null @@ -1,3 +0,0 @@ - - -#include "FunctionSignature.h" diff --git a/src/FunctionSignature.h b/src/FunctionSignature.h deleted file mode 100644 index 5b5fc51..0000000 --- a/src/FunctionSignature.h +++ /dev/null @@ -1,54 +0,0 @@ - - -#ifndef WASMINT_FUNCTIONSIGNATURE_H -#define WASMINT_FUNCTIONSIGNATURE_H - -#include -#include -#include - -#include "types/Type.h" -#include "Variable.h" - -/** - * Contains all information that are relevant to an caller of the given function. - */ -class FunctionSignature { - - std::string name_; - Type* returnType_ = Void::instance(); - std::vector parameterTypes_; - bool isExported_ = false; - -public: - FunctionSignature() { - - } - - FunctionSignature(std::string name, Type* returnType, - std::vector parameterTypes, bool exported) - : name_(name), returnType_(returnType), parameterTypes_(parameterTypes), - isExported_(exported) - { - } - - Type* returnType() { - return returnType_; - } - - std::vector parameters() { - return parameterTypes_; - } - - - std::string name() { - return name_; - } - - bool isExported() { - return isExported_; - } -}; - - -#endif //WASMINT_FUNCTIONSIGNATURE_H diff --git a/src/FunctionTable.cpp b/src/FunctionTable.cpp deleted file mode 100644 index 9b82639..0000000 --- a/src/FunctionTable.cpp +++ /dev/null @@ -1,3 +0,0 @@ - - -#include "FunctionTable.h" diff --git a/src/FunctionTable.h b/src/FunctionTable.h deleted file mode 100644 index 7d9d0ad..0000000 --- a/src/FunctionTable.h +++ /dev/null @@ -1,37 +0,0 @@ - - -#ifndef WASMINT_FUNCTIONTABLE_H -#define WASMINT_FUNCTIONTABLE_H - -#include -#include -#include -#include "FunctionSignature.h" -#include "ExceptionWithMessage.h" - -ExceptionMessage(UnknownLocalFunctionId) - -/** - * Maps local function ids to function signatures. - */ -class FunctionTable { - - std::vector functionNames_; - -public: - FunctionTable() { - } - - void addFunctionSignature(FunctionSignature signature) { - functionNames_.push_back(signature); - } - - FunctionSignature getFunctionSignature(uint32_t localFunctionId) { - if (localFunctionId > functionNames_.size()) - throw UnknownLocalFunctionId(std::to_string(localFunctionId)); - return functionNames_[localFunctionId]; - } -}; - - -#endif //WASMINT_FUNCTIONTABLE_H diff --git a/src/Global.cpp b/src/Global.cpp deleted file mode 100644 index 0aef58a..0000000 --- a/src/Global.cpp +++ /dev/null @@ -1,5 +0,0 @@ -// -// Created by teemperor on 21.06.15. -// - -#include "Global.h" diff --git a/src/Global.h b/src/Global.h deleted file mode 100644 index 23b5a5b..0000000 --- a/src/Global.h +++ /dev/null @@ -1,29 +0,0 @@ -// -// Created by teemperor on 21.06.15. -// - -#ifndef WASMINT_GLOBAL_H -#define WASMINT_GLOBAL_H - -#include -#include - -class Global { - std::string name_; - Type* type_; -public: - Global(std::string name, Type* type) : name_(name), type_(type) { - - } - - std::string name() { - return name_; - } - - Type* type() { - return type_; - } -}; - - -#endif //WASMINT_GLOBAL_H diff --git a/src/GlobalTable.cpp b/src/GlobalTable.cpp deleted file mode 100644 index 1347c49..0000000 --- a/src/GlobalTable.cpp +++ /dev/null @@ -1,5 +0,0 @@ -// -// Created by teemperor on 21.06.15. -// - -#include "GlobalTable.h" diff --git a/src/GlobalTable.h b/src/GlobalTable.h deleted file mode 100644 index 5ae19da..0000000 --- a/src/GlobalTable.h +++ /dev/null @@ -1,41 +0,0 @@ -// -// Created by teemperor on 21.06.15. -// - -#ifndef WASMINT_GLOBALTABLE_H -#define WASMINT_GLOBALTABLE_H - -#include -#include "Global.h" - -#include "ExceptionWithMessage.h" - -ExceptionMessage(NoGlobalWithIndex) - -class GlobalTable { - - std::vector globals; - std::vector internalGlobals_; - -public: - void addGlobal(Global global, bool internal) { - globals.push_back(global); - if (internal) - internalGlobals_.push_back(global); - } - - Global& getGlobal(uint32_t globalIndex) { - if (globalIndex >= globals.size()) - throw NoGlobalWithIndex(std::to_string(globalIndex)); - - return globals[globalIndex]; - } - - std::vector internalGlobals() { - return internalGlobals_; - } - -}; - - -#endif //WASMINT_GLOBALTABLE_H diff --git a/src/Module.cpp b/src/Module.cpp deleted file mode 100644 index 37979f1..0000000 --- a/src/Module.cpp +++ /dev/null @@ -1,3 +0,0 @@ - - -#include "Module.h" diff --git a/src/Module.h b/src/Module.h deleted file mode 100644 index 1383f4d..0000000 --- a/src/Module.h +++ /dev/null @@ -1,67 +0,0 @@ - - -#ifndef INTERPRETER_MODULE_H -#define INTERPRETER_MODULE_H - -#include -#include "parsing/ByteStream.h" -#include "Section.h" -#include "OpcodeTable.h" -#include "TypeTable.h" -#include "ModuleContext.h" -#include - -class Module { - - std::vector sections_; - ModuleContext context_; - std::vector requiredModules_; - -public: - Module(ModuleContext& context, std::vector sections, - std::vector requiredModules) - : sections_(sections), context_(context), requiredModules_(requiredModules) - { - } - - virtual ~Module() { - for(Section* section : sections_) { - delete section; - } - } - - std::vector functions() { - std::vector result; - for(Section* section : sections_) { - std::vector sectionFunctions = section->functions(); - for(Function* function : sectionFunctions) { - result.push_back(function); - } - } - return result; - } - - std::vector sections() { - return sections_; - } - - OpcodeTable& opcodeTable() { - return context_.opcodeTable(); - } - - TypeTable& typeTable() { - return context_.typeTable(); - } - - std::vector globals() { - return context_.globalTable().internalGlobals(); - } - - std::vector requiredModules() { - return requiredModules_; - } - -}; - - -#endif //INTERPRETER_MODULE_H diff --git a/src/ModuleContext.cpp b/src/ModuleContext.cpp deleted file mode 100644 index f89015a..0000000 --- a/src/ModuleContext.cpp +++ /dev/null @@ -1,3 +0,0 @@ - - -#include "ModuleContext.h" diff --git a/src/ModuleContext.h b/src/ModuleContext.h deleted file mode 100644 index 24dc4ed..0000000 --- a/src/ModuleContext.h +++ /dev/null @@ -1,49 +0,0 @@ - - -#ifndef WASMINT_MODULECONTEXT_H -#define WASMINT_MODULECONTEXT_H - - -#include "TypeTable.h" -#include "OpcodeTable.h" -#include "FunctionTable.h" -#include "GlobalTable.h" - -class ModuleContext { - - OpcodeTable opcodeTable_; - TypeTable typeTable_; - FunctionTable functionTable_; - GlobalTable globalTable_; - - -public: - ModuleContext() { - - } - - ModuleContext(OpcodeTable& opcodeTable, TypeTable& typeTable, FunctionTable& functionTable, GlobalTable& globalTable) - : opcodeTable_(opcodeTable), typeTable_(typeTable), functionTable_(functionTable), globalTable_(globalTable) { - - } - - OpcodeTable& opcodeTable() { - return opcodeTable_; - } - - TypeTable& typeTable() { - return typeTable_; - } - - FunctionTable& functionTable() { - return functionTable_; - } - - GlobalTable& globalTable() { - return globalTable_; - } - -}; - - -#endif //WASMINT_MODULECONTEXT_H diff --git a/src/OpcodeTable.cpp b/src/OpcodeTable.cpp deleted file mode 100644 index dcaaba3..0000000 --- a/src/OpcodeTable.cpp +++ /dev/null @@ -1,3 +0,0 @@ - - -#include "OpcodeTable.h" diff --git a/src/OpcodeTable.h b/src/OpcodeTable.h deleted file mode 100644 index 24780ab..0000000 --- a/src/OpcodeTable.h +++ /dev/null @@ -1,37 +0,0 @@ - - -#ifndef WASMINT_OPCODETABLE_H -#define WASMINT_OPCODETABLE_H - -#include -#include -#include -#include "ExceptionWithMessage.h" - - -ExceptionMessage(UnknownLocalOpcode) - -class OpcodeTable { - - std::map instructionsByLocalOpcode; - -public: - OpcodeTable() { - } - - void addInstruction(uint32_t localOpcode, std::string name) { - instructionsByLocalOpcode[localOpcode] = name; - } - - std::string getInstruction(uint32_t localOpcode) { - auto result = instructionsByLocalOpcode.find(localOpcode); - if (result == instructionsByLocalOpcode.end()) { - throw UnknownLocalOpcode(std::to_string(localOpcode)); - } else { - return result->second; - } - } -}; - - -#endif //WASMINT_OPCODETABLE_H diff --git a/src/Section.cpp b/src/Section.cpp deleted file mode 100644 index 7442b9b..0000000 --- a/src/Section.cpp +++ /dev/null @@ -1,19 +0,0 @@ - - -#include "Section.h" -#include - -Function &Section::getFunction(std::string name) { - for(Function* function : functions_) { - if (function->name() == name) { - return *function; - } - } - throw NoFunctionWithThatName(name); -} - -Section::~Section() { - for(Function* function : functions_) { - delete function; - } -} \ No newline at end of file diff --git a/src/Section.h b/src/Section.h deleted file mode 100644 index d088d69..0000000 --- a/src/Section.h +++ /dev/null @@ -1,55 +0,0 @@ - - -#ifndef INTERPRETER_SECTION_H -#define INTERPRETER_SECTION_H - - -#include -#include - -#include "ExceptionWithMessage.h" - -enum class SectionType { - DATA = 0, - CODE = 1, - INVALID = 200 -}; - -ExceptionMessage(NoFunctionWithThatName) - -class Function; - -class Section { - - SectionType type_; - uint32_t offset_; - std::vector functions_; - -public: - Section(uint32_t offset, SectionType type, std::vector functions) - : offset_(offset), type_(type), functions_(functions) { - } - - virtual ~Section(); - - SectionType type() { - return type_; - } - - uint32_t offset() { - return offset_; - } - - std::vector functions() { - std::vector result; - for(Function* function : functions_) { - result.push_back(function); - } - return result; - } - - Function & getFunction(std::string name); -}; - - -#endif //INTERPRETER_SECTION_H diff --git a/src/TypeTable.cpp b/src/TypeTable.cpp deleted file mode 100644 index eebc697..0000000 --- a/src/TypeTable.cpp +++ /dev/null @@ -1,23 +0,0 @@ - - -#include "TypeTable.h" -#include -#include -#include -#include -#include - -Type *TypeTable::getType(uint32_t localTypeCode) { - std::string typeName = getTypeName(localTypeCode); - if (typeName == "void") { - return Void::instance(); - } else if (typeName == "int32") { - return Int32::instance(); - } else if (typeName == "int364") { - return Int64::instance(); - } else if (typeName == "float32") { - return Float32::instance(); - } else if (typeName == "float364") { - return Float64::instance(); - } -} \ No newline at end of file diff --git a/src/TypeTable.h b/src/TypeTable.h deleted file mode 100644 index bdccf9f..0000000 --- a/src/TypeTable.h +++ /dev/null @@ -1,39 +0,0 @@ - - -#ifndef WASMINT_TYPETABLE_H -#define WASMINT_TYPETABLE_H - -#include -#include -#include -#include "types/Type.h" -#include "ExceptionWithMessage.h" - -ExceptionMessage(UnknownLocalTypeCode) - -class TypeTable { - - std::map typesByLocalTypeCode; - -public: - TypeTable() { - } - - void addType(uint32_t localTypeCode, std::string name) { - typesByLocalTypeCode[localTypeCode] = name; - } - - Type * getType(uint32_t localTypeCode); - - std::string getTypeName(uint32_t localTypeCode) { - auto result = typesByLocalTypeCode.find(localTypeCode); - if (result == typesByLocalTypeCode.end()) { - throw UnknownLocalTypeCode(std::to_string(localTypeCode)); - } else { - return result->second; - } - } -}; - - -#endif //WASMINT_TYPETABLE_H diff --git a/src/Variable.cpp b/src/Variable.cpp deleted file mode 100644 index 46755f2..0000000 --- a/src/Variable.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include -#include "Variable.h" -#include "types/Type.h" - -Variable::Variable(Type* type) : type_(type) { - value_.resize(type->size()); -} - -Variable::Variable() : type_(Void::instance()) { -} - -void Variable::setValue(std::vector newData) { - if (newData.size() != type_->size()) - throw InvalidDataSize(); - value_ = newData; -} \ No newline at end of file diff --git a/src/Variable.h b/src/Variable.h deleted file mode 100644 index 422551c..0000000 --- a/src/Variable.h +++ /dev/null @@ -1,37 +0,0 @@ - - -#ifndef WASMINT_VARIABLE_H -#define WASMINT_VARIABLE_H - -#include -#include - -class InvalidDataSize : public std::exception {}; - -class Type; - -class Variable { - Type* type_; - std::vector value_; - -public: - Variable(); - Variable(Type* type); - - Type& type() { - return *type_; - } - - void* value() { - return (void*) value_.data(); - } - - std::vector data() { - return value_; - } - - void setValue(std::vector newData); -}; - - -#endif //WASMINT_VARIABLE_H diff --git a/src/instructions/FunctionCall.cpp b/src/instructions/FunctionCall.cpp deleted file mode 100644 index 7c08339..0000000 --- a/src/instructions/FunctionCall.cpp +++ /dev/null @@ -1,3 +0,0 @@ - - -#include "FunctionCall.h" diff --git a/src/instructions/FunctionCall.h b/src/instructions/FunctionCall.h deleted file mode 100644 index 82a1282..0000000 --- a/src/instructions/FunctionCall.h +++ /dev/null @@ -1,48 +0,0 @@ - - -#ifndef WASMINT_FUNCTIONCALL_H -#define WASMINT_FUNCTIONCALL_H - - -#include -#include - -class FunctionCall : public Instruction { - - FunctionSignature functionSignature; - -public: - FunctionCall(ByteStream& stream, ModuleContext& context) { - functionSignature = context.functionTable().getFunctionSignature(stream.popULEB128()); - } - - virtual std::string name() { - return "call_direct"; - } - - virtual std::vector childrenTypes() { - return functionSignature.parameters(); - } - - virtual Type* returnType() { - return functionSignature.returnType(); - } - - virtual StepResult execute(Thread &thread) { - InstructionState& state = thread.getInstructionState(); - if (state.state() < children().size()) { - return StepResult(children().at(0)); - } else if (state.state() == children().size()) { - std::vector parameters; - for(uint32_t i = 0; i < parameters.size(); i++) { - parameters[i] = state.results().at(i); - } - return StepResult(thread.callFunction(functionSignature.name())); - } else { - return state.results().back(); - } - } -}; - - -#endif //WASMINT_FUNCTIONCALL_H diff --git a/src/instructions/GetGlobal.cpp b/src/instructions/GetGlobal.cpp deleted file mode 100644 index 13fff84..0000000 --- a/src/instructions/GetGlobal.cpp +++ /dev/null @@ -1,5 +0,0 @@ -// -// Created by teemperor on 21.06.15. -// - -#include "GetGlobal.h" diff --git a/src/instructions/GetGlobal.h b/src/instructions/GetGlobal.h deleted file mode 100644 index 47a9095..0000000 --- a/src/instructions/GetGlobal.h +++ /dev/null @@ -1,42 +0,0 @@ -// -// Created by teemperor on 21.06.15. -// - -#ifndef WASMINT_GETGLOBAL_H -#define WASMINT_GETGLOBAL_H - - -#include "Instruction.h" - -class GetGlobal : public Instruction { - - Type* returnType_; - std::string globalName; - -public: - GetGlobal(ByteStream& stream, ModuleContext& context) { - uint32_t globalIndex = stream.popULEB128(); - returnType_ = context.globalTable().getGlobal(globalIndex).type(); - globalName = context.globalTable().getGlobal(globalIndex).name(); - } - - virtual std::string name() { - return "get_global"; - } - - virtual std::vector childrenTypes() { - return {}; - } - - virtual Type* returnType() { - return returnType_; - } - - virtual StepResult execute(Thread &thread) { - return thread.runtimeEnvironment().global(globalName); - } -}; - - - -#endif //WASMINT_GETGLOBAL_H diff --git a/src/instructions/GetLocal.cpp b/src/instructions/GetLocal.cpp deleted file mode 100644 index bf2a848..0000000 --- a/src/instructions/GetLocal.cpp +++ /dev/null @@ -1,3 +0,0 @@ - - -#include "GetLocal.h" diff --git a/src/instructions/GetLocal.h b/src/instructions/GetLocal.h deleted file mode 100644 index 8a1009a..0000000 --- a/src/instructions/GetLocal.h +++ /dev/null @@ -1,40 +0,0 @@ - - -#ifndef WASMINT_GETLOCAL_H -#define WASMINT_GETLOCAL_H - - -#include -#include -#include - -class GetLocal : public Instruction { - - uint32_t localIndex; - Type* returnType_; - -public: - GetLocal(ByteStream& stream, FunctionContext& context) { - localIndex = stream.popULEB128(); - returnType_ = context.pureLocals().at(localIndex); - } - - virtual std::string name() { - return "get_local"; - } - - virtual std::vector childrenTypes() { - return {}; - } - - virtual Type* returnType() { - return returnType_; - } - - virtual StepResult execute(Thread &thread) { - return thread.variable(localIndex); - } -}; - - -#endif //WASMINT_GETLOCAL_H diff --git a/src/instructions/I32/I32Add.cpp b/src/instructions/I32/I32Add.cpp deleted file mode 100644 index 0efc7fa..0000000 --- a/src/instructions/I32/I32Add.cpp +++ /dev/null @@ -1,3 +0,0 @@ - - -#include "I32Add.h" diff --git a/src/instructions/I32/I32Add.h b/src/instructions/I32/I32Add.h deleted file mode 100644 index 7d04187..0000000 --- a/src/instructions/I32/I32Add.h +++ /dev/null @@ -1,48 +0,0 @@ - - -#ifndef WASMINT_I32ADD_H -#define WASMINT_I32ADD_H - - -#include -#include -#include "instructions/Instruction.h" - -class I32Add : public Instruction { - -public: - virtual std::vector childrenTypes() { - return {Int32::instance(), Int32::instance()}; - } - - virtual std::string name() { - return "int32.add"; - } - - - virtual Type* returnType() { - return Int32::instance(); - } - - virtual StepResult execute(Thread &thread) { - InstructionState& state = thread.getInstructionState(); - assert(state.instruction() == this); - switch(state.state()) { - case 0: - return StepResult(children().at(0)); - case 1: - return StepResult(children().at(1)); - default: - int32_t left = Int32::getValue(state.results().at(0)); - int32_t right = Int32::getValue(state.results().at(1)); - - Variable result = Variable(Int32::instance()); - Int32::setValue(result, left + right); - return result; - } - - } -}; - - -#endif //WASMINT_I32ADD_H diff --git a/src/instructions/I32/I32Div.cpp b/src/instructions/I32/I32Div.cpp deleted file mode 100644 index 5270fcf..0000000 --- a/src/instructions/I32/I32Div.cpp +++ /dev/null @@ -1,3 +0,0 @@ - - -#include "I32Div.h" diff --git a/src/instructions/I32/I32Div.h b/src/instructions/I32/I32Div.h deleted file mode 100644 index ec7b19e..0000000 --- a/src/instructions/I32/I32Div.h +++ /dev/null @@ -1,51 +0,0 @@ - - -#ifndef WASMINT_I32DIV_H -#define WASMINT_I32DIV_H - -#include -#include -#include - -class DivisionThroughZero : std::exception {}; - -class I32Div : public Instruction { - -public: - virtual std::vector childrenTypes() { - return {Int32::instance(), Int32::instance()}; - } - - virtual std::string name() { - return "int32.div"; - } - - - virtual Type* returnType() { - return Int32::instance(); - } - - virtual StepResult execute(Thread &thread) { - - InstructionState& state = thread.getInstructionState(); - switch(state.state()) { - case 0: - return StepResult(children().at(0)); - case 1: - return StepResult(children().at(1)); - default: - int32_t left = Int32::getValue(state.results().at(0)); - int32_t right = Int32::getValue(state.results().at(1)); - - if (right == 0) - throw DivisionThroughZero(); - - Variable result = Variable(Int32::instance()); - Int32::setValue(result, left / right); - return result; - } - } -}; - - -#endif //WASMINT_I32DIV_H diff --git a/src/instructions/I32/I32Mul.cpp b/src/instructions/I32/I32Mul.cpp deleted file mode 100644 index bf1b375..0000000 --- a/src/instructions/I32/I32Mul.cpp +++ /dev/null @@ -1,3 +0,0 @@ - - -#include "I32Mul.h" diff --git a/src/instructions/I32/I32Mul.h b/src/instructions/I32/I32Mul.h deleted file mode 100644 index 5d59318..0000000 --- a/src/instructions/I32/I32Mul.h +++ /dev/null @@ -1,46 +0,0 @@ - - -#ifndef WASMINT_I32MUL_H -#define WASMINT_I32MUL_H - - -#include -#include - -class I32Mul : public Instruction { - -public: - virtual std::vector childrenTypes() { - return {Int32::instance(), Int32::instance()}; - } - - virtual std::string name() { - return "int32.mul"; - } - - - virtual Type* returnType() { - return Int32::instance(); - } - - virtual StepResult execute(Thread &thread) { - - InstructionState& state = thread.getInstructionState(); - switch(state.state()) { - case 0: - return StepResult(children().at(0)); - case 1: - return StepResult(children().at(1)); - default: - int32_t left = Int32::getValue(state.results().at(0)); - int32_t right = Int32::getValue(state.results().at(1)); - - Variable result = Variable(Int32::instance()); - Int32::setValue(result, left * right); - return result; - } - } -}; - - -#endif //WASMINT_I32MUL_H diff --git a/src/instructions/I32/I32Sub.cpp b/src/instructions/I32/I32Sub.cpp deleted file mode 100644 index 367982d..0000000 --- a/src/instructions/I32/I32Sub.cpp +++ /dev/null @@ -1,3 +0,0 @@ - - -#include "I32Sub.h" diff --git a/src/instructions/I32/I32Sub.h b/src/instructions/I32/I32Sub.h deleted file mode 100644 index 47f752e..0000000 --- a/src/instructions/I32/I32Sub.h +++ /dev/null @@ -1,46 +0,0 @@ - - -#ifndef WASMINT_I32SUB_H -#define WASMINT_I32SUB_H - - -#include -#include - -class I32Sub : public Instruction { - -public: - virtual std::vector childrenTypes() { - return {Int32::instance(), Int32::instance()}; - } - - virtual std::string name() { - return "int32.sub"; - } - - - virtual Type* returnType() { - return Int32::instance(); - } - - virtual StepResult execute(Thread &thread) { - - InstructionState& state = thread.getInstructionState(); - switch(state.state()) { - case 0: - return StepResult(children().at(0)); - case 1: - return StepResult(children().at(1)); - default: - int32_t left = Int32::getValue(state.results().at(0)); - int32_t right = Int32::getValue(state.results().at(1)); - - Variable result = Variable(Int32::instance()); - Int32::setValue(result, left - right); - return result; - } - } -}; - - -#endif //WASMINT_I32SUB_H diff --git a/src/instructions/Instruction.cpp b/src/instructions/Instruction.cpp deleted file mode 100644 index b87b8ae..0000000 --- a/src/instructions/Instruction.cpp +++ /dev/null @@ -1,7 +0,0 @@ - - -#include "Instruction.h" - -bool Instruction::handleSignal(InstructionState& currentState, Signal signal) { - return false; -} \ No newline at end of file diff --git a/src/instructions/Instruction.h b/src/instructions/Instruction.h deleted file mode 100644 index 4803f1b..0000000 --- a/src/instructions/Instruction.h +++ /dev/null @@ -1,47 +0,0 @@ - - -#ifndef WASMINT_OPCODE_H -#define WASMINT_OPCODE_H - - -#include -#include - -#include "types/Type.h" -#include "Variable.h" -#include "StepResult.h" -#include -#include - -class InstructionState; - -class Instruction { - - std::vector children_; - -public: - virtual ~Instruction() { - for(Instruction* child : children()) { - delete child; - } - } - - virtual void children(std::vector newChildren) { - children_ = newChildren; - } - std::vector children() { - return children_; - } - - virtual std::string name() = 0; - - virtual std::vector childrenTypes() = 0; - virtual Type* returnType() = 0; - - virtual StepResult execute(Thread &thread) = 0; - - virtual bool handleSignal(InstructionState& currentState, Signal signal); -}; - - -#endif //WASMINT_OPCODE_H diff --git a/src/instructions/InstructionSet.cpp b/src/instructions/InstructionSet.cpp deleted file mode 100644 index 658dfe0..0000000 --- a/src/instructions/InstructionSet.cpp +++ /dev/null @@ -1,69 +0,0 @@ - - -#include "InstructionSet.h" -#include "Literal.h" -#include "SetGlobal.h" -#include "GetGlobal.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -Instruction *InstructionSet::getInstruction(std::string name, ByteStream& stream, ModuleContext& context, FunctionContext& functionContext) { - if (name == "literal") { - return new Literal(stream, context); - } else if (name == "int32.add") { - return new I32Add(); - } else if (name == "int32.sub") { - return new I32Sub(); - } else if (name == "int32.mul") { - return new I32Mul(); - } else if (name == "int32.div") { - return new I32Div(); - } else if (name == "print") { - return new Print(); - } else if (name == "call_direct") { - return new FunctionCall(stream, context); - } else if (name == "get_local") { - return new GetLocal(stream, functionContext); - } else if (name == "block") { - return new Block(stream); - } else if (name == "set_local") { - return new SetLocal(stream, functionContext); - } else if (name == "break") { - return new Break(); - } else if (name == "continue") { - return new Continue(); - } else if (name == "do_while") { - return new DoWhile(); - } else if (name == "forever") { - return new Forever(); - } else if (name == "int32.load") { - return new Int32Load(); - } else if (name == "int32.store") { - return new Int32Store(); - } else if (name == "if") { - return new If(); - } else if (name == "return") { - return new Return(); - } else if (name == "get_global") { - return new GetGlobal(stream, context); - } else if (name == "set_global") { - return new SetGlobal(stream, context); - } else { - throw UnknownInstructionName(name); - } -} \ No newline at end of file diff --git a/src/instructions/InstructionSet.h b/src/instructions/InstructionSet.h deleted file mode 100644 index 1d93c16..0000000 --- a/src/instructions/InstructionSet.h +++ /dev/null @@ -1,19 +0,0 @@ - - -#ifndef WASMINT_INSTRUCTIONSET_H -#define WASMINT_INSTRUCTIONSET_H - -#include -#include -#include "Instruction.h" - -ExceptionMessage(UnknownInstructionName) - -class InstructionSet { - -public: - static Instruction * getInstruction(std::string name, ByteStream& stream, ModuleContext& context, FunctionContext& functionContext); -}; - - -#endif //WASMINT_INSTRUCTIONSET_H diff --git a/src/instructions/Literal.cpp b/src/instructions/Literal.cpp deleted file mode 100644 index f5124de..0000000 --- a/src/instructions/Literal.cpp +++ /dev/null @@ -1,3 +0,0 @@ - - -#include "Literal.h" diff --git a/src/instructions/Literal.h b/src/instructions/Literal.h deleted file mode 100644 index fae2c6f..0000000 --- a/src/instructions/Literal.h +++ /dev/null @@ -1,40 +0,0 @@ - - -#ifndef WASMINT_LITERAL_H -#define WASMINT_LITERAL_H - - -#include "Instruction.h" - -class Literal : public Instruction { - Variable literalValue; - -public: - Literal(ByteStream& stream, ModuleContext& context) { - uint32_t typeId = stream.popULEB128(); - - Type* type = context.typeTable().getType(typeId); - - literalValue = Variable(type); - type->parse(stream, literalValue.value()); - } - - virtual std::vector childrenTypes() { - return {}; - } - - virtual std::string name() { - return "literal"; - } - - virtual Type* returnType() { - return &literalValue.type(); - } - - virtual StepResult execute(Thread &thread) { - return StepResult(literalValue); - } -}; - - -#endif //WASMINT_LITERAL_H diff --git a/src/instructions/Print.cpp b/src/instructions/Print.cpp deleted file mode 100644 index deff9f3..0000000 --- a/src/instructions/Print.cpp +++ /dev/null @@ -1,3 +0,0 @@ - - -#include "Print.h" diff --git a/src/instructions/Print.h b/src/instructions/Print.h deleted file mode 100644 index 49977bc..0000000 --- a/src/instructions/Print.h +++ /dev/null @@ -1,38 +0,0 @@ - - -#ifndef WASMINT_PRINT_H -#define WASMINT_PRINT_H - -#include -#include -#include - -class Print : public Instruction { -public: - virtual std::vector childrenTypes() { - return {Int32::instance()}; - } - - virtual std::string name() { - return "print"; - } - - virtual Type* returnType() { - return Void::instance(); - } - - virtual StepResult execute(Thread &thread) { - InstructionState& state = thread.getInstructionState(); - switch(state.state()) { - case 0: - return children().at(0); - default: - thread.runtimeEnvironment().print(std::to_string(Int32::getValue(state.results().at(0)))); - return StepResult(); - - } - } -}; - - -#endif //WASMINT_PRINT_H diff --git a/src/instructions/SetGlobal.cpp b/src/instructions/SetGlobal.cpp deleted file mode 100644 index 317eb36..0000000 --- a/src/instructions/SetGlobal.cpp +++ /dev/null @@ -1,5 +0,0 @@ -// -// Created by teemperor on 21.06.15. -// - -#include "SetGlobal.h" diff --git a/src/instructions/SetGlobal.h b/src/instructions/SetGlobal.h deleted file mode 100644 index 93c1e5e..0000000 --- a/src/instructions/SetGlobal.h +++ /dev/null @@ -1,50 +0,0 @@ -// -// Created by teemperor on 21.06.15. -// - -#ifndef WASMINT_SETGLOBAL_H -#define WASMINT_SETGLOBAL_H - - -#include "Instruction.h" - -class SetGlobal : public Instruction { - - Type* expectedType; - std::string globalName; - -public: - SetGlobal(ByteStream& stream, ModuleContext& context) { - uint32_t globalIndex = stream.popULEB128(); - expectedType = context.globalTable().getGlobal(globalIndex).type(); - globalName = context.globalTable().getGlobal(globalIndex).name(); - } - - virtual std::string name() { - return "set_global"; - } - - virtual std::vector childrenTypes() { - return {expectedType}; - } - - virtual Type* returnType() { - return expectedType; - } - - virtual StepResult execute(Thread &thread) { - InstructionState& state = thread.getInstructionState(); - switch(state.state()) { - case 0: - return children().at(0); - default: - Variable result = thread.runtimeEnvironment().global(globalName) = state.results().at(0); - return result; - - } - } -}; - - - -#endif //WASMINT_SETGLOBAL_H diff --git a/src/instructions/SetLocal.cpp b/src/instructions/SetLocal.cpp deleted file mode 100644 index 038c777..0000000 --- a/src/instructions/SetLocal.cpp +++ /dev/null @@ -1,3 +0,0 @@ - - -#include "SetLocal.h" diff --git a/src/instructions/SetLocal.h b/src/instructions/SetLocal.h deleted file mode 100644 index 22899a8..0000000 --- a/src/instructions/SetLocal.h +++ /dev/null @@ -1,49 +0,0 @@ - - -#ifndef WASMINT_SETLOCAL_H -#define WASMINT_SETLOCAL_H - -#include -#include -#include -#include -#include - -class SetLocal : public Instruction { - - uint32_t localIndex; - Type* expectedType; - -public: - SetLocal(ByteStream& stream, FunctionContext& functionContext) { - localIndex = stream.popULEB128(); - expectedType = functionContext.pureLocals().at(localIndex); - } - - virtual std::string name() { - return "set_local"; - } - - virtual std::vector childrenTypes() { - return {expectedType}; - } - - virtual Type* returnType() { - return expectedType; - } - - virtual StepResult execute(Thread &thread) { - InstructionState& state = thread.getInstructionState(); - switch(state.state()) { - case 0: - return children().at(0); - default: - Variable result = thread.variable(localIndex) = state.results().at(0); - return result; - - } - } -}; - - -#endif //WASMINT_SETLOCAL_H diff --git a/src/instructions/controlflow/Block.cpp b/src/instructions/controlflow/Block.cpp deleted file mode 100644 index 0e7e285..0000000 --- a/src/instructions/controlflow/Block.cpp +++ /dev/null @@ -1,3 +0,0 @@ - - -#include "Block.h" diff --git a/src/instructions/controlflow/Block.h b/src/instructions/controlflow/Block.h deleted file mode 100644 index 23b7b2f..0000000 --- a/src/instructions/controlflow/Block.h +++ /dev/null @@ -1,46 +0,0 @@ - - -#ifndef WASMINT_BLOCK_H -#define WASMINT_BLOCK_H - - -#include -#include - -class Block : public Instruction { - - uint32_t amountOfChildren; - -public: - Block(ByteStream& stream) { - amountOfChildren = stream.popULEB128(); - } - - virtual std::string name() { - return "block"; - } - - virtual std::vector childrenTypes() { - std::vector result; - for(uint32_t i = 0; i < amountOfChildren; i++) { - result.push_back(Void::instance()); - } - return result; - } - - virtual Type* returnType() { - return Void::instance(); - } - - virtual StepResult execute(Thread &thread) { - InstructionState& state = thread.getInstructionState(); - if (state.state() < children().size()) { - return StepResult(children().at(state.state())); - } else { - return StepResult(); - } - } -}; - - -#endif //WASMINT_BLOCK_H diff --git a/src/instructions/controlflow/Break.cpp b/src/instructions/controlflow/Break.cpp deleted file mode 100644 index 92553bf..0000000 --- a/src/instructions/controlflow/Break.cpp +++ /dev/null @@ -1,3 +0,0 @@ - - -#include "Break.h" diff --git a/src/instructions/controlflow/Break.h b/src/instructions/controlflow/Break.h deleted file mode 100644 index cbde653..0000000 --- a/src/instructions/controlflow/Break.h +++ /dev/null @@ -1,31 +0,0 @@ - - -#ifndef WASMINT_BREAK_H -#define WASMINT_BREAK_H - - -#include - -class CalledBreak {}; - -class Break : public Instruction { -public: - virtual std::vector childrenTypes() { - return {}; - } - virtual std::string name() { - return "break"; - } - - virtual Type* returnType() { - return Void::instance(); - } - - virtual StepResult execute(Thread &thread) { - return StepResult(Signal::Break); - } -}; - - - -#endif //WASMINT_BREAK_H diff --git a/src/instructions/controlflow/Continue.cpp b/src/instructions/controlflow/Continue.cpp deleted file mode 100644 index 10b93f7..0000000 --- a/src/instructions/controlflow/Continue.cpp +++ /dev/null @@ -1,3 +0,0 @@ - - -#include "Continue.h" diff --git a/src/instructions/controlflow/Continue.h b/src/instructions/controlflow/Continue.h deleted file mode 100644 index 47a0c20..0000000 --- a/src/instructions/controlflow/Continue.h +++ /dev/null @@ -1,31 +0,0 @@ - - -#ifndef WASMINT_CONTINUE_H -#define WASMINT_CONTINUE_H - - -#include - -class CalledContinue {}; - -class Continue : public Instruction { -public: - virtual std::vector childrenTypes() { - return {}; - } - virtual std::string name() { - return "continue"; - } - - virtual Type* returnType() { - return Void::instance(); - } - - virtual StepResult execute(Thread &thread) { - return StepResult(Signal::Continue); - } -}; - - - -#endif //WASMINT_CONTINUE_H diff --git a/src/instructions/controlflow/DoWhile.cpp b/src/instructions/controlflow/DoWhile.cpp deleted file mode 100644 index c65b5be..0000000 --- a/src/instructions/controlflow/DoWhile.cpp +++ /dev/null @@ -1,3 +0,0 @@ - - -#include "DoWhile.h" diff --git a/src/instructions/controlflow/DoWhile.h b/src/instructions/controlflow/DoWhile.h deleted file mode 100644 index 82bd133..0000000 --- a/src/instructions/controlflow/DoWhile.h +++ /dev/null @@ -1,54 +0,0 @@ - - -#ifndef WASMINT_DOWHILE_H -#define WASMINT_DOWHILE_H - - -#include -#include -#include "Break.h" -#include "Continue.h" - -class DoWhile : public Instruction { -public: - virtual std::vector childrenTypes() { - return {Void::instance(), Int32::instance()}; - } - - virtual std::string name() { - return "do_while"; - } - - virtual Type* returnType() { - return Void::instance(); - } - - virtual bool handleSignal(InstructionState& currentState, Signal signal) { - if (signal == Signal::Break) { - currentState.state(10); - } - return signal == Signal::Continue; - } - - - virtual StepResult execute(Thread &thread) { - InstructionState& state = thread.getInstructionState(); - switch(state.state()) { - case 0: - case 1: - return children().at(0); - case 2: - return children().at(1); - default: - if (Int32::getValue(state.results().back()) != 0) { - state.state(0); - } else { - return StepResult(); - } - } - } -}; - - - -#endif //WASMINT_DOWHILE_H diff --git a/src/instructions/controlflow/Forever.cpp b/src/instructions/controlflow/Forever.cpp deleted file mode 100644 index d9d0e19..0000000 --- a/src/instructions/controlflow/Forever.cpp +++ /dev/null @@ -1,3 +0,0 @@ - - -#include "Forever.h" diff --git a/src/instructions/controlflow/Forever.h b/src/instructions/controlflow/Forever.h deleted file mode 100644 index 3838a9a..0000000 --- a/src/instructions/controlflow/Forever.h +++ /dev/null @@ -1,45 +0,0 @@ - - -#ifndef WASMINT_FOREVER_H -#define WASMINT_FOREVER_H - - -#include -#include "Break.h" -#include "Continue.h" - -class Forever : public Instruction { -public: - virtual std::vector childrenTypes() { - return {Void::instance()}; - } - - virtual std::string name() { - return "forever"; - } - - virtual Type* returnType() { - return Void::instance(); - } - - virtual bool handleSignal(InstructionState& currentState, Signal signal) { - if (signal == Signal::Break) { - currentState.state(10); - return true; - } - return signal == Signal::Continue; - } - - virtual StepResult execute(Thread &thread) { - if (thread.getInstructionState().state() >= 10) { - return StepResult(); - } - thread.getInstructionState().clearResults(); - thread.getInstructionState().state(0); - return StepResult(children().front()); - } -}; - - - -#endif //WASMINT_FOREVER_H diff --git a/src/instructions/controlflow/If.cpp b/src/instructions/controlflow/If.cpp deleted file mode 100644 index ed482f3..0000000 --- a/src/instructions/controlflow/If.cpp +++ /dev/null @@ -1,3 +0,0 @@ - - -#include "If.h" diff --git a/src/instructions/controlflow/If.h b/src/instructions/controlflow/If.h deleted file mode 100644 index be1fa1b..0000000 --- a/src/instructions/controlflow/If.h +++ /dev/null @@ -1,42 +0,0 @@ - - -#ifndef WASMINT_IF_H -#define WASMINT_IF_H - - -#include -#include - -class If : public Instruction { -public: - virtual std::vector childrenTypes() { - return {Int32::instance(), Void::instance()}; - } - - virtual std::string name() { - return "if"; - } - - virtual Type* returnType() { - return Void::instance(); - } - - virtual StepResult execute(Thread &thread) { - InstructionState& state = thread.getInstructionState(); - switch(state.state()) { - case 0: - return children().at(0); - case 1: - if (Int32::getValue(state.results().front()) != 0) { - return children().at(1); - } - default: - return StepResult(); - - } - } -}; - - - -#endif //WASMINT_IF_H diff --git a/src/instructions/controlflow/Return.cpp b/src/instructions/controlflow/Return.cpp deleted file mode 100644 index 1857b91..0000000 --- a/src/instructions/controlflow/Return.cpp +++ /dev/null @@ -1,3 +0,0 @@ - - -#include "Return.h" diff --git a/src/instructions/controlflow/Return.h b/src/instructions/controlflow/Return.h deleted file mode 100644 index 3567349..0000000 --- a/src/instructions/controlflow/Return.h +++ /dev/null @@ -1,43 +0,0 @@ - - -#ifndef WASMINT_RETURN_H -#define WASMINT_RETURN_H - - -#include -#include - -class CalledReturn { -public: - Variable result; -}; - -class Return : public Instruction { -public: - virtual std::vector childrenTypes() { - return {Int32::instance()}; - } - - virtual std::string name() { - return "return"; - } - - virtual Type* returnType() { - return Void::instance(); - } - - virtual StepResult execute(Thread &thread) { - InstructionState& state = thread.getInstructionState(); - switch(state.state()) { - case 0: - return children().at(0); - default: - return state.results().front(); - - } - } -}; - - - -#endif //WASMINT_RETURN_H diff --git a/src/instructions/heap/Int32Load.cpp b/src/instructions/heap/Int32Load.cpp deleted file mode 100644 index 020a754..0000000 --- a/src/instructions/heap/Int32Load.cpp +++ /dev/null @@ -1,3 +0,0 @@ - - -#include "Int32Load.h" diff --git a/src/instructions/heap/Int32Load.h b/src/instructions/heap/Int32Load.h deleted file mode 100644 index 4e7e83b..0000000 --- a/src/instructions/heap/Int32Load.h +++ /dev/null @@ -1,45 +0,0 @@ - - -#ifndef WASMINT_LOADHEAP_H -#define WASMINT_LOADHEAP_H - - -#include -#include - -class Int32Load : public Instruction { - -public: - virtual std::vector childrenTypes() { - return {Int32::instance()}; - } - - virtual Type* returnType() { - return Int32::instance(); - } - - virtual std::string name() { - return "int32.load"; - } - - virtual StepResult execute(Thread &thread) { - - InstructionState& state = thread.getInstructionState(); - switch(state.state()) { - case 0: - return StepResult(children().at(0)); - default: - uint32_t offset = static_cast(Int32::getValue(state.results().back())); - - std::vector bytes = thread.runtimeEnvironment().heap().getBytes(offset, Int32::instance()->size()); - - Variable result = Variable(Int32::instance()->localType()); - result.setValue(bytes); - return result; - } - - } -}; - - -#endif //WASMINT_LOADHEAP_H diff --git a/src/instructions/heap/Int32Store.cpp b/src/instructions/heap/Int32Store.cpp deleted file mode 100644 index 6600269..0000000 --- a/src/instructions/heap/Int32Store.cpp +++ /dev/null @@ -1,3 +0,0 @@ - - -#include "Int32Store.h" diff --git a/src/instructions/heap/Int32Store.h b/src/instructions/heap/Int32Store.h deleted file mode 100644 index 06020d1..0000000 --- a/src/instructions/heap/Int32Store.h +++ /dev/null @@ -1,45 +0,0 @@ - - -#ifndef WASMINT_STOREHEAP_H -#define WASMINT_STOREHEAP_H - - -#include -#include - -class Int32Store : public Instruction { - -public: - virtual std::vector childrenTypes() { - return {Int32::instance(), Int32::instance()}; - } - - virtual Type* returnType() { - return Int32::instance(); - } - - virtual std::string name() { - return "int32.store"; - } - - virtual StepResult execute(Thread &thread) { - - InstructionState& state = thread.getInstructionState(); - switch(state.state()) { - case 0: - return StepResult(children().at(0)); - case 1: - return StepResult(children().at(1)); - default: - - uint32_t offset = static_cast(Int32::getValue(state.results().at(0))); - - Variable value = state.results().at(1); - thread.runtimeEnvironment().heap().setBytes(offset, value.data()); - return StepResult(value); - } - } -}; - - -#endif //WASMINt_STOREHEAP_H diff --git a/src/interpreter/InstructionExecutor.cpp b/src/interpreter/InstructionExecutor.cpp new file mode 100644 index 0000000..19438c7 --- /dev/null +++ b/src/interpreter/InstructionExecutor.cpp @@ -0,0 +1,245 @@ +#include "InstructionExecutor.h" +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "RuntimeEnvironment.h" + +StepResult InstructionExecutor::execute(Instruction& instruction, Thread& thread) { + InstructionState& state = thread.getInstructionState(); + + /** + * Control flow + */ + if (typeid(instruction) == typeid(Block)) { + if (state.state() < instruction.children().size()) { + return StepResult(instruction.children().at(state.state())); + } else { + return StepResult(); + } + } else if (typeid(instruction) == typeid(Break)) { + return StepResult(Signal::Break); + } else if (typeid(instruction) == typeid(Continue)) { + return StepResult(Signal::Continue); + } else if (typeid(instruction) == typeid(DoWhile)) { + switch(state.state()) { + case 0: + case 1: + return instruction.children().at(0); + case 2: + return instruction.children().at(1); + default: + if (Int32::getValue(state.results().back()) != 0) { + state.state(0); + } else { + return StepResult(); + } + } + } else if (typeid(instruction) == typeid(Forever)) { + if (thread.getInstructionState().state() >= 10) { + return StepResult(); + } + thread.getInstructionState().clearResults(); + thread.getInstructionState().state(0); + return StepResult(instruction.children().front()); + } else if (typeid(instruction) == typeid(If)) { + switch(state.state()) { + case 0: + return instruction.children().at(0); + case 1: + if (Int32::getValue(state.results().front()) != 0) { + return instruction.children().at(1); + } + default: + return StepResult(); + + } + } else if (typeid(instruction) == typeid(Return)) { + switch(state.state()) { + case 0: + return instruction.children().at(0); + default: + return state.results().front(); + + } + } + /** + * heap access + */ + else if (typeid(instruction) == typeid(Int32Load)) { + switch(state.state()) { + case 0: + return StepResult(instruction.children().at(0)); + default: + uint32_t offset = static_cast(Int32::getValue(state.results().back())); + + std::vector bytes = thread.runtimeEnvironment().heap().getBytes(offset, Int32::instance()->size()); + + Variable result = Variable(Int32::instance()->localType()); + result.setValue(bytes); + return result; + } + } else if (typeid(instruction) == typeid(Int32Store)) { + switch(state.state()) { + case 0: + return StepResult(instruction.children().at(0)); + case 1: + return StepResult(instruction.children().at(1)); + default: + + uint32_t offset = static_cast(Int32::getValue(state.results().at(0))); + + Variable value = state.results().at(1); + thread.runtimeEnvironment().heap().setBytes(offset, value.data()); + return StepResult(value); + } + } + /** + * i32 instructions + */ + else if (typeid(instruction) == typeid(I32Add)) { + switch(state.state()) { + case 0: + return StepResult(instruction.children().at(0)); + case 1: + return StepResult(instruction.children().at(1)); + default: + int32_t left = Int32::getValue(state.results().at(0)); + int32_t right = Int32::getValue(state.results().at(1)); + + Variable result = Variable(Int32::instance()); + Int32::setValue(result, left + right); + return result; + } + } else if (typeid(instruction) == typeid(I32Div)) { + switch(state.state()) { + case 0: + return StepResult(instruction.children().at(0)); + case 1: + return StepResult(instruction.children().at(1)); + default: + int32_t left = Int32::getValue(state.results().at(0)); + int32_t right = Int32::getValue(state.results().at(1)); + + if (right == 0) + throw DivisionThroughZero(); + + Variable result = Variable(Int32::instance()); + Int32::setValue(result, left + right); + return result; + } + } else if (typeid(instruction) == typeid(I32Mul)) { + switch(state.state()) { + case 0: + return StepResult(instruction.children().at(0)); + case 1: + return StepResult(instruction.children().at(1)); + default: + int32_t left = Int32::getValue(state.results().at(0)); + int32_t right = Int32::getValue(state.results().at(1)); + + Variable result = Variable(Int32::instance()); + Int32::setValue(result, left * right); + return result; + } + } else if (typeid(instruction) == typeid(I32Sub)) { + switch(state.state()) { + case 0: + return StepResult(instruction.children().at(0)); + case 1: + return StepResult(instruction.children().at(1)); + default: + int32_t left = Int32::getValue(state.results().at(0)); + int32_t right = Int32::getValue(state.results().at(1)); + + Variable result = Variable(Int32::instance()); + Int32::setValue(result, left - right); + return result; + } + } + /** + * other instructions + */ + else if (typeid(instruction) == typeid(FunctionCall)) { + if (state.state() < instruction.children().size()) { + return StepResult(instruction.children().at(0)); + } else if (state.state() == instruction.children().size()) { + std::vector parameters; + for(uint32_t i = 0; i < parameters.size(); i++) { + parameters[i] = state.results().at(i); + } + return StepResult(thread.callFunction(dynamic_cast(instruction).functionSignature.name())); + } else { + return state.results().back(); + } + } else if (typeid(instruction) == typeid(GetGlobal)) { + return thread.runtimeEnvironment().global(dynamic_cast(instruction).globalName); + } else if (typeid(instruction) == typeid(GetLocal)) { + return thread.variable(dynamic_cast(instruction).localIndex); + } else if (typeid(instruction) == typeid(Literal)) { + return StepResult(dynamic_cast(instruction).literalValue); + } else if (typeid(instruction) == typeid(Print)) { + switch(state.state()) { + case 0: + return instruction.children().at(0); + default: + thread.runtimeEnvironment().print(std::to_string(Int32::getValue(state.results().at(0)))); + return StepResult(); + + } + } else if (typeid(instruction) == typeid(SetGlobal)) { + switch(state.state()) { + case 0: + return instruction.children().at(0); + default: + Variable result = thread.runtimeEnvironment().global(dynamic_cast(instruction).globalName) = state.results().at(0); + return result; + + } + } else if (typeid(instruction) == typeid(SetLocal)) { + switch(state.state()) { + case 0: + return instruction.children().at(0); + default: + Variable result = thread.variable(dynamic_cast(instruction).localIndex) = state.results().at(0); + return result; + + } + } + + else { + throw UnknownInstruction(std::string("Pointer points to an unkown Instruction type")); + } +} + +bool InstructionExecutor::handleSignal(Instruction& instruction, InstructionState& currentState, Signal signal) { + if (typeid(instruction) == typeid(Forever) || typeid(instruction) == typeid(DoWhile)) { + if (signal == Signal::Break) { + currentState.state(10); + return true; + } + return signal == Signal::Continue; + } + + return false; +} \ No newline at end of file diff --git a/src/interpreter/InstructionExecutor.h b/src/interpreter/InstructionExecutor.h new file mode 100644 index 0000000..60d8003 --- /dev/null +++ b/src/interpreter/InstructionExecutor.h @@ -0,0 +1,18 @@ +#ifndef WASMINT_INSTRUCTIONEXECUTOR_H +#define WASMINT_INSTRUCTIONEXECUTOR_H + + +#include +#include "Thread.h" + +ExceptionMessage(UnknownInstruction) + +class InstructionExecutor { + +public: + static StepResult execute(Instruction& instruction, Thread& thread); + static bool handleSignal(Instruction& instruction, InstructionState& currentState, Signal signal); +}; + + +#endif //WASMINT_INSTRUCTIONEXECUTOR_H diff --git a/src/interpreter/InstructionState.cpp b/src/interpreter/InstructionState.cpp index 9e93466..f76bacc 100644 --- a/src/interpreter/InstructionState.cpp +++ b/src/interpreter/InstructionState.cpp @@ -1,6 +1,8 @@ #include "InstructionState.h" #include +#include "Thread.h" +#include "InstructionExecutor.h" Signal InstructionState::step(Thread& thread) { if (childInstruction != nullptr) { @@ -11,7 +13,7 @@ Signal InstructionState::step(Thread& thread) { childInstruction = nullptr; } if (signal != Signal::None) { - if (instruction()->handleSignal(*this, signal)) { + if (InstructionExecutor::handleSignal(*instruction(), *this, signal)) { delete childInstruction; childInstruction = nullptr; return Signal::None; @@ -19,7 +21,7 @@ Signal InstructionState::step(Thread& thread) { } return signal; } else { - StepResult result = instruction_->execute(thread); + StepResult result = InstructionExecutor::execute(*instruction(), thread); if (result.newChildInstruction()) { childInstruction = new InstructionState(result.newChildInstruction()); } else if (result.signal() != Signal::None) { diff --git a/src/interpreter/InstructionState.h b/src/interpreter/InstructionState.h index 13b6bf7..55a1c2b 100644 --- a/src/interpreter/InstructionState.h +++ b/src/interpreter/InstructionState.h @@ -4,9 +4,9 @@ #include #include #include -#include "Thread.h" class Instruction; +class Thread; class InstructionState { diff --git a/src/interpreter/Thread.cpp b/src/interpreter/Thread.cpp index 72ce35f..c83a05f 100644 --- a/src/interpreter/Thread.cpp +++ b/src/interpreter/Thread.cpp @@ -4,6 +4,7 @@ #include #include #include "InstructionState.h" +#include "RuntimeEnvironment.h" Thread::Thread(RuntimeEnvironment& env) : env_(env) { diff --git a/src/parsing/ByteStream.cpp b/src/parsing/ByteStream.cpp deleted file mode 100644 index 20bf499..0000000 --- a/src/parsing/ByteStream.cpp +++ /dev/null @@ -1,3 +0,0 @@ - - -#include "ByteStream.h" diff --git a/src/parsing/ByteStream.h b/src/parsing/ByteStream.h deleted file mode 100644 index 8368d9b..0000000 --- a/src/parsing/ByteStream.h +++ /dev/null @@ -1,91 +0,0 @@ - - -#ifndef INTERPRETER_BYTESTREAM_H -#define INTERPRETER_BYTESTREAM_H - - -#include -#include -#include -#include -#include - -class LEB128PayloadBiggerThan32Bit : public std::exception {}; -class EndOfStreamReached : public std::exception {}; - -class ByteStream { - - std::deque bytes_; - uint32_t position_ = 0; - -public: - ByteStream(std::deque bytes) : bytes_(bytes) { - } - ByteStream(std::vector bytes) { - bytes_.resize(bytes.size()); - for(uint32_t i = 0; i < bytes.size(); i++) { - bytes_[i] = bytes[i]; - } - } - ByteStream(const ByteStream& copy); // Don't implement to prevent copying - - uint8_t popChar() { - position_++; - uint8_t result = peekChar(); - bytes_.pop_front(); - - return result; - } - - std::string readCString() { - std::string result = ""; - while (peekChar() != 0) { - result.push_back((unsigned char) popChar()); - } - // remove the \0 at the end - popChar(); - return result; - } - - uint8_t peekChar() { - if (bytes_.empty()) - throw EndOfStreamReached(); - return bytes_.front(); - } - - - uint32_t popULEB128() { - uint32_t result = 0; - uint8_t shift = 0; - for(int i = 0; i < 5; i++) { - uint8_t byte = popChar(); - - // check if first bit is set - if (byte >= 128u) { - // if we currently check the 4th byte, the number has to be smaller than 128 - // or the payload would be bigger thatn 32 bit (which is restricted by the specification) - if (i == 4) { - throw LEB128PayloadBiggerThan32Bit(); - } - } - - // OR the new byte without the MSB into the result integer - result |= (byte & 0x7F) << shift; - - // if the MSB is not set, we are done here - if (byte < 128u) { - break; - } - shift += 7; - } - return result; - } - - uint32_t position() { - return position_; - } - -}; - - -#endif //INTERPRETER_BYTESTREAM_H diff --git a/src/parsing/CodeSectionParser.cpp b/src/parsing/CodeSectionParser.cpp deleted file mode 100644 index a0a9277..0000000 --- a/src/parsing/CodeSectionParser.cpp +++ /dev/null @@ -1,3 +0,0 @@ - - -#include "CodeSectionParser.h" diff --git a/src/parsing/CodeSectionParser.h b/src/parsing/CodeSectionParser.h deleted file mode 100644 index 58f5cd5..0000000 --- a/src/parsing/CodeSectionParser.h +++ /dev/null @@ -1,67 +0,0 @@ - - -#ifndef INTERPRETER_SECTIONPARSER_H -#define INTERPRETER_SECTIONPARSER_H - - -#include -#include -#include "ByteStream.h" -#include "../Section.h" -#include "FunctionParser.h" - -class CodeSectionParser { - - ByteStream& stream; - - std::vector functions; - std::vector signatures; - - ModuleContext& context; - - void parseFunctions() { - uint32_t numberOfFunctions = stream.popULEB128(); - - for (uint32_t i = 0; i < numberOfFunctions; i++) { - std::string functionName = stream.readCString(); - bool exported = stream.popULEB128() != 0; - - Type* returnType = context.typeTable().getType(stream.popULEB128()); - - uint32_t numberOfParameters = stream.popULEB128(); - std::vector parameters; - for (uint32_t j = 0; j < numberOfParameters; j++) { - parameters.push_back(context.typeTable().getType(stream.popULEB128())); - } - - uint32_t offset = stream.popULEB128(); - FunctionSignature signature = FunctionSignature(functionName, returnType, parameters, exported); - signatures.push_back(signature); - context.functionTable().addFunctionSignature(signature); - } - - for (int i = 0; i < numberOfFunctions; i++) { - functions.push_back(FunctionParser::parse(context, signatures[i], stream)); - } - } - -protected: - CodeSectionParser(ModuleContext& context, ByteStream& stream) - : stream(stream), context(context) { - - } - - Section* get(uint32_t offset) { - return new Section(offset, SectionType::CODE, functions); - } - -public: - static Section* parse(uint32_t offset, ModuleContext& context, ByteStream& stream) { - CodeSectionParser parser(context, stream); - parser.parseFunctions(); - return parser.get(offset); - } -}; - - -#endif //INTERPRETER_SECTIONPARSER_H diff --git a/src/parsing/FunctionParser.cpp b/src/parsing/FunctionParser.cpp deleted file mode 100644 index fe35bcf..0000000 --- a/src/parsing/FunctionParser.cpp +++ /dev/null @@ -1,3 +0,0 @@ - - -#include "FunctionParser.h" diff --git a/src/parsing/FunctionParser.h b/src/parsing/FunctionParser.h deleted file mode 100644 index af1c043..0000000 --- a/src/parsing/FunctionParser.h +++ /dev/null @@ -1,89 +0,0 @@ - - -#ifndef WASMINT_FUNCTIONPARSER_H -#define WASMINT_FUNCTIONPARSER_H - - -#include -#include -#include -#include -#include -#include -#include "ByteStream.h" - -ExceptionMessage(InvalidParameterType) - -class FunctionParser { - ByteStream& stream; - FunctionSignature functionSignature_; - FunctionContext functionContext; - - ModuleContext& context_; - Instruction* mainInstruction; - -protected: - FunctionParser(ModuleContext& context, ByteStream& stream, FunctionSignature functionSignature) - : context_(context), stream(stream), functionSignature_(functionSignature) { - } - - void parse() { - uint32_t numberOfLocals = stream.popULEB128(); - - std::vector typeOfLocals; - for (uint32_t i = 0; i < numberOfLocals; i++) { - uint32_t typeData = stream.popULEB128(); - typeOfLocals.push_back(context_.typeTable().getType(typeData)); - } - functionContext = FunctionContext(functionSignature_.name(), functionSignature_.returnType(), - functionSignature_.parameters(), typeOfLocals, - functionSignature_.isExported()); - - mainInstruction = parseInstruction(); - } - - Instruction* parseInstruction() { - uint32_t opcode = stream.popULEB128(); - Instruction* instruction = InstructionSet::getInstruction( - context_.opcodeTable().getInstruction(opcode), stream, context_, functionContext); - - std::vector children; - - for(uint32_t args = 0; args < instruction->childrenTypes().size(); args++) { - Instruction* child = parseInstruction(); - - Type* expectedChildType = instruction->childrenTypes().at(args); - if (expectedChildType != Void::instance()) { - if (expectedChildType != child->returnType()) { - throw InvalidParameterType( - std::string("Error while parsing parameter ") + std::to_string(args + 1) + - std::string(" for instruction ") + instruction->name() + - std::string(". Expected type ") + expectedChildType->name() + - " but got " + instruction->returnType()->name()+ - std::string(". Parameter instruction that delivered wrong type was ") + child->name() - ); - } - } - - if (child->returnType()) - children.push_back(child); - } - - instruction->children(children); - return instruction; - } - - Function* getParsedFunction() { - return new Function(functionContext, mainInstruction); - } - -public: - static Function* parse(ModuleContext& context, FunctionSignature& signature, ByteStream& stream) { - FunctionParser parser(context, stream, signature); - parser.parse(); - return parser.getParsedFunction(); - } -}; - - -#endif //WASMINT_FUNCTIONPARSER_H diff --git a/src/parsing/FunctionTableParser.cpp b/src/parsing/FunctionTableParser.cpp deleted file mode 100644 index e2d86d0..0000000 --- a/src/parsing/FunctionTableParser.cpp +++ /dev/null @@ -1,3 +0,0 @@ - - -#include "FunctionTableParser.h" diff --git a/src/parsing/FunctionTableParser.h b/src/parsing/FunctionTableParser.h deleted file mode 100644 index 1b4db72..0000000 --- a/src/parsing/FunctionTableParser.h +++ /dev/null @@ -1,38 +0,0 @@ - - -#ifndef WASMINT_FUNCTIONTABLEPARSER_H -#define WASMINT_FUNCTIONTABLEPARSER_H - - -#include - -class FunctionTableParser { - - ByteStream& stream; - FunctionTable functionTable; - -protected: - FunctionTableParser(ByteStream& stream) : stream(stream) { - } - - void parse() { - uint32_t numberOfFunctions = stream.popULEB128(); - for(uint32_t i = 0; i < numberOfFunctions; i++) { - functionTable.addFunctionSignature(FunctionSignature()); - } - } - - FunctionTable getParsedTable() { - return functionTable; - } - -public: - static FunctionTable parse(ByteStream& stream) { - FunctionTableParser parser(stream); - parser.parse(); - return parser.getParsedTable(); - } -}; - - -#endif //WASMINT_FUNCTIONTABLEPARSER_H diff --git a/src/parsing/GlobalTableParser.cpp b/src/parsing/GlobalTableParser.cpp deleted file mode 100644 index 1e2e878..0000000 --- a/src/parsing/GlobalTableParser.cpp +++ /dev/null @@ -1,5 +0,0 @@ -// -// Created by teemperor on 21.06.15. -// - -#include "GlobalTableParser.h" diff --git a/src/parsing/GlobalTableParser.h b/src/parsing/GlobalTableParser.h deleted file mode 100644 index 968a376..0000000 --- a/src/parsing/GlobalTableParser.h +++ /dev/null @@ -1,67 +0,0 @@ -// -// Created by teemperor on 21.06.15. -// - -#ifndef WASMINT_GLOBALTABLEPARSER_H -#define WASMINT_GLOBALTABLEPARSER_H - - -#include -#include - -class GlobalTableParser { - - ByteStream& stream; - GlobalTable globalTable; - TypeTable& typeTable_; - -protected: - GlobalTableParser(ByteStream& stream, TypeTable& typeTable) - : stream(stream), typeTable_(typeTable) { - } - - void parseExternGlobals() { - uint32_t numberOfExternalGlobals = stream.popULEB128(); - for(uint32_t i = 0; i < numberOfExternalGlobals; i++) { - uint32_t typeData = stream.popULEB128(); - std::string name = stream.readCString(); - - Type* type = typeTable_.getType(typeData); - - globalTable.addGlobal(Global(name, type), false); - } - } - - void parseInternGlobals() { - uint32_t numberOfInternalGlobals = stream.popULEB128(); - for(uint32_t i = 0; i < numberOfInternalGlobals; i++) { - uint32_t typeData = stream.popULEB128(); - std::string name = stream.readCString(); - - Type* type = typeTable_.getType(typeData); - - globalTable.addGlobal(Global(name, type), true); - - } - } - - - void parse() { - parseExternGlobals(); - parseInternGlobals(); - } - - GlobalTable getParsedTable() { - return globalTable; - } - -public: - static GlobalTable parse(ByteStream& stream, TypeTable& typeTable) { - GlobalTableParser parser(stream, typeTable); - parser.parse(); - return parser.getParsedTable(); - } -}; - - -#endif //WASMINT_GLOBALTABLEPARSER_H diff --git a/src/parsing/ModuleParser.cpp b/src/parsing/ModuleParser.cpp deleted file mode 100644 index 2ae97af..0000000 --- a/src/parsing/ModuleParser.cpp +++ /dev/null @@ -1,3 +0,0 @@ - - -#include "ModuleParser.h" diff --git a/src/parsing/ModuleParser.h b/src/parsing/ModuleParser.h deleted file mode 100644 index 7326389..0000000 --- a/src/parsing/ModuleParser.h +++ /dev/null @@ -1,114 +0,0 @@ - - -#ifndef INTERPRETER_MODULEPARSER_H -#define INTERPRETER_MODULEPARSER_H - - -#include "../Module.h" -#include -#include -#include -#include "ByteStream.h" -#include "CodeSectionParser.h" -#include "OpcodeTableParser.h" -#include "TypeTableParser.h" -#include "FunctionTableParser.h" -#include "GlobalTableParser.h" - -ExceptionMessage(NoSectionWithOffset) -ExceptionMessage(SectionTableNotOrdered) - -class ModuleParser { - - ByteStream& stream; - std::map sectionTypes; - std::vector requiredModules; - - std::vector sections; - - ModuleContext context; - - SectionType getSectionTypeFromOffset(uint32_t offset) { - auto result = sectionTypes.find(offset); - - if (result == sectionTypes.end()) { - throw NoSectionWithOffset(std::to_string(offset)); - } else { - return result->second; - } - } - -protected: - ModuleParser(ByteStream& stream) : stream(stream) { - - } - - void parseRequiredModules() { - uint32_t numberOfModules = stream.popULEB128(); - for(uint32_t i = 0; i < numberOfModules; i++) { - requiredModules.push_back(stream.readCString()); - } - } - - void parseHeader() { - parseRequiredModules(); - - // Instruction table - OpcodeTable opcodeTable = OpcodeTableParser::parse(stream); - - // Type table - TypeTable typeTable = TypeTableParser::parse(stream); - - FunctionTable functionTable = FunctionTableParser::parse(stream); - - GlobalTable globalTable = GlobalTableParser::parse(stream, typeTable); - - // Put everything into the context - context = ModuleContext(opcodeTable, typeTable, functionTable, globalTable); - - // Section header - uint32_t numberOfSections = stream.popULEB128(); - - uint32_t lastOffset = 0; - - for(uint32_t i = 0; i < numberOfSections; i++) { - uint32_t typeData = stream.popULEB128(); - - SectionType type; - switch (typeData) { - case 1: - type = SectionType::CODE; - break; - } - uint32_t offset = stream.popULEB128(); - - sectionTypes[offset] = type; - - if (offset <= lastOffset) - throw SectionTableNotOrdered(std::string("Offset of section ") + std::to_string(i) + " smaller than previous offset"); - lastOffset = offset; - } - } - - - void parseSections() { - SectionType sectionType = getSectionTypeFromOffset(stream.position()); - Section* section = CodeSectionParser::parse(stream.position(), context, stream); - sections.push_back(section); - } - - Module* getParsedModule() { - return new Module(context, sections, requiredModules); - } - -public: - static Module* parse(ByteStream& stream) { - ModuleParser parser(stream); - parser.parseHeader(); - parser.parseSections(); - return parser.getParsedModule(); - } -}; - - -#endif //INTERPRETER_MODULEPARSER_H diff --git a/src/parsing/OpcodeTableParser.cpp b/src/parsing/OpcodeTableParser.cpp deleted file mode 100644 index 9831bd1..0000000 --- a/src/parsing/OpcodeTableParser.cpp +++ /dev/null @@ -1,3 +0,0 @@ - - -#include "OpcodeTableParser.h" diff --git a/src/parsing/OpcodeTableParser.h b/src/parsing/OpcodeTableParser.h deleted file mode 100644 index af00ee6..0000000 --- a/src/parsing/OpcodeTableParser.h +++ /dev/null @@ -1,41 +0,0 @@ - - -#ifndef WASMINT_OPCODETABLEPARSER_H -#define WASMINT_OPCODETABLEPARSER_H - -#include -#include - -#include -#include "ByteStream.h" - -class OpcodeTableParser { - - ByteStream& stream; - OpcodeTable opcodeTable; - -protected: - OpcodeTableParser(ByteStream& stream) : stream(stream) { - } - - void parse() { - uint32_t numberOfOpcodes = stream.popULEB128(); - for(uint32_t i = 0; i < numberOfOpcodes; i++) { - opcodeTable.addInstruction(i, stream.readCString()); - } - } - - OpcodeTable getParsedTable() { - return opcodeTable; - } - -public: - static OpcodeTable parse(ByteStream& stream) { - OpcodeTableParser parser(stream); - parser.parse(); - return parser.getParsedTable(); - } -}; - - -#endif //WASMINT_OPCODETABLEPARSER_H diff --git a/src/parsing/TypeTableParser.cpp b/src/parsing/TypeTableParser.cpp deleted file mode 100644 index 5f08bba..0000000 --- a/src/parsing/TypeTableParser.cpp +++ /dev/null @@ -1,3 +0,0 @@ - - -#include "TypeTableParser.h" diff --git a/src/parsing/TypeTableParser.h b/src/parsing/TypeTableParser.h deleted file mode 100644 index dd45a75..0000000 --- a/src/parsing/TypeTableParser.h +++ /dev/null @@ -1,39 +0,0 @@ - - -#ifndef WASMINT_TYPETABLEPARSER_H -#define WASMINT_TYPETABLEPARSER_H - -#include "ByteStream.h" -#include -#include -#include - -class TypeTableParser { - ByteStream& stream; - TypeTable typeTable; - -protected: - TypeTableParser(ByteStream& stream) : stream(stream) { - } - - void parse() { - uint32_t numberOfTypes = stream.popULEB128(); - for(uint32_t i = 0; i < numberOfTypes; i++) { - typeTable.addType(i, stream.readCString()); - } - } - - TypeTable getParsedTable() { - return typeTable; - } - -public: - static TypeTable parse(ByteStream& stream) { - TypeTableParser parser(stream); - parser.parse(); - return parser.getParsedTable(); - } -}; - - -#endif //WASMINT_TYPETABLEPARSER_H diff --git a/src/types/Float32.cpp b/src/types/Float32.cpp deleted file mode 100644 index 20f3a3a..0000000 --- a/src/types/Float32.cpp +++ /dev/null @@ -1,3 +0,0 @@ - - -#include "Float32.h" diff --git a/src/types/Float32.h b/src/types/Float32.h deleted file mode 100644 index 5017989..0000000 --- a/src/types/Float32.h +++ /dev/null @@ -1,60 +0,0 @@ - - -#ifndef WASMINT_FLOAT32_H -#define WASMINT_FLOAT32_H - - -#include -#include - -class Float32 : public Type { - -protected: - Float32() { - } - - -public: - static Float32* instance() { - static Float32 instance; - return &instance; - } - - virtual std::string name() { - return "float32"; - } - - virtual void parse(ByteStream& stream, void* data) { - ((uint8_t*) data)[0] = stream.popChar(); - ((uint8_t*) data)[1] = stream.popChar(); - ((uint8_t*) data)[2] = stream.popChar(); - ((uint8_t*) data)[3] = stream.popChar(); - } - - static float getValue(Variable variable) { - if (variable.type() == *instance()) { - float result = 0; - float* data = (float*) variable.value(); - result = *data; - return result; - } else { - throw IncompatibleType(); - } - } - - static void setValue(Variable variable, float value) { - if (variable.type() == *instance()) { - float* data = (float*) variable.value(); - (*data) = value; - } else { - throw IncompatibleType(); - } - } - - virtual std::size_t size() { - return 4; - } -}; - - -#endif //WASMINT_FLOAT32_H diff --git a/src/types/Float64.cpp b/src/types/Float64.cpp deleted file mode 100644 index a92e15d..0000000 --- a/src/types/Float64.cpp +++ /dev/null @@ -1,3 +0,0 @@ - - -#include "Float64.h" diff --git a/src/types/Float64.h b/src/types/Float64.h deleted file mode 100644 index c873b5e..0000000 --- a/src/types/Float64.h +++ /dev/null @@ -1,65 +0,0 @@ - - -#ifndef WASMINT_FLOAT64_H -#define WASMINT_FLOAT64_H - - -#include -#include - -class Float64 : public Type { - -protected: - Float64() { - } - - -public: - static Float64* instance() { - static Float64 instance; - return &instance; - } - - - virtual std::string name() { - return "float64"; - } - - virtual void parse(ByteStream& stream, void* data) { - ((uint8_t*) data)[0] = stream.popChar(); - ((uint8_t*) data)[1] = stream.popChar(); - ((uint8_t*) data)[2] = stream.popChar(); - ((uint8_t*) data)[3] = stream.popChar(); - ((uint8_t*) data)[4] = stream.popChar(); - ((uint8_t*) data)[5] = stream.popChar(); - ((uint8_t*) data)[6] = stream.popChar(); - ((uint8_t*) data)[7] = stream.popChar(); - } - - static double getValue(Variable variable) { - if (variable.type() == *instance()) { - double result = 0; - double* data = (double*) variable.value(); - result = *data; - return result; - } else { - throw IncompatibleType(); - } - } - - static void setValue(Variable variable, double value) { - if (variable.type() == *instance()) { - double* data = (double*) variable.value(); - (*data) = value; - } else { - throw IncompatibleType(); - } - } - - virtual std::size_t size() { - return 8; - } -}; - - -#endif //WASMINT_FLOAT64_H diff --git a/src/types/Int32.cpp b/src/types/Int32.cpp deleted file mode 100644 index a638ff3..0000000 --- a/src/types/Int32.cpp +++ /dev/null @@ -1,3 +0,0 @@ - - -#include "Int32.h" diff --git a/src/types/Int32.h b/src/types/Int32.h deleted file mode 100644 index 7b1c95c..0000000 --- a/src/types/Int32.h +++ /dev/null @@ -1,85 +0,0 @@ - - -#ifndef WASMINT_INT32_H -#define WASMINT_INT32_H - - -#include -#include - -class Int32 : public Type { - -protected: - Int32() { - } - - -public: - static Int32* instance() { - static Int32 instance; - return &instance; - } - - virtual std::string name() { - return "int32"; - } - - static int32_t getFromStream(ByteStream& stream) { - int32_t result = 0; - uint32_t shift = 0; - uint32_t size = 32; - - uint8_t byte; - - while(true) { - byte = stream.popChar(); - - - result |= ((byte & 0x7F) << shift); - shift += 7; - - if ((byte & 0x80u) == 0u) - break; - } - - /* sign bit of byte is second high order bit (0x40) */ - if ((shift < size) && ((0x40 & byte) != 0)) - /* sign extend */ - result |= - (1 << shift); - - return result; - } - - virtual void parse(ByteStream& stream, void* data) { - int32_t value = getFromStream(stream); - (*(int32_t*)data) = value; - } - - static int32_t getValue(Variable variable) { - if (variable.type() == *instance()) { - int32_t result = 0; - int32_t* data = (int32_t*) variable.value(); - result = *data; - return result; - } else { - throw IncompatibleType(); - } - } - - static void setValue(Variable& variable, int32_t value) { - if (variable.type() == *instance()) { - int32_t* data = (int32_t*) variable.value(); - (*data) = value; - } else { - throw IncompatibleType(); - } - } - - virtual std::size_t size() { - return 4; - } - -}; - - -#endif //WASMINT_INT32_H diff --git a/src/types/Int64.cpp b/src/types/Int64.cpp deleted file mode 100644 index c2f0607..0000000 --- a/src/types/Int64.cpp +++ /dev/null @@ -1,3 +0,0 @@ - - -#include "Int64.h" diff --git a/src/types/Int64.h b/src/types/Int64.h deleted file mode 100644 index 392434d..0000000 --- a/src/types/Int64.h +++ /dev/null @@ -1,60 +0,0 @@ - - -#ifndef WASMINT_INT64_H -#define WASMINT_INT64_H - - -#include -#include - -class Int64 : public Type { - -protected: - Int64() { - } - - -public: - static Int64* instance() { - static Int64 instance; - return &instance; - } - - virtual std::string name() { - return "int64"; - } - - virtual void parse(ByteStream& stream, void* data) { - int64_t value = stream.popULEB128() << 32; // FIXME - value |= stream.popULEB128(); - (*(int64_t*)data) = value; - } - - static int64_t getValue(Variable variable) { - if (variable.type() == *instance()) { - int64_t result = 0; - int64_t* data = (int64_t*) variable.value(); - result = *data; - return result; - } else { - throw IncompatibleType(); - } - } - - static void setValue(Variable variable, int32_t value) { - if (variable.type() == *instance()) { - int32_t* data = (int32_t*) variable.value(); - (*data) = value; - } else { - throw IncompatibleType(); - } - } - - virtual std::size_t size() { - return 8; - } - -}; - - -#endif //WASMINT_INT64_H diff --git a/src/types/Int8.cpp b/src/types/Int8.cpp deleted file mode 100644 index ddcdf65..0000000 --- a/src/types/Int8.cpp +++ /dev/null @@ -1,5 +0,0 @@ -// -// Created by teemperor on 22.06.15. -// - -#include "Int8.h" diff --git a/src/types/Int8.h b/src/types/Int8.h deleted file mode 100644 index e5040c3..0000000 --- a/src/types/Int8.h +++ /dev/null @@ -1,91 +0,0 @@ -// -// Created by teemperor on 22.06.15. -// - -#ifndef WASMINT_INT8_H -#define WASMINT_INT8_H - -#include -#include -#include -#include "Int32.h" - -class Int8 : public Type { - -protected: - Int8() { - } - -public: - static Int8* instance() { - static Int8 instance; - return &instance; - } - - virtual std::string name() { - return "int8"; - } - - virtual Type* localType() override { - return Int32::instance(); - } - - static int8_t getFromStream(ByteStream& stream) { - int8_t result = 0; - uint8_t shift = 0; - uint8_t size = 8; - - uint8_t byte; - - while(true) { - byte = stream.popChar(); - - result |= ((byte & 0x7F) << shift); - shift += 7; - - if ((byte & 0x80u) == 0u) - break; - } - - /* sign bit of byte is second high order bit (0x40) */ - if ((shift < size) && ((0x40 & byte) != 0)) - /* sign extend */ - result |= - (1 << shift); - - return result; - } - - virtual void parse(ByteStream& stream, void* data) { - int8_t value = getFromStream(stream); - (*(int8_t*)data) = value; - } - - static int8_t getValue(Variable variable) { - if (variable.type() == *instance()) { - int8_t result = 0; - int8_t* data = (int8_t*) variable.value(); - result = *data; - return result; - } else { - throw IncompatibleType(); - } - } - - static void setValue(Variable& variable, int8_t value) { - if (variable.type() == *instance()) { - int8_t* data = (int8_t*) variable.value(); - (*data) = value; - } else { - throw IncompatibleType(); - } - } - - virtual std::size_t size() { - return 1; - } - -}; - - - -#endif //WASMINT_INT8_H diff --git a/src/types/Type.cpp b/src/types/Type.cpp deleted file mode 100644 index 7306e70..0000000 --- a/src/types/Type.cpp +++ /dev/null @@ -1,3 +0,0 @@ - - -#include "types/Type.h" \ No newline at end of file diff --git a/src/types/Type.h b/src/types/Type.h deleted file mode 100644 index 0751b87..0000000 --- a/src/types/Type.h +++ /dev/null @@ -1,51 +0,0 @@ - - -#ifndef WASMINT_TYPE_H -#define WASMINT_TYPE_H - - -#include -#include -#include -#include - -class IncompatibleType : public std::exception {}; - -class Type { - -protected: - Type() { - - } - -public: - Type(const Type& type) { - - } - - virtual Type* localType() { - return this; - } - - virtual std::vector convertFromMemoryType(std::vector bytes, Type* memoryType) { - return bytes; - } - - virtual std::string name() = 0; - - virtual void parse(ByteStream& stream, void* data) = 0; - - virtual std::size_t size() = 0; - - bool operator==(const Type& other) const { - return typeid(*this) == typeid(other); - } - - bool operator!=(const Type& other) const { - return typeid(*this) != typeid(other); - } - -}; - - -#endif //WASMINT_TYPE_H diff --git a/src/types/Void.cpp b/src/types/Void.cpp deleted file mode 100644 index 67c7bff..0000000 --- a/src/types/Void.cpp +++ /dev/null @@ -1,3 +0,0 @@ - - -#include "Void.h" diff --git a/src/types/Void.h b/src/types/Void.h deleted file mode 100644 index 39360eb..0000000 --- a/src/types/Void.h +++ /dev/null @@ -1,38 +0,0 @@ - - -#ifndef WASMINT_VOID_H -#define WASMINT_VOID_H - - -#include - -class NoVoidLiteralsSupported : public std::exception {}; - -class Void : public Type { - -protected: - Void() { - } - -public: - static Void* instance() { - static Void instance; - return &instance; - } - - virtual std::string name() { - return "void"; - } - - virtual void parse(ByteStream& stream, void* data) { - throw NoVoidLiteralsSupported(); - } - - virtual std::size_t size() { - return 1; - } - -}; - - -#endif //WASMINT_VOID_H diff --git a/tests/ByteStreamTest.cpp b/tests/ByteStreamTest.cpp deleted file mode 100644 index 0451034..0000000 --- a/tests/ByteStreamTest.cpp +++ /dev/null @@ -1,34 +0,0 @@ - -#include -#include -#include -#include -#include -#include - -int main() { - std::deque data = { - 0x10, // 16u - 0xE5, 0x8E, 0x26, // 624485u - 0x10, // 16s - 0xE5, 0x8E, 0x26, // 624485s - 0x9b, 0xf1, 0x59 // -624485s - }; - - ByteStream stream(data); - - uint32_t leb = stream.popULEB128(); - assert (leb == 16); - - leb = stream.popULEB128(); - assert (leb == 624485); - - int32_t sleb = Int32::getFromStream(stream); - assert(sleb == 16); - - sleb = Int32::getFromStream(stream); - assert(sleb == 624485); - - sleb = Int32::getFromStream(stream); - assert(sleb == -624485); -} diff --git a/tests/ForeverBreakTest.cpp b/tests/ForeverBreakTest.cpp index 126d207..d6bdd76 100644 --- a/tests/ForeverBreakTest.cpp +++ b/tests/ForeverBreakTest.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #define BLOCK 0x7 #define SET_LOCAL 0x5 diff --git a/tests/ExampleModuleTest.cpp b/tests/GlobalTest.cpp similarity index 99% rename from tests/ExampleModuleTest.cpp rename to tests/GlobalTest.cpp index 293ee1f..7efea9e 100644 --- a/tests/ExampleModuleTest.cpp +++ b/tests/GlobalTest.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #define BLOCK 0x7 #define SET_LOCAL 0x5 diff --git a/tests/LoadStoreTest.cpp b/tests/LoadStoreTest.cpp index dc1e90b..596696b 100644 --- a/tests/LoadStoreTest.cpp +++ b/tests/LoadStoreTest.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #define BLOCK 0x7 #define SET_LOCAL 0x5 diff --git a/tests/SimpleModuleTest.cpp b/tests/SimpleModuleTest.cpp index 7860fb9..a9e597e 100644 --- a/tests/SimpleModuleTest.cpp +++ b/tests/SimpleModuleTest.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #define BLOCK 0x7 #define SET_LOCAL 0x5 diff --git a/wasm-module b/wasm-module new file mode 160000 index 0000000..ebef268 --- /dev/null +++ b/wasm-module @@ -0,0 +1 @@ +Subproject commit ebef2687de5c80c6542d4f07d3248dcfc6678682 From 9e38779b4fdb42afa2ce99139eb11fb21ffe49b7 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Sat, 18 Jul 2015 13:25:15 +0200 Subject: [PATCH 2/2] Moved StepResult to interpreter folder and fixed main.cpp --- CMakeLists.txt | 3 +-- main.cpp | 7 ++++--- src/interpreter/InstructionExecutor.h | 2 +- src/interpreter/InstructionState.h | 2 +- src/{instructions => interpreter}/StepResult.cpp | 0 src/{instructions => interpreter}/StepResult.h | 0 6 files changed, 7 insertions(+), 7 deletions(-) rename src/{instructions => interpreter}/StepResult.cpp (100%) rename src/{instructions => interpreter}/StepResult.h (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6c5df87..9235e8f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,8 +19,7 @@ add_library(core src/interpreter/RuntimeEnvironment.cpp src/interpreter/InstructionExecutor.cpp src/interpreter/Heap.cpp - - src/instructions/StepResult.cpp + src/interpreter/StepResult.cpp ) diff --git a/main.cpp b/main.cpp index 19a4b6e..4cbef3b 100644 --- a/main.cpp +++ b/main.cpp @@ -5,7 +5,8 @@ #include #include #include - +#include +#include int main(int argc, char** argv) { if (argc == 1) { std::cerr << "No modules given. Call programm like this: \n$ wasmint module1.wasm" << std::endl; @@ -41,8 +42,8 @@ int main(int argc, char** argv) { } try { - Thread& thread = environment.createThread(); - thread.callFunction("main"); + Thread& thread = environment.createThread().startAtFunction("main"); + thread.stepUntilFinished(); } catch(NoFunctionWithName e) { if (e.what() == "main") { std::cerr << "None of the given modules has a main function. Exiting..." << std::endl; diff --git a/src/interpreter/InstructionExecutor.h b/src/interpreter/InstructionExecutor.h index 60d8003..120495f 100644 --- a/src/interpreter/InstructionExecutor.h +++ b/src/interpreter/InstructionExecutor.h @@ -2,7 +2,7 @@ #define WASMINT_INSTRUCTIONEXECUTOR_H -#include +#include #include "Thread.h" ExceptionMessage(UnknownInstruction) diff --git a/src/interpreter/InstructionState.h b/src/interpreter/InstructionState.h index 55a1c2b..255366c 100644 --- a/src/interpreter/InstructionState.h +++ b/src/interpreter/InstructionState.h @@ -3,7 +3,7 @@ #include #include -#include +#include class Instruction; class Thread; diff --git a/src/instructions/StepResult.cpp b/src/interpreter/StepResult.cpp similarity index 100% rename from src/instructions/StepResult.cpp rename to src/interpreter/StepResult.cpp diff --git a/src/instructions/StepResult.h b/src/interpreter/StepResult.h similarity index 100% rename from src/instructions/StepResult.h rename to src/interpreter/StepResult.h