Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(105)

Side by Side Diff: src/x64/full-codegen-x64.cc

Issue 6576024: (early draft) Strict mode - throw exception on assignment to read only property. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 715 matching lines...) Expand 10 before | Expand all | Expand 10 after
726 VisitForAccumulatorValue(function); 726 VisitForAccumulatorValue(function);
727 __ pop(rdx); 727 __ pop(rdx);
728 } else { 728 } else {
729 __ movq(rdx, rax); 729 __ movq(rdx, rax);
730 __ LoadRoot(rax, Heap::kTheHoleValueRootIndex); 730 __ LoadRoot(rax, Heap::kTheHoleValueRootIndex);
731 } 731 }
732 ASSERT(prop->key()->AsLiteral() != NULL && 732 ASSERT(prop->key()->AsLiteral() != NULL &&
733 prop->key()->AsLiteral()->handle()->IsSmi()); 733 prop->key()->AsLiteral()->handle()->IsSmi());
734 __ Move(rcx, prop->key()->AsLiteral()->handle()); 734 __ Move(rcx, prop->key()->AsLiteral()->handle());
735 735
736 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); 736 Handle<Code> ic(Builtins::builtin(is_strict()
737 ? Builtins::KeyedStoreIC_Initialize_Strict
738 : Builtins::KeyedStoreIC_Initialize));
737 EmitCallIC(ic, RelocInfo::CODE_TARGET); 739 EmitCallIC(ic, RelocInfo::CODE_TARGET);
738 } 740 }
739 } 741 }
740 } 742 }
741 743
742 744
743 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { 745 void FullCodeGenerator::VisitDeclaration(Declaration* decl) {
744 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); 746 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun());
745 } 747 }
746 748
(...skipping 579 matching lines...) Expand 10 before | Expand all | Expand 10 after
1326 PrepareForBailoutForId(key->id(), NO_REGISTERS); 1328 PrepareForBailoutForId(key->id(), NO_REGISTERS);
1327 } 1329 }
1328 break; 1330 break;
1329 } 1331 }
1330 // Fall through. 1332 // Fall through.
1331 case ObjectLiteral::Property::PROTOTYPE: 1333 case ObjectLiteral::Property::PROTOTYPE:
1332 __ push(Operand(rsp, 0)); // Duplicate receiver. 1334 __ push(Operand(rsp, 0)); // Duplicate receiver.
1333 VisitForStackValue(key); 1335 VisitForStackValue(key);
1334 VisitForStackValue(value); 1336 VisitForStackValue(value);
1335 if (property->emit_store()) { 1337 if (property->emit_store()) {
1336 __ CallRuntime(Runtime::kSetProperty, 3); 1338 __ Push(Smi::FromInt(NONE)); // PropertyAttributes
1339 __ CallRuntime(Runtime::kSetProperty, 4);
1337 } else { 1340 } else {
1338 __ Drop(3); 1341 __ Drop(3);
1339 } 1342 }
1340 break; 1343 break;
1341 case ObjectLiteral::Property::SETTER: 1344 case ObjectLiteral::Property::SETTER:
1342 case ObjectLiteral::Property::GETTER: 1345 case ObjectLiteral::Property::GETTER:
1343 __ push(Operand(rsp, 0)); // Duplicate receiver. 1346 __ push(Operand(rsp, 0)); // Duplicate receiver.
1344 VisitForStackValue(key); 1347 VisitForStackValue(key);
1345 __ Push(property->kind() == ObjectLiteral::Property::SETTER ? 1348 __ Push(property->kind() == ObjectLiteral::Property::SETTER ?
1346 Smi::FromInt(1) : 1349 Smi::FromInt(1) :
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after
1673 EffectContext context(this); 1676 EffectContext context(this);
1674 EmitVariableAssignment(var, Token::ASSIGN); 1677 EmitVariableAssignment(var, Token::ASSIGN);
1675 break; 1678 break;
1676 } 1679 }
1677 case NAMED_PROPERTY: { 1680 case NAMED_PROPERTY: {
1678 __ push(rax); // Preserve value. 1681 __ push(rax); // Preserve value.
1679 VisitForAccumulatorValue(prop->obj()); 1682 VisitForAccumulatorValue(prop->obj());
1680 __ movq(rdx, rax); 1683 __ movq(rdx, rax);
1681 __ pop(rax); // Restore value. 1684 __ pop(rax); // Restore value.
1682 __ Move(rcx, prop->key()->AsLiteral()->handle()); 1685 __ Move(rcx, prop->key()->AsLiteral()->handle());
1683 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); 1686 Handle<Code> ic(Builtins::builtin(
1687 is_strict() ? Builtins::StoreIC_Initialize_Strict
1688 : Builtins::StoreIC_Initialize));
1684 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1689 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1685 break; 1690 break;
1686 } 1691 }
1687 case KEYED_PROPERTY: { 1692 case KEYED_PROPERTY: {
1688 __ push(rax); // Preserve value. 1693 __ push(rax); // Preserve value.
1689 if (prop->is_synthetic()) { 1694 if (prop->is_synthetic()) {
1690 ASSERT(prop->obj()->AsVariableProxy() != NULL); 1695 ASSERT(prop->obj()->AsVariableProxy() != NULL);
1691 ASSERT(prop->key()->AsLiteral() != NULL); 1696 ASSERT(prop->key()->AsLiteral() != NULL);
1692 { AccumulatorValueContext for_object(this); 1697 { AccumulatorValueContext for_object(this);
1693 EmitVariableLoad(prop->obj()->AsVariableProxy()->var()); 1698 EmitVariableLoad(prop->obj()->AsVariableProxy()->var());
1694 } 1699 }
1695 __ movq(rdx, rax); 1700 __ movq(rdx, rax);
1696 __ Move(rcx, prop->key()->AsLiteral()->handle()); 1701 __ Move(rcx, prop->key()->AsLiteral()->handle());
1697 } else { 1702 } else {
1698 VisitForStackValue(prop->obj()); 1703 VisitForStackValue(prop->obj());
1699 VisitForAccumulatorValue(prop->key()); 1704 VisitForAccumulatorValue(prop->key());
1700 __ movq(rcx, rax); 1705 __ movq(rcx, rax);
1701 __ pop(rdx); 1706 __ pop(rdx);
1702 } 1707 }
1703 __ pop(rax); // Restore value. 1708 __ pop(rax); // Restore value.
1704 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); 1709 Handle<Code> ic(Builtins::builtin(
1710 is_strict() ? Builtins::KeyedStoreIC_Initialize_Strict
1711 : Builtins::KeyedStoreIC_Initialize));
1705 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1712 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1706 break; 1713 break;
1707 } 1714 }
1708 } 1715 }
1709 PrepareForBailoutForId(bailout_ast_id, TOS_REG); 1716 PrepareForBailoutForId(bailout_ast_id, TOS_REG);
1710 context()->Plug(rax); 1717 context()->Plug(rax);
1711 } 1718 }
1712 1719
1713 1720
1714 void FullCodeGenerator::EmitVariableAssignment(Variable* var, 1721 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1769 case Slot::LOOKUP: 1776 case Slot::LOOKUP:
1770 // Call the runtime for the assignment. The runtime will ignore 1777 // Call the runtime for the assignment. The runtime will ignore
1771 // const reinitialization. 1778 // const reinitialization.
1772 __ push(rax); // Value. 1779 __ push(rax); // Value.
1773 __ push(rsi); // Context. 1780 __ push(rsi); // Context.
1774 __ Push(var->name()); 1781 __ Push(var->name());
1775 if (op == Token::INIT_CONST) { 1782 if (op == Token::INIT_CONST) {
1776 // The runtime will ignore const redeclaration. 1783 // The runtime will ignore const redeclaration.
1777 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3); 1784 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3);
1778 } else { 1785 } else {
1779 __ CallRuntime(Runtime::kStoreContextSlot, 3); 1786 __ Push(Smi::FromInt(strict_mode_flag()));
1787 __ CallRuntime(Runtime::kStoreContextSlot, 4);
1780 } 1788 }
1781 break; 1789 break;
1782 } 1790 }
1783 __ bind(&done); 1791 __ bind(&done);
1784 } 1792 }
1785 } 1793 }
1786 1794
1787 1795
1788 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 1796 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
1789 // Assignment to a property, using a named store IC. 1797 // Assignment to a property, using a named store IC.
(...skipping 12 matching lines...) Expand all
1802 } 1810 }
1803 1811
1804 // Record source code position before IC call. 1812 // Record source code position before IC call.
1805 SetSourcePosition(expr->position()); 1813 SetSourcePosition(expr->position());
1806 __ Move(rcx, prop->key()->AsLiteral()->handle()); 1814 __ Move(rcx, prop->key()->AsLiteral()->handle());
1807 if (expr->ends_initialization_block()) { 1815 if (expr->ends_initialization_block()) {
1808 __ movq(rdx, Operand(rsp, 0)); 1816 __ movq(rdx, Operand(rsp, 0));
1809 } else { 1817 } else {
1810 __ pop(rdx); 1818 __ pop(rdx);
1811 } 1819 }
1812 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); 1820 Handle<Code> ic(Builtins::builtin(
1821 is_strict() ? Builtins::StoreIC_Initialize_Strict
1822 : Builtins::StoreIC_Initialize));
1813 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1823 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1814 1824
1815 // If the assignment ends an initialization block, revert to fast case. 1825 // If the assignment ends an initialization block, revert to fast case.
1816 if (expr->ends_initialization_block()) { 1826 if (expr->ends_initialization_block()) {
1817 __ push(rax); // Result of assignment, saved even if not needed. 1827 __ push(rax); // Result of assignment, saved even if not needed.
1818 __ push(Operand(rsp, kPointerSize)); // Receiver is under value. 1828 __ push(Operand(rsp, kPointerSize)); // Receiver is under value.
1819 __ CallRuntime(Runtime::kToFastProperties, 1); 1829 __ CallRuntime(Runtime::kToFastProperties, 1);
1820 __ pop(rax); 1830 __ pop(rax);
1821 __ Drop(1); 1831 __ Drop(1);
1822 } 1832 }
(...skipping 17 matching lines...) Expand all
1840 } 1850 }
1841 1851
1842 __ pop(rcx); 1852 __ pop(rcx);
1843 if (expr->ends_initialization_block()) { 1853 if (expr->ends_initialization_block()) {
1844 __ movq(rdx, Operand(rsp, 0)); // Leave receiver on the stack for later. 1854 __ movq(rdx, Operand(rsp, 0)); // Leave receiver on the stack for later.
1845 } else { 1855 } else {
1846 __ pop(rdx); 1856 __ pop(rdx);
1847 } 1857 }
1848 // Record source code position before IC call. 1858 // Record source code position before IC call.
1849 SetSourcePosition(expr->position()); 1859 SetSourcePosition(expr->position());
1850 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); 1860 Handle<Code> ic(Builtins::builtin(
1861 is_strict() ? Builtins::KeyedStoreIC_Initialize_Strict
1862 : Builtins::KeyedStoreIC_Initialize));
1851 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1863 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1852 1864
1853 // If the assignment ends an initialization block, revert to fast case. 1865 // If the assignment ends an initialization block, revert to fast case.
1854 if (expr->ends_initialization_block()) { 1866 if (expr->ends_initialization_block()) {
1855 __ pop(rdx); 1867 __ pop(rdx);
1856 __ push(rax); // Result of assignment, saved even if not needed. 1868 __ push(rax); // Result of assignment, saved even if not needed.
1857 __ push(rdx); 1869 __ push(rdx);
1858 __ CallRuntime(Runtime::kToFastProperties, 1); 1870 __ CallRuntime(Runtime::kToFastProperties, 1);
1859 __ pop(rax); 1871 __ pop(rax);
1860 } 1872 }
(...skipping 1487 matching lines...) Expand 10 before | Expand all | Expand 10 after
3348 // Perform the assignment as if via '='. 3360 // Perform the assignment as if via '='.
3349 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 3361 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3350 Token::ASSIGN); 3362 Token::ASSIGN);
3351 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3363 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3352 context()->Plug(rax); 3364 context()->Plug(rax);
3353 } 3365 }
3354 break; 3366 break;
3355 case NAMED_PROPERTY: { 3367 case NAMED_PROPERTY: {
3356 __ Move(rcx, prop->key()->AsLiteral()->handle()); 3368 __ Move(rcx, prop->key()->AsLiteral()->handle());
3357 __ pop(rdx); 3369 __ pop(rdx);
3358 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); 3370 Handle<Code> ic(Builtins::builtin(
3371 is_strict() ? Builtins::StoreIC_Initialize_Strict
3372 : Builtins::StoreIC_Initialize));
3359 EmitCallIC(ic, RelocInfo::CODE_TARGET); 3373 EmitCallIC(ic, RelocInfo::CODE_TARGET);
3360 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3374 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3361 if (expr->is_postfix()) { 3375 if (expr->is_postfix()) {
3362 if (!context()->IsEffect()) { 3376 if (!context()->IsEffect()) {
3363 context()->PlugTOS(); 3377 context()->PlugTOS();
3364 } 3378 }
3365 } else { 3379 } else {
3366 context()->Plug(rax); 3380 context()->Plug(rax);
3367 } 3381 }
3368 break; 3382 break;
3369 } 3383 }
3370 case KEYED_PROPERTY: { 3384 case KEYED_PROPERTY: {
3371 __ pop(rcx); 3385 __ pop(rcx);
3372 __ pop(rdx); 3386 __ pop(rdx);
3373 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); 3387 Handle<Code> ic(Builtins::builtin(
3388 is_strict() ? Builtins::KeyedStoreIC_Initialize_Strict
3389 : Builtins::KeyedStoreIC_Initialize));
3374 EmitCallIC(ic, RelocInfo::CODE_TARGET); 3390 EmitCallIC(ic, RelocInfo::CODE_TARGET);
3375 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3391 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3376 if (expr->is_postfix()) { 3392 if (expr->is_postfix()) {
3377 if (!context()->IsEffect()) { 3393 if (!context()->IsEffect()) {
3378 context()->PlugTOS(); 3394 context()->PlugTOS();
3379 } 3395 }
3380 } else { 3396 } else {
3381 context()->Plug(rax); 3397 context()->Plug(rax);
3382 } 3398 }
3383 break; 3399 break;
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after
3768 __ ret(0); 3784 __ ret(0);
3769 } 3785 }
3770 3786
3771 3787
3772 #undef __ 3788 #undef __
3773 3789
3774 3790
3775 } } // namespace v8::internal 3791 } } // namespace v8::internal
3776 3792
3777 #endif // V8_TARGET_ARCH_X64 3793 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698