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_MIPS | 7 #if V8_TARGET_ARCH_MIPS |
8 | 8 |
9 // Note on Mips implementation: | 9 // Note on Mips implementation: |
10 // | 10 // |
(...skipping 1856 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1867 } | 1867 } |
1868 | 1868 |
1869 | 1869 |
1870 void FullCodeGenerator::VisitAssignment(Assignment* expr) { | 1870 void FullCodeGenerator::VisitAssignment(Assignment* expr) { |
1871 DCHECK(expr->target()->IsValidReferenceExpression()); | 1871 DCHECK(expr->target()->IsValidReferenceExpression()); |
1872 | 1872 |
1873 Comment cmnt(masm_, "[ Assignment"); | 1873 Comment cmnt(masm_, "[ Assignment"); |
1874 | 1874 |
1875 // Left-hand side can only be a property, a global or a (parameter or local) | 1875 // Left-hand side can only be a property, a global or a (parameter or local) |
1876 // slot. | 1876 // slot. |
1877 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; | 1877 enum LhsKind { |
| 1878 VARIABLE, |
| 1879 NAMED_PROPERTY, |
| 1880 KEYED_PROPERTY, |
| 1881 NAMED_SUPER_PROPERTY |
| 1882 }; |
1878 LhsKind assign_type = VARIABLE; | 1883 LhsKind assign_type = VARIABLE; |
1879 Property* property = expr->target()->AsProperty(); | 1884 Property* property = expr->target()->AsProperty(); |
1880 if (property != NULL) { | 1885 if (property != NULL) { |
1881 assign_type = (property->key()->IsPropertyName()) | 1886 assign_type = (property->key()->IsPropertyName()) |
1882 ? NAMED_PROPERTY | 1887 ? (property->IsSuperAccess() ? NAMED_SUPER_PROPERTY |
1883 : KEYED_PROPERTY; | 1888 : NAMED_PROPERTY) |
| 1889 : KEYED_PROPERTY; |
1884 } | 1890 } |
1885 | 1891 |
1886 // Evaluate LHS expression. | 1892 // Evaluate LHS expression. |
1887 switch (assign_type) { | 1893 switch (assign_type) { |
1888 case VARIABLE: | 1894 case VARIABLE: |
1889 // Nothing to do here. | 1895 // Nothing to do here. |
1890 break; | 1896 break; |
1891 case NAMED_PROPERTY: | 1897 case NAMED_PROPERTY: |
1892 if (expr->is_compound()) { | 1898 if (expr->is_compound()) { |
1893 // We need the receiver both on the stack and in the register. | 1899 // We need the receiver both on the stack and in the register. |
1894 VisitForStackValue(property->obj()); | 1900 VisitForStackValue(property->obj()); |
1895 __ lw(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); | 1901 __ lw(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); |
1896 } else { | 1902 } else { |
1897 VisitForStackValue(property->obj()); | 1903 VisitForStackValue(property->obj()); |
1898 } | 1904 } |
1899 break; | 1905 break; |
| 1906 case NAMED_SUPER_PROPERTY: |
| 1907 VisitForStackValue(property->obj()->AsSuperReference()->this_var()); |
| 1908 EmitLoadHomeObject(property->obj()->AsSuperReference()); |
| 1909 __ Push(result_register()); |
| 1910 if (expr->is_compound()) { |
| 1911 const Register scratch = a1; |
| 1912 __ lw(scratch, MemOperand(sp, kPointerSize)); |
| 1913 __ Push(scratch, result_register()); |
| 1914 } |
| 1915 break; |
1900 case KEYED_PROPERTY: | 1916 case KEYED_PROPERTY: |
1901 // We need the key and receiver on both the stack and in v0 and a1. | 1917 // We need the key and receiver on both the stack and in v0 and a1. |
1902 if (expr->is_compound()) { | 1918 if (expr->is_compound()) { |
1903 VisitForStackValue(property->obj()); | 1919 VisitForStackValue(property->obj()); |
1904 VisitForStackValue(property->key()); | 1920 VisitForStackValue(property->key()); |
1905 __ lw(LoadDescriptor::ReceiverRegister(), | 1921 __ lw(LoadDescriptor::ReceiverRegister(), |
1906 MemOperand(sp, 1 * kPointerSize)); | 1922 MemOperand(sp, 1 * kPointerSize)); |
1907 __ lw(LoadDescriptor::NameRegister(), MemOperand(sp, 0)); | 1923 __ lw(LoadDescriptor::NameRegister(), MemOperand(sp, 0)); |
1908 } else { | 1924 } else { |
1909 VisitForStackValue(property->obj()); | 1925 VisitForStackValue(property->obj()); |
1910 VisitForStackValue(property->key()); | 1926 VisitForStackValue(property->key()); |
1911 } | 1927 } |
1912 break; | 1928 break; |
1913 } | 1929 } |
1914 | 1930 |
1915 // For compound assignments we need another deoptimization point after the | 1931 // For compound assignments we need another deoptimization point after the |
1916 // variable/property load. | 1932 // variable/property load. |
1917 if (expr->is_compound()) { | 1933 if (expr->is_compound()) { |
1918 { AccumulatorValueContext context(this); | 1934 { AccumulatorValueContext context(this); |
1919 switch (assign_type) { | 1935 switch (assign_type) { |
1920 case VARIABLE: | 1936 case VARIABLE: |
1921 EmitVariableLoad(expr->target()->AsVariableProxy()); | 1937 EmitVariableLoad(expr->target()->AsVariableProxy()); |
1922 PrepareForBailout(expr->target(), TOS_REG); | 1938 PrepareForBailout(expr->target(), TOS_REG); |
1923 break; | 1939 break; |
1924 case NAMED_PROPERTY: | 1940 case NAMED_PROPERTY: |
1925 EmitNamedPropertyLoad(property); | 1941 EmitNamedPropertyLoad(property); |
1926 PrepareForBailoutForId(property->LoadId(), TOS_REG); | 1942 PrepareForBailoutForId(property->LoadId(), TOS_REG); |
1927 break; | 1943 break; |
| 1944 case NAMED_SUPER_PROPERTY: |
| 1945 EmitNamedSuperPropertyLoad(property); |
| 1946 PrepareForBailoutForId(property->LoadId(), TOS_REG); |
| 1947 break; |
1928 case KEYED_PROPERTY: | 1948 case KEYED_PROPERTY: |
1929 EmitKeyedPropertyLoad(property); | 1949 EmitKeyedPropertyLoad(property); |
1930 PrepareForBailoutForId(property->LoadId(), TOS_REG); | 1950 PrepareForBailoutForId(property->LoadId(), TOS_REG); |
1931 break; | 1951 break; |
1932 } | 1952 } |
1933 } | 1953 } |
1934 | 1954 |
1935 Token::Value op = expr->binary_op(); | 1955 Token::Value op = expr->binary_op(); |
1936 __ push(v0); // Left operand goes on the stack. | 1956 __ push(v0); // Left operand goes on the stack. |
1937 VisitForAccumulatorValue(expr->value()); | 1957 VisitForAccumulatorValue(expr->value()); |
(...skipping 26 matching lines...) Expand all Loading... |
1964 switch (assign_type) { | 1984 switch (assign_type) { |
1965 case VARIABLE: | 1985 case VARIABLE: |
1966 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), | 1986 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), |
1967 expr->op()); | 1987 expr->op()); |
1968 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 1988 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
1969 context()->Plug(v0); | 1989 context()->Plug(v0); |
1970 break; | 1990 break; |
1971 case NAMED_PROPERTY: | 1991 case NAMED_PROPERTY: |
1972 EmitNamedPropertyAssignment(expr); | 1992 EmitNamedPropertyAssignment(expr); |
1973 break; | 1993 break; |
| 1994 case NAMED_SUPER_PROPERTY: |
| 1995 EmitNamedSuperPropertyAssignment(expr); |
| 1996 break; |
1974 case KEYED_PROPERTY: | 1997 case KEYED_PROPERTY: |
1975 EmitKeyedPropertyAssignment(expr); | 1998 EmitKeyedPropertyAssignment(expr); |
1976 break; | 1999 break; |
1977 } | 2000 } |
1978 } | 2001 } |
1979 | 2002 |
1980 | 2003 |
1981 void FullCodeGenerator::VisitYield(Yield* expr) { | 2004 void FullCodeGenerator::VisitYield(Yield* expr) { |
1982 Comment cmnt(masm_, "[ Yield"); | 2005 Comment cmnt(masm_, "[ Yield"); |
1983 // Evaluate yielded value first; the initial iterator definition depends on | 2006 // Evaluate yielded value first; the initial iterator definition depends on |
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2292 // Only the value field needs a write barrier, as the other values are in the | 2315 // Only the value field needs a write barrier, as the other values are in the |
2293 // root set. | 2316 // root set. |
2294 __ RecordWriteField(v0, JSGeneratorObject::kResultValuePropertyOffset, | 2317 __ RecordWriteField(v0, JSGeneratorObject::kResultValuePropertyOffset, |
2295 a2, a3, kRAHasBeenSaved, kDontSaveFPRegs); | 2318 a2, a3, kRAHasBeenSaved, kDontSaveFPRegs); |
2296 } | 2319 } |
2297 | 2320 |
2298 | 2321 |
2299 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 2322 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
2300 SetSourcePosition(prop->position()); | 2323 SetSourcePosition(prop->position()); |
2301 Literal* key = prop->key()->AsLiteral(); | 2324 Literal* key = prop->key()->AsLiteral(); |
| 2325 DCHECK(!prop->IsSuperAccess()); |
2302 | 2326 |
2303 __ li(LoadDescriptor::NameRegister(), Operand(key->value())); | 2327 __ li(LoadDescriptor::NameRegister(), Operand(key->value())); |
2304 if (FLAG_vector_ics) { | 2328 if (FLAG_vector_ics) { |
2305 __ li(VectorLoadICDescriptor::SlotRegister(), | 2329 __ li(VectorLoadICDescriptor::SlotRegister(), |
2306 Operand(Smi::FromInt(prop->PropertyFeedbackSlot()))); | 2330 Operand(Smi::FromInt(prop->PropertyFeedbackSlot()))); |
2307 CallLoadIC(NOT_CONTEXTUAL); | 2331 CallLoadIC(NOT_CONTEXTUAL); |
2308 } else { | 2332 } else { |
2309 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); | 2333 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); |
2310 } | 2334 } |
2311 } | 2335 } |
2312 | 2336 |
2313 | 2337 |
2314 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { | 2338 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { |
| 2339 // Stack: receiver, home_object. |
2315 SetSourcePosition(prop->position()); | 2340 SetSourcePosition(prop->position()); |
2316 Literal* key = prop->key()->AsLiteral(); | 2341 Literal* key = prop->key()->AsLiteral(); |
2317 DCHECK(!key->value()->IsSmi()); | 2342 DCHECK(!key->value()->IsSmi()); |
2318 DCHECK(prop->IsSuperAccess()); | 2343 DCHECK(prop->IsSuperAccess()); |
2319 | 2344 |
2320 SuperReference* super_ref = prop->obj()->AsSuperReference(); | |
2321 EmitLoadHomeObject(super_ref); | |
2322 __ Push(v0); | |
2323 VisitForStackValue(super_ref->this_var()); | |
2324 __ Push(key->value()); | 2345 __ Push(key->value()); |
2325 __ CallRuntime(Runtime::kLoadFromSuper, 3); | 2346 __ CallRuntime(Runtime::kLoadFromSuper, 3); |
2326 } | 2347 } |
2327 | 2348 |
2328 | 2349 |
2329 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 2350 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
2330 SetSourcePosition(prop->position()); | 2351 SetSourcePosition(prop->position()); |
2331 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code(); | 2352 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code(); |
2332 if (FLAG_vector_ics) { | 2353 if (FLAG_vector_ics) { |
2333 __ li(VectorLoadICDescriptor::SlotRegister(), | 2354 __ li(VectorLoadICDescriptor::SlotRegister(), |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2585 __ li(StoreDescriptor::NameRegister(), | 2606 __ li(StoreDescriptor::NameRegister(), |
2586 Operand(prop->key()->AsLiteral()->value())); | 2607 Operand(prop->key()->AsLiteral()->value())); |
2587 __ pop(StoreDescriptor::ReceiverRegister()); | 2608 __ pop(StoreDescriptor::ReceiverRegister()); |
2588 CallStoreIC(expr->AssignmentFeedbackId()); | 2609 CallStoreIC(expr->AssignmentFeedbackId()); |
2589 | 2610 |
2590 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2611 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2591 context()->Plug(v0); | 2612 context()->Plug(v0); |
2592 } | 2613 } |
2593 | 2614 |
2594 | 2615 |
| 2616 void FullCodeGenerator::EmitNamedSuperPropertyAssignment(Assignment* expr) { |
| 2617 // Assignment to named property of super. |
| 2618 // v0 : value |
| 2619 // stack : receiver ('this'), home_object |
| 2620 Property* prop = expr->target()->AsProperty(); |
| 2621 DCHECK(prop != NULL); |
| 2622 Literal* key = prop->key()->AsLiteral(); |
| 2623 DCHECK(key != NULL); |
| 2624 |
| 2625 __ Push(v0); |
| 2626 __ Push(key->value()); |
| 2627 __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreToSuper_Strict |
| 2628 : Runtime::kStoreToSuper_Sloppy), |
| 2629 4); |
| 2630 context()->Plug(v0); |
| 2631 } |
| 2632 |
| 2633 |
2595 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 2634 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
2596 // Assignment to a property, using a keyed store IC. | 2635 // Assignment to a property, using a keyed store IC. |
2597 | 2636 |
2598 // Record source code position before IC call. | 2637 // Record source code position before IC call. |
2599 SetSourcePosition(expr->position()); | 2638 SetSourcePosition(expr->position()); |
2600 // Call keyed store IC. | 2639 // Call keyed store IC. |
2601 // The arguments are: | 2640 // The arguments are: |
2602 // - a0 is the value, | 2641 // - a0 is the value, |
2603 // - a1 is the key, | 2642 // - a1 is the key, |
2604 // - a2 is the receiver. | 2643 // - a2 is the receiver. |
(...skipping 12 matching lines...) Expand all Loading... |
2617 void FullCodeGenerator::VisitProperty(Property* expr) { | 2656 void FullCodeGenerator::VisitProperty(Property* expr) { |
2618 Comment cmnt(masm_, "[ Property"); | 2657 Comment cmnt(masm_, "[ Property"); |
2619 Expression* key = expr->key(); | 2658 Expression* key = expr->key(); |
2620 | 2659 |
2621 if (key->IsPropertyName()) { | 2660 if (key->IsPropertyName()) { |
2622 if (!expr->IsSuperAccess()) { | 2661 if (!expr->IsSuperAccess()) { |
2623 VisitForAccumulatorValue(expr->obj()); | 2662 VisitForAccumulatorValue(expr->obj()); |
2624 __ Move(LoadDescriptor::ReceiverRegister(), v0); | 2663 __ Move(LoadDescriptor::ReceiverRegister(), v0); |
2625 EmitNamedPropertyLoad(expr); | 2664 EmitNamedPropertyLoad(expr); |
2626 } else { | 2665 } else { |
| 2666 VisitForStackValue(expr->obj()->AsSuperReference()->this_var()); |
| 2667 EmitLoadHomeObject(expr->obj()->AsSuperReference()); |
| 2668 __ Push(result_register()); |
2627 EmitNamedSuperPropertyLoad(expr); | 2669 EmitNamedSuperPropertyLoad(expr); |
2628 } | 2670 } |
2629 PrepareForBailoutForId(expr->LoadId(), TOS_REG); | 2671 PrepareForBailoutForId(expr->LoadId(), TOS_REG); |
2630 context()->Plug(v0); | 2672 context()->Plug(v0); |
2631 } else { | 2673 } else { |
2632 VisitForStackValue(expr->obj()); | 2674 VisitForStackValue(expr->obj()); |
2633 VisitForAccumulatorValue(expr->key()); | 2675 VisitForAccumulatorValue(expr->key()); |
2634 __ Move(LoadDescriptor::NameRegister(), v0); | 2676 __ Move(LoadDescriptor::NameRegister(), v0); |
2635 __ pop(LoadDescriptor::ReceiverRegister()); | 2677 __ pop(LoadDescriptor::ReceiverRegister()); |
2636 EmitKeyedPropertyLoad(expr); | 2678 EmitKeyedPropertyLoad(expr); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2685 Property* prop = callee->AsProperty(); | 2727 Property* prop = callee->AsProperty(); |
2686 DCHECK(prop->IsSuperAccess()); | 2728 DCHECK(prop->IsSuperAccess()); |
2687 | 2729 |
2688 SetSourcePosition(prop->position()); | 2730 SetSourcePosition(prop->position()); |
2689 Literal* key = prop->key()->AsLiteral(); | 2731 Literal* key = prop->key()->AsLiteral(); |
2690 DCHECK(!key->value()->IsSmi()); | 2732 DCHECK(!key->value()->IsSmi()); |
2691 // Load the function from the receiver. | 2733 // Load the function from the receiver. |
2692 const Register scratch = a1; | 2734 const Register scratch = a1; |
2693 SuperReference* super_ref = prop->obj()->AsSuperReference(); | 2735 SuperReference* super_ref = prop->obj()->AsSuperReference(); |
2694 EmitLoadHomeObject(super_ref); | 2736 EmitLoadHomeObject(super_ref); |
2695 __ Push(v0); | 2737 __ mov(scratch, v0); |
2696 VisitForAccumulatorValue(super_ref->this_var()); | 2738 VisitForAccumulatorValue(super_ref->this_var()); |
2697 __ Push(v0); | 2739 __ Push(scratch, v0, v0, scratch); |
2698 __ lw(scratch, MemOperand(sp, kPointerSize)); | |
2699 __ Push(scratch, v0); | |
2700 __ Push(key->value()); | 2740 __ Push(key->value()); |
2701 | 2741 |
2702 // Stack here: | 2742 // Stack here: |
2703 // - home_object | 2743 // - home_object |
2704 // - this (receiver) | 2744 // - this (receiver) |
2705 // - home_object <-- LoadFromSuper will pop here and below. | 2745 // - this (receiver) <-- LoadFromSuper will pop here and below. |
2706 // - this (receiver) | 2746 // - home_object |
2707 // - key | 2747 // - key |
2708 __ CallRuntime(Runtime::kLoadFromSuper, 3); | 2748 __ CallRuntime(Runtime::kLoadFromSuper, 3); |
2709 | 2749 |
2710 // Replace home_object with target function. | 2750 // Replace home_object with target function. |
2711 __ sw(v0, MemOperand(sp, kPointerSize)); | 2751 __ sw(v0, MemOperand(sp, kPointerSize)); |
2712 | 2752 |
2713 // Stack here: | 2753 // Stack here: |
2714 // - target function | 2754 // - target function |
2715 // - this (receiver) | 2755 // - this (receiver) |
2716 EmitCall(expr, CallICState::METHOD); | 2756 EmitCall(expr, CallICState::METHOD); |
(...skipping 1626 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4343 // Expression can only be a property, a global or a (parameter or local) | 4383 // Expression can only be a property, a global or a (parameter or local) |
4344 // slot. | 4384 // slot. |
4345 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; | 4385 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; |
4346 LhsKind assign_type = VARIABLE; | 4386 LhsKind assign_type = VARIABLE; |
4347 Property* prop = expr->expression()->AsProperty(); | 4387 Property* prop = expr->expression()->AsProperty(); |
4348 // In case of a property we use the uninitialized expression context | 4388 // In case of a property we use the uninitialized expression context |
4349 // of the key to detect a named property. | 4389 // of the key to detect a named property. |
4350 if (prop != NULL) { | 4390 if (prop != NULL) { |
4351 assign_type = | 4391 assign_type = |
4352 (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY; | 4392 (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY; |
| 4393 if (prop->IsSuperAccess()) { |
| 4394 // throw exception. |
| 4395 VisitSuperReference(prop->obj()->AsSuperReference()); |
| 4396 return; |
| 4397 } |
4353 } | 4398 } |
4354 | 4399 |
4355 // Evaluate expression and get value. | 4400 // Evaluate expression and get value. |
4356 if (assign_type == VARIABLE) { | 4401 if (assign_type == VARIABLE) { |
4357 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); | 4402 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); |
4358 AccumulatorValueContext context(this); | 4403 AccumulatorValueContext context(this); |
4359 EmitVariableLoad(expr->expression()->AsVariableProxy()); | 4404 EmitVariableLoad(expr->expression()->AsVariableProxy()); |
4360 } else { | 4405 } else { |
4361 // Reserve space for result of postfix operation. | 4406 // Reserve space for result of postfix operation. |
4362 if (expr->is_postfix() && !context()->IsEffect()) { | 4407 if (expr->is_postfix() && !context()->IsEffect()) { |
(...skipping 593 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4956 Assembler::target_address_at(pc_immediate_load_address)) == | 5001 Assembler::target_address_at(pc_immediate_load_address)) == |
4957 reinterpret_cast<uint32_t>( | 5002 reinterpret_cast<uint32_t>( |
4958 isolate->builtins()->OsrAfterStackCheck()->entry())); | 5003 isolate->builtins()->OsrAfterStackCheck()->entry())); |
4959 return OSR_AFTER_STACK_CHECK; | 5004 return OSR_AFTER_STACK_CHECK; |
4960 } | 5005 } |
4961 | 5006 |
4962 | 5007 |
4963 } } // namespace v8::internal | 5008 } } // namespace v8::internal |
4964 | 5009 |
4965 #endif // V8_TARGET_ARCH_MIPS | 5010 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |