The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / deps / v8 / test / cctest / test-types.cc @ f230a1cf

History | View | Annotate | Download (26.7 KB)

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 "cctest.h"
29
#include "types.h"
30

    
31
using namespace v8::internal;
32

    
33
// Testing auxiliaries (breaking the Type abstraction).
34
static bool IsBitset(Type* type) { return type->IsSmi(); }
35
static bool IsClass(Type* type) { return type->IsMap(); }
36
static bool IsConstant(Type* type) { return type->IsBox(); }
37
static bool IsUnion(Type* type) { return type->IsFixedArray(); }
38

    
39
static int AsBitset(Type* type) { return Smi::cast(type)->value(); }
40
static Map* AsClass(Type* type) { return Map::cast(type); }
41
static Object* AsConstant(Type* type) { return Box::cast(type)->value(); }
42
static FixedArray* AsUnion(Type* type) { return FixedArray::cast(type); }
43

    
44

    
45
static void CheckEqual(Handle<Type> type1, Handle<Type> type2) {
46
  CHECK_EQ(IsBitset(*type1), IsBitset(*type2));
47
  CHECK_EQ(IsClass(*type1), IsClass(*type2));
48
  CHECK_EQ(IsConstant(*type1), IsConstant(*type2));
49
  CHECK_EQ(IsUnion(*type1), IsUnion(*type2));
50
  CHECK_EQ(type1->NumClasses(), type2->NumClasses());
51
  CHECK_EQ(type1->NumConstants(), type2->NumConstants());
52
  if (IsBitset(*type1)) {
53
    CHECK_EQ(AsBitset(*type1), AsBitset(*type2));
54
  } else if (IsClass(*type1)) {
55
    CHECK_EQ(AsClass(*type1), AsClass(*type2));
56
  } else if (IsConstant(*type1)) {
57
    CHECK_EQ(AsConstant(*type1), AsConstant(*type2));
58
  } else if (IsUnion(*type1)) {
59
    CHECK_EQ(AsUnion(*type1)->length(), AsUnion(*type2)->length());
60
  }
61
  CHECK(type1->Is(type2));
62
  CHECK(type2->Is(type1));
63
}
64

    
65

    
66
static void CheckSub(Handle<Type> type1, Handle<Type> type2) {
67
  CHECK(type1->Is(type2));
68
  CHECK(!type2->Is(type1));
69
  if (IsBitset(*type1) && IsBitset(*type2)) {
70
    CHECK_NE(AsBitset(*type1), AsBitset(*type2));
71
  }
72
}
73

    
74

    
75
static void CheckUnordered(Handle<Type> type1, Handle<Type> type2) {
76
  CHECK(!type1->Is(type2));
77
  CHECK(!type2->Is(type1));
78
  if (IsBitset(*type1) && IsBitset(*type2)) {
79
    CHECK_NE(AsBitset(*type1), AsBitset(*type2));
80
  }
81
}
82

    
83

    
84
static void CheckOverlap(Handle<Type> type1, Handle<Type> type2) {
85
  CHECK(type1->Maybe(type2));
86
  CHECK(type2->Maybe(type1));
87
  if (IsBitset(*type1) && IsBitset(*type2)) {
88
    CHECK_NE(0, AsBitset(*type1) & AsBitset(*type2));
89
  }
90
}
91

    
92

    
93
static void CheckDisjoint(Handle<Type> type1, Handle<Type> type2) {
94
  CHECK(!type1->Is(type2));
95
  CHECK(!type2->Is(type1));
96
  CHECK(!type1->Maybe(type2));
97
  CHECK(!type2->Maybe(type1));
98
  if (IsBitset(*type1) && IsBitset(*type2)) {
99
    CHECK_EQ(0, AsBitset(*type1) & AsBitset(*type2));
100
  }
101
}
102

    
103

    
104
class HandlifiedTypes {
105
 public:
106
  explicit HandlifiedTypes(Isolate* isolate) :
107
      None(Type::None(), isolate),
108
      Any(Type::Any(), isolate),
109
      Oddball(Type::Oddball(), isolate),
110
      Boolean(Type::Boolean(), isolate),
111
      Null(Type::Null(), isolate),
112
      Undefined(Type::Undefined(), isolate),
113
      Number(Type::Number(), isolate),
114
      Smi(Type::Smi(), isolate),
115
      Signed32(Type::Signed32(), isolate),
116
      Double(Type::Double(), isolate),
117
      Name(Type::Name(), isolate),
118
      UniqueName(Type::UniqueName(), isolate),
119
      String(Type::String(), isolate),
120
      InternalizedString(Type::InternalizedString(), isolate),
121
      Symbol(Type::Symbol(), isolate),
122
      Receiver(Type::Receiver(), isolate),
123
      Object(Type::Object(), isolate),
124
      Array(Type::Array(), isolate),
125
      Function(Type::Function(), isolate),
126
      Proxy(Type::Proxy(), isolate),
127
      object_map(isolate->factory()->NewMap(JS_OBJECT_TYPE, 3 * kPointerSize)),
128
      array_map(isolate->factory()->NewMap(JS_ARRAY_TYPE, 4 * kPointerSize)),
129
      isolate_(isolate) {
130
    smi = handle(Smi::FromInt(666), isolate);
131
    signed32 = isolate->factory()->NewHeapNumber(0x40000000);
132
    object1 = isolate->factory()->NewJSObjectFromMap(object_map);
133
    object2 = isolate->factory()->NewJSObjectFromMap(object_map);
134
    array = isolate->factory()->NewJSArray(20);
135
    ObjectClass = Class(object_map);
136
    ArrayClass = Class(array_map);
137
    SmiConstant = Constant(smi);
138
    Signed32Constant = Constant(signed32);
139
    ObjectConstant1 = Constant(object1);
140
    ObjectConstant2 = Constant(object2);
141
    ArrayConstant1 = Constant(array);
142
    ArrayConstant2 = Constant(array);
143
  }
144

    
145
  Handle<Type> None;
146
  Handle<Type> Any;
147
  Handle<Type> Oddball;
148
  Handle<Type> Boolean;
149
  Handle<Type> Null;
150
  Handle<Type> Undefined;
151
  Handle<Type> Number;
152
  Handle<Type> Smi;
153
  Handle<Type> Signed32;
154
  Handle<Type> Double;
155
  Handle<Type> Name;
156
  Handle<Type> UniqueName;
157
  Handle<Type> String;
158
  Handle<Type> InternalizedString;
159
  Handle<Type> Symbol;
160
  Handle<Type> Receiver;
161
  Handle<Type> Object;
162
  Handle<Type> Array;
163
  Handle<Type> Function;
164
  Handle<Type> Proxy;
165

    
166
  Handle<Type> ObjectClass;
167
  Handle<Type> ArrayClass;
168

    
169
  Handle<Type> SmiConstant;
170
  Handle<Type> Signed32Constant;
171
  Handle<Type> ObjectConstant1;
172
  Handle<Type> ObjectConstant2;
173
  Handle<Type> ArrayConstant1;
174
  Handle<Type> ArrayConstant2;
175

    
176
  Handle<Map> object_map;
177
  Handle<Map> array_map;
178

    
179
  Handle<i::Smi> smi;
180
  Handle<HeapNumber> signed32;
181
  Handle<JSObject> object1;
182
  Handle<JSObject> object2;
183
  Handle<JSArray> array;
184

    
185
  Handle<Type> Class(Handle<Map> map) {
186
    return handle(Type::Class(map), isolate_);
187
  }
188
  Handle<Type> Constant(Handle<i::Object> value) {
189
    return handle(Type::Constant(value, isolate_), isolate_);
190
  }
191
  Handle<Type> Union(Handle<Type> type1, Handle<Type> type2) {
192
    return handle(Type::Union(type1, type2), isolate_);
193
  }
194
  Handle<Type> Intersect(Handle<Type> type1, Handle<Type> type2) {
195
    return handle(Type::Intersect(type1, type2), isolate_);
196
  }
197

    
198
 private:
199
  Isolate* isolate_;
200
};
201

    
202

    
203
TEST(Bitset) {
204
  CcTest::InitializeVM();
205
  Isolate* isolate = CcTest::i_isolate();
206
  HandleScope scope(isolate);
207
  HandlifiedTypes T(isolate);
208

    
209
  CHECK(IsBitset(*T.None));
210
  CHECK(IsBitset(*T.Any));
211
  CHECK(IsBitset(*T.String));
212
  CHECK(IsBitset(*T.Object));
213

    
214
  CHECK(IsBitset(Type::Union(T.String, T.Number)));
215
  CHECK(IsBitset(Type::Union(T.String, T.Receiver)));
216
  CHECK(IsBitset(Type::Optional(T.Object)));
217

    
218
  CHECK_EQ(0, AsBitset(*T.None));
219
  CHECK_EQ(AsBitset(*T.Number) | AsBitset(*T.String),
220
           AsBitset(Type::Union(T.String, T.Number)));
221
  CHECK_EQ(AsBitset(*T.Receiver),
222
           AsBitset(Type::Union(T.Receiver, T.Object)));
223
  CHECK_EQ(AsBitset(*T.String) | AsBitset(*T.Undefined),
224
           AsBitset(Type::Optional(T.String)));
225
}
226

    
227

    
228
TEST(Class) {
229
  CcTest::InitializeVM();
230
  Isolate* isolate = CcTest::i_isolate();
231
  HandleScope scope(isolate);
232
  HandlifiedTypes T(isolate);
233

    
234
  CHECK(IsClass(*T.ObjectClass));
235
  CHECK(IsClass(*T.ArrayClass));
236

    
237
  CHECK(*T.object_map == AsClass(*T.ObjectClass));
238
  CHECK(*T.array_map == AsClass(*T.ArrayClass));
239
}
240

    
241

    
242
TEST(Constant) {
243
  CcTest::InitializeVM();
244
  Isolate* isolate = CcTest::i_isolate();
245
  HandleScope scope(isolate);
246
  HandlifiedTypes T(isolate);
247

    
248
  CHECK(IsConstant(*T.SmiConstant));
249
  CHECK(IsConstant(*T.ObjectConstant1));
250
  CHECK(IsConstant(*T.ObjectConstant2));
251
  CHECK(IsConstant(*T.ArrayConstant1));
252
  CHECK(IsConstant(*T.ArrayConstant2));
253

    
254
  CHECK(*T.smi == AsConstant(*T.SmiConstant));
255
  CHECK(*T.object1 == AsConstant(*T.ObjectConstant1));
256
  CHECK(*T.object2 == AsConstant(*T.ObjectConstant2));
257
  CHECK(*T.object1 != AsConstant(*T.ObjectConstant2));
258
  CHECK(*T.array == AsConstant(*T.ArrayConstant1));
259
  CHECK(*T.array == AsConstant(*T.ArrayConstant2));
260
}
261

    
262

    
263
TEST(Is) {
264
  CcTest::InitializeVM();
265
  Isolate* isolate = CcTest::i_isolate();
266
  HandleScope scope(isolate);
267
  HandlifiedTypes T(isolate);
268

    
269
  // Reflexivity
270
  CHECK(T.None->Is(T.None));
271
  CHECK(T.Any->Is(T.Any));
272
  CHECK(T.Object->Is(T.Object));
273

    
274
  CHECK(T.ObjectClass->Is(T.ObjectClass));
275
  CHECK(T.ObjectConstant1->Is(T.ObjectConstant1));
276
  CHECK(T.ArrayConstant1->Is(T.ArrayConstant2));
277

    
278
  // Symmetry and Transitivity
279
  CheckSub(T.None, T.Number);
280
  CheckSub(T.None, T.Any);
281

    
282
  CheckSub(T.Oddball, T.Any);
283
  CheckSub(T.Boolean, T.Oddball);
284
  CheckSub(T.Null, T.Oddball);
285
  CheckSub(T.Undefined, T.Oddball);
286
  CheckUnordered(T.Boolean, T.Null);
287
  CheckUnordered(T.Undefined, T.Null);
288
  CheckUnordered(T.Boolean, T.Undefined);
289

    
290
  CheckSub(T.Number, T.Any);
291
  CheckSub(T.Smi, T.Number);
292
  CheckSub(T.Signed32, T.Number);
293
  CheckSub(T.Double, T.Number);
294
  CheckSub(T.Smi, T.Signed32);
295
  CheckUnordered(T.Smi, T.Double);
296
  CheckUnordered(T.Signed32, T.Double);
297

    
298
  CheckSub(T.Name, T.Any);
299
  CheckSub(T.UniqueName, T.Any);
300
  CheckSub(T.UniqueName, T.Name);
301
  CheckSub(T.String, T.Name);
302
  CheckSub(T.InternalizedString, T.String);
303
  CheckSub(T.InternalizedString, T.UniqueName);
304
  CheckSub(T.InternalizedString, T.Name);
305
  CheckSub(T.Symbol, T.UniqueName);
306
  CheckSub(T.Symbol, T.Name);
307
  CheckUnordered(T.String, T.UniqueName);
308
  CheckUnordered(T.String, T.Symbol);
309
  CheckUnordered(T.InternalizedString, T.Symbol);
310

    
311
  CheckSub(T.Receiver, T.Any);
312
  CheckSub(T.Object, T.Any);
313
  CheckSub(T.Object, T.Receiver);
314
  CheckSub(T.Array, T.Object);
315
  CheckSub(T.Function, T.Object);
316
  CheckSub(T.Proxy, T.Receiver);
317
  CheckUnordered(T.Object, T.Proxy);
318
  CheckUnordered(T.Array, T.Function);
319

    
320
  // Structured subtyping
321
  CheckSub(T.None, T.ObjectClass);
322
  CheckSub(T.None, T.ObjectConstant1);
323
  CheckSub(T.ObjectClass, T.Any);
324
  CheckSub(T.ObjectConstant1, T.Any);
325

    
326
  CheckSub(T.ObjectClass, T.Object);
327
  CheckSub(T.ArrayClass, T.Object);
328
  CheckUnordered(T.ObjectClass, T.ArrayClass);
329

    
330
  CheckSub(T.SmiConstant, T.Smi);
331
  CheckSub(T.SmiConstant, T.Signed32);
332
  CheckSub(T.SmiConstant, T.Number);
333
  CheckSub(T.ObjectConstant1, T.Object);
334
  CheckSub(T.ObjectConstant2, T.Object);
335
  CheckSub(T.ArrayConstant1, T.Object);
336
  CheckSub(T.ArrayConstant1, T.Array);
337
  CheckUnordered(T.ObjectConstant1, T.ObjectConstant2);
338
  CheckUnordered(T.ObjectConstant1, T.ArrayConstant1);
339

    
340
  CheckUnordered(T.ObjectConstant1, T.ObjectClass);
341
  CheckUnordered(T.ObjectConstant2, T.ObjectClass);
342
  CheckUnordered(T.ObjectConstant1, T.ArrayClass);
343
  CheckUnordered(T.ObjectConstant2, T.ArrayClass);
344
  CheckUnordered(T.ArrayConstant1, T.ObjectClass);
345
}
346

    
347

    
348
TEST(Maybe) {
349
  CcTest::InitializeVM();
350
  Isolate* isolate = CcTest::i_isolate();
351
  HandleScope scope(isolate);
352
  HandlifiedTypes T(isolate);
353

    
354
  CheckOverlap(T.Any, T.Any);
355
  CheckOverlap(T.Object, T.Object);
356

    
357
  CheckOverlap(T.Oddball, T.Any);
358
  CheckOverlap(T.Boolean, T.Oddball);
359
  CheckOverlap(T.Null, T.Oddball);
360
  CheckOverlap(T.Undefined, T.Oddball);
361
  CheckDisjoint(T.Boolean, T.Null);
362
  CheckDisjoint(T.Undefined, T.Null);
363
  CheckDisjoint(T.Boolean, T.Undefined);
364

    
365
  CheckOverlap(T.Number, T.Any);
366
  CheckOverlap(T.Smi, T.Number);
367
  CheckOverlap(T.Double, T.Number);
368
  CheckDisjoint(T.Signed32, T.Double);
369

    
370
  CheckOverlap(T.Name, T.Any);
371
  CheckOverlap(T.UniqueName, T.Any);
372
  CheckOverlap(T.UniqueName, T.Name);
373
  CheckOverlap(T.String, T.Name);
374
  CheckOverlap(T.InternalizedString, T.String);
375
  CheckOverlap(T.InternalizedString, T.UniqueName);
376
  CheckOverlap(T.InternalizedString, T.Name);
377
  CheckOverlap(T.Symbol, T.UniqueName);
378
  CheckOverlap(T.Symbol, T.Name);
379
  CheckOverlap(T.String, T.UniqueName);
380
  CheckDisjoint(T.String, T.Symbol);
381
  CheckDisjoint(T.InternalizedString, T.Symbol);
382

    
383
  CheckOverlap(T.Receiver, T.Any);
384
  CheckOverlap(T.Object, T.Any);
385
  CheckOverlap(T.Object, T.Receiver);
386
  CheckOverlap(T.Array, T.Object);
387
  CheckOverlap(T.Function, T.Object);
388
  CheckOverlap(T.Proxy, T.Receiver);
389
  CheckDisjoint(T.Object, T.Proxy);
390
  CheckDisjoint(T.Array, T.Function);
391

    
392
  CheckOverlap(T.ObjectClass, T.Any);
393
  CheckOverlap(T.ObjectConstant1, T.Any);
394

    
395
  CheckOverlap(T.ObjectClass, T.Object);
396
  CheckOverlap(T.ArrayClass, T.Object);
397
  CheckOverlap(T.ObjectClass, T.ObjectClass);
398
  CheckOverlap(T.ArrayClass, T.ArrayClass);
399
  CheckDisjoint(T.ObjectClass, T.ArrayClass);
400

    
401
  CheckOverlap(T.SmiConstant, T.Smi);
402
  CheckOverlap(T.SmiConstant, T.Signed32);
403
  CheckOverlap(T.SmiConstant, T.Number);
404
  CheckDisjoint(T.SmiConstant, T.Double);
405
  CheckOverlap(T.ObjectConstant1, T.Object);
406
  CheckOverlap(T.ObjectConstant2, T.Object);
407
  CheckOverlap(T.ArrayConstant1, T.Object);
408
  CheckOverlap(T.ArrayConstant1, T.Array);
409
  CheckOverlap(T.ArrayConstant1, T.ArrayConstant2);
410
  CheckOverlap(T.ObjectConstant1, T.ObjectConstant1);
411
  CheckDisjoint(T.ObjectConstant1, T.ObjectConstant2);
412
  CheckDisjoint(T.ObjectConstant1, T.ArrayConstant1);
413

    
414
  CheckDisjoint(T.ObjectConstant1, T.ObjectClass);
415
  CheckDisjoint(T.ObjectConstant2, T.ObjectClass);
416
  CheckDisjoint(T.ObjectConstant1, T.ArrayClass);
417
  CheckDisjoint(T.ObjectConstant2, T.ArrayClass);
418
  CheckDisjoint(T.ArrayConstant1, T.ObjectClass);
419
}
420

    
421

    
422
TEST(Union) {
423
  CcTest::InitializeVM();
424
  Isolate* isolate = CcTest::i_isolate();
425
  HandleScope scope(isolate);
426
  HandlifiedTypes T(isolate);
427

    
428
  // Bitset-bitset
429
  CHECK(IsBitset(Type::Union(T.Object, T.Number)));
430
  CHECK(IsBitset(Type::Union(T.Object, T.Object)));
431
  CHECK(IsBitset(Type::Union(T.Any, T.None)));
432

    
433
  CheckEqual(T.Union(T.None, T.Number), T.Number);
434
  CheckEqual(T.Union(T.Object, T.Proxy), T.Receiver);
435
  CheckEqual(T.Union(T.Number, T.String), T.Union(T.String, T.Number));
436
  CheckSub(T.Union(T.Number, T.String), T.Any);
437

    
438
  // Class-class
439
  CHECK(IsClass(Type::Union(T.ObjectClass, T.ObjectClass)));
440
  CHECK(IsUnion(Type::Union(T.ObjectClass, T.ArrayClass)));
441

    
442
  CheckEqual(T.Union(T.ObjectClass, T.ObjectClass), T.ObjectClass);
443
  CheckSub(T.None, T.Union(T.ObjectClass, T.ArrayClass));
444
  CheckSub(T.Union(T.ObjectClass, T.ArrayClass), T.Any);
445
  CheckSub(T.ObjectClass, T.Union(T.ObjectClass, T.ArrayClass));
446
  CheckSub(T.ArrayClass, T.Union(T.ObjectClass, T.ArrayClass));
447
  CheckSub(T.Union(T.ObjectClass, T.ArrayClass), T.Object);
448
  CheckUnordered(T.Union(T.ObjectClass, T.ArrayClass), T.Array);
449
  CheckOverlap(T.Union(T.ObjectClass, T.ArrayClass), T.Array);
450
  CheckDisjoint(T.Union(T.ObjectClass, T.ArrayClass), T.Number);
451

    
452
  // Constant-constant
453
  CHECK(IsConstant(Type::Union(T.ObjectConstant1, T.ObjectConstant1)));
454
  CHECK(IsConstant(Type::Union(T.ArrayConstant1, T.ArrayConstant1)));
455
  CHECK(IsUnion(Type::Union(T.ObjectConstant1, T.ObjectConstant2)));
456

    
457
  CheckEqual(T.Union(T.ObjectConstant1, T.ObjectConstant1), T.ObjectConstant1);
458
  CheckEqual(T.Union(T.ArrayConstant1, T.ArrayConstant1), T.ArrayConstant1);
459
  CheckEqual(T.Union(T.ArrayConstant1, T.ArrayConstant1), T.ArrayConstant2);
460
  CheckSub(T.None, T.Union(T.ObjectConstant1, T.ObjectConstant2));
461
  CheckSub(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.Any);
462
  CheckSub(T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2));
