From 0534138668dd780cbdb413cd78c03c1ee878e651 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Thu, 25 Feb 2021 15:31:09 +0000 Subject: [PATCH] test: Refactor translate_signature in wasm_engine This replaces the implementation in fizzy_engine with a template. --- test/utils/fizzy_engine.cpp | 29 +++----------------------- test/utils/wasm_engine.hpp | 41 +++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 26 deletions(-) diff --git a/test/utils/fizzy_engine.cpp b/test/utils/fizzy_engine.cpp index 9055f19be..cbba53301 100644 --- a/test/utils/fizzy_engine.cpp +++ b/test/utils/fizzy_engine.cpp @@ -28,31 +28,6 @@ class FizzyEngine final : public WasmEngine namespace { -ValType translate_valtype(char input) -{ - if (input == 'i') - return fizzy::ValType::i32; - else if (input == 'I') - return fizzy::ValType::i64; - else - throw std::runtime_error{"invalid type"}; -} - -FuncType translate_signature(std::string_view signature) -{ - const auto delimiter_pos = signature.find(':'); - assert(delimiter_pos != std::string_view::npos); - const auto inputs = signature.substr(0, delimiter_pos); - const auto outputs = signature.substr(delimiter_pos + 1); - - FuncType func_type; - std::transform(std::begin(inputs), std::end(inputs), std::back_inserter(func_type.inputs), - translate_valtype); - std::transform(std::begin(outputs), std::end(outputs), std::back_inserter(func_type.outputs), - translate_valtype); - return func_type; -} - fizzy::ExecutionResult env_adler32(fizzy::Instance& instance, const fizzy::Value* args, int) { assert(instance.memory != nullptr); @@ -124,7 +99,9 @@ std::optional FizzyEngine::find_function( if (func_idx.has_value()) { const auto func_type = m_instance->module->get_function_type(*func_idx); - const auto sig_type = translate_signature(signature); + FuncType sig_type; + std::tie(sig_type.inputs, sig_type.outputs) = + translate_function_signature(signature); if (sig_type != func_type) return std::nullopt; } diff --git a/test/utils/wasm_engine.hpp b/test/utils/wasm_engine.hpp index d09e0e197..aaacd96f3 100644 --- a/test/utils/wasm_engine.hpp +++ b/test/utils/wasm_engine.hpp @@ -5,8 +5,11 @@ #pragma once #include "bytes.hpp" +#include +#include #include #include +#include #include #include @@ -58,8 +61,46 @@ class WasmEngine virtual Result execute(FuncRef func_ref, const std::vector& args) = 0; }; +/// Throws exception if the signature is non-conformant. +/// +/// A function signature consist of input and output types delimited by a colon. Zero number of +/// types is allowed. A type is represented with a single character, where `i` means i32, and +/// `I` means i64. +/// +/// As an example `iI:i` translates to `(i32, i64) -> (i32)`, `I:` to `(i64) -> void`, etc. void validate_function_signature(std::string_view signature); +/// Parses a validated signature and returns a pair of input and output type vectors of type +/// `ValueType`. +/// +/// Note that calling `validate_function_signature` first is advised for better error reporting. +template +std::pair, std::vector> translate_function_signature( + std::string_view signature) +{ + constexpr auto translate_valtype = [](char input) { + if (input == 'i') + return i32_type; + else if (input == 'I') + return i64_type; + else + throw std::runtime_error{"invalid type"}; + }; + + const auto delimiter_pos = signature.find(':'); + assert(delimiter_pos != std::string_view::npos); + const auto inputs = signature.substr(0, delimiter_pos); + const auto outputs = signature.substr(delimiter_pos + 1); + + std::vector input_types; + std::vector output_types; + std::transform( + std::begin(inputs), std::end(inputs), std::back_inserter(input_types), translate_valtype); + std::transform(std::begin(outputs), std::end(outputs), std::back_inserter(output_types), + translate_valtype); + return {std::move(input_types), std::move(output_types)}; +} + std::unique_ptr create_fizzy_engine(); std::unique_ptr create_fizzy_c_engine(); std::unique_ptr create_wabt_engine();