Skip to content

Commit 7681a93

Browse files
committed
add link-dl-openable component test and make output deterministic
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
1 parent e9d8834 commit 7681a93

File tree

8 files changed

+246
-41
lines changed

8 files changed

+246
-41
lines changed

crates/wit-component/src/linking.rs

Lines changed: 15 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use {
2828
indexmap::IndexSet,
2929
metadata::{Export, FunctionType, GlobalType, Metadata, Type, ValueType},
3030
std::{
31-
collections::{hash_map::Entry, BTreeMap, BTreeSet, HashMap, HashSet},
31+
collections::{hash_map::Entry, BTreeMap, HashMap, HashSet},
3232
iter,
3333
},
3434
wasm_encoder::{
@@ -1249,27 +1249,20 @@ impl Linker {
12491249
name: format!("{name}:table_base"),
12501250
},
12511251
])
1252-
.chain(
1253-
metadata
1254-
.env_imports
1255-
.iter()
1256-
.collect::<BTreeSet<_>>()
1257-
.into_iter()
1258-
.map(|(name, ty)| {
1259-
let exporter = find_function_exporter(name, ty, &exporters).unwrap();
1260-
1261-
Item {
1262-
alias: (*name).into(),
1263-
kind: ExportKind::Func,
1264-
which: if seen.contains(exporter) {
1265-
MainOrAdapter::Adapter(exporter.to_owned())
1266-
} else {
1267-
MainOrAdapter::Main
1268-
},
1269-
name: (*name).into(),
1270-
}
1271-
}),
1272-
)
1252+
.chain(metadata.env_imports.iter().map(|(name, ty)| {
1253+
let exporter = find_function_exporter(name, ty, &exporters).unwrap();
1254+
1255+
Item {
1256+
alias: (*name).into(),
1257+
kind: ExportKind::Func,
1258+
which: if seen.contains(exporter) {
1259+
MainOrAdapter::Adapter(exporter.to_owned())
1260+
} else {
1261+
MainOrAdapter::Main
1262+
},
1263+
name: (*name).into(),
1264+
}
1265+
}))
12731266
.collect();
12741267

12751268
let global_item = |address_name: &str| Item {
@@ -1282,8 +1275,6 @@ impl Linker {
12821275
let mem_items = metadata
12831276
.memory_address_imports
12841277
.iter()
1285-
.collect::<BTreeSet<_>>()
1286-
.into_iter()
12871278
.copied()
12881279
.map(global_item)
12891280
.chain(["__heap_base", "__heap_end"].into_iter().map(|name| Item {
@@ -1297,8 +1288,6 @@ impl Linker {
12971288
let func_items = metadata
12981289
.table_address_imports
12991290
.iter()
1300-
.collect::<BTreeSet<_>>()
1301-
.into_iter()
13021291
.copied()
13031292
.map(global_item)
13041293
.collect();

crates/wit-component/src/linking/metadata.rs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
44
use {
55
anyhow::{bail, Context, Error, Result},
6-
std::collections::HashSet,
6+
std::collections::{BTreeSet, HashSet},
77
wasmparser::{
88
BinaryReader, BinaryReaderError, ExternalKind, FuncType, Parser, Payload, RefType,
99
StructuralType, Subsection, Subsections, TableType, TypeRef, ValType,
@@ -76,14 +76,14 @@ impl TryFrom<&FuncType> for FunctionType {
7676
}
7777

7878
/// Represents a core Wasm global variable type
79-
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
79+
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
8080
pub struct GlobalType {
8181
pub ty: ValueType,
8282
pub mutable: bool,
8383
}
8484

8585
/// Represents a core Wasm export or import type
86-
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
86+
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
8787
pub enum Type {
8888
Function(FunctionType),
8989
Global(GlobalType),
@@ -99,15 +99,15 @@ impl From<&Type> for wasm_encoder::ExportKind {
9999
}
100100

101101
/// Represents a core Wasm import
102-
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
102+
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
103103
pub struct Import<'a> {
104104
pub module: &'a str,
105105
pub name: &'a str,
106106
pub ty: Type,
107107
}
108108

109109
/// Represents a core Wasm export
110-
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
110+
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
111111
pub struct Export<'a> {
112112
pub name: &'a str,
113113
pub ty: Type,
@@ -165,19 +165,19 @@ pub struct Metadata<'a> {
165165
pub has_component_exports: bool,
166166

167167
/// The functions imported from the `env` module, if any
168-
pub env_imports: HashSet<(&'a str, FunctionType)>,
168+
pub env_imports: BTreeSet<(&'a str, FunctionType)>,
169169

170170
/// The memory addresses imported from `GOT.mem`, if any
171-
pub memory_address_imports: HashSet<&'a str>,
171+
pub memory_address_imports: BTreeSet<&'a str>,
172172

173173
/// The table addresses imported from `GOT.func`, if any
174-
pub table_address_imports: HashSet<&'a str>,
174+
pub table_address_imports: BTreeSet<&'a str>,
175175

176176
/// The symbols exported by this module, if any
177-
pub exports: HashSet<Export<'a>>,
177+
pub exports: BTreeSet<Export<'a>>,
178178

179179
/// The symbols imported by this module (and not accounted for in the above fields), if any
180-
pub imports: HashSet<Import<'a>>,
180+
pub imports: BTreeSet<Import<'a>>,
181181
}
182182

183183
#[allow(dead_code)]
@@ -266,11 +266,11 @@ impl<'a> Metadata<'a> {
266266
has_ctors: false,
267267
has_set_libraries: false,
268268
has_component_exports,
269-
env_imports: HashSet::new(),
270-
memory_address_imports: HashSet::new(),
271-
table_address_imports: HashSet::new(),
272-
exports: HashSet::new(),
273-
imports: HashSet::new(),
269+
env_imports: BTreeSet::new(),
270+
memory_address_imports: BTreeSet::new(),
271+
table_address_imports: BTreeSet::new(),
272+
exports: BTreeSet::new(),
273+
imports: BTreeSet::new(),
274274
};
275275
let mut types = Vec::new();
276276
let mut function_types = Vec::new();
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
(component
2+
(type (;0;)
3+
(instance
4+
(type (;0;) (func (param "v" s32) (result s32)))
5+
(export (;0;) "foo" (func (type 0)))
6+
)
7+
)
8+
(import (interface "test:test/test") (instance (;0;) (type 0)))
9+
(core module (;0;)
10+
(table (;0;) 3 funcref)
11+
(memory (;0;) 17)
12+
(global (;0;) (mut i32) i32.const 1048576)
13+
(global (;1;) i32 i32.const 1048688)
14+
(global (;2;) i32 i32.const 3)
15+
(global (;3;) (mut i32) i32.const 1048688)
16+
(global (;4;) (mut i32) i32.const 1114112)
17+
(export "__stack_pointer" (global 0))
18+
(export "foo:memory_base" (global 1))
19+
(export "foo:table_base" (global 2))
20+
(export "__heap_base" (global 3))
21+
(export "__heap_end" (global 4))
22+
(export "__indirect_function_table" (table 0))
23+
(export "memory" (memory 0))
24+
(@producers
25+
(processed-by "wit-component" "$CARGO_PKG_VERSION")
26+
)
27+
)
28+
(core module (;1;)
29+
(@dylink.0
30+
(mem-info (memory 0 4))
31+
)
32+
(type (;0;) (func (param i32) (result i32)))
33+
(import "test:test/test" "foo" (func $import_foo (;0;) (type 0)))
34+
(func $foo (;1;) (type 0) (param i32) (result i32)
35+
unreachable
36+
)
37+
(global $what (;0;) i32 i32.const 42)
38+
(export "test:test/test#foo" (func $foo))
39+
(export "bar" (func $foo))
40+
(export "baz" (func $foo))
41+
(export "what" (global $what))
42+
)
43+
(core module (;2;)
44+
(type (;0;) (func))
45+
(type (;1;) (func (param i32)))
46+
(type (;2;) (func (param i32) (result i32)))
47+
(type (;3;) (func (param i32) (result i32)))
48+
(type (;4;) (func (param i32) (result i32)))
49+
(import "env" "memory" (memory (;0;) 0))
50+
(import "env" "__indirect_function_table" (table (;0;) 0 funcref))
51+
(import "env" "foo:memory_base" (global (;0;) i32))
52+
(import "foo" "what" (global (;1;) i32))
53+
(import "foo" "bar" (func (;0;) (type 2)))
54+
(import "foo" "baz" (func (;1;) (type 3)))
55+
(import "foo" "test:test/test#foo" (func (;2;) (type 4)))
56+
(func (;3;) (type 0)
57+
i32.const 1048656
58+
global.get 0
59+
global.get 1
60+
i32.add
61+
i32.store
62+
)
63+
(start 3)
64+
(elem (;0;) (i32.const 0) func 0 1 2)
65+
(elem (;1;) (i32.const 3) func)
66+
(data (;0;) (i32.const 1048576) "foo\00bar\00baz\00test:test/test#foo\00\00what\03\00\00\00\04\00\10\00\00\00\00\00\03\00\00\00\08\00\10\00\01\00\00\00\12\00\00\00\0c\00\10\00\02\00\00\00\04\00\00\00 \00\10\00\00\00\00\00\03\00\00\00\00\00\10\00\04\00\00\00$\00\10\00\01\00\00\00T\00\10\00")
67+
(@producers
68+
(processed-by "wit-component" "$CARGO_PKG_VERSION")
69+
)
70+
)
71+
(core instance (;0;) (instantiate 0))
72+
(alias core export 0 "memory" (core memory (;0;)))
73+
(alias core export 0 "__heap_base" (core global (;0;)))
74+
(alias core export 0 "__heap_end" (core global (;1;)))
75+
(core instance (;1;)
76+
(export "__heap_base" (global 0))
77+
(export "__heap_end" (global 1))
78+
)
79+
(core instance (;2;))
80+
(alias core export 0 "memory" (core memory (;1;)))
81+
(alias core export 0 "__indirect_function_table" (core table (;0;)))
82+
(alias core export 0 "__stack_pointer" (core global (;2;)))
83+
(alias core export 0 "foo:memory_base" (core global (;3;)))
84+
(alias core export 0 "foo:table_base" (core global (;4;)))
85+
(core instance (;3;)
86+
(export "memory" (memory 1))
87+
(export "__indirect_function_table" (table 0))
88+
(export "__stack_pointer" (global 2))
89+
(export "__memory_base" (global 3))
90+
(export "__table_base" (global 4))
91+
)
92+
(alias export 0 "foo" (func (;0;)))
93+
(core func (;0;) (canon lower (func 0)))
94+
(core instance (;4;)
95+
(export "foo" (func 0))
96+
)
97+
(core instance (;5;) (instantiate 1
98+
(with "GOT.mem" (instance 1))
99+
(with "GOT.func" (instance 2))
100+
(with "env" (instance 3))
101+
(with "test:test/test" (instance 4))
102+
)
103+
)
104+
(core instance (;6;) (instantiate 2
105+
(with "env" (instance 0))
106+
(with "foo" (instance 5))
107+
)
108+
)
109+
(type (;1;) (func (param "v" s32) (result s32)))
110+
(alias core export 5 "test:test/test#foo" (core func (;1;)))
111+
(func (;1;) (type 1) (canon lift (core func 1)))
112+
(component (;0;)
113+
(type (;0;) (func (param "v" s32) (result s32)))
114+
(import "import-func-foo" (func (;0;) (type 0)))
115+
(type (;1;) (func (param "v" s32) (result s32)))
116+
(export (;1;) "foo" (func 0) (func (type 1)))
117+
)
118+
(instance (;1;) (instantiate 0
119+
(with "import-func-foo" (func 1))
120+
)
121+
)
122+
(export (;2;) (interface "test:test/test") (instance 1))
123+
(@producers
124+
(processed-by "wit-component" "$CARGO_PKG_VERSION")
125+
)
126+
)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package root:component
2+
3+
world root {
4+
import test:test/test
5+
6+
export test:test/test
7+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
(module
2+
(@dylink.0
3+
(mem-info (memory 0 4))
4+
)
5+
(type (func (param i32) (result i32)))
6+
(import "test:test/test" "foo" (func $import_foo (type 0)))
7+
(func $foo (type 0) (param i32) (result i32)
8+
unreachable
9+
)
10+
(global $what i32 i32.const 42)
11+
(export "test:test/test#foo" (func $foo))
12+
(export "bar" (func $foo))
13+
(export "baz" (func $foo))
14+
(export "what" (global $what))
15+
)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package test:test
2+
3+
interface test {
4+
foo: func(v: s32) -> s32
5+
}
6+
7+
world dlopen-lib-foo {
8+
import test
9+
export test
10+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
(module
2+
(@dylink.0
3+
(mem-info (memory 4 4))
4+
(needed "c")
5+
)
6+
(type (func))
7+
(type (func (param i32) (result i32)))
8+
(import "env" "memory" (memory 1))
9+
(import "env" "__indirect_function_table" (table 0 funcref))
10+
(import "env" "__stack_pointer" (global $__stack_pointer (mut i32)))
11+
(import "env" "__memory_base" (global $__memory_base i32))
12+
(import "env" "__table_base" (global $__table_base i32))
13+
(import "env" "malloc" (func $malloc (type 1)))
14+
(import "env" "abort" (func $abort (type 0)))
15+
(import "GOT.mem" "um" (global $um (mut i32)))
16+
(import "test:test/test" "bar" (func $bar (type 1)))
17+
(func $__wasm_call_ctors (type 0))
18+
(func $__wasm_apply_data_relocs (type 0))
19+
(func $foo (type 1) (param i32) (result i32)
20+
global.get $__stack_pointer
21+
i32.const 16
22+
i32.sub
23+
global.set $__stack_pointer
24+
25+
i32.const 4
26+
call $malloc
27+
28+
i32.const 0
29+
i32.eq
30+
if
31+
call $abort
32+
unreachable
33+
end
34+
35+
local.get 0
36+
global.get $um
37+
i32.load offset=16
38+
i32.add
39+
i32.const 42
40+
i32.add
41+
42+
call $bar
43+
44+
global.get $__stack_pointer
45+
i32.const 16
46+
i32.add
47+
global.set $__stack_pointer
48+
)
49+
(global i32 i32.const 0)
50+
(export "__wasm_call_ctors" (func $__wasm_call_ctors))
51+
(export "__wasm_apply_data_relocs" (func $__wasm_apply_data_relocs))
52+
(export "foo2" (func $foo))
53+
(export "well2" (global 4))
54+
(data $.data (global.get $__memory_base) "\04\00\00\00")
55+
)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package test:test
2+
3+
world lib-unused { }

0 commit comments

Comments
 (0)