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 |