Skip to content

Commit 40ce6fc

Browse files
fix(deps): update rust dependencies (#79)
* fix(deps): update rust dependencies * fix: align tools and implement map type --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Tomasz Andrzejak <andreiltd@gmail.com>
1 parent 60ea380 commit 40ce6fc

14 files changed

Lines changed: 461 additions & 442 deletions

File tree

‎Cargo.lock‎

Lines changed: 236 additions & 399 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Cargo.toml‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ clap = { version = "4", features = ["derive"] }
1919
tokio = { version = "1", default-features = false, features = ["rt", "macros"] }
2020
wasmtime = { version = "47", features = ["component-model", "async"] }
2121
wasmtime-wasi = { version = "47", default-features = false, features = ["p2", "p3"] }
22-
wit-parser = "0.256"
22+
wit-parser = "0.258"
2323

2424
[package]
2525
name = "componentize-qjs-cli"
@@ -57,11 +57,11 @@ componentize-qjs.workspace = true
5757
anyhow.workspace = true
5858
clap.workspace = true
5959
tokio.workspace = true
60-
oxc_minifier = "0.144.0"
61-
oxc_allocator = "0.144.0"
62-
oxc_codegen = "0.144.0"
63-
oxc_parser = "0.144.0"
64-
oxc_span = "0.144.0"
60+
oxc_minifier = "0.147.0"
61+
oxc_allocator = "0.147.0"
62+
oxc_codegen = "0.147.0"
63+
oxc_parser = "0.147.0"
64+
oxc_span = "0.147.0"
6565

6666
[features]
6767
default = ["component-model-async"]

‎README.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ a project root that contains shared files or `node_modules`.
197197
|----------|---------|---------|
198198
| `list<T>` | `Array` | `[1, 2, 3]` |
199199
| `list<u8>` | `Uint8Array` or `Array` | `new Uint8Array([1, 2, 3])` |
200+
| `map<K, V>` | `Map` | `new Map([["key", value]])` |
200201
| `tuple<T, U, ...>` | `Array` | `[42, "hello"]` |
201202
| `option<T>` | `T \| null` (nested: `{ tag: "some"\|"none", val }`) | `null` for none; `option<option<T>>` is wrapped |
202203
| `result<T, E>` | top-level function result: return `T` or throw `E`; nested result: `{ tag: "ok"\|"err", val?: T\|E }` | `return 42` / `throw "error"` |

‎crates/core/Cargo.toml‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,15 @@ bytes = "1"
3737
oxc_resolver = "11.21.0"
3838
tokio.workspace = true
3939
wit-parser.workspace = true
40-
wit-component = { version = "0.256", features = ["dummy-module"] }
41-
wit-dylib = "0.256"
40+
wit-component = { version = "0.258", features = ["dummy-module"] }
41+
wit-dylib = "0.258"
4242
wasi-preview1-component-adapter-provider = "47"
4343
wasmtime.workspace = true
4444
wasmtime-wasi.workspace = true
4545
wasmtime-wizer = { version = "47", features = ["component-model", "wasmtime"] }
46-
wac-graph = "0.10"
46+
wasm-compose = { version = "0.258", default-features = false }
4747
indexmap = "2"
48+
tempfile = "3"
4849

4950
[build-dependencies]
5051
anyhow.workspace = true

‎crates/core/src/codegen.rs‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,11 @@ fn typedef_const_name(resolve: &Resolve, id: TypeId, style: ConstNameStyle) -> S
283283
TypeDefKind::List(inner) => {
284284
format!("LIST_{}", type_const_name(resolve, Some(inner), style))
285285
}
286+
TypeDefKind::Map(key, value) => {
287+
let key = type_const_name(resolve, Some(key), style);
288+
let value = type_const_name(resolve, Some(value), style);
289+
format!("MAP_{key}_{value}")
290+
}
286291
TypeDefKind::Future(inner) => {
287292
let inner = inner
288293
.as_ref()

‎crates/core/src/lib.rs‎

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -136,18 +136,20 @@ pub async fn componentize(opts: &ComponentizeOpts<'_>) -> Result<Vec<u8>> {
136136
wit_component::StringEncoding::UTF8,
137137
)?;
138138

139-
let pre_wizer_component = wit_component::Linker::default()
140-
.validate(true)
141-
.library(
142-
"componentize_qjs_runtime.wasm",
143-
runtime_wasm(opts.runtime),
144-
false,
145-
)?
146-
.library("wit-dylib.wasm", &wit_dylib, false)?
147-
.adapter(
148-
"wasi_snapshot_preview1",
149-
WASI_SNAPSHOT_PREVIEW1_REACTOR_ADAPTER,
150-
)?
139+
let mut linker = wit_component::Linker::default();
140+
linker.encoder().validate(true);
141+
linker.library(
142+
"componentize_qjs_runtime.wasm",
143+
runtime_wasm(opts.runtime),
144+
false,
145+
)?;
146+
linker.library("wit-dylib.wasm", &wit_dylib, false)?;
147+
linker.encoder().adapter(
148+
"wasi_snapshot_preview1",
149+
WASI_SNAPSHOT_PREVIEW1_REACTOR_ADAPTER,
150+
)?;
151+
152+
let pre_wizer_component = linker
151153
.encode()
152154
.context("failed to link and encode component")?;
153155

@@ -231,6 +233,7 @@ async fn wizer_init(
231233
let mut config = Config::new();
232234
config.wasm_component_model(true);
233235
config.wasm_component_model_async(true);
236+
config.wasm_component_model_map(true);
234237

235238
let engine = Engine::new(&config)?;
236239
let mut store = Store::new(&engine, Ctx { wasi, table });

‎crates/core/src/stubwasi.rs‎

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
//! 2. Create a "stub world" where the WASI imports become exports
66
//! 3. Use `dummy_module` to generate a core module with trap implementations
77
//! 4. Encode it as a stub component
8-
//! 5. Use `wac-graph` to compose the stub into the original component
8+
//! 5. Use `wasm-compose` to compose the stub into the original component
99
1010
use anyhow::{Context, Result, bail};
1111
use indexmap::IndexMap;
12-
use wac_graph::{CompositionGraph, EncodeOptions, plug, types::Package};
12+
use wasm_compose::{composer::ComponentComposer, config::Config as ComposeConfig};
1313
use wit_component::{ComponentEncoder, StringEncoding, dummy_module, embed_component_metadata};
1414
use wit_parser::decoding::{DecodedWasm, decode};
1515
use wit_parser::{Docs, ManglingAndAbi, Resolve, Stability, World, WorldItem, WorldKey};
@@ -47,22 +47,22 @@ fn stub_imports(component: &[u8], should_stub: impl Fn(&str) -> bool) -> Result<
4747
let stub_component =
4848
make_stub_component(&resolve, world, &imports).context("failed to build stub component")?;
4949

50-
let mut graph = CompositionGraph::new();
50+
let dir = tempfile::tempdir().context("failed to create composition directory")?;
51+
let component_path = dir.path().join("original.wasm");
52+
let stub_path = dir.path().join("stubs.wasm");
5153

52-
let orig_pkg = Package::from_bytes("original", None, component.to_vec(), graph.types_mut())
53-
.context("failed to register original component")?;
54+
std::fs::write(&component_path, component).context("failed to stage original component")?;
55+
std::fs::write(&stub_path, stub_component).context("failed to stage stub component")?;
5456

55-
let stub_pkg = Package::from_bytes("stubs", None, stub_component, graph.types_mut())
56-
.context("failed to register stub component")?;
57-
58-
let orig_id = graph.register_package(orig_pkg)?;
59-
let stub_id = graph.register_package(stub_pkg)?;
60-
61-
plug(&mut graph, vec![stub_id], orig_id)?;
57+
let config = ComposeConfig {
58+
dir: dir.path().to_path_buf(),
59+
definitions: vec!["stubs.wasm".into()],
60+
..Default::default()
61+
};
6262

63-
graph
64-
.encode(EncodeOptions::default())
65-
.context("failed to encode composed component")
63+
ComponentComposer::new(&component_path, &config)
64+
.compose()
65+
.context("failed to compose stub component")
6666
}
6767

6868
/// Build a component that exports trap implementations for the given imports.

‎crates/runtime/Cargo.toml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ crate-type = ["cdylib"]
1313

1414
[dependencies]
1515
rquickjs = { version = "0.12", default-features = false, features = ["bindgen", "disable-assertions", "loader", "std", "macro"] }
16-
wit-bindgen = "0.60"
17-
wit-dylib-ffi = { version = "0.1.0", git = "https://github.com/bytecodealliance/wasm-tools", default-features = false, features = ["async-raw"] }
16+
wit-bindgen = "0.61"
17+
wit-dylib-ffi = { version = "0.1.0", git = "https://github.com/bytecodealliance/wasm-tools", tag = "v1.258.0", default-features = false, features = ["async-raw"] }
1818
heck = "0.5"
1919
num_enum = { version = "0.7", default-features = false }
2020
smallvec = "1"

‎crates/runtime/src/call.rs‎

Lines changed: 73 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@ use crate::trivia::fn_lookup;
99
use crate::{BorrowedResource, QjsCallContext, with_ctx};
1010

1111
use rquickjs::class::Class;
12-
use rquickjs::{Coerced, IntoJs, Persistent, Symbol, Value};
12+
use rquickjs::function::This;
13+
use rquickjs::{Coerced, Constructor, Function, IntoJs, Persistent, Symbol, Value};
1314
use smallvec::SmallVec;
1415
use wit_dylib_ffi::{
15-
Call, Enum, Flags, Future, List, Record, Resource, Stream, Tuple, Type, Variant, WitOption,
16-
WitResult,
16+
Call, Enum, Flags, Future, List, Map, Record, Resource, Stream, Tuple, Type, Variant,
17+
WitOption, WitResult,
1718
};
1819

1920
use std::alloc::Layout;
@@ -202,7 +203,7 @@ impl Call for QjsCallContext {
202203
})
203204
}
204205

