1 #include <gtest/gtest.h>
2 #include <wasmtime/linker.hh>
3 
4 using namespace wasmtime;
5 
TEST(Linker,Smoke)6 TEST(Linker, Smoke) {
7   Engine engine;
8   Linker linker(engine);
9   Store store(engine);
10   linker.allow_shadowing(false);
11   Global g = Global::create(store, GlobalType(ValKind::I32, false), 1).unwrap();
12   linker.define(store, "a", "g", g).unwrap();
13   linker.define_wasi().unwrap();
14   linker
15       .func_new("a", "f", FuncType({}, {}),
16                 [](auto caller, auto params, auto results) -> auto {
17                   return std::monostate();
18                 })
19       .unwrap();
20   linker.func_wrap("a", "f2", []() {}).unwrap();
21   linker.func_wrap("a", "f3", [](Caller arg) {}).unwrap();
22   linker.func_wrap("a", "f4", [](Caller arg, int32_t a) {}).unwrap();
23   Module mod = Module::compile(engine, "(module)").unwrap();
24   Instance i = Instance::create(store, mod, {}).unwrap();
25   linker.define_instance(store, "x", i).unwrap();
26   linker.instantiate(store, mod).unwrap();
27   linker.module(store, "y", mod).unwrap();
28   EXPECT_TRUE(linker.get(store, "a", "g"));
29   linker.get_default(store, "g").unwrap();
30   EXPECT_TRUE(linker.get(store, "a", "f"));
31   EXPECT_TRUE(std::holds_alternative<Func>(*linker.get(store, "a", "f")));
32 }
33 
TEST(Linker,CallableMove)34 TEST(Linker, CallableMove) {
35   Engine engine;
36   Linker linker(engine);
37   Store store(engine);
38   linker.allow_shadowing(false);
39 
40   struct CallableFunc {
41     CallableFunc() = default;
42     CallableFunc(const CallableFunc &) = delete;
43     CallableFunc(CallableFunc &&) = default;
44 
45     Result<std::monostate, Trap>
46     operator()(Caller caller, Span<const Val> params, Span<Val> results) {
47       return std::monostate();
48     }
49   };
50 
51   CallableFunc cf;
52   linker.func_new("a", "f", FuncType({}, {}), std::move(cf)).unwrap();
53 }
54 
TEST(Linker,CallableCopy)55 TEST(Linker, CallableCopy) {
56   Engine engine;
57   Linker linker(engine);
58   Store store(engine);
59   linker.allow_shadowing(false);
60 
61   struct CallableFunc {
62     CallableFunc() = default;
63     CallableFunc(const CallableFunc &) = default;
64     CallableFunc(CallableFunc &&) = default;
65 
66     Result<std::monostate, Trap>
67     operator()(Caller caller, Span<const Val> params, Span<Val> results) {
68       return std::monostate();
69     }
70   };
71 
72   CallableFunc cf;
73   linker.func_new("a", "f", FuncType({}, {}), cf).unwrap();
74 }
75 
TEST(Linker,DefineUnknownImportsAsTraps)76 TEST(Linker, DefineUnknownImportsAsTraps) {
77   Engine engine;
78   Linker linker(engine);
79   Store store(engine);
80   Module mod =
81       Module::compile(
82           engine,
83           "(module (import \"\" \"\" (func)) (func (export \"x\") call 0))")
84           .unwrap();
85   linker.define_unknown_imports_as_traps(mod).unwrap();
86 
87   auto instance = linker.instantiate(store.context(), mod).unwrap();
88   Func f = std::get<Func>(*instance.get(store.context(), "x"));
89   TrapError err = f.call(store.context(), {}).err();
90   std::get<Error>(err.data);
91 }
92 
TEST(Linker,DefineUnknownImportsAsDefaultValues)93 TEST(Linker, DefineUnknownImportsAsDefaultValues) {
94   Engine engine;
95   Linker linker(engine);
96   Store store(engine);
97   Module mod =
98       Module::compile(
99           engine,
100           "(module (import \"\" \"\" (func)) (func (export \"x\") call 0))")
101           .unwrap();
102   linker.define_unknown_imports_as_default_values(store.context(), mod)
103       .unwrap();
104 
105   auto instance = linker.instantiate(store.context(), mod).unwrap();
106   Func f = std::get<Func>(*instance.get(store.context(), "x"));
107   f.call(store.context(), {}).unwrap();
108 }
109