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