Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/crates/c-api/tests/val.cc
3068 views
1
#include <wasmtime/val.hh>
2
3
#include <gtest/gtest.h>
4
#include <wasmtime.hh>
5
6
using namespace wasmtime;
7
8
TEST(Val, Smoke) {
9
Val val(1);
10
EXPECT_EQ(val.kind(), ValKind::I32);
11
EXPECT_EQ(val.i32(), 1);
12
13
val = (int32_t)3;
14
EXPECT_EQ(val.kind(), ValKind::I32);
15
EXPECT_EQ(val.i32(), 3);
16
17
val = (int64_t)4;
18
EXPECT_EQ(val.kind(), ValKind::I64);
19
EXPECT_EQ(val.i64(), 4);
20
21
val = (float)5;
22
EXPECT_EQ(val.kind(), ValKind::F32);
23
EXPECT_EQ(val.f32(), 5);
24
25
val = (double)6;
26
EXPECT_EQ(val.kind(), ValKind::F64);
27
EXPECT_EQ(val.f64(), 6);
28
29
val = V128();
30
EXPECT_EQ(val.kind(), ValKind::V128);
31
for (int i = 0; i < 16; i++) {
32
EXPECT_EQ(val.v128().v128[i], 0);
33
}
34
35
Engine engine;
36
Store store(engine);
37
val = std::optional<ExternRef>(std::nullopt);
38
EXPECT_EQ(val.kind(), ValKind::ExternRef);
39
EXPECT_EQ(val.externref(), std::nullopt);
40
41
val = std::optional<ExternRef>(ExternRef(store, 5));
42
EXPECT_EQ(val.kind(), ValKind::ExternRef);
43
EXPECT_EQ(std::any_cast<int>(val.externref()->data(store)), 5);
44
45
val = ExternRef(store, 5);
46
EXPECT_EQ(val.kind(), ValKind::ExternRef);
47
EXPECT_EQ(std::any_cast<int>(val.externref()->data(store)), 5);
48
49
val = std::optional<AnyRef>(std::nullopt);
50
EXPECT_EQ(val.kind(), ValKind::AnyRef);
51
EXPECT_EQ(val.anyref(), std::nullopt);
52
53
val = std::optional<AnyRef>(AnyRef::i31(store, 5));
54
EXPECT_EQ(val.kind(), ValKind::AnyRef);
55
EXPECT_EQ(val.anyref()->i31(store), 5);
56
EXPECT_EQ(val.anyref()->u31(store), 5);
57
58
val = AnyRef::i31(store, -5);
59
EXPECT_EQ(val.kind(), ValKind::AnyRef);
60
EXPECT_EQ(val.anyref()->i31(store), -5);
61
EXPECT_EQ(val.anyref()->u31(store), 0x7ffffffb);
62
63
val = std::optional<Func>(std::nullopt);
64
EXPECT_EQ(val.kind(), ValKind::FuncRef);
65
EXPECT_EQ(val.funcref(), std::nullopt);
66
67
Func func(store, FuncType({}, {}),
68
[](auto caller, auto params, auto results) -> auto {
69
return std::monostate();
70
});
71
72
val = std::optional<Func>(func);
73
EXPECT_EQ(val.kind(), ValKind::FuncRef);
74
75
val = func;
76
EXPECT_EQ(val.kind(), ValKind::FuncRef);
77
}
78
79
class SetOnDrop {
80
std::shared_ptr<std::atomic<bool>> flag_;
81
82
public:
83
SetOnDrop() : flag_(std::make_shared<std::atomic<bool>>(false)) {}
84
SetOnDrop(const SetOnDrop &) = delete;
85
SetOnDrop(SetOnDrop &&obj) : flag_(obj.flag_) { obj.flag_.reset(); }
86
~SetOnDrop() {
87
if (flag_)
88
flag_->store(true);
89
}
90
91
const std::shared_ptr<std::atomic<bool>> &flag() { return this->flag_; }
92
};
93
94
TEST(Val, DropsExternRef) {
95
std::shared_ptr<std::atomic<bool>> flag;
96
Engine engine;
97
Store store(engine);
98
99
// smoke test for `SetOnDrop` itself
100
{
101
SetOnDrop guard;
102
flag = guard.flag();
103
EXPECT_FALSE(flag->load());
104
}
105
EXPECT_TRUE(flag->load());
106
107
// Test that if an `ExternRef` is created and dropped it doesn't leak.
108
{
109
SetOnDrop guard;
110
flag = guard.flag();
111
ExternRef r(store, std::make_shared<SetOnDrop>(std::move(guard)));
112
EXPECT_FALSE(flag->load());
113
store.gc();
114
EXPECT_FALSE(flag->load());
115
}
116
EXPECT_FALSE(flag->load());
117
store.gc();
118
EXPECT_TRUE(flag->load());
119
120
// Test that if a `Val(ExternRef)` is created and dropped it doesn't leak.
121
{
122
SetOnDrop guard;
123
flag = guard.flag();
124
ExternRef r(store, std::make_shared<SetOnDrop>(std::move(guard)));
125
Val v(r);
126
EXPECT_FALSE(flag->load());
127
store.gc();
128
EXPECT_FALSE(flag->load());
129
}
130
EXPECT_FALSE(flag->load());
131
store.gc();
132
EXPECT_TRUE(flag->load());
133
134
// Similar to above testing a variety of APIs.
135
{
136
SetOnDrop guard;
137
flag = guard.flag();
138
ExternRef r(store, std::make_shared<SetOnDrop>(std::move(guard)));
139
ExternRef r2 = r;
140
ExternRef r3(r2);
141
r3 = r2;
142
r = std::move(r2);
143
144
Val v(r3);
145
Val v2 = v;
146
Val v3(v2);
147
v3 = v2;
148
v = std::move(v2);
149
150
store.gc();
151
EXPECT_FALSE(flag->load());
152
}
153
EXPECT_FALSE(flag->load());
154
store.gc();
155
EXPECT_TRUE(flag->load());
156
}
157
158