blob: 7bf9700b405b75e131a699073cb8da684649f449 [file] [log] [blame]
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001// Copyright 2014 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#ifndef V8_TEST_CCTEST_TYPES_H_
29#define V8_TEST_CCTEST_TYPES_H_
30
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000031#include "src/base/utils/random-number-generator.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040032#include "src/v8.h"
33
34namespace v8 {
35namespace internal {
36
37
Emily Bernierd0a1eb72015-03-24 16:35:39 -040038class Types {
39 public:
Ben Murdoch097c5b22016-05-18 11:27:45 +010040 Types(Zone* zone, Isolate* isolate, v8::base::RandomNumberGenerator* rng)
41 : zone_(zone), isolate_(isolate), rng_(rng) {
42#define DECLARE_TYPE(name, value) \
43 name = Type::name(); \
44 types.push_back(name);
Emily Bernierd0a1eb72015-03-24 16:35:39 -040045 PROPER_BITSET_TYPE_LIST(DECLARE_TYPE)
46 #undef DECLARE_TYPE
47
Ben Murdoch097c5b22016-05-18 11:27:45 +010048 SignedSmall = Type::SignedSmall();
49 UnsignedSmall = Type::UnsignedSmall();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000050
Emily Bernierd0a1eb72015-03-24 16:35:39 -040051 object_map = isolate->factory()->NewMap(
52 JS_OBJECT_TYPE, JSObject::kHeaderSize);
53 array_map = isolate->factory()->NewMap(
54 JS_ARRAY_TYPE, JSArray::kSize);
55 number_map = isolate->factory()->NewMap(
56 HEAP_NUMBER_TYPE, HeapNumber::kSize);
57 uninitialized_map = isolate->factory()->uninitialized_map();
Ben Murdoch097c5b22016-05-18 11:27:45 +010058 ObjectClass = Type::Class(object_map, zone);
59 ArrayClass = Type::Class(array_map, zone);
60 NumberClass = Type::Class(number_map, zone);
61 UninitializedClass = Type::Class(uninitialized_map, zone);
Emily Bernierd0a1eb72015-03-24 16:35:39 -040062
63 maps.push_back(object_map);
64 maps.push_back(array_map);
65 maps.push_back(uninitialized_map);
66 for (MapVector::iterator it = maps.begin(); it != maps.end(); ++it) {
Ben Murdoch097c5b22016-05-18 11:27:45 +010067 types.push_back(Type::Class(*it, zone));
Emily Bernierd0a1eb72015-03-24 16:35:39 -040068 }
69
70 smi = handle(Smi::FromInt(666), isolate);
71 signed32 = isolate->factory()->NewHeapNumber(0x40000000);
72 object1 = isolate->factory()->NewJSObjectFromMap(object_map);
73 object2 = isolate->factory()->NewJSObjectFromMap(object_map);
74 array = isolate->factory()->NewJSArray(20);
75 uninitialized = isolate->factory()->uninitialized_value();
Ben Murdoch097c5b22016-05-18 11:27:45 +010076 SmiConstant = Type::Constant(smi, zone);
77 Signed32Constant = Type::Constant(signed32, zone);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000078
Ben Murdoch097c5b22016-05-18 11:27:45 +010079 ObjectConstant1 = Type::Constant(object1, zone);
80 ObjectConstant2 = Type::Constant(object2, zone);
81 ArrayConstant = Type::Constant(array, zone);
82 UninitializedConstant = Type::Constant(uninitialized, zone);
Emily Bernierd0a1eb72015-03-24 16:35:39 -040083
84 values.push_back(smi);
85 values.push_back(signed32);
86 values.push_back(object1);
87 values.push_back(object2);
88 values.push_back(array);
89 values.push_back(uninitialized);
90 for (ValueVector::iterator it = values.begin(); it != values.end(); ++it) {
Ben Murdoch097c5b22016-05-18 11:27:45 +010091 types.push_back(Type::Constant(*it, zone));
Emily Bernierd0a1eb72015-03-24 16:35:39 -040092 }
93
94 integers.push_back(isolate->factory()->NewNumber(-V8_INFINITY));
95 integers.push_back(isolate->factory()->NewNumber(+V8_INFINITY));
96 integers.push_back(isolate->factory()->NewNumber(-rng_->NextInt(10)));
97 integers.push_back(isolate->factory()->NewNumber(+rng_->NextInt(10)));
98 for (int i = 0; i < 10; ++i) {
99 double x = rng_->NextInt();
100 integers.push_back(isolate->factory()->NewNumber(x));
101 x *= rng_->NextInt();
102 if (!IsMinusZero(x)) integers.push_back(isolate->factory()->NewNumber(x));
103 }
104
Ben Murdoch097c5b22016-05-18 11:27:45 +0100105 Integer = Type::Range(-V8_INFINITY, +V8_INFINITY, zone);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400106
Ben Murdoch097c5b22016-05-18 11:27:45 +0100107 NumberArray = Type::Array(Number, zone);
108 StringArray = Type::Array(String, zone);
109 AnyArray = Type::Array(Any, zone);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400110
Ben Murdoch097c5b22016-05-18 11:27:45 +0100111 SignedFunction1 = Type::Function(SignedSmall, SignedSmall, zone);
112 NumberFunction1 = Type::Function(Number, Number, zone);
113 NumberFunction2 = Type::Function(Number, Number, Number, zone);
114 MethodFunction = Type::Function(String, Object, 0, zone);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400115
116 for (int i = 0; i < 30; ++i) {
117 types.push_back(Fuzz());
118 }
119 }
120
121 Handle<i::Map> object_map;
122 Handle<i::Map> array_map;
123 Handle<i::Map> number_map;
124 Handle<i::Map> uninitialized_map;
125
126 Handle<i::Smi> smi;
127 Handle<i::HeapNumber> signed32;
128 Handle<i::JSObject> object1;
129 Handle<i::JSObject> object2;
130 Handle<i::JSArray> array;
131 Handle<i::Oddball> uninitialized;
132
Ben Murdoch097c5b22016-05-18 11:27:45 +0100133#define DECLARE_TYPE(name, value) Type* name;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400134 PROPER_BITSET_TYPE_LIST(DECLARE_TYPE)
135 #undef DECLARE_TYPE
136
Ben Murdoch097c5b22016-05-18 11:27:45 +0100137#define DECLARE_TYPE(name, value) Type* Mask##name##ForTesting;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000138 MASK_BITSET_TYPE_LIST(DECLARE_TYPE)
139#undef DECLARE_TYPE
Ben Murdoch097c5b22016-05-18 11:27:45 +0100140 Type* SignedSmall;
141 Type* UnsignedSmall;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000142
Ben Murdoch097c5b22016-05-18 11:27:45 +0100143 Type* ObjectClass;
144 Type* ArrayClass;
145 Type* NumberClass;
146 Type* UninitializedClass;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400147
Ben Murdoch097c5b22016-05-18 11:27:45 +0100148 Type* SmiConstant;
149 Type* Signed32Constant;
150 Type* ObjectConstant1;
151 Type* ObjectConstant2;
152 Type* ArrayConstant;
153 Type* UninitializedConstant;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400154
Ben Murdoch097c5b22016-05-18 11:27:45 +0100155 Type* Integer;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400156
Ben Murdoch097c5b22016-05-18 11:27:45 +0100157 Type* NumberArray;
158 Type* StringArray;
159 Type* AnyArray;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400160
Ben Murdoch097c5b22016-05-18 11:27:45 +0100161 Type* SignedFunction1;
162 Type* NumberFunction1;
163 Type* NumberFunction2;
164 Type* MethodFunction;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400165
Ben Murdoch097c5b22016-05-18 11:27:45 +0100166 typedef std::vector<Type*> TypeVector;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400167 typedef std::vector<Handle<i::Map> > MapVector;
168 typedef std::vector<Handle<i::Object> > ValueVector;
169
170 TypeVector types;
171 MapVector maps;
172 ValueVector values;
173 ValueVector integers; // "Integer" values used for range limits.
174
Ben Murdoch097c5b22016-05-18 11:27:45 +0100175 Type* Of(Handle<i::Object> value) { return Type::Of(value, zone_); }
176
177 Type* NowOf(Handle<i::Object> value) { return Type::NowOf(value, zone_); }
178
179 Type* Class(Handle<i::Map> map) { return Type::Class(map, zone_); }
180
181 Type* Constant(Handle<i::Object> value) {
182 return Type::Constant(value, zone_);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400183 }
184
Ben Murdoch097c5b22016-05-18 11:27:45 +0100185 Type* Range(double min, double max) { return Type::Range(min, max, zone_); }
186
187 Type* Context(Type* outer) { return Type::Context(outer, zone_); }
188
189 Type* Array1(Type* element) { return Type::Array(element, zone_); }
190
191 Type* Function0(Type* result, Type* receiver) {
192 return Type::Function(result, receiver, 0, zone_);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400193 }
194
Ben Murdoch097c5b22016-05-18 11:27:45 +0100195 Type* Function1(Type* result, Type* receiver, Type* arg) {
196 Type* type = Type::Function(result, receiver, 1, zone_);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400197 type->AsFunction()->InitParameter(0, arg);
198 return type;
199 }
200
Ben Murdoch097c5b22016-05-18 11:27:45 +0100201 Type* Function2(Type* result, Type* arg1, Type* arg2) {
202 return Type::Function(result, arg1, arg2, zone_);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400203 }
204
Ben Murdoch097c5b22016-05-18 11:27:45 +0100205 Type* Union(Type* t1, Type* t2) { return Type::Union(t1, t2, zone_); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000206
Ben Murdoch097c5b22016-05-18 11:27:45 +0100207 Type* Intersect(Type* t1, Type* t2) { return Type::Intersect(t1, t2, zone_); }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400208
Ben Murdoch097c5b22016-05-18 11:27:45 +0100209 Type* Representation(Type* t) { return Type::Representation(t, zone_); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000210
Ben Murdoch097c5b22016-05-18 11:27:45 +0100211 Type* Semantic(Type* t) { return Type::Semantic(t, zone_); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000212
Ben Murdoch097c5b22016-05-18 11:27:45 +0100213 Type* Random() {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400214 return types[rng_->NextInt(static_cast<int>(types.size()))];
215 }
216
Ben Murdoch097c5b22016-05-18 11:27:45 +0100217 Type* Fuzz(int depth = 4) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400218 switch (rng_->NextInt(depth == 0 ? 3 : 20)) {
219 case 0: { // bitset
220 #define COUNT_BITSET_TYPES(type, value) + 1
221 int n = 0 PROPER_BITSET_TYPE_LIST(COUNT_BITSET_TYPES);
222 #undef COUNT_BITSET_TYPES
223 // Pick a bunch of named bitsets and return their intersection.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100224 Type* result = Type::Any();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400225 for (int i = 0, m = 1 + rng_->NextInt(3); i < m; ++i) {
226 int j = rng_->NextInt(n);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100227#define PICK_BITSET_TYPE(type, value) \
228 if (j-- == 0) { \
229 Type* tmp = Type::Intersect(result, Type::type(), zone_); \
230 if (tmp->Is(Type::None()) && i != 0) { \
231 break; \
232 } else { \
233 result = tmp; \
234 continue; \
235 } \
236 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400237 PROPER_BITSET_TYPE_LIST(PICK_BITSET_TYPE)
238 #undef PICK_BITSET_TYPE
239 }
240 return result;
241 }
242 case 1: { // class
243 int i = rng_->NextInt(static_cast<int>(maps.size()));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100244 return Type::Class(maps[i], zone_);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400245 }
246 case 2: { // constant
247 int i = rng_->NextInt(static_cast<int>(values.size()));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100248 return Type::Constant(values[i], zone_);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400249 }
250 case 3: { // range
251 int i = rng_->NextInt(static_cast<int>(integers.size()));
252 int j = rng_->NextInt(static_cast<int>(integers.size()));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000253 double min = integers[i]->Number();
254 double max = integers[j]->Number();
255 if (min > max) std::swap(min, max);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100256 return Type::Range(min, max, zone_);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400257 }
258 case 4: { // context
259 int depth = rng_->NextInt(3);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100260 Type* type = Type::Internal();
261 for (int i = 0; i < depth; ++i) type = Type::Context(type, zone_);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400262 return type;
263 }
264 case 5: { // array
Ben Murdoch097c5b22016-05-18 11:27:45 +0100265 Type* element = Fuzz(depth / 2);
266 return Type::Array(element, zone_);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400267 }
268 case 6:
269 case 7: { // function
Ben Murdoch097c5b22016-05-18 11:27:45 +0100270 Type* result = Fuzz(depth / 2);
271 Type* receiver = Fuzz(depth / 2);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400272 int arity = rng_->NextInt(3);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100273 Type* type = Type::Function(result, receiver, arity, zone_);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400274 for (int i = 0; i < type->AsFunction()->Arity(); ++i) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100275 Type* parameter = Fuzz(depth / 2);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400276 type->AsFunction()->InitParameter(i, parameter);
277 }
278 return type;
279 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000280 case 8: { // simd
281 static const int num_simd_types =
282 #define COUNT_SIMD_TYPE(NAME, Name, name, lane_count, lane_type) +1
283 SIMD128_TYPES(COUNT_SIMD_TYPE);
284 #undef COUNT_SIMD_TYPE
Ben Murdoch097c5b22016-05-18 11:27:45 +0100285 Type* (*simd_constructors[num_simd_types])(Isolate*, Zone*) = {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000286 #define COUNT_SIMD_TYPE(NAME, Name, name, lane_count, lane_type) \
287 &Type::Name,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100288 SIMD128_TYPES(COUNT_SIMD_TYPE)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000289 #undef COUNT_SIMD_TYPE
290 };
Ben Murdoch097c5b22016-05-18 11:27:45 +0100291 return simd_constructors[rng_->NextInt(num_simd_types)](isolate_,
292 zone_);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000293 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400294 default: { // union
295 int n = rng_->NextInt(10);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100296 Type* type = None;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400297 for (int i = 0; i < n; ++i) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100298 Type* operand = Fuzz(depth - 1);
299 type = Type::Union(type, operand, zone_);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400300 }
301 return type;
302 }
303 }
304 UNREACHABLE();
305 }
306
Ben Murdoch097c5b22016-05-18 11:27:45 +0100307 Zone* zone() { return zone_; }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400308
309 private:
Ben Murdoch097c5b22016-05-18 11:27:45 +0100310 Zone* zone_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000311 Isolate* isolate_;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400312 v8::base::RandomNumberGenerator* rng_;
313};
314
315
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000316} // namespace internal
317} // namespace v8
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400318
319#endif