Line data Source code
1 : // Copyright 2013 the V8 project authors. All rights reserved.
2 : // Redistribution and use in source and binary forms, with or without
3 : // modification, are permitted provided that the following conditions are
4 : // met:
5 : //
6 : // * Redistributions of source code must retain the above copyright
7 : // notice, this list of conditions and the following disclaimer.
8 : // * Redistributions in binary form must reproduce the above
9 : // copyright notice, this list of conditions and the following
10 : // disclaimer in the documentation and/or other materials provided
11 : // with the distribution.
12 : // * Neither the name of Google Inc. nor the names of its
13 : // contributors may be used to endorse or promote products derived
14 : // from this software without specific prior written permission.
15 : //
16 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 : // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 : // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 : // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 : // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 : // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 : // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 : // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 : // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 : // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 :
28 : #include <stdlib.h>
29 :
30 : #include <limits>
31 :
32 : #include "src/v8.h"
33 :
34 : #include "src/base/platform/platform.h"
35 : #include "src/code-stubs.h"
36 : #include "src/double.h"
37 : #include "src/factory.h"
38 : #include "src/macro-assembler.h"
39 : #include "src/objects-inl.h"
40 : #include "test/cctest/cctest.h"
41 : #include "test/cctest/test-code-stubs.h"
42 :
43 : namespace v8 {
44 : namespace internal {
45 :
46 0 : int STDCALL ConvertDToICVersion(double d) {
47 : #if defined(V8_TARGET_BIG_ENDIAN)
48 : const int kExponentIndex = 0;
49 : const int kMantissaIndex = 1;
50 : #elif defined(V8_TARGET_LITTLE_ENDIAN)
51 : const int kExponentIndex = 1;
52 : const int kMantissaIndex = 0;
53 : #else
54 : #error Unsupported endianness
55 : #endif
56 : union { double d; uint32_t u[2]; } dbl;
57 0 : dbl.d = d;
58 0 : uint32_t exponent_bits = dbl.u[kExponentIndex];
59 : int32_t shifted_mask = static_cast<int32_t>(Double::kExponentMask >> 32);
60 0 : int32_t exponent = (((exponent_bits & shifted_mask) >>
61 0 : (Double::kPhysicalSignificandSize - 32)) -
62 0 : HeapNumber::kExponentBias);
63 0 : if (exponent < 0) {
64 : return 0;
65 : }
66 : uint32_t unsigned_exponent = static_cast<uint32_t>(exponent);
67 : int result = 0;
68 : uint32_t max_exponent =
69 : static_cast<uint32_t>(Double::kPhysicalSignificandSize);
70 0 : if (unsigned_exponent >= max_exponent) {
71 0 : if ((exponent - Double::kPhysicalSignificandSize) < 32) {
72 0 : result = dbl.u[kMantissaIndex]
73 0 : << (exponent - Double::kPhysicalSignificandSize);
74 : }
75 : } else {
76 : uint64_t big_result =
77 0 : (bit_cast<uint64_t>(d) & Double::kSignificandMask) | Double::kHiddenBit;
78 0 : big_result = big_result >> (Double::kPhysicalSignificandSize - exponent);
79 0 : result = static_cast<uint32_t>(big_result);
80 : }
81 0 : if (static_cast<int32_t>(exponent_bits) < 0) {
82 0 : return (0 - result);
83 : } else {
84 : return result;
85 : }
86 : }
87 :
88 :
89 2640 : void RunOneTruncationTestWithTest(ConvertDToICallWrapper callWrapper,
90 : ConvertDToIFunc func,
91 : double from,
92 : int32_t to) {
93 2640 : int32_t result = (*callWrapper)(func, from);
94 2640 : CHECK_EQ(to, result);
95 2640 : }
96 :
97 :
98 2640 : int32_t DefaultCallWrapper(ConvertDToIFunc func,
99 : double from) {
100 2640 : return (*func)(from);
101 : }
102 :
103 :
104 : // #define NaN and Infinity so that it's possible to cut-and-paste these tests
105 : // directly to a .js file and run them.
106 : #define NaN (std::numeric_limits<double>::quiet_NaN())
107 : #define Infinity (std::numeric_limits<double>::infinity())
108 : #define RunOneTruncationTest(p1, p2) \
109 : RunOneTruncationTestWithTest(callWrapper, func, p1, p2)
110 :
111 :
112 48 : void RunAllTruncationTests(ConvertDToIFunc func) {
113 48 : RunAllTruncationTests(DefaultCallWrapper, func);
114 48 : }
115 :
116 :
117 48 : void RunAllTruncationTests(ConvertDToICallWrapper callWrapper,
118 : ConvertDToIFunc func) {
119 48 : RunOneTruncationTest(0, 0);
120 48 : RunOneTruncationTest(0.5, 0);
121 48 : RunOneTruncationTest(-0.5, 0);
122 48 : RunOneTruncationTest(1.5, 1);
123 48 : RunOneTruncationTest(-1.5, -1);
124 48 : RunOneTruncationTest(5.5, 5);
125 48 : RunOneTruncationTest(-5.0, -5);
126 48 : RunOneTruncationTest(NaN, 0);
127 48 : RunOneTruncationTest(Infinity, 0);
128 48 : RunOneTruncationTest(-NaN, 0);
129 48 : RunOneTruncationTest(-Infinity, 0);
130 48 : RunOneTruncationTest(4.94065645841e-324, 0);
131 48 : RunOneTruncationTest(-4.94065645841e-324, 0);
132 :
133 48 : RunOneTruncationTest(0.9999999999999999, 0);
134 48 : RunOneTruncationTest(-0.9999999999999999, 0);
135 48 : RunOneTruncationTest(4294967296.0, 0);
136 48 : RunOneTruncationTest(-4294967296.0, 0);
137 48 : RunOneTruncationTest(9223372036854775000.0, -1024);
138 48 : RunOneTruncationTest(-9223372036854775000.0, 1024);
139 48 : RunOneTruncationTest(4.5036e+15, 372629504);
140 48 : RunOneTruncationTest(-4.5036e+15, -372629504);
141 :
142 48 : RunOneTruncationTest(287524199.5377777, 0x11234567);
143 48 : RunOneTruncationTest(-287524199.5377777, -0x11234567);
144 48 : RunOneTruncationTest(2300193596.302222, -1994773700);
145 48 : RunOneTruncationTest(-2300193596.302222, 1994773700);
146 48 : RunOneTruncationTest(4600387192.604444, 305419896);
147 48 : RunOneTruncationTest(-4600387192.604444, -305419896);
148 48 : RunOneTruncationTest(4823855600872397.0, 1737075661);
149 48 : RunOneTruncationTest(-4823855600872397.0, -1737075661);
150 :
151 48 : RunOneTruncationTest(4503603922337791.0, -1);
152 48 : RunOneTruncationTest(-4503603922337791.0, 1);
153 48 : RunOneTruncationTest(4503601774854143.0, 2147483647);
154 48 : RunOneTruncationTest(-4503601774854143.0, -2147483647);
155 48 : RunOneTruncationTest(9007207844675582.0, -2);
156 48 : RunOneTruncationTest(-9007207844675582.0, 2);
157 :
158 48 : RunOneTruncationTest(2.4178527921507624e+24, -536870912);
159 48 : RunOneTruncationTest(-2.4178527921507624e+24, 536870912);
160 48 : RunOneTruncationTest(2.417853945072267e+24, -536870912);
161 48 : RunOneTruncationTest(-2.417853945072267e+24, 536870912);
162 :
163 48 : RunOneTruncationTest(4.8357055843015248e+24, -1073741824);
164 48 : RunOneTruncationTest(-4.8357055843015248e+24, 1073741824);
165 48 : RunOneTruncationTest(4.8357078901445341e+24, -1073741824);
166 48 : RunOneTruncationTest(-4.8357078901445341e+24, 1073741824);
167 :
168 48 : RunOneTruncationTest(2147483647.0, 2147483647);
169 48 : RunOneTruncationTest(-2147483648.0, -2147483647-1);
170 48 : RunOneTruncationTest(9.6714111686030497e+24, -2147483647-1);
171 48 : RunOneTruncationTest(-9.6714111686030497e+24, -2147483647-1);
172 48 : RunOneTruncationTest(9.6714157802890681e+24, -2147483647-1);
173 48 : RunOneTruncationTest(-9.6714157802890681e+24, -2147483647-1);
174 48 : RunOneTruncationTest(1.9342813113834065e+25, -2147483647-1);
175 48 : RunOneTruncationTest(-1.9342813113834065e+25, -2147483647-1);
176 :
177 48 : RunOneTruncationTest(3.868562622766813e+25, 0);
178 48 : RunOneTruncationTest(-3.868562622766813e+25, 0);
179 48 : RunOneTruncationTest(1.7976931348623157e+308, 0);
180 48 : RunOneTruncationTest(-1.7976931348623157e+308, 0);
181 48 : }
182 :
183 : #undef NaN
184 : #undef Infinity
185 : #undef RunOneTruncationTest
186 :
187 :
188 23724 : TEST(CodeStubMajorKeys) {
189 6 : CcTest::InitializeVM();
190 6 : LocalContext context;
191 : Isolate* isolate = CcTest::i_isolate();
192 :
193 : #define CHECK_STUB(NAME) \
194 : { \
195 : HandleScope scope(isolate); \
196 : NAME##Stub stub_impl(0xabcd, isolate); \
197 : CodeStub* stub = &stub_impl; \
198 : CHECK_EQ(stub->MajorKey(), CodeStub::NAME); \
199 : }
200 192 : CODE_STUB_LIST(CHECK_STUB);
201 6 : }
202 :
203 : } // namespace internal
204 71154 : } // namespace v8
|