Skip to content

Commit

Permalink
capi: Add functions to access import definitions in module
Browse files Browse the repository at this point in the history
  • Loading branch information
gumb0 committed Jan 6, 2021
1 parent 76e7db1 commit 251f2cf
Show file tree
Hide file tree
Showing 3 changed files with 203 additions and 0 deletions.
42 changes: 42 additions & 0 deletions include/fizzy/fizzy.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,32 @@ typedef struct FizzyExternalGlobal
FizzyGlobalType type;
} FizzyExternalGlobal;

/// External kind.
typedef enum FizzyExternalKind
{
FizzyExternalKindFunction,
FizzyExternalKindTable,
FizzyExternalKindMemory,
FizzyExternalKindGlobal
} FizzyExternalKind;

/// Import definition.
///
/// @note Only one member of `desc` union corresponding to `kind` is defined for each import.
typedef struct FizzyImportType
{
const char* module;
const char* name;
FizzyExternalKind kind;
union
{
FizzyFunctionType function_type;
FizzyLimits memory_limits;
FizzyLimits table_limits;
FizzyGlobalType global_type;
} desc;
} FizzyImportType;

/// Imported function.
typedef struct FizzyImportedFunction
{
Expand Down Expand Up @@ -210,6 +236,22 @@ uint32_t fizzy_get_global_count(const FizzyModule* module);
/// @note All module global indices are greater than all imported global indices.
FizzyGlobalType fizzy_get_global_type(const FizzyModule* module, uint32_t global_idx);

/// Get number of imports defined in the module.
///
/// @param module Pointer to module. Cannot be NULL.
/// @return Number of imports in the module.
uint32_t fizzy_get_import_count(const FizzyModule* module);

/// Get the import type defined in the module.
///
/// @param module Pointer to module. Cannot be NULL.
/// @param import_idx Import index. Behaviour is undefined if index is not valid according
/// to module definition.
/// @return Type of the import corresponding to the index. `module` and `name` fields
/// point to the string stored inside the module and are valid as long as
/// module is alive.
FizzyImportType fizzy_get_import_type(const FizzyModule* module, uint32_t import_idx);

/// Find index of exported function by name.
///
/// @param module Pointer to module. Cannot be NULL.
Expand Down
40 changes: 40 additions & 0 deletions lib/fizzy/capi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,35 @@ inline std::vector<fizzy::ExternalGlobal> unwrap(
external_globals.begin(), unwrap_external_global_fn);
return external_globals;
}

inline FizzyExternalKind wrap(fizzy::ExternalKind kind) noexcept
{
return static_cast<FizzyExternalKind>(kind);
}

inline FizzyImportType wrap(const fizzy::Import& import, const fizzy::Module& module) noexcept
{
FizzyImportType c_import_type;
c_import_type.module = import.module.c_str();
c_import_type.name = import.name.c_str();
c_import_type.kind = wrap(import.kind);
switch (c_import_type.kind)
{
case FizzyExternalKindFunction:
c_import_type.desc.function_type = wrap(module.typesec[import.desc.function_type_index]);
break;
case FizzyExternalKindTable:
c_import_type.desc.table_limits = wrap(import.desc.table.limits);
break;
case FizzyExternalKindMemory:
c_import_type.desc.memory_limits = wrap(import.desc.memory.limits);
break;
case FizzyExternalKindGlobal:
c_import_type.desc.global_type = wrap(import.desc.global);
break;
}
return c_import_type;
}
} // namespace

