1 // 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 31 #include "src/base/utils/random-number-generator.h" 32 #include "src/v8.h" 33 34 namespace v8 { 35 namespace internal { 36 37 38 class Types { 39 public: 40 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); 45 PROPER_BITSET_TYPE_LIST(DECLARE_TYPE) 46 #undef DECLARE_TYPE 47 48 SignedSmall = Type::SignedSmall(); 49 UnsignedSmall = Type::UnsignedSmall(); 50 51 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(); 58 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); 62 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) { 67 types.push_back(Type::Class(*it, zone)); 68 } 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(); 76 SmiConstant = Type::Constant(smi, zone); 77 Signed32Constant = Type::Constant(signed32, zone); 78 79 ObjectConstant1 = Type::Constant(object1, zone); 80 ObjectConstant2 = Type::Constant(object2, zone); 81 ArrayConstant = Type::Constant(array, zone); 82 UninitializedConstant = Type::Constant(uninitialized, zone); 83 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) { 91 types.push_back(Type::Constant(*it, zone)); 92 } 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 105 Integer = Type::Range(-V8_INFINITY, +V8_INFINITY, zone); 106 107 NumberArray = Type::Array(Number, zone); 108 StringArray = Type::Array(String, zone); 109 AnyArray = Type::Array(Any, zone); 110 111 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); 115 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 133 #define DECLARE_TYPE(name, value) Type* name; 134 PROPER_BITSET_TYPE_LIST(DECLARE_TYPE) 135 #undef DECLARE_TYPE 136 137 #define DECLARE_TYPE(name, value) Type* Mask##name##ForTesting; 138 MASK_BITSET_TYPE_LIST(DECLARE_TYPE) 139 #undef DECLARE_TYPE 140 Type* SignedSmall; 141 Type* UnsignedSmall; 142 143 Type* ObjectClass; 144 Type* ArrayClass; 145 Type* NumberClass; 146 Type* UninitializedClass; 147 148 Type* SmiConstant; 149 Type* Signed32Constant; 150 Type* ObjectConstant1; 151 Type* ObjectConstant2; 152 Type* ArrayConstant; 153 Type* UninitializedConstant; 154 155 Type* Integer; 156 157 Type* NumberArray; 158 Type* StringArray; 159 Type* AnyArray; 160 161 Type* SignedFunction1; 162 Type* NumberFunction1; 163 Type* NumberFunction2; 164 Type* MethodFunction; 165 166 typedef std::vector<Type*> TypeVector; 167 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 175 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_); 183 } 184 185 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_); 193 } 194 195 Type* Function1(Type* result, Type* receiver, Type* arg) { 196 Type* type = Type::Function(result, receiver, 1, zone_); 197 type->AsFunction()->InitParameter(0, arg); 198 return type; 199 } 200 201 Type* Function2(Type* result, Type* arg1, Type* arg2) { 202 return Type::Function(result, arg1, arg2, zone_); 203 } 204 205 Type* Union(Type* t1, Type* t2) { return Type::Union(t1, t2, zone_); } 206 207 Type* Intersect(Type* t1, Type* t2) { return Type::Intersect(t1, t2, zone_); } 208 209 Type* Representation(Type* t) { return Type::Representation(t, zone_); } 210 211 Type* Semantic(Type* t) { return Type::Semantic(t, zone_); } 212 213 Type* Random() { 214 return types[rng_->NextInt(static_cast<int>(types.size()))]; 215 } 216 217 Type* Fuzz(int depth = 4) { 218 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. 224 Type* result = Type::Any(); 225 for (int i = 0, m = 1 + rng_->NextInt(3); i < m; ++i) { 226 int j = rng_->NextInt(n); 227 #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 } 237 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())); 244 return Type::Class(maps[i], zone_); 245 } 246 case 2: { // constant 247 int i = rng_->NextInt(static_cast<int>(values.size())); 248 return Type::Constant(values[i], zone_); 249 } 250 case 3: { // range 251 int i = rng_->NextInt(static_cast<int>(integers.size())); 252 int j = rng_->NextInt(static_cast<int>(integers.size())); 253 double min = integers[i]->Number(); 254 double max = integers[j]->Number(); 255 if (min > max) std::swap(min, max); 256 return Type::Range(min, max, zone_); 257 } 258 case 4: { // context 259 int depth = rng_->NextInt(3); 260 Type* type = Type::Internal(); 261 for (int i = 0; i < depth; ++i) type = Type::Context(type, zone_); 262 return type; 263 } 264 case 5: { // array 265 Type* element = Fuzz(depth / 2); 266 return Type::Array(element, zone_); 267 } 268 case 6: 269 case 7: { // function 270 Type* result = Fuzz(depth / 2); 271 Type* receiver = Fuzz(depth / 2); 272 int arity = rng_->NextInt(3); 273 Type* type = Type::Function(result, receiver, arity, zone_); 274 for (int i = 0; i < type->AsFunction()->Arity(); ++i) { 275 Type* parameter = Fuzz(depth / 2); 276 type->AsFunction()->InitParameter(i, parameter); 277 } 278 return type; 279 } 280 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 285 Type* (*simd_constructors[num_simd_types])(Isolate*, Zone*) = { 286 #define COUNT_SIMD_TYPE(NAME, Name, name, lane_count, lane_type) \ 287 &Type::Name, 288 SIMD128_TYPES(COUNT_SIMD_TYPE) 289 #undef COUNT_SIMD_TYPE 290 }; 291 return simd_constructors[rng_->NextInt(num_simd_types)](isolate_, 292 zone_); 293 } 294 default: { // union 295 int n = rng_->NextInt(10); 296 Type* type = None; 297 for (int i = 0; i < n; ++i) { 298 Type* operand = Fuzz(depth - 1); 299 type = Type::Union(type, operand, zone_); 300 } 301 return type; 302 } 303 } 304 UNREACHABLE(); 305 } 306 307 Zone* zone() { return zone_; } 308 309 private: 310 Zone* zone_; 311 Isolate* isolate_; 312 v8::base::RandomNumberGenerator* rng_; 313 }; 314 315 316 } // namespace internal 317 } // namespace v8 318 319 #endif 320