forked from luajit-remake/luajit-remake
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtest_boxing.cpp
106 lines (97 loc) · 3.31 KB
/
test_boxing.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#include "runtime_utils.h"
#include "gtest/gtest.h"
TEST(NaNBoxing, Correctness)
{
// test int
//
for (int testcase = 0; testcase < 100000; testcase++)
{
int x1 = rand() % 65536;
int x2 = rand() % 65536;
uint32_t v = (static_cast<uint32_t>(x1) << 16) + static_cast<uint32_t>(x2);
int32_t value = static_cast<int32_t>(v);
TValue r = TValue::CreateInt32(value);
ReleaseAssert(r.IsInt32());
ReleaseAssert(!r.IsMIV());
ReleaseAssert(!r.IsDouble());
ReleaseAssert(!r.IsPointer());
ReleaseAssert(r.AsInt32() == value);
}
// test MIV
//
{
auto testValue = [](MiscImmediateValue value)
{
TValue r = TValue::CreateMIV(value);
ReleaseAssert(!r.IsInt32());
ReleaseAssert(r.IsMIV());
ReleaseAssert(!r.IsDouble());
ReleaseAssert(!r.IsPointer());
ReleaseAssert(r.AsMIV().m_value == value.m_value);
};
testValue(MiscImmediateValue { MiscImmediateValue::x_nil });
testValue(MiscImmediateValue { MiscImmediateValue::x_false });
testValue(MiscImmediateValue { MiscImmediateValue::x_true });
}
// test double
//
{
auto testValue = [](double value)
{
TValue r = TValue::CreateDouble(value);
ReleaseAssert(!r.IsInt32());
ReleaseAssert(!r.IsMIV());
ReleaseAssert(r.IsDouble());
ReleaseAssert(!r.IsPointer());
if (std::isnan(value))
{
ReleaseAssert(std::isnan(r.AsDouble()));
}
else
{
SUPRESS_FLOAT_EQUAL_WARNING(ReleaseAssert(r.AsDouble() == value);)
}
};
auto testWithRange = [&testValue](double lb, double ub)
{
std::uniform_real_distribution<double> unif(lb, ub);
std::default_random_engine re;
for (int testcase = 0; testcase < 50000; testcase++)
{
double value = unif(re);
testValue(value);
}
};
testWithRange(-1e300, 1e300);
testWithRange(-10000, 10000);
testWithRange(-1, 1);
testWithRange(-1e-30, 1e-30);
testWithRange(-1e-305, 1e-305);
testWithRange(-1e-315, 1e-315);
testWithRange(-1e-321, 1e-321);
testValue(std::numeric_limits<double>::infinity());
testValue(-std::numeric_limits<double>::infinity());
testValue(std::numeric_limits<double>::quiet_NaN());
testValue(0);
testValue(-0);
}
// test pointer
//
{
for (int testcase = 0; testcase < 100000; testcase++)
{
int x1 = rand() % 65536;
int x2 = rand() % 65536;
uint32_t v = (static_cast<uint32_t>(x1) << 16) + static_cast<uint32_t>(x2);
v &= ~7U;
int64_t ptr = static_cast<int64_t>(0xFFFFFFFE00000000ULL + static_cast<uint32_t>(v));
UserHeapPointer<void> value { reinterpret_cast<HeapPtr<void>>(ptr) };
TValue r = TValue::CreatePointer(value);
ReleaseAssert(!r.IsInt32());
ReleaseAssert(!r.IsMIV());
ReleaseAssert(!r.IsDouble());
ReleaseAssert(r.IsPointer());
ReleaseAssert(r.AsPointer() == value);
}
}
}