463
  CheckSub(T.ObjectConstant2, T.Union(T.ObjectConstant1, T.ObjectConstant2));
464
  CheckSub(T.ArrayConstant2, T.Union(T.ArrayConstant1, T.ObjectConstant2));
465
  CheckSub(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.Object);
466
  CheckUnordered(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.ObjectClass);
467
  CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.Array);
468
  CheckOverlap(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.Array);
469
  CheckOverlap(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.ArrayConstant2);
470
  CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.Number);
471
  CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.ObjectClass);
472

    
473
  // Bitset-class
474
  CHECK(IsBitset(Type::Union(T.ObjectClass, T.Object)));
475
  CHECK(IsUnion(Type::Union(T.ObjectClass, T.Number)));
476

    
477
  CheckEqual(T.Union(T.ObjectClass, T.Object), T.Object);
478
  CheckSub(T.None, T.Union(T.ObjectClass, T.Number));
479
  CheckSub(T.Union(T.ObjectClass, T.Number), T.Any);
480
  CheckSub(T.Union(T.ObjectClass, T.Smi), T.Union(T.Object, T.Number));
481
  CheckSub(T.Union(T.ObjectClass, T.Array), T.Object);
482
  CheckUnordered(T.Union(T.ObjectClass, T.String), T.Array);
