Stream: git-wasmtime

Topic: wasmtime / Issue #2211 Linker does not properly define im...


view this post on Zulip Wasmtime GitHub notifications bot (Sep 20 2020 at 07:35):

7Hazard labeled Issue #2211:

Using the C API, defining imports with the Linker do not work properly. When attempting to instantiate the module in question, it errors with the following:
unknown import: `env::Test` has not been defined

This is how the module is attempted to be instantiated:

wasm_trap_t* trap = nullptr;
wasm_instance_t* instance = nullptr;

wasm_engine_t* engine = wasm_engine_new();
wasm_store_t* store = wasm_store_new(engine);
wasmtime_linker_t* linker = wasmtime_linker_new(store);

// Read wasm file
wasm_byte_vec_t wasm;
std::ifstream file("wasmtest.wasm", std::ios::binary | std::ios::ate);
if(!file.good()) {
    std::cout << "File wasmtest.wasm bad" << std::endl;
    return 1;
}
auto filesize = file.tellg();
file.seekg(0, std::ios::beg);
wasm_byte_vec_new_uninitialized(&wasm, filesize);
if(!file.read(wasm.data, filesize))
{
    std::cout << "Could not read file" << std::endl;
    return 1;
}

// Compile module
wasm_module_t* module = nullptr;
error = wasmtime_module_new(engine, &wasm, &module);
if (error != nullptr)
{
    logWasmError("Failed to compile module", error, nullptr);
    return 1;
}
wasm_byte_vec_delete(&wasm);

// MAKE IMPORTS
{
    auto import = [](const wasm_val_t args[], wasm_val_t results[])->wasm_trap_t*{
        printf("Hello world");
        return nullptr;
    };
    wasm_valtype_vec_t types;
    wasm_valtype_vec_new_uninitialized(&types, 0);
    wasm_functype_t *type = wasm_functype_new(&types, &types);
    auto function = wasm_func_new(store, type, import);
    auto extern_ = wasm_func_as_extern(function);

    wasm_name_t module;
    wasm_name_new_from_string(&module, "env");
    wasm_name_t func;
    wasm_name_new_from_string(&func, "Test");
    wasmtime_linker_define(linker, &module, &func, extern_);
    wasm_name_delete(&func);
}

// INSTANTIATE MODULE
error = wasmtime_linker_instantiate(linker, module, &instance, &trap);
if (error || trap)
{
    logWasmError("Failed to instantiate module", error, trap);
    return 1;
}

This is the module that is being attempted to be loaded (compiled with clang):

extern "C" void Test();

extern "C" void main() {
    Test();
}

The imports in the wat looks like this:

(type $t0 (func))
(type $t1 (func (param i32) (result i32)))
(import "env" "Test" (func $Test (type $t0)))

This was tested on Windows 10, using the C API build from https://github.com/bytecodealliance/wasmtime/releases/tag/v0.19.0.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 20 2020 at 07:35):

7Hazard opened Issue #2211:

Using the C API, defining imports with the Linker do not work properly. When attempting to instantiate the module in question, it errors with the following:
unknown import: `env::Test` has not been defined

This is how the module is attempted to be instantiated:

wasm_trap_t* trap = nullptr;
wasm_instance_t* instance = nullptr;

wasm_engine_t* engine = wasm_engine_new();
wasm_store_t* store = wasm_store_new(engine);
wasmtime_linker_t* linker = wasmtime_linker_new(store);

// Read wasm file
wasm_byte_vec_t wasm;
std::ifstream file("wasmtest.wasm", std::ios::binary | std::ios::ate);
if(!file.good()) {
    std::cout << "File wasmtest.wasm bad" << std::endl;
    return 1;
}
auto filesize = file.tellg();
file.seekg(0, std::ios::beg);
wasm_byte_vec_new_uninitialized(&wasm, filesize);
if(!file.read(wasm.data, filesize))
{
    std::cout << "Could not read file" << std::endl;
    return 1;
}

// Compile module
wasm_module_t* module = nullptr;
error = wasmtime_module_new(engine, &wasm, &module);
if (error != nullptr)
{
    logWasmError("Failed to compile module", error, nullptr);
    return 1;
}
wasm_byte_vec_delete(&wasm);

// MAKE IMPORTS
{
    auto import = [](const wasm_val_t args[], wasm_val_t results[])->wasm_trap_t*{
        printf("Hello world");
        return nullptr;
    };
    wasm_valtype_vec_t types;
    wasm_valtype_vec_new_uninitialized(&types, 0);
    wasm_functype_t *type = wasm_functype_new(&types, &types);
    auto function = wasm_func_new(store, type, import);
    auto extern_ = wasm_func_as_extern(function);

    wasm_name_t module;
    wasm_name_new_from_string(&module, "env");
    wasm_name_t func;
    wasm_name_new_from_string(&func, "Test");
    wasmtime_linker_define(linker, &module, &func, extern_);
    wasm_name_delete(&func);
}

