From d046b250748e594c40e8803fecac3e684524d7b7 Mon Sep 17 00:00:00 2001 From: Andrei Maiboroda Date: Mon, 4 Jan 2021 18:02:51 +0100 Subject: [PATCH 1/2] capi: Add function to get type by index --- include/fizzy/fizzy.h | 14 ++++ lib/fizzy/capi.cpp | 10 +++ test/unittests/capi_test.cpp | 125 +++++++++++++++++++++++++++++++++++ 3 files changed, 149 insertions(+) diff --git a/include/fizzy/fizzy.h b/include/fizzy/fizzy.h index 81b98dcac..284dc5f6d 100644 --- a/include/fizzy/fizzy.h +++ b/include/fizzy/fizzy.h @@ -169,6 +169,20 @@ void fizzy_free_module(const FizzyModule* module); /// @note Input module is not modified neither in success nor in failure case. const FizzyModule* fizzy_clone_module(const FizzyModule* module); +/// Get number of types defined in the module. +/// +/// @param module Pointer to module. Cannot be NULL. +/// @return Number of type in the module. +uint32_t fizzy_get_type_count(const FizzyModule* module); + +/// Get type defined in the module. +/// +/// @param module Pointer to module. Cannot be NULL. +/// @param type_idx Type index. Behaviour is undefined if index is not valid according +/// to module definition. +/// @return Type corresponding to the index. +FizzyFunctionType fizzy_get_type(const FizzyModule* module, uint32_t type_idx); + /// Get type of the function defined in the module. /// /// @param module Pointer to module. Cannot be NULL. diff --git a/lib/fizzy/capi.cpp b/lib/fizzy/capi.cpp index 268231303..195558b6c 100644 --- a/lib/fizzy/capi.cpp +++ b/lib/fizzy/capi.cpp @@ -329,6 +329,16 @@ const FizzyModule* fizzy_clone_module(const FizzyModule* module) } } +uint32_t fizzy_get_type_count(const FizzyModule* module) +{ + return static_cast(unwrap(module)->typesec.size()); +} + +FizzyFunctionType fizzy_get_type(const FizzyModule* module, uint32_t type_idx) +{ + return wrap(unwrap(module)->typesec[type_idx]); +} + FizzyFunctionType fizzy_get_function_type(const FizzyModule* module, uint32_t func_idx) { return wrap(unwrap(module)->get_function_type(func_idx)); diff --git a/test/unittests/capi_test.cpp b/test/unittests/capi_test.cpp index 9082c5075..258010a5b 100644 --- a/test/unittests/capi_test.cpp +++ b/test/unittests/capi_test.cpp @@ -1069,3 +1069,128 @@ TEST(capi, imported_global_from_another_module) fizzy_free_instance(instance2); fizzy_free_instance(instance1); } + +TEST(capi, get_type_count) +{ + /* wat2wasm + (module) + */ + const auto wasm = from_hex("0061736d01000000"); + + const auto* module_empty = fizzy_parse(wasm.data(), wasm.size()); + ASSERT_NE(module_empty, nullptr); + + EXPECT_EQ(fizzy_get_type_count(module_empty), 0); + fizzy_free_module(module_empty); + + /* wat2wasm + (func) + */ + const auto wasm_one_func = from_hex("0061736d01000000010401600000030201000a040102000b"); + + const auto* module_one_func = fizzy_parse(wasm_one_func.data(), wasm_one_func.size()); + ASSERT_NE(module_one_func, nullptr); + + EXPECT_EQ(fizzy_get_type_count(module_one_func), 1); + fizzy_free_module(module_one_func); + + /* wat2wasm + (type (func (param i32))) + (type (func (param i32) (result i32))) + (type (func (result i32))) + (func (type 0)) + (func (type 1) (return (i32.const 0))) + (func (type 1) (return (i32.const 0))) + (func (type 2) (return (i32.const 0))) + */ + const auto wasm_three_types = from_hex( + "0061736d01000000010e0360017f0060017f017f6000017f030504000101020a160402000b050041000f0b0500" + "41000f0b050041000f0b"); + + const auto* module_three_types = fizzy_parse(wasm_three_types.data(), wasm_three_types.size()); + ASSERT_NE(module_three_types, nullptr); + + EXPECT_EQ(fizzy_get_type_count(module_three_types), 3); + fizzy_free_module(module_three_types); +} + +TEST(capi, get_type) +{ + /* wat2wasm + (func) + */ + const auto wasm_one_func = from_hex("0061736d01000000010401600000030201000a040102000b"); + + const auto* module_one_func = fizzy_parse(wasm_one_func.data(), wasm_one_func.size()); + ASSERT_NE(module_one_func, nullptr); + ASSERT_EQ(fizzy_get_type_count(module_one_func), 1); + + const auto type_one_func = fizzy_get_type(module_one_func, 0); + EXPECT_EQ(type_one_func.inputs_size, 0); + EXPECT_EQ(type_one_func.output, FizzyValueTypeVoid); + fizzy_free_module(module_one_func); + + /* wat2wasm + (type (func)) + (type (func (param i32))) + (type (func (param i32) (result i32))) + (type (func (result i32))) + (func (type 0)) + (func (type 1)) + (func (type 2) (return (i32.const 0))) + (func (type 2) (return (i32.const 0))) + (func (type 3) (return (i32.const 0))) + */ + const auto wasm_three_types = from_hex( + "0061736d0100000001110460000060017f0060017f017f6000017f03060500010202030a190502000b02000b05" + "0041000f0b050041000f0b050041000f0b"); + + const auto* module_three_types = fizzy_parse(wasm_three_types.data(), wasm_three_types.size()); + ASSERT_NE(module_three_types, nullptr); + ASSERT_EQ(fizzy_get_type_count(module_three_types), 4); + + const auto type0 = fizzy_get_type(module_three_types, 0); + ASSERT_EQ(type0.inputs_size, 0); + EXPECT_EQ(type0.output, FizzyValueTypeVoid); + + const auto type1 = fizzy_get_type(module_three_types, 1); + ASSERT_EQ(type1.inputs_size, 1); + EXPECT_EQ(type1.inputs[0], FizzyValueTypeI32); + EXPECT_EQ(type1.output, FizzyValueTypeVoid); + + const auto type2 = fizzy_get_type(module_three_types, 2); + ASSERT_EQ(type2.inputs_size, 1); + EXPECT_EQ(type2.inputs[0], FizzyValueTypeI32); + EXPECT_EQ(type2.output, FizzyValueTypeI32); + + const auto type3 = fizzy_get_type(module_three_types, 3); + EXPECT_EQ(type3.inputs_size, 0); + EXPECT_EQ(type3.output, FizzyValueTypeI32); + + fizzy_free_module(module_three_types); + + /* wat2wasm + (func (import "mod" "f") (param i64 i64)) + (func (param i32)) + */ + const auto wasm_imported_func = from_hex( + "0061736d01000000010a0260027e7e0060017f00020901036d6f6401660000030201010a040102000b"); + + const auto* module_imported_func = + fizzy_parse(wasm_imported_func.data(), wasm_imported_func.size()); + ASSERT_NE(module_imported_func, nullptr); + ASSERT_EQ(fizzy_get_type_count(module_imported_func), 2); + + const auto type_imported = fizzy_get_type(module_imported_func, 0); + ASSERT_EQ(type_imported.inputs_size, 2); + EXPECT_EQ(type_imported.inputs[0], FizzyValueTypeI64); + EXPECT_EQ(type_imported.inputs[1], FizzyValueTypeI64); + EXPECT_EQ(type_imported.output, FizzyValueTypeVoid); + + const auto type_local = fizzy_get_type(module_imported_func, 1); + ASSERT_EQ(type_local.inputs_size, 1); + EXPECT_EQ(type_local.inputs[0], FizzyValueTypeI32); + EXPECT_EQ(type_local.output, FizzyValueTypeVoid); + + fizzy_free_module(module_imported_func); +} From 8f7ff1564ca82835575d7b339f853a877dc0d96f Mon Sep 17 00:00:00 2001 From: Andrei Maiboroda Date: Mon, 4 Jan 2021 18:15:22 +0100 Subject: [PATCH 2/2] capi: Add function to get global type by index --- include/fizzy/fizzy.h | 17 +++++++ lib/fizzy/capi.cpp | 10 ++++ test/unittests/capi_test.cpp | 91 ++++++++++++++++++++++++++++++++++++ 3 files changed, 118 insertions(+) diff --git a/include/fizzy/fizzy.h b/include/fizzy/fizzy.h index 284dc5f6d..d7342021b 100644 --- a/include/fizzy/fizzy.h +++ b/include/fizzy/fizzy.h @@ -205,6 +205,23 @@ bool fizzy_module_has_table(const FizzyModule* module); /// @return true if module has a memory definition, false otherwise. bool fizzy_module_has_memory(const FizzyModule* module); +/// Get number of globals defined in the module. +/// +/// @param module Pointer to module. Cannot be NULL. +/// @return Number of globals in the module. +uint32_t fizzy_get_global_count(const FizzyModule* module); + +/// Get type of a given global defined in the module. +/// +/// @param module Pointer to module. Cannot be NULL. +/// @param global_idx Global index. Can be either index of an imported global or of a global +/// defined in module. Behaviour is undefined if index is not valid according +/// to module definition. +/// @return Type of the global corresponding to the index. +/// +/// @note All module global indices are greater than all imported global indices. +FizzyGlobalType fizzy_get_global_type(const FizzyModule* module, uint32_t global_idx); + /// Find index of exported function by name. /// /// @param module Pointer to module. Cannot be NULL. diff --git a/lib/fizzy/capi.cpp b/lib/fizzy/capi.cpp index 195558b6c..6caf11bb8 100644 --- a/lib/fizzy/capi.cpp +++ b/lib/fizzy/capi.cpp @@ -354,6 +354,16 @@ bool fizzy_module_has_memory(const FizzyModule* module) return unwrap(module)->has_memory(); } +uint32_t fizzy_get_global_count(const FizzyModule* module) +{ + return static_cast(unwrap(module)->get_global_count()); +} + +FizzyGlobalType fizzy_get_global_type(const FizzyModule* module, uint32_t global_idx) +{ + return wrap(unwrap(module)->get_global_type(global_idx)); +} + bool fizzy_find_exported_function_index( const FizzyModule* module, const char* name, uint32_t* out_func_idx) { diff --git a/test/unittests/capi_test.cpp b/test/unittests/capi_test.cpp index 258010a5b..c26e5cf49 100644 --- a/test/unittests/capi_test.cpp +++ b/test/unittests/capi_test.cpp @@ -1194,3 +1194,94 @@ TEST(capi, get_type) fizzy_free_module(module_imported_func); } + +TEST(capi, get_global_count) +{ + /* wat2wasm + (module) + */ + const auto wasm = from_hex("0061736d01000000"); + + const auto* module_empty = fizzy_parse(wasm.data(), wasm.size()); + ASSERT_NE(module_empty, nullptr); + + EXPECT_EQ(fizzy_get_global_count(module_empty), 0); + fizzy_free_module(module_empty); + + /* wat2wasm + (global i32 (i32.const 0)) + */ + const auto wasm_one_global = from_hex("0061736d010000000606017f0041000b"); + + const auto* module_one_global = fizzy_parse(wasm_one_global.data(), wasm_one_global.size()); + ASSERT_NE(module_one_global, nullptr); + + EXPECT_EQ(fizzy_get_global_count(module_one_global), 1); + fizzy_free_module(module_one_global); + + /* wat2wasm + (global (import "mod" "g") i32) + (global i32 (i32.const 0)) + */ + const auto wasm_imported_global = + from_hex("0061736d01000000020a01036d6f640167037f000606017f0041000b"); + + const auto* module_imported_global = + fizzy_parse(wasm_imported_global.data(), wasm_imported_global.size()); + ASSERT_NE(module_imported_global, nullptr); + + EXPECT_EQ(fizzy_get_global_count(module_imported_global), 2); + fizzy_free_module(module_imported_global); +} + +TEST(capi, get_global_type) +{ + /* wat2wasm + (global i32 (i32.const 0)) + (global (mut i64) (i64.const 0)) + (global f32 (f32.const 0)) + (global (mut f64) (f64.const 0)) + */ + const auto wasm = from_hex( + "0061736d01000000061f047f0041000b7e0142000b7d0043000000000b7c014400000000000000000b"); + + const auto* module = fizzy_parse(wasm.data(), wasm.size()); + ASSERT_NE(module, nullptr); + ASSERT_EQ(fizzy_get_global_count(module), 4); + + EXPECT_EQ(fizzy_get_global_type(module, 0).value_type, FizzyValueTypeI32); + EXPECT_EQ(fizzy_get_global_type(module, 0).is_mutable, false); + EXPECT_EQ(fizzy_get_global_type(module, 1).value_type, FizzyValueTypeI64); + EXPECT_EQ(fizzy_get_global_type(module, 1).is_mutable, true); + EXPECT_EQ(fizzy_get_global_type(module, 2).value_type, FizzyValueTypeF32); + EXPECT_EQ(fizzy_get_global_type(module, 2).is_mutable, false); + EXPECT_EQ(fizzy_get_global_type(module, 3).value_type, FizzyValueTypeF64); + EXPECT_EQ(fizzy_get_global_type(module, 3).is_mutable, true); + + fizzy_free_module(module); + + /* wat2wasm + (global (import "mod" "g1") i32) + (global (import "mod" "g2") (mut i64)) + (global (import "mod" "g3") f32) + (global (import "mod" "g4") (mut f64)) + */ + const auto wasm_imports = from_hex( + "0061736d01000000022904036d6f64026731037f00036d6f64026732037e01036d6f64026733037d00036d6f64" + "026734037c01"); + + const auto* module_imports = fizzy_parse(wasm_imports.data(), wasm_imports.size()); + ASSERT_NE(module_imports, nullptr); + ASSERT_EQ(fizzy_get_global_count(module_imports), 4); + + EXPECT_EQ(fizzy_get_global_type(module_imports, 0).value_type, FizzyValueTypeI32); + EXPECT_EQ(fizzy_get_global_type(module_imports, 0).is_mutable, false); + EXPECT_EQ(fizzy_get_global_type(module_imports, 1).value_type, FizzyValueTypeI64); + EXPECT_EQ(fizzy_get_global_type(module_imports, 1).is_mutable, true); + EXPECT_EQ(fizzy_get_global_type(module_imports, 2).value_type, FizzyValueTypeF32); + EXPECT_EQ(fizzy_get_global_type(module_imports, 2).is_mutable, false); + EXPECT_EQ(fizzy_get_global_type(module_imports, 3).value_type, FizzyValueTypeF64); + EXPECT_EQ(fizzy_get_global_type(module_imports, 3).is_mutable, true); + + fizzy_free_module(module_imports); +}