483
  CheckOverlap(T.Union(T.ObjectClass, T.String), T.Object);
484
  CheckDisjoint(T.Union(T.ObjectClass, T.String), T.Number);
485

    
486
  // Bitset-constant
487
  CHECK(IsBitset(Type::Union(T.SmiConstant, T.Number)));
488
  CHECK(IsBitset(Type::Union(T.ObjectConstant1, T.Object)));
489
  CHECK(IsUnion(Type::Union(T.ObjectConstant2, T.Number)));
490

    
491
  CheckEqual(T.Union(T.SmiConstant, T.Number), T.Number);
492
  CheckEqual(T.Union(T.ObjectConstant1, T.Object), T.Object);
493
  CheckSub(T.None, T.Union(T.ObjectConstant1, T.Number));
494
  CheckSub(T.Union(T.ObjectConstant1, T.Number), T.Any);
495
  CheckSub(T.Union(T.ObjectConstant1, T.Signed32), T.Union(T.Object, T.Number));
496
  CheckSub(T.Union(T.ObjectConstant1, T.Array), T.Object);
497
  CheckUnordered(T.Union(T.ObjectConstant1, T.String), T.Array);
498
  CheckOverlap(T.Union(T.ObjectConstant1, T.String), T.Object);
499
  CheckDisjoint(T.Union(T.ObjectConstant1, T.String), T.Number);