// INSTANTIATE MODULE
error = wasmtime_linker_instantiate(linker, module, &instance, &trap);
if (error || trap)
{
    logWasmError("Failed to instantiate module", error, trap);
    return 1;
}

This is the module that is being attempted to be loaded (compiled with clang):

extern "C" void Test();

extern "C" void main() {
    Test();
}

The imports in the wat looks like this:

(type $t0 (func))
(type $t1 (func (param i32) (result i32)))
(import "env" "Test" (func $Test (type $t0)))

This was tested on Windows 10, using the C API build from https://github.com/bytecodealliance/wasmtime/releases/tag/v0.19.0.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 20 2020 at 07:35):

7Hazard edited Issue #2211:

Using the C API, defining imports with the Linker do not work properly. When attempting to instantiate the module in question, it errors with the following:
unknown import: `env::Test` has not been defined

This is how the module is attempted to be instantiated:

wasm_trap_t* trap = nullptr;
wasm_instance_t* instance = nullptr;

wasm_engine_t* engine = wasm_engine_new();
wasm_store_t* store = wasm_store_new(engine);
wasmtime_linker_t* linker = wasmtime_linker_new(store);

// Read wasm file
wasm_byte_vec_t wasm;
std::ifstream file("wasmtest.wasm", std::ios::binary | std::ios::ate);
if(!file.good()) {
    std::cout << "File wasmtest.wasm bad" << std::endl;
    return 1;
}
auto filesize = file.tellg();
file.seekg(0, std::ios::beg);
wasm_byte_vec_new_uninitialized(&wasm, filesize);
if(!file.read(wasm.data, filesize))
{
    std::cout << "Could not read file" << std::endl;
    return 1;
}

// Compile module
wasm_module_t* module = nullptr;
error = wasmtime_module_new(engine, &wasm, &module);
if (error != nullptr)
{
    logWasmError("Failed to compile module", error, nullptr);
    return 1;
}
wasm_byte_vec_delete(&wasm);

// MAKE IMPORTS
{
    auto import = [](const wasm_val_t args[], wasm_val_t results[])->wasm_trap_t*{
        printf("Hello world");
        return nullptr;
    };
    wasm_valtype_vec_t types;
    wasm_valtype_vec_new_uninitialized(&types, 0);
    wasm_functype_t *type = wasm_functype_new(&types, &types);
    auto function = wasm_func_new(store, type, import);
    auto extern_ = wasm_func_as_extern(function);

    wasm_name_t module;
    wasm_name_new_from_string(&module, "env");
    wasm_name_t func;
    wasm_name_new_from_string(&func, "Test");
    wasmtime_linker_define(linker, &module, &func, extern_);
    wasm_name_delete(&func);
}

// INSTANTIATE MODULE
error = wasmtime_linker_instantiate(linker, module, &instance, &trap);
if (error || trap)
{
    logWasmError("Failed to instantiate module", error, trap);
    return 1;
}

This is the module that is being attempted to be loaded (compiled with clang):

extern "C" void Test();

extern "C" void main() {
    Test();
}

The imports in the wat looks like this:

(type $t0 (func))
(import "env" "Test" (func $Test (type $t0)))

This was tested on Windows 10, using the C API build from https://github.com/bytecodealliance/wasmtime/releases/tag/v0.19.0.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 22 2020 at 17:31):

alexcrichton commented on Issue #2211:

Thanks for the report! The issue here is somewhat subtle and unfortunate. The wasm_name_new_from_string function will have the length of the name including the terminating nul character, but the wasmtime_linker_define API does not expect the nul character to be included, so the name you're defining is actually ("env\u{0}", "Test\u{0}"), which isn't what you want here.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 22 2020 at 21:33):

7Hazard commented on Issue #2211:

I see, indeed it was very subtle. However wouldn't this be a defect for wasm_name_new_from_string as an API function? I'm not sure if there are other purposes for wasm_name_new_from_string and wasm_name_t.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 25 2020 at 00:29):

alexcrichton commented on Issue #2211:

I believe the upstream API was adjusted in https://github.com/WebAssembly/wasm-c-api/pull/151, and we haven't pulled in that update yet.

view this post on Zulip Wasmtime GitHub notifications bot (Jan 12 2021 at 19:42):

Dakror commented on Issue #2211:

Could this be addressed? The fix of pulling upstream should be trivial, no?

view this post on Zulip Wasmtime GitHub notifications bot (Jan 13 2021 at 04:06):

peterhuene assigned Issue #2211:

Using the C API, defining imports with the Linker do not work properly. When attempting to instantiate the module in question, it errors with the following:
unknown import: `env::Test` has not been defined

This is how the module is attempted to be instantiated:

wasm_trap_t* trap = nullptr;
wasm_instance_t* instance = nullptr;

wasm_engine_t* engine = wasm_engine_new();
wasm_store_t* store = wasm_store_new(engine);
wasmtime_linker_t* linker = wasmtime_linker_new(store);

// Read wasm file
wasm_byte_vec_t wasm;
std::ifstream file("wasmtest.wasm", std::ios::binary | std::ios::ate);
if(!file.good()) {
    std::cout << "File wasmtest.wasm bad" << std::endl;
    return 1;
}
auto filesize = file.tellg();
file.seekg(0, std::ios::beg);
wasm_byte_vec_new_uninitialized(&wasm, filesize);
if(!file.read(wasm.data, filesize))
{
    std::cout << "Could not read file" << std::endl;
    return 1;
}

// Compile module
wasm_module_t* module = nullptr;
error = wasmtime_module_new(engine, &wasm, &module);
if (error != nullptr)
{
    logWasmError("Failed to compile module", error, nullptr);
    return 1;
}
wasm_byte_vec_delete(&wasm);

// MAKE IMPORTS
{
    auto import = [](const wasm_val_t args[], wasm_val_t results[])->wasm_trap_t*{
        printf("Hello world");
        return nullptr;
    };
    wasm_valtype_vec_t types;
    wasm_valtype_vec_new_uninitialized(&types, 0);
    wasm_functype_t *type = wasm_functype_new(&types, &types);
    auto function = wasm_func_new(store, type, import);
    auto extern_ = wasm_func_as_extern(function);

    wasm_name_t module;
    wasm_name_new_from_string(&module, "env");
    wasm_name_t func;
    wasm_name_new_from_string(&func, "Test");
    wasmtime_linker_define(linker, &module, &func, extern_);
    wasm_name_delete(&func);
}

// INSTANTIATE MODULE
error = wasmtime_linker_instantiate(linker, module, &instance, &trap);
if (error || trap)
{
    logWasmError("Failed to instantiate module", error, trap);
    return 1;
}

This is the module that is being attempted to be loaded (compiled with clang):

extern "C" void Test();

extern "C" void main() {
    Test();
}

The imports in the wat looks like this:

(type $t0 (func))
(import "env" "Test" (func $Test (type $t0)))

This was tested on Windows 10, using the C API build from https://github.com/bytecodealliance/wasmtime/releases/tag/v0.19.0.

view this post on Zulip Wasmtime GitHub notifications bot (Jan 13 2021 at 04:07):

peterhuene commented on Issue #2211:

We should be able to update the Wasmtime C API to fix this now. I'll try to get a fix up tomorrow.

You should be able to work around the issue using wasm_name_new with the current implementation, if needed.

view this post on Zulip Wasmtime GitHub notifications bot (Jan 14 2021 at 15:36):

alexcrichton closed Issue #2211 (assigned to peterhuene):

Using the C API, defining imports with the Linker do not work properly. When attempting to instantiate the module in question, it errors with the following:
unknown import: `env::Test` has not been defined

This is how the module is attempted to be instantiated:

wasm_trap_t* trap = nullptr;
wasm_instance_t* instance = nullptr;

wasm_engine_t* engine = wasm_engine_new();
wasm_store_t* store = wasm_store_new(engine);
wasmtime_linker_t* linker = wasmtime_linker_new(store);

// Read wasm file
wasm_byte_vec_t wasm;
std::ifstream file("wasmtest.wasm", std::ios::binary | std::ios::ate);
if(!file.good()) {
    std::cout << "File wasmtest.wasm bad" << std::endl;
    return 1;
}
auto filesize = file.tellg();
file.seekg(0, std::ios::beg);
wasm_byte_vec_new_uninitialized(&wasm, filesize);
if(!file.read(wasm.data, filesize))
{
    std::cout << "Could not read file" << std::endl;
    return 1;
}

// Compile module
wasm_module_t* module = nullptr;
error = wasmtime_module_new(engine, &wasm, &module);
if (error != nullptr)
{
    logWasmError("Failed to compile module", error, nullptr);
    return 1;
}
wasm_byte_vec_delete(&wasm);

// MAKE IMPORTS
{
    auto import = [](const wasm_val_t args[], wasm_val_t results[])->wasm_trap_t*{
        printf("Hello world");
        return nullptr;
    };
    wasm_valtype_vec_t types;
    wasm_valtype_vec_new_uninitialized(&types, 0);
    wasm_functype_t *type = wasm_functype_new(&types, &types);
    auto function = wasm_func_new(store, type, import);
    auto extern_ = wasm_func_as_extern(function);

    wasm_name_t module;
    wasm_name_new_from_string(&module, "env");
    wasm_name_t func;
    wasm_name_new_from_string(&func, "Test");
    wasmtime_linker_define(linker, &module, &func, extern_);
    wasm_name_delete(&func);
}

// INSTANTIATE MODULE
error = wasmtime_linker_instantiate(linker, module, &instance, &trap);
if (error || trap)
{
    logWasmError("Failed to instantiate module", error, trap);
    return 1;
}

This is the module that is being attempted to be loaded (compiled with clang):

extern "C" void Test();

extern "C" void main() {
    Test();
}

The imports in the wat looks like this:

(type $t0 (func))
(import "env" "Test" (func $Test (type $t0)))

This was tested on Windows 10, using the C API build from https://github.com/bytecodealliance/wasmtime/releases/tag/v0.19.0.


Last updated: Nov 22 2024 at 16:03 UTC