205-
fn pop_iter_next(&mut self, _ty: List) {
206+
fn pop_list_iter_next(&mut self, _ty: List) {
206207
let index = *self.iter_stack.last().expect("iter_stack underflow");
207208
let arr_persistent = self.stack.last().expect("stack underflow").clone();
208209

@@ -216,11 +217,53 @@ impl Call for QjsCallContext {
216217
*self.iter_stack.last_mut().unwrap() = index + 1;
217218
}
218219

219-
fn pop_iter(&mut self, _ty: List) {
220+
fn pop_list_iter(&mut self, _ty: List) {
220221
self.iter_stack.pop().expect("iter_stack underflow");
221222
self.stack.pop().expect("stack underflow");
222223
}
223224

225+
fn pop_map(&mut self, _ty: Map) -> usize {
226+
let persistent = self.stack.pop().expect("stack underflow");
227+
228+
with_ctx(|ctx| {
229+
let value = persistent.restore(ctx).unwrap();
230+
let map = value.as_object().expect("expected Map");
231+
let constructor: Constructor = ctx.globals().get("Map").expect("Map not found");
232+
assert!(map.is_instance_of(&constructor), "expected Map");
233+
234+
let len = map.get("size").expect("expected Map size");
235+
let entries: Function = map.get("entries").expect("Map.entries not found");
236+
let iterator: Value = entries
237+
.call((This(map.clone()),))
238+
.expect("failed to create Map iterator");
239+
self.stack.push(Persistent::save(ctx, iterator));
240+
len
241+
})
242+
}
243+
244+
fn pop_map_iter_next(&mut self, _ty: Map) {
245+
let persistent = self.stack.last().expect("stack underflow").clone();
246+
247+
with_ctx(|ctx| {
248+
let value = persistent.restore(ctx).unwrap();
249+
let iterator = value.as_object().expect("expected Map iterator");
250+
let next: Function = iterator.get("next").expect("Map iterator.next not found");
251+
let result: rquickjs::Object = next
252+
.call((This(iterator.clone()),))
253+
.expect("failed to advance Map iterator");
254+
let entry: rquickjs::Array = result.get("value").expect("expected Map entry");
255+
let key: Value = entry.get(0).expect("expected Map key");
256+
let value: Value = entry.get(1).expect("expected Map value");
257+
258+
self.stack.push(Persistent::save(ctx, value));
259+
self.stack.push(Persistent::save(ctx, key));
260+
});
261+
}
262+
263+
fn pop_map_iter(&mut self, _ty: Map) {
264+
self.stack.pop().expect("stack underflow");
265+
}
266+
224267
fn pop_option(&mut self, ty: WitOption) -> u32 {
225268
let persistent = self.stack.pop().expect("stack underflow");
226269

@@ -509,6 +552,31 @@ impl Call for QjsCallContext {
509552
});
510553
}
511554

555+
fn push_map(&mut self, _ty: Map, _capacity: usize) {
556+
with_ctx(|ctx| {
557+
let constructor: Constructor = ctx.globals().get("Map").expect("Map not found");
558+
let map: Value = constructor.construct(()).expect("failed to create Map");
559+
self.stack.push(Persistent::save(ctx, map));
560+
});
561+
}
562+
563+
fn map_append(&mut self, _ty: Map) {
564+
let value = self.stack.pop().expect("stack underflow");
565+
let key = self.stack.pop().expect("stack underflow");
566+
let map_persistent = self.stack.last().expect("stack underflow").clone();
567+
568+
with_ctx(|ctx| {
569+
let map_value = map_persistent.restore(ctx).unwrap();
570+
let map = map_value.as_object().expect("expected Map");
571+
let set: Function = map.get("set").expect("Map.set not found");
572+
let key = key.restore(ctx).unwrap();
573+
let value = value.restore(ctx).unwrap();
574+
let _: Value = set
575+
.call((This(map.clone()), key, value))
576+
.expect("failed to append Map entry");
577+
});
578+
}
579+
512580
fn push_option(&mut self, ty: WitOption, is_some: bool) {
513581
if option_is_nested(ty) {
514582
// Nested option: wrap so `none` and `some(none)` stay distinct.

‎docs/runtime-intrinsics.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ stream<message>` adds `wit.Stream.PROMPT_STREAM`.
140140
| Results | `RESULT_STRING_U32` | `result<string, u32>` |
141141
| Tuples | `TUPLE_U32_STRING` | `tuple<u32, string>` |
142142
| Lists | `LIST_U8` | `list<u8>` |
143+
| Maps | `MAP_STRING_U32` | `map<string, u32>` |
143144
| Nested streams/futures | `STREAM_U8`, `FUTURE_STRING` | `stream<u8>`, `future<string>` |
144145
| Unit | `UNIT` | (no payload) |
145146

@@ -268,6 +269,7 @@ represented directly by their values. Resources are exposed as classes.
268269
| Variants | `{ tag, val }` (string tag) | `{ tag: "case-a", val }` |
269270
| Flags | `{ name: boolean }` object | `{ flagA: true, flagB: false }` |
270271
| Records | object, camelCase fields | `{ fieldName: value }` |
272+
| Maps | `Map` | `new Map([["key", value]])` |
271273
| Resources | class instance; methods on prototype | `input.blockingRead(n)` |
272274

273275
### Export Functions

0 commit comments

Comments
 (0)