500
  CheckEqual(T.Union(T.Signed32, T.Signed32Constant), T.Signed32);
501

    
502
  // Class-constant
503
  CHECK(IsUnion(Type::Union(T.ObjectConstant1, T.ObjectClass)));
504
  CHECK(IsUnion(Type::Union(T.ArrayClass, T.ObjectConstant2)));
505

    
506
  CheckSub(T.None, T.Union(T.ObjectConstant1, T.ArrayClass));
507
  CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass), T.Any);
508
  CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass), T.Object);
509
  CheckSub(T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ArrayClass));
510
  CheckSub(T.ArrayClass, T.Union(T.ObjectConstant1, T.ArrayClass));
511
  CheckUnordered(T.ObjectClass, T.Union(T.ObjectConstant1, T.ArrayClass));
512
  CheckSub(
513
      T.Union(T.ObjectConstant1, T.ArrayClass), T.Union(T.Array, T.Object));
514
  CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayClass), T.ArrayConstant1);
515
  CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectConstant2);
516
  CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectClass);
517

    
518
  // Bitset-union
519
  CHECK(IsBitset(
520
      Type::Union(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass))));
521
  CHECK(IsUnion(
522
      Type::Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.Number)));
523

    
524
  CheckEqual(
525
      T.Union(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)),
526
      T.Object);
527
  CheckEqual(
528
      T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number),
529
      T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass)));
530
  CheckSub(
531
      T.Double,
532
      T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number));
533
  CheckSub(
534
      T.ObjectConstant1,
535
      T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double));
536
  CheckSub(
537
      T.None,
538
      T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double));
539
  CheckSub(
540
      T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double),
541
      T.Any);
542
  CheckSub(
543
      T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double),
544
      T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass)));
545

    
546
  // Class-union
547
  CHECK(IsUnion(
548
      Type::Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass)));
549
  CHECK(IsUnion(
550
      Type::Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ObjectClass)));
551

    
552
  CheckEqual(
553
      T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)),
554
      T.Union(T.ObjectClass, T.ObjectConstant1));
555
  CheckSub(
556
      T.None,
557
      T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)));
558
  CheckSub(
559
      T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)),
560
      T.Any);
561
  CheckSub(
562
      T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)),
563
      T.Object);
564
  CheckEqual(
565
      T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass),
566
      T.Union(T.ArrayClass, T.ObjectConstant2));
567

    
568
  // Constant-union
569
  CHECK(IsUnion(Type::Union(
570
      T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2))));
571
  CHECK(IsUnion(Type::Union(
572
      T.Union(T.ArrayConstant1, T.ObjectClass), T.ObjectConstant1)));
