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 1785 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1796 } | 1796 } |
1797 | 1797 |
1798 | 1798 |
1799 void FullCodeGenerator::VisitAssignment(Assignment* expr) { | 1799 void FullCodeGenerator::VisitAssignment(Assignment* expr) { |
1800 DCHECK(expr->target()->IsValidReferenceExpression()); | 1800 DCHECK(expr->target()->IsValidReferenceExpression()); |
1801 | 1801 |
1802 Comment cmnt(masm_, "[ Assignment"); | 1802 Comment cmnt(masm_, "[ Assignment"); |
1803 | 1803 |
1804 // Left-hand side can only be a property, a global or a (parameter or local) | 1804 // Left-hand side can only be a property, a global or a (parameter or local) |
1805 // slot. | 1805 // slot. |
1806 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; | 1806 enum LhsKind { |
| 1807 VARIABLE, |
| 1808 NAMED_PROPERTY, |
| 1809 KEYED_PROPERTY, |
| 1810 NAMED_SUPER_PROPERTY |
| 1811 }; |
1807 LhsKind assign_type = VARIABLE; | 1812 LhsKind assign_type = VARIABLE; |
1808 Property* property = expr->target()->AsProperty(); | 1813 Property* property = expr->target()->AsProperty(); |
1809 if (property != NULL) { | 1814 if (property != NULL) { |
1810 assign_type = (property->key()->IsPropertyName()) | 1815 assign_type = (property->key()->IsPropertyName()) |
1811 ? NAMED_PROPERTY | 1816 ? (property->IsSuperAccess() ? NAMED_SUPER_PROPERTY |
1812 : KEYED_PROPERTY; | 1817 : NAMED_PROPERTY) |
| 1818 : KEYED_PROPERTY; |
1813 } | 1819 } |
1814 | 1820 |
1815 // Evaluate LHS expression. | 1821 // Evaluate LHS expression. |
1816 switch (assign_type) { | 1822 switch (assign_type) { |
1817 case VARIABLE: | 1823 case VARIABLE: |
1818 // Nothing to do here. | 1824 // Nothing to do here. |
1819 break; | 1825 break; |
| 1826 case NAMED_SUPER_PROPERTY: |
| 1827 VisitForStackValue(property->obj()->AsSuperReference()->this_var()); |
| 1828 EmitLoadHomeObject(property->obj()->AsSuperReference()); |
| 1829 __ push(result_register()); |
| 1830 if (expr->is_compound()) { |
| 1831 __ push(MemOperand(esp, kPointerSize)); |
| 1832 __ push(result_register()); |
| 1833 } |
| 1834 break; |
1820 case NAMED_PROPERTY: | 1835 case NAMED_PROPERTY: |
1821 if (expr->is_compound()) { | 1836 if (expr->is_compound()) { |
1822 // We need the receiver both on the stack and in the register. | 1837 // We need the receiver both on the stack and in the register. |
1823 VisitForStackValue(property->obj()); | 1838 VisitForStackValue(property->obj()); |
1824 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); | 1839 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); |
1825 } else { | 1840 } else { |
1826 VisitForStackValue(property->obj()); | 1841 VisitForStackValue(property->obj()); |
1827 } | 1842 } |
1828 break; | 1843 break; |
1829 case KEYED_PROPERTY: { | 1844 case KEYED_PROPERTY: { |
(...skipping 13 matching lines...) Expand all Loading... |
1843 // For compound assignments we need another deoptimization point after the | 1858 // For compound assignments we need another deoptimization point after the |
1844 // variable/property load. | 1859 // variable/property load. |
1845 if (expr->is_compound()) { | 1860 if (expr->is_compound()) { |
1846 AccumulatorValueContext result_context(this); | 1861 AccumulatorValueContext result_context(this); |
1847 { AccumulatorValueContext left_operand_context(this); | 1862 { AccumulatorValueContext left_operand_context(this); |
1848 switch (assign_type) { | 1863 switch (assign_type) { |
1849 case VARIABLE: | 1864 case VARIABLE: |
1850 EmitVariableLoad(expr->target()->AsVariableProxy()); | 1865 EmitVariableLoad(expr->target()->AsVariableProxy()); |
1851 PrepareForBailout(expr->target(), TOS_REG); | 1866 PrepareForBailout(expr->target(), TOS_REG); |
1852 break; | 1867 break; |
| 1868 case NAMED_SUPER_PROPERTY: |
| 1869 EmitNamedSuperPropertyLoad(property); |
| 1870 PrepareForBailoutForId(property->LoadId(), TOS_REG); |
| 1871 break; |
1853 case NAMED_PROPERTY: | 1872 case NAMED_PROPERTY: |
1854 EmitNamedPropertyLoad(property); | 1873 EmitNamedPropertyLoad(property); |
1855 PrepareForBailoutForId(property->LoadId(), TOS_REG); | 1874 PrepareForBailoutForId(property->LoadId(), TOS_REG); |
1856 break; | 1875 break; |
1857 case KEYED_PROPERTY: | 1876 case KEYED_PROPERTY: |
1858 EmitKeyedPropertyLoad(property); | 1877 EmitKeyedPropertyLoad(property); |
1859 PrepareForBailoutForId(property->LoadId(), TOS_REG); | 1878 PrepareForBailoutForId(property->LoadId(), TOS_REG); |
1860 break; | 1879 break; |
1861 } | 1880 } |
1862 } | 1881 } |
(...skipping 29 matching lines...) Expand all Loading... |
1892 switch (assign_type) { | 1911 switch (assign_type) { |
1893 case VARIABLE: | 1912 case VARIABLE: |
1894 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), | 1913 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), |
1895 expr->op()); | 1914 expr->op()); |
1896 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 1915 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
1897 context()->Plug(eax); | 1916 context()->Plug(eax); |
1898 break; | 1917 break; |
1899 case NAMED_PROPERTY: | 1918 case NAMED_PROPERTY: |
1900 EmitNamedPropertyAssignment(expr); | 1919 EmitNamedPropertyAssignment(expr); |
1901 break; | 1920 break; |
| 1921 case NAMED_SUPER_PROPERTY: |
| 1922 EmitNamedSuperPropertyAssignment(expr); |
| 1923 break; |
1902 case KEYED_PROPERTY: | 1924 case KEYED_PROPERTY: |
1903 EmitKeyedPropertyAssignment(expr); | 1925 EmitKeyedPropertyAssignment(expr); |
1904 break; | 1926 break; |
1905 } | 1927 } |
1906 } | 1928 } |
1907 | 1929 |
1908 | 1930 |
1909 void FullCodeGenerator::VisitYield(Yield* expr) { | 1931 void FullCodeGenerator::VisitYield(Yield* expr) { |
1910 Comment cmnt(masm_, "[ Yield"); | 1932 Comment cmnt(masm_, "[ Yield"); |
1911 // Evaluate yielded value first; the initial iterator definition depends on | 1933 // Evaluate yielded value first; the initial iterator definition depends on |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2219 // root set. | 2241 // root set. |
2220 __ RecordWriteField(eax, JSGeneratorObject::kResultValuePropertyOffset, ecx, | 2242 __ RecordWriteField(eax, JSGeneratorObject::kResultValuePropertyOffset, ecx, |
2221 edx, kDontSaveFPRegs); | 2243 edx, kDontSaveFPRegs); |
2222 } | 2244 } |
2223 | 2245 |
2224 | 2246 |
2225 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 2247 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
2226 SetSourcePosition(prop->position()); | 2248 SetSourcePosition(prop->position()); |
2227 Literal* key = prop->key()->AsLiteral(); | 2249 Literal* key = prop->key()->AsLiteral(); |
2228 DCHECK(!key->value()->IsSmi()); | 2250 DCHECK(!key->value()->IsSmi()); |
| 2251 DCHECK(!prop->IsSuperAccess()); |
| 2252 |
2229 __ mov(LoadDescriptor::NameRegister(), Immediate(key->value())); | 2253 __ mov(LoadDescriptor::NameRegister(), Immediate(key->value())); |
2230 if (FLAG_vector_ics) { | 2254 if (FLAG_vector_ics) { |
2231 __ mov(VectorLoadICDescriptor::SlotRegister(), | 2255 __ mov(VectorLoadICDescriptor::SlotRegister(), |
2232 Immediate(Smi::FromInt(prop->PropertyFeedbackSlot()))); | 2256 Immediate(Smi::FromInt(prop->PropertyFeedbackSlot()))); |
2233 CallLoadIC(NOT_CONTEXTUAL); | 2257 CallLoadIC(NOT_CONTEXTUAL); |
2234 } else { | 2258 } else { |
2235 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); | 2259 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); |
2236 } | 2260 } |
2237 } | 2261 } |
2238 | 2262 |
2239 | 2263 |
2240 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { | 2264 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { |
| 2265 // Stack: receiver, home_object. |
2241 SetSourcePosition(prop->position()); | 2266 SetSourcePosition(prop->position()); |
2242 Literal* key = prop->key()->AsLiteral(); | 2267 Literal* key = prop->key()->AsLiteral(); |
2243 DCHECK(!key->value()->IsSmi()); | 2268 DCHECK(!key->value()->IsSmi()); |
2244 DCHECK(prop->IsSuperAccess()); | 2269 DCHECK(prop->IsSuperAccess()); |
2245 | 2270 |
2246 SuperReference* super_ref = prop->obj()->AsSuperReference(); | |
2247 EmitLoadHomeObject(super_ref); | |
2248 __ push(eax); | |
2249 VisitForStackValue(super_ref->this_var()); | |
2250 __ push(Immediate(key->value())); | 2271 __ push(Immediate(key->value())); |
2251 __ CallRuntime(Runtime::kLoadFromSuper, 3); | 2272 __ CallRuntime(Runtime::kLoadFromSuper, 3); |
2252 } | 2273 } |
2253 | 2274 |
2254 | 2275 |
2255 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 2276 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
2256 SetSourcePosition(prop->position()); | 2277 SetSourcePosition(prop->position()); |
2257 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code(); | 2278 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code(); |
2258 if (FLAG_vector_ics) { | 2279 if (FLAG_vector_ics) { |
2259 __ mov(VectorLoadICDescriptor::SlotRegister(), | 2280 __ mov(VectorLoadICDescriptor::SlotRegister(), |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2510 // Record source code position before IC call. | 2531 // Record source code position before IC call. |
2511 SetSourcePosition(expr->position()); | 2532 SetSourcePosition(expr->position()); |
2512 __ mov(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value()); | 2533 __ mov(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value()); |
2513 __ pop(StoreDescriptor::ReceiverRegister()); | 2534 __ pop(StoreDescriptor::ReceiverRegister()); |
2514 CallStoreIC(expr->AssignmentFeedbackId()); | 2535 CallStoreIC(expr->AssignmentFeedbackId()); |
2515 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2536 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2516 context()->Plug(eax); | 2537 context()->Plug(eax); |
2517 } | 2538 } |
2518 | 2539 |
2519 | 2540 |
| 2541 void FullCodeGenerator::EmitNamedSuperPropertyAssignment(Assignment* expr) { |
| 2542 // Assignment to named property of super. |
| 2543 // eax : value |
| 2544 // stack : receiver ('this'), home_object |
| 2545 Property* prop = expr->target()->AsProperty(); |
| 2546 DCHECK(prop != NULL); |
| 2547 Literal* key = prop->key()->AsLiteral(); |
| 2548 DCHECK(key != NULL); |
| 2549 |
| 2550 __ push(eax); |
| 2551 __ push(Immediate(key->value())); |
| 2552 __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreToSuper_Strict |
| 2553 : Runtime::kStoreToSuper_Sloppy), |
| 2554 4); |
| 2555 context()->Plug(eax); |
| 2556 } |
| 2557 |
| 2558 |
2520 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 2559 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
2521 // Assignment to a property, using a keyed store IC. | 2560 // Assignment to a property, using a keyed store IC. |
2522 // eax : value | 2561 // eax : value |
2523 // esp[0] : key | 2562 // esp[0] : key |
2524 // esp[kPointerSize] : receiver | 2563 // esp[kPointerSize] : receiver |
2525 | 2564 |
2526 __ pop(StoreDescriptor::NameRegister()); // Key. | 2565 __ pop(StoreDescriptor::NameRegister()); // Key. |
2527 __ pop(StoreDescriptor::ReceiverRegister()); | 2566 __ pop(StoreDescriptor::ReceiverRegister()); |
2528 DCHECK(StoreDescriptor::ValueRegister().is(eax)); | 2567 DCHECK(StoreDescriptor::ValueRegister().is(eax)); |
2529 // Record source code position before IC call. | 2568 // Record source code position before IC call. |
2530 SetSourcePosition(expr->position()); | 2569 SetSourcePosition(expr->position()); |
2531 Handle<Code> ic = CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code(); | 2570 Handle<Code> ic = CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code(); |
2532 CallIC(ic, expr->AssignmentFeedbackId()); | 2571 CallIC(ic, expr->AssignmentFeedbackId()); |
2533 | 2572 |
2534 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2573 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2535 context()->Plug(eax); | 2574 context()->Plug(eax); |
2536 } | 2575 } |
2537 | 2576 |
2538 | 2577 |
2539 void FullCodeGenerator::VisitProperty(Property* expr) { | 2578 void FullCodeGenerator::VisitProperty(Property* expr) { |
2540 Comment cmnt(masm_, "[ Property"); | 2579 Comment cmnt(masm_, "[ Property"); |
2541 Expression* key = expr->key(); | 2580 Expression* key = expr->key(); |
2542 | 2581 |
2543 if (key->IsPropertyName()) { | 2582 if (key->IsPropertyName()) { |
2544 if (!expr->IsSuperAccess()) { | 2583 if (!expr->IsSuperAccess()) { |
2545 VisitForAccumulatorValue(expr->obj()); | 2584 VisitForAccumulatorValue(expr->obj()); |
2546 __ Move(LoadDescriptor::ReceiverRegister(), result_register()); | 2585 __ Move(LoadDescriptor::ReceiverRegister(), result_register()); |
2547 EmitNamedPropertyLoad(expr); | 2586 EmitNamedPropertyLoad(expr); |
2548 } else { | 2587 } else { |
| 2588 VisitForStackValue(expr->obj()->AsSuperReference()->this_var()); |
| 2589 EmitLoadHomeObject(expr->obj()->AsSuperReference()); |
| 2590 __ push(result_register()); |
2549 EmitNamedSuperPropertyLoad(expr); | 2591 EmitNamedSuperPropertyLoad(expr); |
2550 } | 2592 } |
2551 PrepareForBailoutForId(expr->LoadId(), TOS_REG); | 2593 PrepareForBailoutForId(expr->LoadId(), TOS_REG); |
2552 context()->Plug(eax); | 2594 context()->Plug(eax); |
2553 } else { | 2595 } else { |
2554 VisitForStackValue(expr->obj()); | 2596 VisitForStackValue(expr->obj()); |
2555 VisitForAccumulatorValue(expr->key()); | 2597 VisitForAccumulatorValue(expr->key()); |
2556 __ pop(LoadDescriptor::ReceiverRegister()); // Object. | 2598 __ pop(LoadDescriptor::ReceiverRegister()); // Object. |
2557 __ Move(LoadDescriptor::NameRegister(), result_register()); // Key. | 2599 __ Move(LoadDescriptor::NameRegister(), result_register()); // Key. |
2558 EmitKeyedPropertyLoad(expr); | 2600 EmitKeyedPropertyLoad(expr); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2607 | 2649 |
2608 SetSourcePosition(prop->position()); | 2650 SetSourcePosition(prop->position()); |
2609 Literal* key = prop->key()->AsLiteral(); | 2651 Literal* key = prop->key()->AsLiteral(); |
2610 DCHECK(!key->value()->IsSmi()); | 2652 DCHECK(!key->value()->IsSmi()); |
2611 // Load the function from the receiver. | 2653 // Load the function from the receiver. |
2612 SuperReference* super_ref = callee->AsProperty()->obj()->AsSuperReference(); | 2654 SuperReference* super_ref = callee->AsProperty()->obj()->AsSuperReference(); |
2613 EmitLoadHomeObject(super_ref); | 2655 EmitLoadHomeObject(super_ref); |
2614 __ push(eax); | 2656 __ push(eax); |
2615 VisitForAccumulatorValue(super_ref->this_var()); | 2657 VisitForAccumulatorValue(super_ref->this_var()); |
2616 __ push(eax); | 2658 __ push(eax); |
2617 __ push(Operand(esp, kPointerSize)); | |
2618 __ push(eax); | 2659 __ push(eax); |
| 2660 __ push(Operand(esp, kPointerSize * 2)); |
2619 __ push(Immediate(key->value())); | 2661 __ push(Immediate(key->value())); |
2620 // Stack here: | 2662 // Stack here: |
2621 // - home_object | 2663 // - home_object |
2622 // - this (receiver) | 2664 // - this (receiver) |
2623 // - home_object <-- LoadFromSuper will pop here and below. | 2665 // - this (receiver) <-- LoadFromSuper will pop here and below. |
2624 // - this (receiver) | 2666 // - home_object |
2625 // - key | 2667 // - key |
2626 __ CallRuntime(Runtime::kLoadFromSuper, 3); | 2668 __ CallRuntime(Runtime::kLoadFromSuper, 3); |
2627 | 2669 |
2628 // Replace home_object with target function. | 2670 // Replace home_object with target function. |
2629 __ mov(Operand(esp, kPointerSize), eax); | 2671 __ mov(Operand(esp, kPointerSize), eax); |
2630 | 2672 |
2631 // Stack here: | 2673 // Stack here: |
2632 // - target function | 2674 // - target function |
2633 // - this (receiver) | 2675 // - this (receiver) |
2634 EmitCall(expr, CallICState::METHOD); | 2676 EmitCall(expr, CallICState::METHOD); |
(...skipping 1642 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4277 // Expression can only be a property, a global or a (parameter or local) | 4319 // Expression can only be a property, a global or a (parameter or local) |
4278 // slot. | 4320 // slot. |
4279 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; | 4321 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; |
4280 LhsKind assign_type = VARIABLE; | 4322 LhsKind assign_type = VARIABLE; |
4281 Property* prop = expr->expression()->AsProperty(); | 4323 Property* prop = expr->expression()->AsProperty(); |
4282 // In case of a property we use the uninitialized expression context | 4324 // In case of a property we use the uninitialized expression context |
4283 // of the key to detect a named property. | 4325 // of the key to detect a named property. |
4284 if (prop != NULL) { | 4326 if (prop != NULL) { |
4285 assign_type = | 4327 assign_type = |
4286 (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY; | 4328 (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY; |
| 4329 if (prop->IsSuperAccess()) { |
| 4330 // throw exception. |
| 4331 VisitSuperReference(prop->obj()->AsSuperReference()); |
| 4332 return; |
| 4333 } |
4287 } | 4334 } |
4288 | 4335 |
4289 // Evaluate expression and get value. | 4336 // Evaluate expression and get value. |
4290 if (assign_type == VARIABLE) { | 4337 if (assign_type == VARIABLE) { |
4291 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); | 4338 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); |
4292 AccumulatorValueContext context(this); | 4339 AccumulatorValueContext context(this); |
4293 EmitVariableLoad(expr->expression()->AsVariableProxy()); | 4340 EmitVariableLoad(expr->expression()->AsVariableProxy()); |
4294 } else { | 4341 } else { |
4295 // Reserve space for result of postfix operation. | 4342 // Reserve space for result of postfix operation. |
4296 if (expr->is_postfix() && !context()->IsEffect()) { | 4343 if (expr->is_postfix() && !context()->IsEffect()) { |
(...skipping 593 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4890 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 4937 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
4891 Assembler::target_address_at(call_target_address, | 4938 Assembler::target_address_at(call_target_address, |
4892 unoptimized_code)); | 4939 unoptimized_code)); |
4893 return OSR_AFTER_STACK_CHECK; | 4940 return OSR_AFTER_STACK_CHECK; |
4894 } | 4941 } |
4895 | 4942 |
4896 | 4943 |
4897 } } // namespace v8::internal | 4944 } } // namespace v8::internal |
4898 | 4945 |
4899 #endif // V8_TARGET_ARCH_X87 | 4946 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |