OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/ast/ast.h" | 5 #include "src/ast/ast.h" |
6 | 6 |
7 #include <cmath> // For isfinite. | 7 #include <cmath> // For isfinite. |
8 | 8 |
9 #include "src/ast/prettyprinter.h" | 9 #include "src/ast/prettyprinter.h" |
10 #include "src/ast/scopes.h" | 10 #include "src/ast/scopes.h" |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
52 return IsLiteral() && AsLiteral()->value()->IsSmi(); | 52 return IsLiteral() && AsLiteral()->value()->IsSmi(); |
53 } | 53 } |
54 | 54 |
55 | 55 |
56 bool Expression::IsStringLiteral() const { | 56 bool Expression::IsStringLiteral() const { |
57 return IsLiteral() && AsLiteral()->value()->IsString(); | 57 return IsLiteral() && AsLiteral()->value()->IsString(); |
58 } | 58 } |
59 | 59 |
60 | 60 |
61 bool Expression::IsNullLiteral() const { | 61 bool Expression::IsNullLiteral() const { |
62 return IsLiteral() && AsLiteral()->value()->IsNull(); | 62 if (!IsLiteral()) return false; |
| 63 Handle<Object> value = AsLiteral()->value(); |
| 64 return !value->IsSmi() && |
| 65 value->IsNull(HeapObject::cast(*value)->GetIsolate()); |
63 } | 66 } |
64 | 67 |
65 bool Expression::IsUndefinedLiteral() const { | 68 bool Expression::IsUndefinedLiteral() const { |
66 if (IsLiteral() && AsLiteral()->value()->IsUndefined()) { | 69 if (IsLiteral()) { |
67 return true; | 70 Handle<Object> value = AsLiteral()->value(); |
| 71 if (!value->IsSmi() && |
| 72 value->IsUndefined(HeapObject::cast(*value)->GetIsolate())) { |
| 73 return true; |
| 74 } |
68 } | 75 } |
69 | 76 |
70 const VariableProxy* var_proxy = AsVariableProxy(); | 77 const VariableProxy* var_proxy = AsVariableProxy(); |
71 if (var_proxy == NULL) return false; | 78 if (var_proxy == NULL) return false; |
72 Variable* var = var_proxy->var(); | 79 Variable* var = var_proxy->var(); |
73 // The global identifier "undefined" is immutable. Everything | 80 // The global identifier "undefined" is immutable. Everything |
74 // else could be reassigned. | 81 // else could be reassigned. |
75 return var != NULL && var->IsUnallocatedOrGlobalSlot() && | 82 return var != NULL && var->IsUnallocatedOrGlobalSlot() && |
76 var_proxy->raw_name()->IsOneByteEqualTo("undefined"); | 83 var_proxy->raw_name()->IsOneByteEqualTo("undefined"); |
77 } | 84 } |
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
380 | 387 |
381 ZoneAllocationPolicy allocator(zone); | 388 ZoneAllocationPolicy allocator(zone); |
382 | 389 |
383 ZoneHashMap table(Literal::Match, ZoneHashMap::kDefaultHashMapCapacity, | 390 ZoneHashMap table(Literal::Match, ZoneHashMap::kDefaultHashMapCapacity, |
384 allocator); | 391 allocator); |
385 for (int i = properties()->length() - 1; i >= 0; i--) { | 392 for (int i = properties()->length() - 1; i >= 0; i--) { |
386 ObjectLiteral::Property* property = properties()->at(i); | 393 ObjectLiteral::Property* property = properties()->at(i); |
387 if (property->is_computed_name()) continue; | 394 if (property->is_computed_name()) continue; |
388 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) continue; | 395 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) continue; |
389 Literal* literal = property->key()->AsLiteral(); | 396 Literal* literal = property->key()->AsLiteral(); |
390 DCHECK(!literal->value()->IsNull()); | 397 DCHECK(!literal->IsNullLiteral()); |
391 | 398 |
392 // If there is an existing entry do not emit a store unless the previous | 399 // If there is an existing entry do not emit a store unless the previous |
393 // entry was also an accessor. | 400 // entry was also an accessor. |
394 uint32_t hash = literal->Hash(); | 401 uint32_t hash = literal->Hash(); |
395 ZoneHashMap::Entry* entry = table.LookupOrInsert(literal, hash, allocator); | 402 ZoneHashMap::Entry* entry = table.LookupOrInsert(literal, hash, allocator); |
396 if (entry->value != NULL) { | 403 if (entry->value != NULL) { |
397 auto previous_kind = | 404 auto previous_kind = |
398 static_cast<ObjectLiteral::Property*>(entry->value)->kind(); | 405 static_cast<ObjectLiteral::Property*>(entry->value)->kind(); |
399 if (!((property->kind() == GETTER && previous_kind == SETTER) || | 406 if (!((property->kind() == GETTER && previous_kind == SETTER) || |
400 (property->kind() == SETTER && previous_kind == GETTER))) { | 407 (property->kind() == SETTER && previous_kind == GETTER))) { |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
450 // runtime. The enumeration order is maintained. | 457 // runtime. The enumeration order is maintained. |
451 Handle<Object> key = property->key()->AsLiteral()->value(); | 458 Handle<Object> key = property->key()->AsLiteral()->value(); |
452 Handle<Object> value = GetBoilerplateValue(property->value(), isolate); | 459 Handle<Object> value = GetBoilerplateValue(property->value(), isolate); |
453 | 460 |
454 // Ensure objects that may, at any point in time, contain fields with double | 461 // Ensure objects that may, at any point in time, contain fields with double |
455 // representation are always treated as nested objects. This is true for | 462 // representation are always treated as nested objects. This is true for |
456 // computed fields (value is undefined), and smi and double literals | 463 // computed fields (value is undefined), and smi and double literals |
457 // (value->IsNumber()). | 464 // (value->IsNumber()). |
458 // TODO(verwaest): Remove once we can store them inline. | 465 // TODO(verwaest): Remove once we can store them inline. |
459 if (FLAG_track_double_fields && | 466 if (FLAG_track_double_fields && |
460 (value->IsNumber() || value->IsUninitialized())) { | 467 (value->IsNumber() || value->IsUninitialized(isolate))) { |
461 may_store_doubles_ = true; | 468 may_store_doubles_ = true; |
462 } | 469 } |
463 | 470 |
464 is_simple = is_simple && !value->IsUninitialized(); | 471 is_simple = is_simple && !value->IsUninitialized(isolate); |
465 | 472 |
466 // Keep track of the number of elements in the object literal and | 473 // Keep track of the number of elements in the object literal and |
467 // the largest element index. If the largest element index is | 474 // the largest element index. If the largest element index is |
468 // much larger than the number of elements, creating an object | 475 // much larger than the number of elements, creating an object |
469 // literal with fast elements will be a waste of space. | 476 // literal with fast elements will be a waste of space. |
470 uint32_t element_index = 0; | 477 uint32_t element_index = 0; |
471 if (key->IsString() && String::cast(*key)->AsArrayIndex(&element_index)) { | 478 if (key->IsString() && String::cast(*key)->AsArrayIndex(&element_index)) { |
472 max_element_index = Max(element_index, max_element_index); | 479 max_element_index = Max(element_index, max_element_index); |
473 elements++; | 480 elements++; |
474 key = isolate->factory()->NewNumberFromUint(element_index); | 481 key = isolate->factory()->NewNumberFromUint(element_index); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
522 } | 529 } |
523 | 530 |
524 // New handle scope here, needs to be after BuildContants(). | 531 // New handle scope here, needs to be after BuildContants(). |
525 HandleScope scope(isolate); | 532 HandleScope scope(isolate); |
526 Handle<Object> boilerplate_value = GetBoilerplateValue(element, isolate); | 533 Handle<Object> boilerplate_value = GetBoilerplateValue(element, isolate); |
527 if (boilerplate_value->IsTheHole(isolate)) { | 534 if (boilerplate_value->IsTheHole(isolate)) { |
528 is_holey = true; | 535 is_holey = true; |
529 continue; | 536 continue; |
530 } | 537 } |
531 | 538 |
532 if (boilerplate_value->IsUninitialized()) { | 539 if (boilerplate_value->IsUninitialized(isolate)) { |
533 boilerplate_value = handle(Smi::FromInt(0), isolate); | 540 boilerplate_value = handle(Smi::FromInt(0), isolate); |
534 is_simple = false; | 541 is_simple = false; |
535 } | 542 } |
536 | 543 |
537 JSObject::AddDataElement(array, array_index, boilerplate_value, NONE) | 544 JSObject::AddDataElement(array, array_index, boilerplate_value, NONE) |
538 .Assert(); | 545 .Assert(); |
539 } | 546 } |
540 | 547 |
541 JSObject::ValidateElements(array); | 548 JSObject::ValidateElements(array); |
542 Handle<FixedArrayBase> element_values(array->elements()); | 549 Handle<FixedArrayBase> element_values(array->elements()); |
(...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1134 bool Literal::Match(void* literal1, void* literal2) { | 1141 bool Literal::Match(void* literal1, void* literal2) { |
1135 const AstValue* x = static_cast<Literal*>(literal1)->raw_value(); | 1142 const AstValue* x = static_cast<Literal*>(literal1)->raw_value(); |
1136 const AstValue* y = static_cast<Literal*>(literal2)->raw_value(); | 1143 const AstValue* y = static_cast<Literal*>(literal2)->raw_value(); |
1137 return (x->IsString() && y->IsString() && x->AsString() == y->AsString()) || | 1144 return (x->IsString() && y->IsString() && x->AsString() == y->AsString()) || |
1138 (x->IsNumber() && y->IsNumber() && x->AsNumber() == y->AsNumber()); | 1145 (x->IsNumber() && y->IsNumber() && x->AsNumber() == y->AsNumber()); |
1139 } | 1146 } |
1140 | 1147 |
1141 | 1148 |
1142 } // namespace internal | 1149 } // namespace internal |
1143 } // namespace v8 | 1150 } // namespace v8 |
OLD | NEW |