573
  CHECK(IsUnion(Type::Union(
574
      T.Union(T.ArrayConstant1, T.ObjectConstant2), T.ObjectConstant1)));
575

    
576
  CheckEqual(
577
      T.Union(T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)),
578
      T.Union(T.ObjectConstant2, T.ObjectConstant1));
579
  CheckEqual(
580
      T.Union(T.Union(T.ArrayConstant1, T.ObjectConstant2), T.ObjectConstant1),
581
      T.Union(T.ObjectConstant2, T.Union(T.ArrayConstant1, T.ObjectConstant1)));
582

    
583
  // Union-union
584
  CHECK(IsBitset(Type::Union(
585
      T.Union(T.Number, T.ArrayClass), T.Union(T.Signed32, T.Array))));
586
  CHECK(IsUnion(Type::Union(
587
      T.Union(T.Number, T.ArrayClass), T.Union(T.ObjectClass, T.ArrayClass))));
588

    
589
  CheckEqual(
590
      T.Union(
591
          T.Union(T.ObjectConstant2, T.ObjectConstant1),
592
          T.Union(T.ObjectConstant1, T.ObjectConstant2)),
593
      T.Union(T.ObjectConstant2, T.ObjectConstant1));
594
  CheckEqual(
595
      T.Union(
596
          T.Union(T.ObjectConstant2, T.ArrayConstant1),
597
          T.Union(T.ObjectConstant1, T.ArrayConstant2)),
598
      T.Union(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.ArrayConstant1));
