Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/actions/install-wasi-sdk/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,4 @@ runs:
- name: Setup `wasmtime`
uses: bytecodealliance/actions/wasmtime/setup@v1
with:
version: "48.0.1"
version: "dev"
2 changes: 1 addition & 1 deletion crates/test/src/c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ fn compile(runner: &Runner, compile: &Compile<'_>, compiler: PathBuf) -> Result<
runner.run_command(&mut cmd)?;

runner
.convert_p1_to_component(&output, compile)
.convert_core_module_to_component(&output, compile)
.with_context(|| format!("failed to convert {output:?}"))?;
Ok(())
}
Expand Down
8 changes: 7 additions & 1 deletion crates/test/src/cpp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ impl LanguageMethods for Cpp {

// Now compile the runner's source code to with the above object and the
// component-type object into a final component.
let output = compile.output.with_extension("core.wasm");
let mut cmd = Command::new(compiler);
cmd.arg(&compile.component.path)
.arg(&bindings_object)
Expand All @@ -170,12 +171,17 @@ impl LanguageMethods for Cpp {
.arg("-std=c++20")
.arg("-g")
.arg("-o")
.arg(&compile.output);
.arg(&output);
for flag in Vec::from(config.cflags) {
cmd.arg(flag);
}
cmd.arg("-mexec-model=reactor");
cmd.arg("-Wl,--skip-wit-component");
runner.run_command(&mut cmd)?;

runner
.convert_core_module_to_component(&output, compile)
.with_context(|| format!("failed to convert {output:?}"))?;
Ok(())
}

Expand Down
2 changes: 1 addition & 1 deletion crates/test/src/d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ fn compile(runner: &Runner, compile: &Compile<'_>, compiler: PathBuf) -> Result<
runner.run_command(&mut cmd)?;

runner
.convert_p1_to_component(&output, compile)
.convert_core_module_to_component(&output, compile)
.with_context(|| format!("failed to convert {output:?}"))?;

Ok(())
Expand Down
2 changes: 1 addition & 1 deletion crates/test/src/go.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ func main() {}
.arg("-ldflags=-checklinkname=0"),
)?;

runner.convert_p1_to_component(&output, compile)?;
runner.convert_core_module_to_component(&output, compile)?;

Ok(())
}
Expand Down
12 changes: 7 additions & 5 deletions crates/test/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1090,7 +1090,7 @@ status: {}",
/// Converts the list of dynamic libraries in `dylibs` into a component and places it
/// in the destination specified by `compile`.
///
/// This is similar to `convert_p1_to_component` except usese a
/// This is similar to `convert_core_module_to_component` except uses a
/// `wit_component::Linker` instead of a `wit_component::ComponentEncoder`.
fn link_dylibs_to_component(&self, dylibs: &[PathBuf], compile: &Compile<'_>) -> Result<()> {
let mut linker = wit_component::Linker::default();
Expand All @@ -1110,17 +1110,19 @@ status: {}",
Ok(())
}

