|
5 | 5 | #pragma once |
6 | 6 |
|
7 | 7 | #include "bytes.hpp" |
| 8 | +#include <algorithm> |
| 9 | +#include <cassert> |
8 | 10 | #include <memory> |
9 | 11 | #include <optional> |
| 12 | +#include <stdexcept> |
10 | 13 | #include <string_view> |
11 | 14 | #include <vector> |
12 | 15 |
|
@@ -58,8 +61,46 @@ class WasmEngine |
58 | 61 | virtual Result execute(FuncRef func_ref, const std::vector<uint64_t>& args) = 0; |
59 | 62 | }; |
60 | 63 |
|
| 64 | +/// Throws exception if the signature is non-conformant. |
| 65 | +/// |
| 66 | +/// A function signature consist of input and output types delimited by a colon. Zero number of |
| 67 | +/// types is allowed. A type is represented with a single character, where `i` means i32, and |
| 68 | +/// `I` means i64. |
| 69 | +/// |
| 70 | +/// As an example `iI:i` translates to `(i32, i64) -> (i32)`, `I:` to `(i64) -> void`, etc. |
61 | 71 | void validate_function_signature(std::string_view signature); |
62 | 72 |
|
| 73 | +/// Parses a validated signature and returns a pair of input and output type vectors of type |
| 74 | +/// `ValueType`. |
| 75 | +/// |
| 76 | +/// Note that calling `validate_function_signature` first is advised for better error reporting. |
| 77 | +template <typename ValueType, ValueType i32_type, ValueType i64_type> |
| 78 | +std::pair<std::vector<ValueType>, std::vector<ValueType>> translate_function_signature( |
| 79 | + std::string_view signature) |
| 80 | +{ |
| 81 | + constexpr auto translate_valtype = [](char input) { |
| 82 | + if (input == 'i') |
| 83 | + return i32_type; |
| 84 | + else if (input == 'I') |
| 85 | + return i64_type; |
| 86 | + else |
| 87 | + throw std::runtime_error{"invalid type"}; |
| 88 | + }; |
| 89 | + |
| 90 | + const auto delimiter_pos = signature.find(':'); |
| 91 | + assert(delimiter_pos != std::string_view::npos); |
| 92 | + const auto inputs = signature.substr(0, delimiter_pos); |
| 93 | + const auto outputs = signature.substr(delimiter_pos + 1); |
| 94 | + |
| 95 | + std::vector<ValueType> input_types; |
| 96 | + std::vector<ValueType> output_types; |
| 97 | + std::transform( |
| 98 | + std::begin(inputs), std::end(inputs), std::back_inserter(input_types), translate_valtype); |
| 99 | + std::transform(std::begin(outputs), std::end(outputs), std::back_inserter(output_types), |
| 100 | + translate_valtype); |
| 101 | + return {std::move(input_types), std::move(output_types)}; |
| 102 | +} |
| 103 | + |
63 | 104 | std::unique_ptr<WasmEngine> create_fizzy_engine(); |
64 | 105 | std::unique_ptr<WasmEngine> create_fizzy_c_engine(); |
65 | 106 | std::unique_ptr<WasmEngine> create_wabt_engine(); |
|
0 commit comments