1 #include <gtest/gtest.h>
2 #include <wasmtime.hh>
3
4 using namespace wasmtime;
5
unwrap(Result<T,E> result)6 template <typename T, typename E> T unwrap(Result<T, E> result) {
7 if (result) {
8 return result.ok();
9 }
10 std::cerr << "error: " << result.err().message() << "\n";
11 std::abort();
12 }
13
TEST(Engine,Smoke)14 TEST(Engine, Smoke) {
15 Engine engine;
16 Config config;
17 engine = Engine(std::move(config));
18 }
19
TEST(wat2wasm,Smoke)20 TEST(wat2wasm, Smoke) {
21 wat2wasm("(module)").ok();
22 wat2wasm("xxx").err();
23 }
24
TEST(Module,Smoke)25 TEST(Module, Smoke) {
26 Engine engine;
27 Module::compile(engine, "(module)").ok();
28 Module::compile(engine, "wat").err();
29
30 auto wasm = wat2wasm("(module)").ok();
31 Module::compile(engine, wasm).ok();
32 std::vector<uint8_t> emptyWasm;
33 Module::compile(engine, emptyWasm).err();
34
35 Module::validate(engine, wasm).ok();
36 Module::validate(engine, emptyWasm).err();
37
38 Module m2 = unwrap(Module::compile(engine, "(module)"));
39 Module m3 = m2;
40 Module m4(m3);
41 m4 = m2;
42 Module m5(std::move(m3));
43 m4 = std::move(m5);
44 }
45
TEST(Module,Serialize)46 TEST(Module, Serialize) {
47 Engine engine;
48 Module m = unwrap(Module::compile(engine, "(module)"));
49 auto bytes = unwrap(m.serialize());
50 m = unwrap(Module::deserialize(engine, bytes));
51 std::string path("test_deserialize_file.cwasm");
52 auto fh = ::fopen(path.c_str(), "wb");
53 ::fwrite(bytes.data(), sizeof(uint8_t), bytes.size(), fh);
54 ::fclose(fh);
55 m = unwrap(Module::deserialize_file(engine, path));
56 ::remove(path.c_str());
57 }
58
TEST(ExternRef,Smoke)59 TEST(ExternRef, Smoke) {
60 Engine engine;
61 Store store(engine);
62 ExternRef a(store, "foo");
63 ExternRef b(store, 3);
64 EXPECT_STREQ(std::any_cast<const char *>(a.data(store)), "foo");
65 EXPECT_EQ(std::any_cast<int>(b.data(store)), 3);
66 a = b;
67 }
68
TEST(Caller,Smoke)69 TEST(Caller, Smoke) {
70 Engine engine;
71 Store store(engine);
72 Func f(store, FuncType({}, {}),
73 [](auto caller, auto params, auto results) -> auto {
74 EXPECT_FALSE(caller.get_export("foo"));
75 return std::monostate();
76 });
77 unwrap(f.call(store, {}));
78
79 Module m = unwrap(Module::compile(engine, "(module "
80 "(import \"\" \"\" (func))"
81 "(memory (export \"m\") 1)"
82 "(func (export \"f\") call 0)"
83 ")"));
84 Func f2(store, FuncType({}, {}),
85 [](auto caller, auto params, auto results) -> auto {
86 EXPECT_FALSE(caller.get_export("foo"));
87 EXPECT_TRUE(caller.get_export("m"));
88 EXPECT_TRUE(caller.get_export("f"));
89 Memory m = std::get<Memory>(*caller.get_export("m"));
90 EXPECT_EQ(m.type(caller)->min(), 1);
91 return std::monostate();
92 });
93 Instance i = unwrap(Instance::create(store, m, {f2}));
94 f = std::get<Func>(*i.get(store, "f"));
95 unwrap(f.call(store, {}));
96 }
97
TEST(Func,Smoke)98 TEST(Func, Smoke) {
99 Engine engine;
100 Store store(engine);
101 Func f(store, FuncType({}, {}),
102 [](auto caller, auto params, auto results) -> auto {
103 return std::monostate();
104 });
105 unwrap(f.call(store, {}));
106
107 Func f2(store, FuncType({}, {}),
108 [](auto caller, auto params, auto results) -> auto {
109 return Trap("message");
110 });
111 EXPECT_EQ(f2.call(store, {}).err().message(), "message");
112 }
113
TEST(Data,Smoke)114 TEST(Data, Smoke) {
115
116 Engine engine;
117 Store store(engine);
118 store.context().set_data(10);
119 Func f0(store, FuncType({}, {}),
120 [](auto caller, auto params,
121 auto results) -> Result<std::monostate, Trap> {
122 auto data = std::any_cast<int>(caller.context().get_data());
123 if (data != 10) {
124 return Trap("message");
125 }
126 return std::monostate();
127 });
128 unwrap(f0.call(store, {}));
129
130 store.context().set_data(std::make_pair<int, int>(10, -3));
131 Func f1(store, FuncType({}, {}),
132 [](auto caller, auto params,
133 auto results) -> Result<std::monostate, Trap> {
134 auto data =
135 std::any_cast<std::pair<int, int>>(caller.context().get_data());
136 if (data.first != 10 || data.second != -3) {
137 return Trap("message");
138 }
139 return std::monostate();
140 });
141 unwrap(f1.call(store, {}));
142
143 store.context().set_data(std::string("hello world"));
144 Func f2(store, FuncType({}, {}),
145 [](auto caller, auto params,
146 auto results) -> Result<std::monostate, Trap> {
147 auto data = std::any_cast<std::string>(caller.context().get_data());
148 if (data != "hello world") {
149 return Trap("message");
150 }
151 return std::monostate();
152 });
153 unwrap(f2.call(store, {}));
154
155 struct test_object {
156 test_object() : v(nullptr) {}
157 test_object(int i) : v(new int(i)) {}
158 test_object(const test_object &other)
159 : v((other.v) ? new int(*other.v) : nullptr) {}
160 test_object(test_object &&other) : v(other.v) { other.v = nullptr; }
161 ~test_object() {
162 if (v) {
163 delete v;
164 v = nullptr;
165 }
166 }
167 int *v;
168 };
169
170 test_object data(7);
171 store.context().set_data(&data); // by pointer
172 Func f3(store, FuncType({}, {}),
173 [](auto caller, auto params,
174 auto results) -> Result<std::monostate, Trap> {
175 auto data =
176 std::any_cast<test_object *>(caller.context().get_data());
177 if (*data->v != 7) {
178 return Trap("message");
179 }
180 return std::monostate();
181 });
182 unwrap(f3.call(store, {}));
183 EXPECT_EQ(*data.v, 7);
184
185 store.context().set_data(data); // by copy
186 Func f4(store, FuncType({}, {}),
187 [](auto caller, auto params,
188 auto results) -> Result<std::monostate, Trap> {
189 auto data =
190 std::any_cast<test_object &>(caller.context().get_data());
191 if (*data.v != 7) {
192 return Trap("message");
193 }
194 return std::monostate();
195 });
196 unwrap(f4.call(store, {}));
197 EXPECT_EQ(*data.v, 7);
198
199 store.context().set_data(std::move(data)); // by move
200 Func f5(store, FuncType({}, {}),
201 [](auto caller, auto params,
202 auto results) -> Result<std::monostate, Trap> {
203 auto data =
204 std::any_cast<test_object &>(caller.context().get_data());
205 if (*data.v != 7) {
206 return Trap("message");
207 }
208 return std::monostate();
209 });
210 unwrap(f5.call(store, {}));
211 EXPECT_EQ(data.v, nullptr);
212 }
213