599
  CheckEqual(
600
      T.Union(T.Union(T.Number, T.ArrayClass), T.Union(T.Smi, T.Array)),
601
      T.Union(T.Number, T.Array));
602
}
603

    
604

    
605
TEST(Intersect) {
606
  CcTest::InitializeVM();
607
  Isolate* isolate = CcTest::i_isolate();
608
  HandleScope scope(isolate);
609
  HandlifiedTypes T(isolate);
610

    
611
  // Bitset-bitset
612
  CHECK(IsBitset(Type::Intersect(T.Object, T.Number)));
613
  CHECK(IsBitset(Type::Intersect(T.Object, T.Object)));
614
  CHECK(IsBitset(Type::Intersect(T.Any, T.None)));
615

    
616
  CheckEqual(T.Intersect(T.None, T.Number), T.None);
617
  CheckEqual(T.Intersect(T.Object, T.Proxy), T.None);
618
  CheckEqual(T.Intersect(T.Name, T.String), T.Intersect(T.String, T.Name));
619
  CheckEqual(T.Intersect(T.UniqueName, T.String), T.InternalizedString);
620

    
621
  // Class-class
622
  CHECK(IsClass(Type::Intersect(T.ObjectClass, T.ObjectClass)));
623
  CHECK(IsBitset(Type::Intersect(T.ObjectClass, T.ArrayClass)));
624

    
625
  CheckEqual(T.Intersect(T.ObjectClass, T.ObjectClass), T.ObjectClass);
626
  CheckEqual(T.Intersect(T.ObjectClass, T.ArrayClass), T.None);
627

    
628
  // Constant-constant
629
  CHECK(IsConstant(Type::Intersect(T.ObjectConstant1, T.ObjectConstant1)));
630
  CHECK(IsConstant(Type::Intersect(T.ArrayConstant1, T.ArrayConstant2)));
631
  CHECK(IsBitset(Type::Intersect(T.ObjectConstant1, T.ObjectConstant2)));
632

    
633
  CheckEqual(
634
      T.Intersect(T.ObjectConstant1, T.ObjectConstant1), T.ObjectConstant1);
635
  CheckEqual(
636
      T.Intersect(T.ArrayConstant1, T.ArrayConstant2), T.ArrayConstant1);
637
  CheckEqual(T.Intersect(T.ObjectConstant1, T.ObjectConstant2), T.None);
638

    
639
  // Bitset-class
640
  CHECK(IsClass(Type::Intersect(T.ObjectClass, T.Object)));
641
  CHECK(IsBitset(Type::Intersect(T.ObjectClass, T.Number)));
642

    
643
  CheckEqual(T.Intersect(T.ObjectClass, T.Object), T.ObjectClass);
644
  CheckEqual(T.Intersect(T.ObjectClass, T.Array), T.None);
645
  CheckEqual(T.Intersect(T.ObjectClass, T.Number), T.None);
646

    
647
  // Bitset-constant
648
  CHECK(IsBitset(Type::Intersect(T.Smi, T.Number)));
649
  CHECK(IsConstant(Type::Intersect(T.SmiConstant, T.Number)));
650
  CHECK(IsConstant(Type::Intersect(T.ObjectConstant1, T.Object)));
651

    
652
  CheckEqual(T.Intersect(T.Smi, T.Number), T.Smi);
653
  CheckEqual(T.Intersect(T.SmiConstant, T.Number), T.SmiConstant);
654
  CheckEqual(T.Intersect(T.ObjectConstant1, T.Object), T.ObjectConstant1);
655

    
656
  // Class-constant
657
  CHECK(IsBitset(Type::Intersect(T.ObjectConstant1, T.ObjectClass)));
658
  CHECK(IsBitset(Type::Intersect(T.ArrayClass, T.ObjectConstant2)));
659

    
660
  CheckEqual(T.Intersect(T.ObjectConstant1, T.ObjectClass), T.None);
661
  CheckEqual(T.Intersect(T.ArrayClass, T.ObjectConstant2), T.None);
662

    
663
  // Bitset-union
664
  CHECK(IsUnion(
665
      Type::Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass))));