/// Converts the WASIp1 module at `p1` to a component using the information
/// stored within `compile`.
/// Converts the core module at `path` (wasip1 or otherwise) to a component
/// using the information stored within `compile`. Can handle both wasip1
/// modules and modules built with components in mind (e.g. those built
/// with --skip-wit-component in wasm-component-ld).
///
/// Stores the output at `compile.output`.
fn convert_p1_to_component(&self, p1: &Path, compile: &Compile<'_>) -> Result<()> {
fn convert_core_module_to_component(&self, path: &Path, compile: &Compile<'_>) -> Result<()> {
let mut resolve = wit_parser::Resolve::default();
let (pkg, _) = resolve
.push_path(&compile.component.bindgen.wit_path)
.context("failed to load WIT")?;
let world = resolve.select_world(&[pkg], Some(&compile.component.bindgen.world))?;
let mut module = fs::read(&p1).context("failed to read wasm file")?;
let mut module = fs::read(&path).context("failed to read wasm file")?;

if !has_component_type_sections(&module) {
let encoded = wit_component::metadata::encode(
Expand Down
2 changes: 1 addition & 1 deletion crates/test/src/rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ path = 'lib.rs'
.with_context(|| format!("failed to link {output:?}"))?;
} else {
runner
.convert_p1_to_component(&output, compile)
.convert_core_module_to_component(&output, compile)
.with_context(|| format!("failed to convert {output:?}"))?;
}

Expand Down
2 changes: 1 addition & 1 deletion crates/test/src/wat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ impl LanguageMethods for Wat {

let p1 = compile.output.with_extension("core.wasm");
super::write_if_different(&p1, wasm)?;
runner.convert_p1_to_component(&p1, compile)?;
runner.convert_core_module_to_component(&p1, compile)?;
Ok(())
}

Expand Down
45 changes: 45 additions & 0 deletions tests/runtime/accessors/cpp/exports-test-accessors-i-Blob.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#pragma once
#include <cstdint>
#include <utility>
#include <expected>
#include <map>
#include <string> // Added
#include <vector> // Added
#include "wit.h"
/* User class definition file, autogenerated once, then user modified
* Updated versions of this file are generated into Blob.template.
*/
namespace exports {
namespace test {
namespace accessors {
namespace i {
class Blob : public wit::ResourceExportBase<Blob>{

public:

static void Dtor(i::Blob* self){delete self;}
Blob(wit::vector<uint8_t> init);
static Owned New(wit::vector<uint8_t> init){return Owned(new Blob(std::move(init)));}
wit::vector<uint8_t> Contents();
uint64_t Position();
void SetPosition(uint64_t value);
wit::string Label();
std::expected<void, wit::string> SetLabel(wit::string value);
static uint64_t MaxSize();
static std::expected<void, wit::string> SetMaxSize(uint64_t value);
static int32_t ResourceNew(i::Blob* self);
static Blob* ResourceRep(int32_t id);
static void ResourceDrop(int32_t id);

// Modifications to the template below this line
private:
std::vector<uint8_t> contents;
uint64_t position;
std::string label;
static uint64_t max_size;
};

}
}
}
}
91 changes: 91 additions & 0 deletions tests/runtime/accessors/runner.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
//@ wasmtime-flags = '-Wcomponent-model-accessors'

#include <assert.h>
#include <string.h>
#include <runner.h>

static void assert_str(runner_string_t *str, const char *expected) {
size_t expected_len = strlen(expected);
assert(str->len == expected_len);
assert(memcmp(str->ptr, expected, expected_len) == 0);
}

void exports_runner_run(void) {
runner_string_t str;
runner_string_t err;

assert(test_accessors_i_get_counter() == 0);
test_accessors_i_set_counter(5);
assert(test_accessors_i_get_counter() == 5);
test_accessors_i_set_counter(UINT32_MAX);
assert(test_accessors_i_get_counter() == UINT32_MAX);

test_accessors_i_get_read_only(&str);
assert_str(&str, "read only");
runner_string_free(&str);

assert(test_accessors_i_get_bounded() == 0);
assert(test_accessors_i_set_bounded(10, &err));
assert(test_accessors_i_get_bounded() == 10);
assert(!test_accessors_i_set_bounded(101, &err));
assert_str(&err, "101 is out of bounds");
runner_string_free(&err);
assert(test_accessors_i_get_bounded() == 10);

uint8_t a_init[] = {1, 2, 3};
uint8_t b_init[] = {4, 5};
runner_list_u8_t a_list = {a_init, 3};
runner_list_u8_t b_list = {b_init, 2};
test_accessors_i_own_blob_t a_own = test_accessors_i_constructor_blob(&a_list);
test_accessors_i_own_blob_t b_own = test_accessors_i_constructor_blob(&b_list);
test_accessors_i_borrow_blob_t a = test_accessors_i_borrow_blob(a_own);
test_accessors_i_borrow_blob_t b = test_accessors_i_borrow_blob(b_own);

runner_list_u8_t contents;
test_accessors_i_method_blob_contents(a, &contents);
assert(contents.len == 3);
assert(memcmp(contents.ptr, a_init, 3) == 0);
runner_list_u8_free(&contents);

assert(test_accessors_i_method_get_blob_position(a) == 0);
assert(test_accessors_i_method_get_blob_position(b) == 0);
test_accessors_i_method_set_blob_position(a, 2);
assert(test_accessors_i_method_get_blob_position(a) == 2);
assert(test_accessors_i_method_get_blob_position(b) == 0);
test_accessors_i_method_set_blob_position(b, 1);
assert(test_accessors_i_method_get_blob_position(a) == 2);
assert(test_accessors_i_method_get_blob_position(b) == 1);

test_accessors_i_method_get_blob_label(a, &str);
assert_str(&str, "");
runner_string_free(&str);

runner_string_t label;
runner_string_set(&label, "hello");
assert(test_accessors_i_method_set_blob_label(a, &label, &err));
test_accessors_i_method_get_blob_label(a, &str);
assert_str(&str, "hello");
runner_string_free(&str);
test_accessors_i_method_get_blob_label(b, &str);
assert_str(&str, "");
runner_string_free(&str);

runner_string_set(&label, "");
assert(!test_accessors_i_method_set_blob_label(a, &label, &err));
assert_str(&err, "label must not be empty");
runner_string_free(&err);
test_accessors_i_method_get_blob_label(a, &str);
assert_str(&str, "hello");
runner_string_free(&str);

assert(test_accessors_i_static_get_blob_max_size() == 1024);
assert(test_accessors_i_static_set_blob_max_size(2048, &err));
assert(test_accessors_i_static_get_blob_max_size() == 2048);
assert(!test_accessors_i_static_set_blob_max_size(0, &err));
assert_str(&err, "max size must be nonzero");
runner_string_free(&err);
assert(test_accessors_i_static_get_blob_max_size() == 2048);

test_accessors_i_blob_drop_own(a_own);
test_accessors_i_blob_drop_own(b_own);
}
60 changes: 60 additions & 0 deletions tests/runtime/accessors/runner.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
//@ wasmtime-flags = '-Wcomponent-model-accessors'

#include <assert.h>
#include <limits.h>
#include <vector>
#include <runner_cpp.h>

namespace test_imports = ::test::accessors::i;

static bool is_err(std::expected<void, wit::string> const& r, std::string_view msg) {
return !r.has_value() && r.error().get_view() == msg;
}

static bool equal(wit::vector<uint8_t> const& a, std::vector<uint8_t> const& b) {
auto view = a.get_const_view();
return std::vector<uint8_t>(view.begin(), view.end()) == b;
}

void exports::runner::Run() {
assert(test_imports::Counter() == 0);
test_imports::SetCounter(5);
assert(test_imports::Counter() == 5);
test_imports::SetCounter(UINT32_MAX);
assert(test_imports::Counter() == UINT32_MAX);

assert(test_imports::ReadOnly().get_view() == "read only");

assert(test_imports::Bounded() == 0);
assert(test_imports::SetBounded(10).has_value());
assert(test_imports::Bounded() == 10);
assert(is_err(test_imports::SetBounded(101), "101 is out of bounds"));
assert(test_imports::Bounded() == 10);

std::vector<uint8_t> a_init{1, 2, 3};
std::vector<uint8_t> b_init{4, 5};
auto a = test_imports::Blob(std::span<const uint8_t>(a_init));
auto b = test_imports::Blob(std::span<const uint8_t>(b_init));
assert(equal(a.Contents(), a_init));
assert(a.Position() == 0);
assert(b.Position() == 0);
a.SetPosition(2);
assert(a.Position() == 2);
assert(b.Position() == 0);
b.SetPosition(1);
assert(a.Position() == 2);
assert(b.Position() == 1);

assert(a.Label().get_view() == "");
assert(a.SetLabel("hello").has_value());
assert(a.Label().get_view() == "hello");
assert(b.Label().get_view() == "");
assert(is_err(a.SetLabel(""), "label must not be empty"));
assert(a.Label().get_view() == "hello");

assert(test_imports::Blob::MaxSize() == 1024);
assert(test_imports::Blob::SetMaxSize(2048).has_value());
assert(test_imports::Blob::MaxSize() == 2048);
assert(is_err(test_imports::Blob::SetMaxSize(0), "max size must be nonzero"));
assert(test_imports::Blob::MaxSize() == 2048);
}
55 changes: 55 additions & 0 deletions tests/runtime/accessors/runner.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//@ wasmtime-flags = '-Wcomponent-model-accessors'

include!(env!("BINDINGS"));

use crate::test::accessors::i::*;

struct Component;

export!(Component);

impl Guest for Component {
fn run() {
assert_eq!(counter(), 0);
set_counter(5);
assert_eq!(counter(), 5);
set_counter(u32::MAX);
assert_eq!(counter(), u32::MAX);

assert_eq!(read_only(), "read only");

assert_eq!(bounded(), 0);
assert_eq!(set_bounded(10), Ok(()));
assert_eq!(bounded(), 10);
assert_eq!(set_bounded(101), Err("101 is out of bounds".to_string()));
assert_eq!(bounded(), 10);

let a = Blob::new(&[1, 2, 3]);
let b = Blob::new(&[4, 5]);
assert_eq!(a.contents(), [1, 2, 3]);
assert_eq!(a.position(), 0);
assert_eq!(b.position(), 0);
a.set_position(2);
assert_eq!(a.position(), 2);
assert_eq!(b.position(), 0);
b.set_position(1);
assert_eq!(a.position(), 2);
assert_eq!(b.position(), 1);

assert_eq!(a.label(), "");
assert_eq!(a.set_label("hello"), Ok(()));
assert_eq!(a.label(), "hello");
assert_eq!(b.label(), "");
assert_eq!(a.set_label(""), Err("label must not be empty".to_string()));
assert_eq!(a.label(), "hello");

assert_eq!(Blob::max_size(), 1024);
assert_eq!(Blob::set_max_size(2048), Ok(()));
assert_eq!(Blob::max_size(), 2048);
assert_eq!(
Blob::set_max_size(0),
Err("max size must be nonzero".to_string())
);
assert_eq!(Blob::max_size(), 2048);
}
}
Loading
Loading