extern "C" {
Expand Down Expand Up @@ -354,6 +383,17 @@ FizzyGlobalType fizzy_get_global_type(const FizzyModule* module, uint32_t global
return wrap(unwrap(module)->get_global_type(global_idx));
}

uint32_t fizzy_get_import_count(const FizzyModule* module)
{
return static_cast<uint32_t>(unwrap(module)->importsec.size());
}

FizzyImportType fizzy_get_import_type(const FizzyModule* c_module, uint32_t import_idx)
{
const auto* module = unwrap(c_module);
return wrap(module->importsec[import_idx], *module);
}

bool fizzy_find_exported_function_index(
const FizzyModule* module, const char* name, uint32_t* out_func_idx)
{
Expand Down
121 changes: 121 additions & 0 deletions test/unittests/capi_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1185,3 +1185,124 @@ TEST(capi, get_global_type)

fizzy_free_module(module_imports);
}

TEST(capi, get_import_count)
{
/* wat2wasm
(module)
*/
const auto wasm_empty = from_hex("0061736d01000000");

const auto* module_empty = fizzy_parse(wasm_empty.data(), wasm_empty.size());
ASSERT_NE(module_empty, nullptr);

EXPECT_EQ(fizzy_get_import_count(module_empty), 0);
fizzy_free_module(module_empty);

/* wat2wasm
(func (import "m" "f") (result i32))
(global (import "m" "g") i32)
(table (import "m" "t") 0 anyfunc)
(memory (import "m" "m") 1)
*/
const auto wasm = from_hex(
"0061736d010000000105016000017f021d04016d01660000016d0167037f00016d017401700000016d016d0200"
"01");

const auto* module = fizzy_parse(wasm.data(), wasm.size());
ASSERT_NE(module, nullptr);

EXPECT_EQ(fizzy_get_import_count(module), 4);
fizzy_free_module(module);
}

TEST(capi, get_import_type)
{
/* wat2wasm
(func (import "m" "f1") (result i32))
(func (import "m" "f2") (param i64))
(global (import "m" "g1") i32)
(global (import "m" "g2") (mut f64))
(table (import "m" "t") 10 anyfunc)
(memory (import "m" "mem") 1 4)
*/
const auto wasm = from_hex(
"0061736d010000000109026000017f60017e00023106016d0266310000016d0266320001016d026731037f0001"
"6d026732037c01016d01740170000a016d036d656d02010104");

const auto* module = fizzy_parse(wasm.data(), wasm.size());
ASSERT_NE(module, nullptr);
ASSERT_EQ(fizzy_get_import_count(module), 6);

const auto import0 = fizzy_get_import_type(module, 0);
EXPECT_STREQ(import0.module, "m");
EXPECT_STREQ(import0.name, "f1");
EXPECT_EQ(import0.kind, FizzyExternalKindFunction);
EXPECT_EQ(import0.desc.function_type.inputs_size, 0);
EXPECT_EQ(import0.desc.function_type.output, FizzyValueTypeI32);

const auto import1 = fizzy_get_import_type(module, 1);
EXPECT_STREQ(import1.module, "m");
EXPECT_STREQ(import1.name, "f2");
EXPECT_EQ(import1.kind, FizzyExternalKindFunction);
ASSERT_EQ(import1.desc.function_type.inputs_size, 1);
EXPECT_EQ(import1.desc.function_type.inputs[0], FizzyValueTypeI64);
EXPECT_EQ(import1.desc.function_type.output, FizzyValueTypeVoid);

const auto import2 = fizzy_get_import_type(module, 2);
EXPECT_STREQ(import2.module, "m");
EXPECT_STREQ(import2.name, "g1");
EXPECT_EQ(import2.kind, FizzyExternalKindGlobal);
EXPECT_EQ(import2.desc.global_type.value_type, FizzyValueTypeI32);
EXPECT_FALSE(import2.desc.global_type.is_mutable);

const auto import3 = fizzy_get_import_type(module, 3);
EXPECT_STREQ(import3.module, "m");
EXPECT_STREQ(import3.name, "g2");
EXPECT_EQ(import3.kind, FizzyExternalKindGlobal);
EXPECT_EQ(import3.desc.global_type.value_type, FizzyValueTypeF64);
EXPECT_TRUE(import3.desc.global_type.is_mutable);

const auto import4 = fizzy_get_import_type(module, 4);
EXPECT_STREQ(import4.module, "m");
EXPECT_STREQ(import4.name, "t");
EXPECT_EQ(import4.kind, FizzyExternalKindTable);
EXPECT_EQ(import4.desc.table_limits.min, 10);
EXPECT_FALSE(import4.desc.table_limits.has_max);

const auto import5 = fizzy_get_import_type(module, 5);
EXPECT_STREQ(import5.module, "m");
EXPECT_STREQ(import5.name, "mem");
EXPECT_EQ(import5.kind, FizzyExternalKindMemory);
EXPECT_EQ(import5.desc.memory_limits.min, 1);
EXPECT_TRUE(import5.desc.memory_limits.has_max);
EXPECT_EQ(import5.desc.memory_limits.max, 4);

fizzy_free_module(module);
}

TEST(capi, import_name_after_instantiate)
{
/* wat2wasm
(func (import "m" "f1") (result i32))
*/
const auto wasm = from_hex("0061736d010000000105016000017f020801016d0266310000");

const auto* module = fizzy_parse(wasm.data(), wasm.size());
ASSERT_NE(module, nullptr);
ASSERT_EQ(fizzy_get_import_count(module), 1);

const auto import0 = fizzy_get_import_type(module, 0);
EXPECT_STREQ(import0.module, "m");
EXPECT_STREQ(import0.name, "f1");

FizzyExternalFunction host_funcs[] = {{{FizzyValueTypeI32, nullptr, 0}, NullFn, nullptr}};

auto instance = fizzy_instantiate(module, host_funcs, 1, nullptr, nullptr, nullptr, 0);
EXPECT_NE(instance, nullptr);

EXPECT_STREQ(import0.module, "m");
EXPECT_STREQ(import0.name, "f1");

fizzy_free_instance(instance);
}

0 comments on commit 251f2cf

Please sign in to comment.