666
  CHECK(IsBitset(
667
      Type::Intersect(T.Union(T.ArrayClass, T.ObjectConstant2), T.Number)));
668

    
669
  CheckEqual(
670
      T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)),
671
      T.Union(T.ObjectConstant1, T.ObjectClass));
672
  CheckEqual(
673
      T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number),
674
      T.None);
675

    
676
  // Class-union
677
  CHECK(IsClass(
678
      Type::Intersect(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass)));
679
  CHECK(IsClass(
680
      Type::Intersect(T.Union(T.Object, T.SmiConstant), T.ArrayClass)));
681
  CHECK(IsBitset(
682
      Type::Intersect(T.Union(T.ObjectClass, T.ArrayConstant1), T.ArrayClass)));
683

    
684
  CheckEqual(
685
      T.Intersect(T.ArrayClass, T.Union(T.ObjectConstant2, T.ArrayClass)),
686
      T.ArrayClass);
687
  CheckEqual(
688
      T.Intersect(T.ArrayClass, T.Union(T.Object, T.SmiConstant)),
689
      T.ArrayClass);
690
  CheckEqual(
691
      T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant1), T.ArrayClass),
692
      T.None);
693

    
694
  // Constant-union
695
  CHECK(IsConstant(Type::Intersect(
696
      T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2))));
697
  CHECK(IsConstant(Type::Intersect(
698
      T.Union(T.Number, T.ObjectClass), T.SmiConstant)));
699
  CHECK(IsBitset(Type::Intersect(
700
      T.Union(T.ArrayConstant1, T.ObjectClass), T.ObjectConstant1)));
701

    
702
  CheckEqual(
703
      T.Intersect(
704
          T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)),
705
      T.ObjectConstant1);
706
  CheckEqual(
707
      T.Intersect(T.SmiConstant, T.Union(T.Number, T.ObjectConstant2)),
708
      T.SmiConstant);
709
  CheckEqual(
710
      T.Intersect(T.Union(T.ArrayConstant1, T.ObjectClass), T.ObjectConstant1),
711
      T.None);
712

    
713
  // Union-union
714
  CHECK(IsUnion(Type::Intersect(
715
      T.Union(T.Number, T.ArrayClass), T.Union(T.Signed32, T.Array))));
716
  CHECK(IsBitset(Type::Intersect(
717
      T.Union(T.Number, T.ObjectClass), T.Union(T.Signed32, T.Array))));
718

    
719
  CheckEqual(
720
      T.Intersect(
721
          T.Union(T.Number, T.ArrayClass),
722
          T.Union(T.Smi, T.Array)),
723
      T.Union(T.Smi, T.ArrayClass));
724
  CheckEqual(
725
      T.Intersect(
726
          T.Union(T.Number, T.ObjectClass),
727
          T.Union(T.Signed32, T.Array)),
728
      T.Signed32);
729
  CheckEqual(
730
      T.Intersect(
731
          T.Union(T.ObjectConstant2, T.ObjectConstant1),
732
          T.Union(T.ObjectConstant1, T.ObjectConstant2)),
733
      T.Union(T.ObjectConstant2, T.ObjectConstant1));
734
  CheckEqual(
735
      T.Intersect(
736
          T.Union(T.Union(T.ObjectConstant2, T.ObjectConstant1), T.ArrayClass),
737
          T.Union(
738
              T.ObjectConstant1, T.Union(T.ArrayConstant1, T.ObjectConstant2))),
739
      T.Union(T.ObjectConstant2, T.ObjectConstant1));
740
  CheckEqual(
741
      T.Intersect(
742
          T.Union(T.ObjectConstant2, T.ArrayConstant1),
743
          T.Union(T.ObjectConstant1, T.ArrayConstant2)),
744
      T.ArrayConstant1);
745
}