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/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_X87 | 7 #if V8_TARGET_ARCH_X87 |
8 | 8 |
9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 1588 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1599 // If result_saved is true the result is on top of the stack. If | 1599 // If result_saved is true the result is on top of the stack. If |
1600 // result_saved is false the result is in eax. | 1600 // result_saved is false the result is in eax. |
1601 bool result_saved = false; | 1601 bool result_saved = false; |
1602 | 1602 |
1603 // Mark all computed expressions that are bound to a key that | 1603 // Mark all computed expressions that are bound to a key that |
1604 // is shadowed by a later occurrence of the same key. For the | 1604 // is shadowed by a later occurrence of the same key. For the |
1605 // marked expressions, no store code is emitted. | 1605 // marked expressions, no store code is emitted. |
1606 expr->CalculateEmitStore(zone()); | 1606 expr->CalculateEmitStore(zone()); |
1607 | 1607 |
1608 AccessorTable accessor_table(zone()); | 1608 AccessorTable accessor_table(zone()); |
1609 for (int i = 0; i < expr->properties()->length(); i++) { | 1609 int property_index = 0; |
1610 ObjectLiteral::Property* property = expr->properties()->at(i); | 1610 for (; property_index < expr->properties()->length(); property_index++) { |
| 1611 ObjectLiteral::Property* property = expr->properties()->at(property_index); |
| 1612 if (property->is_computed_name()) break; |
1611 if (property->IsCompileTimeValue()) continue; | 1613 if (property->IsCompileTimeValue()) continue; |
1612 | 1614 |
1613 Literal* key = property->key(); | 1615 Literal* key = property->key()->AsLiteral(); |
1614 Expression* value = property->value(); | 1616 Expression* value = property->value(); |
1615 if (!result_saved) { | 1617 if (!result_saved) { |
1616 __ push(eax); // Save result on the stack | 1618 __ push(eax); // Save result on the stack |
1617 result_saved = true; | 1619 result_saved = true; |
1618 } | 1620 } |
1619 switch (property->kind()) { | 1621 switch (property->kind()) { |
1620 case ObjectLiteral::Property::CONSTANT: | 1622 case ObjectLiteral::Property::CONSTANT: |
1621 UNREACHABLE(); | 1623 UNREACHABLE(); |
1622 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1624 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
1623 DCHECK(!CompileTimeValue::IsCompileTimeValue(value)); | 1625 DCHECK(!CompileTimeValue::IsCompileTimeValue(value)); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1683 __ push(Operand(esp, 0)); // Duplicate receiver. | 1685 __ push(Operand(esp, 0)); // Duplicate receiver. |
1684 VisitForStackValue(it->first); | 1686 VisitForStackValue(it->first); |
1685 EmitAccessor(it->second->getter); | 1687 EmitAccessor(it->second->getter); |
1686 EmitSetHomeObjectIfNeeded(it->second->getter, 2); | 1688 EmitSetHomeObjectIfNeeded(it->second->getter, 2); |
1687 EmitAccessor(it->second->setter); | 1689 EmitAccessor(it->second->setter); |
1688 EmitSetHomeObjectIfNeeded(it->second->setter, 3); | 1690 EmitSetHomeObjectIfNeeded(it->second->setter, 3); |
1689 __ push(Immediate(Smi::FromInt(NONE))); | 1691 __ push(Immediate(Smi::FromInt(NONE))); |
1690 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); | 1692 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); |
1691 } | 1693 } |
1692 | 1694 |
| 1695 // Object literals have two parts. The "static" part on the left contains no |
| 1696 // computed property names, and so we can compute its map ahead of time; see |
| 1697 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part |
| 1698 // starts with the first computed property name, and continues with all |
| 1699 // properties to its right. All the code from above initializes the static |
| 1700 // component of the object literal, and arranges for the map of the result to |
| 1701 // reflect the static order in which the keys appear. For the dynamic |
| 1702 // properties, we compile them into a series of "SetOwnProperty" runtime |
| 1703 // calls. This will preserve insertion order. |
| 1704 for (; property_index < expr->properties()->length(); property_index++) { |
| 1705 ObjectLiteral::Property* property = expr->properties()->at(property_index); |
| 1706 |
| 1707 Expression* value = property->value(); |
| 1708 if (!result_saved) { |
| 1709 __ push(eax); // Save result on the stack |
| 1710 result_saved = true; |
| 1711 } |
| 1712 |
| 1713 __ push(Operand(esp, 0)); // Duplicate receiver. |
| 1714 |
| 1715 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { |
| 1716 DCHECK(!property->is_computed_name()); |
| 1717 VisitForStackValue(value); |
| 1718 if (property->emit_store()) { |
| 1719 __ CallRuntime(Runtime::kInternalSetPrototype, 2); |
| 1720 } else { |
| 1721 __ Drop(2); |
| 1722 } |
| 1723 } else { |
| 1724 EmitPropertyKey(property); |
| 1725 VisitForStackValue(value); |
| 1726 |
| 1727 switch (property->kind()) { |
| 1728 case ObjectLiteral::Property::CONSTANT: |
| 1729 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 1730 case ObjectLiteral::Property::COMPUTED: |
| 1731 if (property->emit_store()) { |
| 1732 __ push(Immediate(Smi::FromInt(NONE))); |
| 1733 __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4); |
| 1734 } else { |
| 1735 __ Drop(3); |
| 1736 } |
| 1737 break; |
| 1738 |
| 1739 case ObjectLiteral::Property::PROTOTYPE: |
| 1740 UNREACHABLE(); |
| 1741 break; |
| 1742 |
| 1743 case ObjectLiteral::Property::GETTER: |
| 1744 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked, 3); |
| 1745 break; |
| 1746 |
| 1747 case ObjectLiteral::Property::SETTER: |
| 1748 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked, 3); |
| 1749 break; |
| 1750 } |
| 1751 } |
| 1752 } |
| 1753 |
1693 if (expr->has_function()) { | 1754 if (expr->has_function()) { |
1694 DCHECK(result_saved); | 1755 DCHECK(result_saved); |
1695 __ push(Operand(esp, 0)); | 1756 __ push(Operand(esp, 0)); |
1696 __ CallRuntime(Runtime::kToFastProperties, 1); | 1757 __ CallRuntime(Runtime::kToFastProperties, 1); |
1697 } | 1758 } |
1698 | 1759 |
1699 if (result_saved) { | 1760 if (result_saved) { |
1700 context()->PlugTOS(); | 1761 context()->PlugTOS(); |
1701 } else { | 1762 } else { |
1702 context()->Plug(eax); | 1763 context()->Plug(eax); |
(...skipping 671 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2374 __ push(eax); | 2435 __ push(eax); |
2375 | 2436 |
2376 // No access check is needed here since the constructor is created by the | 2437 // No access check is needed here since the constructor is created by the |
2377 // class literal. | 2438 // class literal. |
2378 Register scratch = ebx; | 2439 Register scratch = ebx; |
2379 __ mov(scratch, FieldOperand(eax, JSFunction::kPrototypeOrInitialMapOffset)); | 2440 __ mov(scratch, FieldOperand(eax, JSFunction::kPrototypeOrInitialMapOffset)); |
2380 __ Push(scratch); | 2441 __ Push(scratch); |
2381 | 2442 |
2382 for (int i = 0; i < lit->properties()->length(); i++) { | 2443 for (int i = 0; i < lit->properties()->length(); i++) { |
2383 ObjectLiteral::Property* property = lit->properties()->at(i); | 2444 ObjectLiteral::Property* property = lit->properties()->at(i); |
2384 Literal* key = property->key()->AsLiteral(); | |
2385 Expression* value = property->value(); | 2445 Expression* value = property->value(); |
2386 DCHECK(key != NULL); | |
2387 | 2446 |
2388 if (property->is_static()) { | 2447 if (property->is_static()) { |
2389 __ push(Operand(esp, kPointerSize)); // constructor | 2448 __ push(Operand(esp, kPointerSize)); // constructor |
2390 } else { | 2449 } else { |
2391 __ push(Operand(esp, 0)); // prototype | 2450 __ push(Operand(esp, 0)); // prototype |
2392 } | 2451 } |
2393 VisitForStackValue(key); | 2452 EmitPropertyKey(property); |
2394 VisitForStackValue(value); | 2453 VisitForStackValue(value); |
2395 EmitSetHomeObjectIfNeeded(value, 2); | 2454 EmitSetHomeObjectIfNeeded(value, 2); |
2396 | 2455 |
2397 switch (property->kind()) { | 2456 switch (property->kind()) { |
2398 case ObjectLiteral::Property::CONSTANT: | 2457 case ObjectLiteral::Property::CONSTANT: |
2399 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 2458 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
2400 case ObjectLiteral::Property::COMPUTED: | 2459 case ObjectLiteral::Property::COMPUTED: |
2401 case ObjectLiteral::Property::PROTOTYPE: | 2460 case ObjectLiteral::Property::PROTOTYPE: |
2402 __ CallRuntime(Runtime::kDefineClassMethod, 3); | 2461 __ CallRuntime(Runtime::kDefineClassMethod, 3); |
2403 break; | 2462 break; |
2404 | 2463 |
2405 case ObjectLiteral::Property::GETTER: | 2464 case ObjectLiteral::Property::GETTER: |
2406 __ CallRuntime(Runtime::kDefineClassGetter, 3); | 2465 __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked, 3); |
2407 break; | 2466 break; |
2408 | 2467 |
2409 case ObjectLiteral::Property::SETTER: | 2468 case ObjectLiteral::Property::SETTER: |
2410 __ CallRuntime(Runtime::kDefineClassSetter, 3); | 2469 __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked, 3); |
2411 break; | 2470 break; |
2412 | 2471 |
2413 default: | 2472 default: |
2414 UNREACHABLE(); | 2473 UNREACHABLE(); |
2415 } | 2474 } |
2416 } | 2475 } |
2417 | 2476 |
2418 // prototype | 2477 // prototype |
2419 __ CallRuntime(Runtime::kToFastProperties, 1); | 2478 __ CallRuntime(Runtime::kToFastProperties, 1); |
2420 | 2479 |
(...skipping 2742 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5163 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 5222 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
5164 Assembler::target_address_at(call_target_address, | 5223 Assembler::target_address_at(call_target_address, |
5165 unoptimized_code)); | 5224 unoptimized_code)); |
5166 return OSR_AFTER_STACK_CHECK; | 5225 return OSR_AFTER_STACK_CHECK; |
5167 } | 5226 } |
5168 | 5227 |
5169 | 5228 |
5170 } } // namespace v8::internal | 5229 } } // namespace v8::internal |
5171 | 5230 |
5172 #endif // V8_TARGET_ARCH_X87 | 5231 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |