OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 724 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
735 VisitForAccumulatorValue(function); | 735 VisitForAccumulatorValue(function); |
736 __ pop(rdx); | 736 __ pop(rdx); |
737 } else { | 737 } else { |
738 __ movq(rdx, rax); | 738 __ movq(rdx, rax); |
739 __ LoadRoot(rax, Heap::kTheHoleValueRootIndex); | 739 __ LoadRoot(rax, Heap::kTheHoleValueRootIndex); |
740 } | 740 } |
741 ASSERT(prop->key()->AsLiteral() != NULL && | 741 ASSERT(prop->key()->AsLiteral() != NULL && |
742 prop->key()->AsLiteral()->handle()->IsSmi()); | 742 prop->key()->AsLiteral()->handle()->IsSmi()); |
743 __ Move(rcx, prop->key()->AsLiteral()->handle()); | 743 __ Move(rcx, prop->key()->AsLiteral()->handle()); |
744 | 744 |
745 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); | 745 Handle<Code> ic(Builtins::builtin(is_strict() |
| 746 ? Builtins::KeyedStoreIC_Initialize_Strict |
| 747 : Builtins::KeyedStoreIC_Initialize)); |
746 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 748 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
747 } | 749 } |
748 } | 750 } |
749 } | 751 } |
750 | 752 |
751 | 753 |
752 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { | 754 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { |
753 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); | 755 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); |
754 } | 756 } |
755 | 757 |
756 | 758 |
757 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { | 759 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { |
758 // Call the runtime to declare the globals. | 760 // Call the runtime to declare the globals. |
759 __ push(rsi); // The context is the first argument. | 761 __ push(rsi); // The context is the first argument. |
760 __ Push(pairs); | 762 __ Push(pairs); |
761 __ Push(Smi::FromInt(is_eval() ? 1 : 0)); | 763 __ Push(Smi::FromInt(is_eval() ? 1 : 0)); |
762 __ CallRuntime(Runtime::kDeclareGlobals, 3); | 764 __ Push(Smi::FromInt(strict_mode_flag())); |
| 765 __ CallRuntime(Runtime::kDeclareGlobals, 4); |
763 // Return value is ignored. | 766 // Return value is ignored. |
764 } | 767 } |
765 | 768 |
766 | 769 |
767 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { | 770 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { |
768 Comment cmnt(masm_, "[ SwitchStatement"); | 771 Comment cmnt(masm_, "[ SwitchStatement"); |
769 Breakable nested_statement(this, stmt); | 772 Breakable nested_statement(this, stmt); |
770 SetStatementPosition(stmt); | 773 SetStatementPosition(stmt); |
771 | 774 |
772 // Keep the switch value on the stack until a case matches. | 775 // Keep the switch value on the stack until a case matches. |
(...skipping 623 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1396 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1399 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
1397 } | 1400 } |
1398 break; | 1401 break; |
1399 } | 1402 } |
1400 // Fall through. | 1403 // Fall through. |
1401 case ObjectLiteral::Property::PROTOTYPE: | 1404 case ObjectLiteral::Property::PROTOTYPE: |
1402 __ push(Operand(rsp, 0)); // Duplicate receiver. | 1405 __ push(Operand(rsp, 0)); // Duplicate receiver. |
1403 VisitForStackValue(key); | 1406 VisitForStackValue(key); |
1404 VisitForStackValue(value); | 1407 VisitForStackValue(value); |
1405 if (property->emit_store()) { | 1408 if (property->emit_store()) { |
1406 __ CallRuntime(Runtime::kSetProperty, 3); | 1409 __ Push(Smi::FromInt(NONE)); // PropertyAttributes |
| 1410 __ CallRuntime(Runtime::kSetProperty, 4); |
1407 } else { | 1411 } else { |
1408 __ Drop(3); | 1412 __ Drop(3); |
1409 } | 1413 } |
1410 break; | 1414 break; |
1411 case ObjectLiteral::Property::SETTER: | 1415 case ObjectLiteral::Property::SETTER: |
1412 case ObjectLiteral::Property::GETTER: | 1416 case ObjectLiteral::Property::GETTER: |
1413 __ push(Operand(rsp, 0)); // Duplicate receiver. | 1417 __ push(Operand(rsp, 0)); // Duplicate receiver. |
1414 VisitForStackValue(key); | 1418 VisitForStackValue(key); |
1415 __ Push(property->kind() == ObjectLiteral::Property::SETTER ? | 1419 __ Push(property->kind() == ObjectLiteral::Property::SETTER ? |
1416 Smi::FromInt(1) : | 1420 Smi::FromInt(1) : |
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1743 EffectContext context(this); | 1747 EffectContext context(this); |
1744 EmitVariableAssignment(var, Token::ASSIGN); | 1748 EmitVariableAssignment(var, Token::ASSIGN); |
1745 break; | 1749 break; |
1746 } | 1750 } |
1747 case NAMED_PROPERTY: { | 1751 case NAMED_PROPERTY: { |
1748 __ push(rax); // Preserve value. | 1752 __ push(rax); // Preserve value. |
1749 VisitForAccumulatorValue(prop->obj()); | 1753 VisitForAccumulatorValue(prop->obj()); |
1750 __ movq(rdx, rax); | 1754 __ movq(rdx, rax); |
1751 __ pop(rax); // Restore value. | 1755 __ pop(rax); // Restore value. |
1752 __ Move(rcx, prop->key()->AsLiteral()->handle()); | 1756 __ Move(rcx, prop->key()->AsLiteral()->handle()); |
1753 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 1757 Handle<Code> ic(Builtins::builtin( |
| 1758 is_strict() ? Builtins::StoreIC_Initialize_Strict |
| 1759 : Builtins::StoreIC_Initialize)); |
1754 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1760 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
1755 break; | 1761 break; |
1756 } | 1762 } |
1757 case KEYED_PROPERTY: { | 1763 case KEYED_PROPERTY: { |
1758 __ push(rax); // Preserve value. | 1764 __ push(rax); // Preserve value. |
1759 if (prop->is_synthetic()) { | 1765 if (prop->is_synthetic()) { |
1760 ASSERT(prop->obj()->AsVariableProxy() != NULL); | 1766 ASSERT(prop->obj()->AsVariableProxy() != NULL); |
1761 ASSERT(prop->key()->AsLiteral() != NULL); | 1767 ASSERT(prop->key()->AsLiteral() != NULL); |
1762 { AccumulatorValueContext for_object(this); | 1768 { AccumulatorValueContext for_object(this); |
1763 EmitVariableLoad(prop->obj()->AsVariableProxy()->var()); | 1769 EmitVariableLoad(prop->obj()->AsVariableProxy()->var()); |
1764 } | 1770 } |
1765 __ movq(rdx, rax); | 1771 __ movq(rdx, rax); |
1766 __ Move(rcx, prop->key()->AsLiteral()->handle()); | 1772 __ Move(rcx, prop->key()->AsLiteral()->handle()); |
1767 } else { | 1773 } else { |
1768 VisitForStackValue(prop->obj()); | 1774 VisitForStackValue(prop->obj()); |
1769 VisitForAccumulatorValue(prop->key()); | 1775 VisitForAccumulatorValue(prop->key()); |
1770 __ movq(rcx, rax); | 1776 __ movq(rcx, rax); |
1771 __ pop(rdx); | 1777 __ pop(rdx); |
1772 } | 1778 } |
1773 __ pop(rax); // Restore value. | 1779 __ pop(rax); // Restore value. |
1774 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); | 1780 Handle<Code> ic(Builtins::builtin( |
| 1781 is_strict() ? Builtins::KeyedStoreIC_Initialize_Strict |
| 1782 : Builtins::KeyedStoreIC_Initialize)); |
1775 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1783 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
1776 break; | 1784 break; |
1777 } | 1785 } |
1778 } | 1786 } |
1779 PrepareForBailoutForId(bailout_ast_id, TOS_REG); | 1787 PrepareForBailoutForId(bailout_ast_id, TOS_REG); |
1780 context()->Plug(rax); | 1788 context()->Plug(rax); |
1781 } | 1789 } |
1782 | 1790 |
1783 | 1791 |
1784 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 1792 void FullCodeGenerator::EmitVariableAssignment(Variable* var, |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1859 int offset = Context::SlotOffset(slot->index()); | 1867 int offset = Context::SlotOffset(slot->index()); |
1860 __ RecordWrite(rcx, offset, rdx, rbx); | 1868 __ RecordWrite(rcx, offset, rdx, rbx); |
1861 break; | 1869 break; |
1862 } | 1870 } |
1863 | 1871 |
1864 case Slot::LOOKUP: | 1872 case Slot::LOOKUP: |
1865 // Call the runtime for the assignment. | 1873 // Call the runtime for the assignment. |
1866 __ push(rax); // Value. | 1874 __ push(rax); // Value. |
1867 __ push(rsi); // Context. | 1875 __ push(rsi); // Context. |
1868 __ Push(var->name()); | 1876 __ Push(var->name()); |
1869 __ CallRuntime(Runtime::kStoreContextSlot, 3); | 1877 __ Push(Smi::FromInt(strict_mode_flag())); |
| 1878 __ CallRuntime(Runtime::kStoreContextSlot, 4); |
1870 break; | 1879 break; |
1871 } | 1880 } |
1872 } | 1881 } |
1873 } | 1882 } |
1874 | 1883 |
1875 | 1884 |
1876 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { | 1885 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { |
1877 // Assignment to a property, using a named store IC. | 1886 // Assignment to a property, using a named store IC. |
1878 Property* prop = expr->target()->AsProperty(); | 1887 Property* prop = expr->target()->AsProperty(); |
1879 ASSERT(prop != NULL); | 1888 ASSERT(prop != NULL); |
(...skipping 10 matching lines...) Expand all Loading... |
1890 } | 1899 } |
1891 | 1900 |
1892 // Record source code position before IC call. | 1901 // Record source code position before IC call. |
1893 SetSourcePosition(expr->position()); | 1902 SetSourcePosition(expr->position()); |
1894 __ Move(rcx, prop->key()->AsLiteral()->handle()); | 1903 __ Move(rcx, prop->key()->AsLiteral()->handle()); |
1895 if (expr->ends_initialization_block()) { | 1904 if (expr->ends_initialization_block()) { |
1896 __ movq(rdx, Operand(rsp, 0)); | 1905 __ movq(rdx, Operand(rsp, 0)); |
1897 } else { | 1906 } else { |
1898 __ pop(rdx); | 1907 __ pop(rdx); |
1899 } | 1908 } |
1900 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 1909 Handle<Code> ic(Builtins::builtin( |
| 1910 is_strict() ? Builtins::StoreIC_Initialize_Strict |
| 1911 : Builtins::StoreIC_Initialize)); |
1901 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1912 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
1902 | 1913 |
1903 // If the assignment ends an initialization block, revert to fast case. | 1914 // If the assignment ends an initialization block, revert to fast case. |
1904 if (expr->ends_initialization_block()) { | 1915 if (expr->ends_initialization_block()) { |
1905 __ push(rax); // Result of assignment, saved even if not needed. | 1916 __ push(rax); // Result of assignment, saved even if not needed. |
1906 __ push(Operand(rsp, kPointerSize)); // Receiver is under value. | 1917 __ push(Operand(rsp, kPointerSize)); // Receiver is under value. |
1907 __ CallRuntime(Runtime::kToFastProperties, 1); | 1918 __ CallRuntime(Runtime::kToFastProperties, 1); |
1908 __ pop(rax); | 1919 __ pop(rax); |
1909 __ Drop(1); | 1920 __ Drop(1); |
1910 } | 1921 } |
(...skipping 17 matching lines...) Expand all Loading... |
1928 } | 1939 } |
1929 | 1940 |
1930 __ pop(rcx); | 1941 __ pop(rcx); |
1931 if (expr->ends_initialization_block()) { | 1942 if (expr->ends_initialization_block()) { |
1932 __ movq(rdx, Operand(rsp, 0)); // Leave receiver on the stack for later. | 1943 __ movq(rdx, Operand(rsp, 0)); // Leave receiver on the stack for later. |
1933 } else { | 1944 } else { |
1934 __ pop(rdx); | 1945 __ pop(rdx); |
1935 } | 1946 } |
1936 // Record source code position before IC call. | 1947 // Record source code position before IC call. |
1937 SetSourcePosition(expr->position()); | 1948 SetSourcePosition(expr->position()); |
1938 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); | 1949 Handle<Code> ic(Builtins::builtin( |
| 1950 is_strict() ? Builtins::KeyedStoreIC_Initialize_Strict |
| 1951 : Builtins::KeyedStoreIC_Initialize)); |
1939 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1952 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
1940 | 1953 |
1941 // If the assignment ends an initialization block, revert to fast case. | 1954 // If the assignment ends an initialization block, revert to fast case. |
1942 if (expr->ends_initialization_block()) { | 1955 if (expr->ends_initialization_block()) { |
1943 __ pop(rdx); | 1956 __ pop(rdx); |
1944 __ push(rax); // Result of assignment, saved even if not needed. | 1957 __ push(rax); // Result of assignment, saved even if not needed. |
1945 __ push(rdx); | 1958 __ push(rdx); |
1946 __ CallRuntime(Runtime::kToFastProperties, 1); | 1959 __ CallRuntime(Runtime::kToFastProperties, 1); |
1947 __ pop(rax); | 1960 __ pop(rax); |
1948 } | 1961 } |
(...skipping 1493 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3442 // Perform the assignment as if via '='. | 3455 // Perform the assignment as if via '='. |
3443 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 3456 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
3444 Token::ASSIGN); | 3457 Token::ASSIGN); |
3445 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3458 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
3446 context()->Plug(rax); | 3459 context()->Plug(rax); |
3447 } | 3460 } |
3448 break; | 3461 break; |
3449 case NAMED_PROPERTY: { | 3462 case NAMED_PROPERTY: { |
3450 __ Move(rcx, prop->key()->AsLiteral()->handle()); | 3463 __ Move(rcx, prop->key()->AsLiteral()->handle()); |
3451 __ pop(rdx); | 3464 __ pop(rdx); |
3452 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 3465 Handle<Code> ic(Builtins::builtin( |
| 3466 is_strict() ? Builtins::StoreIC_Initialize_Strict |
| 3467 : Builtins::StoreIC_Initialize)); |
3453 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 3468 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
3454 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3469 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
3455 if (expr->is_postfix()) { | 3470 if (expr->is_postfix()) { |
3456 if (!context()->IsEffect()) { | 3471 if (!context()->IsEffect()) { |
3457 context()->PlugTOS(); | 3472 context()->PlugTOS(); |
3458 } | 3473 } |
3459 } else { | 3474 } else { |
3460 context()->Plug(rax); | 3475 context()->Plug(rax); |
3461 } | 3476 } |
3462 break; | 3477 break; |
3463 } | 3478 } |
3464 case KEYED_PROPERTY: { | 3479 case KEYED_PROPERTY: { |
3465 __ pop(rcx); | 3480 __ pop(rcx); |
3466 __ pop(rdx); | 3481 __ pop(rdx); |
3467 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); | 3482 Handle<Code> ic(Builtins::builtin( |
| 3483 is_strict() ? Builtins::KeyedStoreIC_Initialize_Strict |
| 3484 : Builtins::KeyedStoreIC_Initialize)); |
3468 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 3485 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
3469 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3486 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
3470 if (expr->is_postfix()) { | 3487 if (expr->is_postfix()) { |
3471 if (!context()->IsEffect()) { | 3488 if (!context()->IsEffect()) { |
3472 context()->PlugTOS(); | 3489 context()->PlugTOS(); |
3473 } | 3490 } |
3474 } else { | 3491 } else { |
3475 context()->Plug(rax); | 3492 context()->Plug(rax); |
3476 } | 3493 } |
3477 break; | 3494 break; |
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3878 __ ret(0); | 3895 __ ret(0); |
3879 } | 3896 } |
3880 | 3897 |
3881 | 3898 |
3882 #undef __ | 3899 #undef __ |
3883 | 3900 |
3884 | 3901 |
3885 } } // namespace v8::internal | 3902 } } // namespace v8::internal |
3886 | 3903 |
3887 #endif // V8_TARGET_ARCH_X64 | 3904 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |