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_IA32 | 7 #if V8_TARGET_ARCH_IA32 |
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 1798 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1809 } | 1809 } |
1810 | 1810 |
1811 | 1811 |
1812 void FullCodeGenerator::VisitAssignment(Assignment* expr) { | 1812 void FullCodeGenerator::VisitAssignment(Assignment* expr) { |
1813 DCHECK(expr->target()->IsValidReferenceExpression()); | 1813 DCHECK(expr->target()->IsValidReferenceExpression()); |
1814 | 1814 |
1815 Comment cmnt(masm_, "[ Assignment"); | 1815 Comment cmnt(masm_, "[ Assignment"); |
1816 | 1816 |
1817 // Left-hand side can only be a property, a global or a (parameter or local) | 1817 // Left-hand side can only be a property, a global or a (parameter or local) |
1818 // slot. | 1818 // slot. |
1819 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; | 1819 enum LhsKind { |
| 1820 VARIABLE, |
| 1821 NAMED_PROPERTY, |
| 1822 KEYED_PROPERTY, |
| 1823 NAMED_SUPER_PROPERTY |
| 1824 }; |
1820 LhsKind assign_type = VARIABLE; | 1825 LhsKind assign_type = VARIABLE; |
1821 Property* property = expr->target()->AsProperty(); | 1826 Property* property = expr->target()->AsProperty(); |
1822 if (property != NULL) { | 1827 if (property != NULL) { |
1823 assign_type = (property->key()->IsPropertyName()) | 1828 assign_type = (property->key()->IsPropertyName()) |
1824 ? NAMED_PROPERTY | 1829 ? (property->IsSuperAccess() ? NAMED_SUPER_PROPERTY |
1825 : KEYED_PROPERTY; | 1830 : NAMED_PROPERTY) |
| 1831 : KEYED_PROPERTY; |
1826 } | 1832 } |
1827 | 1833 |
1828 // Evaluate LHS expression. | 1834 // Evaluate LHS expression. |
1829 switch (assign_type) { | 1835 switch (assign_type) { |
1830 case VARIABLE: | 1836 case VARIABLE: |
1831 // Nothing to do here. | 1837 // Nothing to do here. |
1832 break; | 1838 break; |
| 1839 case NAMED_SUPER_PROPERTY: |
| 1840 VisitForStackValue(property->obj()->AsSuperReference()->this_var()); |
| 1841 EmitLoadHomeObject(property->obj()->AsSuperReference()); |
| 1842 __ push(result_register()); |
| 1843 if (expr->is_compound()) { |
| 1844 __ push(MemOperand(esp, kPointerSize)); |
| 1845 __ push(result_register()); |
| 1846 } |
| 1847 break; |
1833 case NAMED_PROPERTY: | 1848 case NAMED_PROPERTY: |
1834 if (expr->is_compound()) { | 1849 if (expr->is_compound()) { |
1835 // We need the receiver both on the stack and in the register. | 1850 // We need the receiver both on the stack and in the register. |
1836 VisitForStackValue(property->obj()); | 1851 VisitForStackValue(property->obj()); |
1837 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); | 1852 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); |
1838 } else { | 1853 } else { |
1839 VisitForStackValue(property->obj()); | 1854 VisitForStackValue(property->obj()); |
1840 } | 1855 } |
1841 break; | 1856 break; |
1842 case KEYED_PROPERTY: { | 1857 case KEYED_PROPERTY: { |
(...skipping 13 matching lines...) Expand all Loading... |
1856 // For compound assignments we need another deoptimization point after the | 1871 // For compound assignments we need another deoptimization point after the |
1857 // variable/property load. | 1872 // variable/property load. |
1858 if (expr->is_compound()) { | 1873 if (expr->is_compound()) { |
1859 AccumulatorValueContext result_context(this); | 1874 AccumulatorValueContext result_context(this); |
1860 { AccumulatorValueContext left_operand_context(this); | 1875 { AccumulatorValueContext left_operand_context(this); |
1861 switch (assign_type) { | 1876 switch (assign_type) { |
1862 case VARIABLE: | 1877 case VARIABLE: |
1863 EmitVariableLoad(expr->target()->AsVariableProxy()); | 1878 EmitVariableLoad(expr->target()->AsVariableProxy()); |
1864 PrepareForBailout(expr->target(), TOS_REG); | 1879 PrepareForBailout(expr->target(), TOS_REG); |
1865 break; | 1880 break; |
| 1881 case NAMED_SUPER_PROPERTY: |
| 1882 EmitNamedSuperPropertyLoad(property); |
| 1883 PrepareForBailoutForId(property->LoadId(), TOS_REG); |
| 1884 break; |
1866 case NAMED_PROPERTY: | 1885 case NAMED_PROPERTY: |
1867 EmitNamedPropertyLoad(property); | 1886 EmitNamedPropertyLoad(property); |
1868 PrepareForBailoutForId(property->LoadId(), TOS_REG); | 1887 PrepareForBailoutForId(property->LoadId(), TOS_REG); |
1869 break; | 1888 break; |
1870 case KEYED_PROPERTY: | 1889 case KEYED_PROPERTY: |
1871 EmitKeyedPropertyLoad(property); | 1890 EmitKeyedPropertyLoad(property); |
1872 PrepareForBailoutForId(property->LoadId(), TOS_REG); | 1891 PrepareForBailoutForId(property->LoadId(), TOS_REG); |
1873 break; | 1892 break; |
1874 } | 1893 } |
1875 } | 1894 } |
(...skipping 29 matching lines...) Expand all Loading... |
1905 switch (assign_type) { | 1924 switch (assign_type) { |
1906 case VARIABLE: | 1925 case VARIABLE: |
1907 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), | 1926 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), |
1908 expr->op()); | 1927 expr->op()); |
1909 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 1928 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
1910 context()->Plug(eax); | 1929 context()->Plug(eax); |
1911 break; | 1930 break; |
1912 case NAMED_PROPERTY: | 1931 case NAMED_PROPERTY: |
1913 EmitNamedPropertyAssignment(expr); | 1932 EmitNamedPropertyAssignment(expr); |
1914 break; | 1933 break; |
| 1934 case NAMED_SUPER_PROPERTY: |
| 1935 EmitNamedSuperPropertyAssignment(expr); |
| 1936 break; |
1915 case KEYED_PROPERTY: | 1937 case KEYED_PROPERTY: |
1916 EmitKeyedPropertyAssignment(expr); | 1938 EmitKeyedPropertyAssignment(expr); |
1917 break; | 1939 break; |
1918 } | 1940 } |
1919 } | 1941 } |
1920 | 1942 |
1921 | 1943 |
1922 void FullCodeGenerator::VisitYield(Yield* expr) { | 1944 void FullCodeGenerator::VisitYield(Yield* expr) { |
1923 Comment cmnt(masm_, "[ Yield"); | 1945 Comment cmnt(masm_, "[ Yield"); |
1924 // Evaluate yielded value first; the initial iterator definition depends on | 1946 // Evaluate yielded value first; the initial iterator definition depends on |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2232 // root set. | 2254 // root set. |
2233 __ RecordWriteField(eax, JSGeneratorObject::kResultValuePropertyOffset, | 2255 __ RecordWriteField(eax, JSGeneratorObject::kResultValuePropertyOffset, |
2234 ecx, edx, kDontSaveFPRegs); | 2256 ecx, edx, kDontSaveFPRegs); |
2235 } | 2257 } |
2236 | 2258 |
2237 | 2259 |
2238 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 2260 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
2239 SetSourcePosition(prop->position()); | 2261 SetSourcePosition(prop->position()); |
2240 Literal* key = prop->key()->AsLiteral(); | 2262 Literal* key = prop->key()->AsLiteral(); |
2241 DCHECK(!key->value()->IsSmi()); | 2263 DCHECK(!key->value()->IsSmi()); |
| 2264 DCHECK(!prop->IsSuperAccess()); |
| 2265 |
2242 __ mov(LoadDescriptor::NameRegister(), Immediate(key->value())); | 2266 __ mov(LoadDescriptor::NameRegister(), Immediate(key->value())); |
2243 if (FLAG_vector_ics) { | 2267 if (FLAG_vector_ics) { |
2244 __ mov(VectorLoadICDescriptor::SlotRegister(), | 2268 __ mov(VectorLoadICDescriptor::SlotRegister(), |
2245 Immediate(Smi::FromInt(prop->PropertyFeedbackSlot()))); | 2269 Immediate(Smi::FromInt(prop->PropertyFeedbackSlot()))); |
2246 CallLoadIC(NOT_CONTEXTUAL); | 2270 CallLoadIC(NOT_CONTEXTUAL); |
2247 } else { | 2271 } else { |
2248 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); | 2272 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); |
2249 } | 2273 } |
2250 } | 2274 } |
2251 | 2275 |
2252 | 2276 |
2253 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { | 2277 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { |
| 2278 // Stack: receiver, home_object. |
2254 SetSourcePosition(prop->position()); | 2279 SetSourcePosition(prop->position()); |
2255 Literal* key = prop->key()->AsLiteral(); | 2280 Literal* key = prop->key()->AsLiteral(); |
2256 DCHECK(!key->value()->IsSmi()); | 2281 DCHECK(!key->value()->IsSmi()); |
2257 DCHECK(prop->IsSuperAccess()); | 2282 DCHECK(prop->IsSuperAccess()); |
2258 | 2283 |
2259 SuperReference* super_ref = prop->obj()->AsSuperReference(); | |
2260 EmitLoadHomeObject(super_ref); | |
2261 __ push(eax); | |
2262 VisitForStackValue(super_ref->this_var()); | |
2263 __ push(Immediate(key->value())); | 2284 __ push(Immediate(key->value())); |
2264 __ CallRuntime(Runtime::kLoadFromSuper, 3); | 2285 __ CallRuntime(Runtime::kLoadFromSuper, 3); |
2265 } | 2286 } |
2266 | 2287 |
2267 | 2288 |
2268 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 2289 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
2269 SetSourcePosition(prop->position()); | 2290 SetSourcePosition(prop->position()); |
2270 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code(); | 2291 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code(); |
2271 if (FLAG_vector_ics) { | 2292 if (FLAG_vector_ics) { |
2272 __ mov(VectorLoadICDescriptor::SlotRegister(), | 2293 __ mov(VectorLoadICDescriptor::SlotRegister(), |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2523 // Record source code position before IC call. | 2544 // Record source code position before IC call. |
2524 SetSourcePosition(expr->position()); | 2545 SetSourcePosition(expr->position()); |
2525 __ mov(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value()); | 2546 __ mov(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value()); |
2526 __ pop(StoreDescriptor::ReceiverRegister()); | 2547 __ pop(StoreDescriptor::ReceiverRegister()); |
2527 CallStoreIC(expr->AssignmentFeedbackId()); | 2548 CallStoreIC(expr->AssignmentFeedbackId()); |
2528 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2549 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2529 context()->Plug(eax); | 2550 context()->Plug(eax); |
2530 } | 2551 } |
2531 | 2552 |
2532 | 2553 |
| 2554 void FullCodeGenerator::EmitNamedSuperPropertyAssignment(Assignment* expr) { |
| 2555 // Assignment to named property of super. |
| 2556 // eax : value |
| 2557 // stack : receiver ('this'), home_object |
| 2558 Property* prop = expr->target()->AsProperty(); |
| 2559 DCHECK(prop != NULL); |
| 2560 Literal* key = prop->key()->AsLiteral(); |
| 2561 DCHECK(key != NULL); |
| 2562 |
| 2563 __ push(eax); |
| 2564 __ push(Immediate(key->value())); |
| 2565 __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreToSuper_Strict |
| 2566 : Runtime::kStoreToSuper_Sloppy), |
| 2567 4); |
| 2568 context()->Plug(eax); |
| 2569 } |
| 2570 |
| 2571 |
2533 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 2572 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
2534 // Assignment to a property, using a keyed store IC. | 2573 // Assignment to a property, using a keyed store IC. |
2535 // eax : value | 2574 // eax : value |
2536 // esp[0] : key | 2575 // esp[0] : key |
2537 // esp[kPointerSize] : receiver | 2576 // esp[kPointerSize] : receiver |
2538 | 2577 |
2539 __ pop(StoreDescriptor::NameRegister()); // Key. | 2578 __ pop(StoreDescriptor::NameRegister()); // Key. |
2540 __ pop(StoreDescriptor::ReceiverRegister()); | 2579 __ pop(StoreDescriptor::ReceiverRegister()); |
2541 DCHECK(StoreDescriptor::ValueRegister().is(eax)); | 2580 DCHECK(StoreDescriptor::ValueRegister().is(eax)); |
2542 // Record source code position before IC call. | 2581 // Record source code position before IC call. |
2543 SetSourcePosition(expr->position()); | 2582 SetSourcePosition(expr->position()); |
2544 Handle<Code> ic = CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code(); | 2583 Handle<Code> ic = CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code(); |
2545 CallIC(ic, expr->AssignmentFeedbackId()); | 2584 CallIC(ic, expr->AssignmentFeedbackId()); |
2546 | 2585 |
2547 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2586 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2548 context()->Plug(eax); | 2587 context()->Plug(eax); |
2549 } | 2588 } |
2550 | 2589 |
2551 | 2590 |
2552 void FullCodeGenerator::VisitProperty(Property* expr) { | 2591 void FullCodeGenerator::VisitProperty(Property* expr) { |
2553 Comment cmnt(masm_, "[ Property"); | 2592 Comment cmnt(masm_, "[ Property"); |
2554 Expression* key = expr->key(); | 2593 Expression* key = expr->key(); |
2555 | 2594 |
2556 if (key->IsPropertyName()) { | 2595 if (key->IsPropertyName()) { |
2557 if (!expr->IsSuperAccess()) { | 2596 if (!expr->IsSuperAccess()) { |
2558 VisitForAccumulatorValue(expr->obj()); | 2597 VisitForAccumulatorValue(expr->obj()); |
2559 __ Move(LoadDescriptor::ReceiverRegister(), result_register()); | 2598 __ Move(LoadDescriptor::ReceiverRegister(), result_register()); |
2560 EmitNamedPropertyLoad(expr); | 2599 EmitNamedPropertyLoad(expr); |
2561 } else { | 2600 } else { |
| 2601 VisitForStackValue(expr->obj()->AsSuperReference()->this_var()); |
| 2602 EmitLoadHomeObject(expr->obj()->AsSuperReference()); |
| 2603 __ push(result_register()); |
2562 EmitNamedSuperPropertyLoad(expr); | 2604 EmitNamedSuperPropertyLoad(expr); |
2563 } | 2605 } |
2564 PrepareForBailoutForId(expr->LoadId(), TOS_REG); | 2606 PrepareForBailoutForId(expr->LoadId(), TOS_REG); |
2565 context()->Plug(eax); | 2607 context()->Plug(eax); |
2566 } else { | 2608 } else { |
2567 VisitForStackValue(expr->obj()); | 2609 VisitForStackValue(expr->obj()); |
2568 VisitForAccumulatorValue(expr->key()); | 2610 VisitForAccumulatorValue(expr->key()); |
2569 __ pop(LoadDescriptor::ReceiverRegister()); // Object. | 2611 __ pop(LoadDescriptor::ReceiverRegister()); // Object. |
2570 __ Move(LoadDescriptor::NameRegister(), result_register()); // Key. | 2612 __ Move(LoadDescriptor::NameRegister(), result_register()); // Key. |
2571 EmitKeyedPropertyLoad(expr); | 2613 EmitKeyedPropertyLoad(expr); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2620 | 2662 |
2621 SetSourcePosition(prop->position()); | 2663 SetSourcePosition(prop->position()); |
2622 Literal* key = prop->key()->AsLiteral(); | 2664 Literal* key = prop->key()->AsLiteral(); |
2623 DCHECK(!key->value()->IsSmi()); | 2665 DCHECK(!key->value()->IsSmi()); |
2624 // Load the function from the receiver. | 2666 // Load the function from the receiver. |
2625 SuperReference* super_ref = callee->AsProperty()->obj()->AsSuperReference(); | 2667 SuperReference* super_ref = callee->AsProperty()->obj()->AsSuperReference(); |
2626 EmitLoadHomeObject(super_ref); | 2668 EmitLoadHomeObject(super_ref); |
2627 __ push(eax); | 2669 __ push(eax); |
2628 VisitForAccumulatorValue(super_ref->this_var()); | 2670 VisitForAccumulatorValue(super_ref->this_var()); |
2629 __ push(eax); | 2671 __ push(eax); |
2630 __ push(Operand(esp, kPointerSize)); | |
2631 __ push(eax); | 2672 __ push(eax); |
| 2673 __ push(Operand(esp, kPointerSize * 2)); |
2632 __ push(Immediate(key->value())); | 2674 __ push(Immediate(key->value())); |
2633 // Stack here: | 2675 // Stack here: |
2634 // - home_object | 2676 // - home_object |
2635 // - this (receiver) | 2677 // - this (receiver) |
2636 // - home_object <-- LoadFromSuper will pop here and below. | 2678 // - this (receiver) <-- LoadFromSuper will pop here and below. |
2637 // - this (receiver) | 2679 // - home_object |
2638 // - key | 2680 // - key |
2639 __ CallRuntime(Runtime::kLoadFromSuper, 3); | 2681 __ CallRuntime(Runtime::kLoadFromSuper, 3); |
2640 | 2682 |
2641 // Replace home_object with target function. | 2683 // Replace home_object with target function. |
2642 __ mov(Operand(esp, kPointerSize), eax); | 2684 __ mov(Operand(esp, kPointerSize), eax); |
2643 | 2685 |
2644 // Stack here: | 2686 // Stack here: |
2645 // - target function | 2687 // - target function |
2646 // - this (receiver) | 2688 // - this (receiver) |
2647 EmitCall(expr, CallICState::METHOD); | 2689 EmitCall(expr, CallICState::METHOD); |
(...skipping 1643 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4291 // Expression can only be a property, a global or a (parameter or local) | 4333 // Expression can only be a property, a global or a (parameter or local) |
4292 // slot. | 4334 // slot. |
4293 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; | 4335 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; |
4294 LhsKind assign_type = VARIABLE; | 4336 LhsKind assign_type = VARIABLE; |
4295 Property* prop = expr->expression()->AsProperty(); | 4337 Property* prop = expr->expression()->AsProperty(); |
4296 // In case of a property we use the uninitialized expression context | 4338 // In case of a property we use the uninitialized expression context |
4297 // of the key to detect a named property. | 4339 // of the key to detect a named property. |
4298 if (prop != NULL) { | 4340 if (prop != NULL) { |
4299 assign_type = | 4341 assign_type = |
4300 (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY; | 4342 (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY; |
| 4343 if (prop->IsSuperAccess()) { |
| 4344 // throw exception. |
| 4345 VisitSuperReference(prop->obj()->AsSuperReference()); |
| 4346 return; |
| 4347 } |
4301 } | 4348 } |
4302 | 4349 |
4303 // Evaluate expression and get value. | 4350 // Evaluate expression and get value. |
4304 if (assign_type == VARIABLE) { | 4351 if (assign_type == VARIABLE) { |
4305 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); | 4352 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); |
4306 AccumulatorValueContext context(this); | 4353 AccumulatorValueContext context(this); |
4307 EmitVariableLoad(expr->expression()->AsVariableProxy()); | 4354 EmitVariableLoad(expr->expression()->AsVariableProxy()); |
4308 } else { | 4355 } else { |
4309 // Reserve space for result of postfix operation. | 4356 // Reserve space for result of postfix operation. |
4310 if (expr->is_postfix() && !context()->IsEffect()) { | 4357 if (expr->is_postfix() && !context()->IsEffect()) { |
(...skipping 593 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4904 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 4951 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
4905 Assembler::target_address_at(call_target_address, | 4952 Assembler::target_address_at(call_target_address, |
4906 unoptimized_code)); | 4953 unoptimized_code)); |
4907 return OSR_AFTER_STACK_CHECK; | 4954 return OSR_AFTER_STACK_CHECK; |
4908 } | 4955 } |
4909 | 4956 |
4910 | 4957 |
4911 } } // namespace v8::internal | 4958 } } // namespace v8::internal |
4912 | 4959 |
4913 #endif // V8_TARGET_ARCH_IA32 | 4960 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |