| 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 |