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

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

Issue 8417035: Introduce extended mode. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebased to tip of tree. Created 9 years, 1 month 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 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 if (strlen(FLAG_stop_at) > 0 && 126 if (strlen(FLAG_stop_at) > 0 &&
127 info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { 127 info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
128 __ int3(); 128 __ int3();
129 } 129 }
130 #endif 130 #endif
131 131
132 // Strict mode functions and builtins need to replace the receiver 132 // Strict mode functions and builtins need to replace the receiver
133 // with undefined when called as functions (without an explicit 133 // with undefined when called as functions (without an explicit
134 // receiver object). rcx is zero for method calls and non-zero for 134 // receiver object). rcx is zero for method calls and non-zero for
135 // function calls. 135 // function calls.
136 if (info->is_strict_mode() || info->is_native()) { 136 if (!info->is_classic_mode() || info->is_native()) {
137 Label ok; 137 Label ok;
138 __ testq(rcx, rcx); 138 __ testq(rcx, rcx);
139 __ j(zero, &ok, Label::kNear); 139 __ j(zero, &ok, Label::kNear);
140 // +1 for return address. 140 // +1 for return address.
141 int receiver_offset = (info->scope()->num_parameters() + 1) * kPointerSize; 141 int receiver_offset = (info->scope()->num_parameters() + 1) * kPointerSize;
142 __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex); 142 __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex);
143 __ movq(Operand(rsp, receiver_offset), kScratchRegister); 143 __ movq(Operand(rsp, receiver_offset), kScratchRegister);
144 __ bind(&ok); 144 __ bind(&ok);
145 } 145 }
146 146
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 int offset = num_parameters * kPointerSize; 220 int offset = num_parameters * kPointerSize;
221 __ lea(rdx, 221 __ lea(rdx,
222 Operand(rbp, StandardFrameConstants::kCallerSPOffset + offset)); 222 Operand(rbp, StandardFrameConstants::kCallerSPOffset + offset));
223 __ push(rdx); 223 __ push(rdx);
224 __ Push(Smi::FromInt(num_parameters)); 224 __ Push(Smi::FromInt(num_parameters));
225 // Arguments to ArgumentsAccessStub: 225 // Arguments to ArgumentsAccessStub:
226 // function, receiver address, parameter count. 226 // function, receiver address, parameter count.
227 // The stub will rewrite receiver and parameter count if the previous 227 // The stub will rewrite receiver and parameter count if the previous
228 // stack frame was an arguments adapter frame. 228 // stack frame was an arguments adapter frame.
229 ArgumentsAccessStub stub( 229 ArgumentsAccessStub stub(
230 is_strict_mode() ? ArgumentsAccessStub::NEW_STRICT 230 is_classic_mode() ? ArgumentsAccessStub::NEW_NON_STRICT_SLOW
231 : ArgumentsAccessStub::NEW_NON_STRICT_SLOW); 231 : ArgumentsAccessStub::NEW_STRICT);
232 __ CallStub(&stub); 232 __ CallStub(&stub);
233 233
234 SetVar(arguments, rax, rbx, rdx); 234 SetVar(arguments, rax, rbx, rdx);
235 } 235 }
236 236
237 if (FLAG_trace) { 237 if (FLAG_trace) {
238 __ CallRuntime(Runtime::kTraceEnter, 0); 238 __ CallRuntime(Runtime::kTraceEnter, 0);
239 } 239 }
240 240
241 // Visit the declarations and body unless there is an illegal 241 // Visit the declarations and body unless there is an illegal
(...skipping 825 matching lines...) Expand 10 before | Expand all | Expand 10 after
1067 // space for nested functions that don't need literals cloning. If 1067 // space for nested functions that don't need literals cloning. If
1068 // we're running with the --always-opt or the --prepare-always-opt 1068 // we're running with the --always-opt or the --prepare-always-opt
1069 // flag, we need to use the runtime function so that the new function 1069 // flag, we need to use the runtime function so that the new function
1070 // we are creating here gets a chance to have its code optimized and 1070 // we are creating here gets a chance to have its code optimized and
1071 // doesn't just get a copy of the existing unoptimized code. 1071 // doesn't just get a copy of the existing unoptimized code.
1072 if (!FLAG_always_opt && 1072 if (!FLAG_always_opt &&
1073 !FLAG_prepare_always_opt && 1073 !FLAG_prepare_always_opt &&
1074 !pretenure && 1074 !pretenure &&
1075 scope()->is_function_scope() && 1075 scope()->is_function_scope() &&
1076 info->num_literals() == 0) { 1076 info->num_literals() == 0) {
1077 FastNewClosureStub stub(info->strict_mode_flag()); 1077 FastNewClosureStub stub(info->language_mode());
1078 __ Push(info); 1078 __ Push(info);
1079 __ CallStub(&stub); 1079 __ CallStub(&stub);
1080 } else { 1080 } else {
1081 __ push(rsi); 1081 __ push(rsi);
1082 __ Push(info); 1082 __ Push(info);
1083 __ Push(pretenure 1083 __ Push(pretenure
1084 ? isolate()->factory()->true_value() 1084 ? isolate()->factory()->true_value()
1085 : isolate()->factory()->false_value()); 1085 : isolate()->factory()->false_value());
1086 __ CallRuntime(Runtime::kNewClosure, 3); 1086 __ CallRuntime(Runtime::kNewClosure, 3);
1087 } 1087 }
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after
1417 UNREACHABLE(); 1417 UNREACHABLE();
1418 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1418 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1419 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); 1419 ASSERT(!CompileTimeValue::IsCompileTimeValue(value));
1420 // Fall through. 1420 // Fall through.
1421 case ObjectLiteral::Property::COMPUTED: 1421 case ObjectLiteral::Property::COMPUTED:
1422 if (key->handle()->IsSymbol()) { 1422 if (key->handle()->IsSymbol()) {
1423 if (property->emit_store()) { 1423 if (property->emit_store()) {
1424 VisitForAccumulatorValue(value); 1424 VisitForAccumulatorValue(value);
1425 __ Move(rcx, key->handle()); 1425 __ Move(rcx, key->handle());
1426 __ movq(rdx, Operand(rsp, 0)); 1426 __ movq(rdx, Operand(rsp, 0));
1427 Handle<Code> ic = is_strict_mode() 1427 Handle<Code> ic = is_classic_mode()
1428 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1428 ? isolate()->builtins()->StoreIC_Initialize()
1429 : isolate()->builtins()->StoreIC_Initialize(); 1429 : isolate()->builtins()->StoreIC_Initialize_Strict();
1430 __ call(ic, RelocInfo::CODE_TARGET, key->id()); 1430 __ call(ic, RelocInfo::CODE_TARGET, key->id());
1431 PrepareForBailoutForId(key->id(), NO_REGISTERS); 1431 PrepareForBailoutForId(key->id(), NO_REGISTERS);
1432 } else { 1432 } else {
1433 VisitForEffect(value); 1433 VisitForEffect(value);
1434 } 1434 }
1435 break; 1435 break;
1436 } 1436 }
1437 // Fall through. 1437 // Fall through.
1438 case ObjectLiteral::Property::PROTOTYPE: 1438 case ObjectLiteral::Property::PROTOTYPE:
1439 __ push(Operand(rsp, 0)); // Duplicate receiver. 1439 __ push(Operand(rsp, 0)); // Duplicate receiver.
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after
1776 EffectContext context(this); 1776 EffectContext context(this);
1777 EmitVariableAssignment(var, Token::ASSIGN); 1777 EmitVariableAssignment(var, Token::ASSIGN);
1778 break; 1778 break;
1779 } 1779 }
1780 case NAMED_PROPERTY: { 1780 case NAMED_PROPERTY: {
1781 __ push(rax); // Preserve value. 1781 __ push(rax); // Preserve value.
1782 VisitForAccumulatorValue(prop->obj()); 1782 VisitForAccumulatorValue(prop->obj());
1783 __ movq(rdx, rax); 1783 __ movq(rdx, rax);
1784 __ pop(rax); // Restore value. 1784 __ pop(rax); // Restore value.
1785 __ Move(rcx, prop->key()->AsLiteral()->handle()); 1785 __ Move(rcx, prop->key()->AsLiteral()->handle());
1786 Handle<Code> ic = is_strict_mode() 1786 Handle<Code> ic = is_classic_mode()
1787 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1787 ? isolate()->builtins()->StoreIC_Initialize()
1788 : isolate()->builtins()->StoreIC_Initialize(); 1788 : isolate()->builtins()->StoreIC_Initialize_Strict();
1789 __ call(ic); 1789 __ call(ic);
1790 break; 1790 break;
1791 } 1791 }
1792 case KEYED_PROPERTY: { 1792 case KEYED_PROPERTY: {
1793 __ push(rax); // Preserve value. 1793 __ push(rax); // Preserve value.
1794 VisitForStackValue(prop->obj()); 1794 VisitForStackValue(prop->obj());
1795 VisitForAccumulatorValue(prop->key()); 1795 VisitForAccumulatorValue(prop->key());
1796 __ movq(rcx, rax); 1796 __ movq(rcx, rax);
1797 __ pop(rdx); 1797 __ pop(rdx);
1798 __ pop(rax); // Restore value. 1798 __ pop(rax); // Restore value.
1799 Handle<Code> ic = is_strict_mode() 1799 Handle<Code> ic = is_classic_mode()
1800 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 1800 ? isolate()->builtins()->KeyedStoreIC_Initialize()
1801 : isolate()->builtins()->KeyedStoreIC_Initialize(); 1801 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
1802 __ call(ic); 1802 __ call(ic);
1803 break; 1803 break;
1804 } 1804 }
1805 } 1805 }
1806 PrepareForBailoutForId(bailout_ast_id, TOS_REG); 1806 PrepareForBailoutForId(bailout_ast_id, TOS_REG);
1807 context()->Plug(rax); 1807 context()->Plug(rax);
1808 } 1808 }
1809 1809
1810 1810
1811 void FullCodeGenerator::EmitVariableAssignment(Variable* var, 1811 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
1812 Token::Value op) { 1812 Token::Value op) {
1813 if (var->IsUnallocated()) { 1813 if (var->IsUnallocated()) {
1814 // Global var, const, or let. 1814 // Global var, const, or let.
1815 __ Move(rcx, var->name()); 1815 __ Move(rcx, var->name());
1816 __ movq(rdx, GlobalObjectOperand()); 1816 __ movq(rdx, GlobalObjectOperand());
1817 Handle<Code> ic = is_strict_mode() 1817 Handle<Code> ic = is_classic_mode()
1818 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1818 ? isolate()->builtins()->StoreIC_Initialize()
1819 : isolate()->builtins()->StoreIC_Initialize(); 1819 : isolate()->builtins()->StoreIC_Initialize_Strict();
1820 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); 1820 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT);
1821 } else if (op == Token::INIT_CONST) { 1821 } else if (op == Token::INIT_CONST) {
1822 // Const initializers need a write barrier. 1822 // Const initializers need a write barrier.
1823 ASSERT(!var->IsParameter()); // No const parameters. 1823 ASSERT(!var->IsParameter()); // No const parameters.
1824 if (var->IsStackLocal()) { 1824 if (var->IsStackLocal()) {
1825 Label skip; 1825 Label skip;
1826 __ movq(rdx, StackOperand(var)); 1826 __ movq(rdx, StackOperand(var));
1827 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex); 1827 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex);
1828 __ j(not_equal, &skip); 1828 __ j(not_equal, &skip);
1829 __ movq(StackOperand(var), rax); 1829 __ movq(StackOperand(var), rax);
(...skipping 10 matching lines...) Expand all
1840 __ Push(var->name()); 1840 __ Push(var->name());
1841 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3); 1841 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3);
1842 } 1842 }
1843 1843
1844 } else if (var->mode() == LET && op != Token::INIT_LET) { 1844 } else if (var->mode() == LET && op != Token::INIT_LET) {
1845 // Non-initializing assignment to let variable needs a write barrier. 1845 // Non-initializing assignment to let variable needs a write barrier.
1846 if (var->IsLookupSlot()) { 1846 if (var->IsLookupSlot()) {
1847 __ push(rax); // Value. 1847 __ push(rax); // Value.
1848 __ push(rsi); // Context. 1848 __ push(rsi); // Context.
1849 __ Push(var->name()); 1849 __ Push(var->name());
1850 __ Push(Smi::FromInt(strict_mode_flag())); 1850 __ Push(Smi::FromInt(language_mode()));
1851 __ CallRuntime(Runtime::kStoreContextSlot, 4); 1851 __ CallRuntime(Runtime::kStoreContextSlot, 4);
1852 } else { 1852 } else {
1853 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); 1853 ASSERT(var->IsStackAllocated() || var->IsContextSlot());
1854 Label assign; 1854 Label assign;
1855 MemOperand location = VarOperand(var, rcx); 1855 MemOperand location = VarOperand(var, rcx);
1856 __ movq(rdx, location); 1856 __ movq(rdx, location);
1857 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex); 1857 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex);
1858 __ j(not_equal, &assign, Label::kNear); 1858 __ j(not_equal, &assign, Label::kNear);
1859 __ Push(var->name()); 1859 __ Push(var->name());
1860 __ CallRuntime(Runtime::kThrowReferenceError, 1); 1860 __ CallRuntime(Runtime::kThrowReferenceError, 1);
(...skipping 22 matching lines...) Expand all
1883 if (var->IsContextSlot()) { 1883 if (var->IsContextSlot()) {
1884 __ movq(rdx, rax); 1884 __ movq(rdx, rax);
1885 __ RecordWriteContextSlot( 1885 __ RecordWriteContextSlot(
1886 rcx, Context::SlotOffset(var->index()), rdx, rbx, kDontSaveFPRegs); 1886 rcx, Context::SlotOffset(var->index()), rdx, rbx, kDontSaveFPRegs);
1887 } 1887 }
1888 } else { 1888 } else {
1889 ASSERT(var->IsLookupSlot()); 1889 ASSERT(var->IsLookupSlot());
1890 __ push(rax); // Value. 1890 __ push(rax); // Value.
1891 __ push(rsi); // Context. 1891 __ push(rsi); // Context.
1892 __ Push(var->name()); 1892 __ Push(var->name());
1893 __ Push(Smi::FromInt(strict_mode_flag())); 1893 __ Push(Smi::FromInt(language_mode()));
1894 __ CallRuntime(Runtime::kStoreContextSlot, 4); 1894 __ CallRuntime(Runtime::kStoreContextSlot, 4);
1895 } 1895 }
1896 } 1896 }
1897 // Non-initializing assignments to consts are ignored. 1897 // Non-initializing assignments to consts are ignored.
1898 } 1898 }
1899 1899
1900 1900
1901 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 1901 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
1902 // Assignment to a property, using a named store IC. 1902 // Assignment to a property, using a named store IC.
1903 Property* prop = expr->target()->AsProperty(); 1903 Property* prop = expr->target()->AsProperty();
(...skipping 11 matching lines...) Expand all
1915 } 1915 }
1916 1916
1917 // Record source code position before IC call. 1917 // Record source code position before IC call.
1918 SetSourcePosition(expr->position()); 1918 SetSourcePosition(expr->position());
1919 __ Move(rcx, prop->key()->AsLiteral()->handle()); 1919 __ Move(rcx, prop->key()->AsLiteral()->handle());
1920 if (expr->ends_initialization_block()) { 1920 if (expr->ends_initialization_block()) {
1921 __ movq(rdx, Operand(rsp, 0)); 1921 __ movq(rdx, Operand(rsp, 0));
1922 } else { 1922 } else {
1923 __ pop(rdx); 1923 __ pop(rdx);
1924 } 1924 }
1925 Handle<Code> ic = is_strict_mode() 1925 Handle<Code> ic = is_classic_mode()
1926 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1926 ? isolate()->builtins()->StoreIC_Initialize()
1927 : isolate()->builtins()->StoreIC_Initialize(); 1927 : isolate()->builtins()->StoreIC_Initialize_Strict();
1928 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); 1928 __ call(ic, RelocInfo::CODE_TARGET, expr->id());
1929 1929
1930 // If the assignment ends an initialization block, revert to fast case. 1930 // If the assignment ends an initialization block, revert to fast case.
1931 if (expr->ends_initialization_block()) { 1931 if (expr->ends_initialization_block()) {
1932 __ push(rax); // Result of assignment, saved even if not needed. 1932 __ push(rax); // Result of assignment, saved even if not needed.
1933 __ push(Operand(rsp, kPointerSize)); // Receiver is under value. 1933 __ push(Operand(rsp, kPointerSize)); // Receiver is under value.
1934 __ CallRuntime(Runtime::kToFastProperties, 1); 1934 __ CallRuntime(Runtime::kToFastProperties, 1);
1935 __ pop(rax); 1935 __ pop(rax);
1936 __ Drop(1); 1936 __ Drop(1);
1937 } 1937 }
(...skipping 17 matching lines...) Expand all
1955 } 1955 }
1956 1956
1957 __ pop(rcx); 1957 __ pop(rcx);
1958 if (expr->ends_initialization_block()) { 1958 if (expr->ends_initialization_block()) {
1959 __ movq(rdx, Operand(rsp, 0)); // Leave receiver on the stack for later. 1959 __ movq(rdx, Operand(rsp, 0)); // Leave receiver on the stack for later.
1960 } else { 1960 } else {
1961 __ pop(rdx); 1961 __ pop(rdx);
1962 } 1962 }
1963 // Record source code position before IC call. 1963 // Record source code position before IC call.
1964 SetSourcePosition(expr->position()); 1964 SetSourcePosition(expr->position());
1965 Handle<Code> ic = is_strict_mode() 1965 Handle<Code> ic = is_classic_mode()
1966 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 1966 ? isolate()->builtins()->KeyedStoreIC_Initialize()
1967 : isolate()->builtins()->KeyedStoreIC_Initialize(); 1967 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
1968 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); 1968 __ call(ic, RelocInfo::CODE_TARGET, expr->id());
1969 1969
1970 // If the assignment ends an initialization block, revert to fast case. 1970 // If the assignment ends an initialization block, revert to fast case.
1971 if (expr->ends_initialization_block()) { 1971 if (expr->ends_initialization_block()) {
1972 __ pop(rdx); 1972 __ pop(rdx);
1973 __ push(rax); // Result of assignment, saved even if not needed. 1973 __ push(rax); // Result of assignment, saved even if not needed.
1974 __ push(rdx); 1974 __ push(rdx);
1975 __ CallRuntime(Runtime::kToFastProperties, 1); 1975 __ CallRuntime(Runtime::kToFastProperties, 1);
1976 __ pop(rax); 1976 __ pop(rax);
1977 } 1977 }
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
2083 // Push copy of the first argument or undefined if it doesn't exist. 2083 // Push copy of the first argument or undefined if it doesn't exist.
2084 if (arg_count > 0) { 2084 if (arg_count > 0) {
2085 __ push(Operand(rsp, arg_count * kPointerSize)); 2085 __ push(Operand(rsp, arg_count * kPointerSize));
2086 } else { 2086 } else {
2087 __ PushRoot(Heap::kUndefinedValueRootIndex); 2087 __ PushRoot(Heap::kUndefinedValueRootIndex);
2088 } 2088 }
2089 2089
2090 // Push the receiver of the enclosing function and do runtime call. 2090 // Push the receiver of the enclosing function and do runtime call.
2091 __ push(Operand(rbp, (2 + info_->scope()->num_parameters()) * kPointerSize)); 2091 __ push(Operand(rbp, (2 + info_->scope()->num_parameters()) * kPointerSize));
2092 2092
2093 // Push the strict mode flag. In harmony mode every eval call 2093 // Push the language mode.
Rico 2011/11/15 08:25:07 same comment as on arm,
Steven 2011/11/15 13:33:30 Done.
2094 // is a strict mode eval call. 2094 __ Push(Smi::FromInt(language_mode()));
2095 StrictModeFlag strict_mode =
2096 FLAG_harmony_scoping ? kStrictMode : strict_mode_flag();
2097 __ Push(Smi::FromInt(strict_mode));
2098 2095
2099 // Push the start position of the scope the calls resides in. 2096 // Push the start position of the scope the calls resides in.
2100 __ Push(Smi::FromInt(scope()->start_position())); 2097 __ Push(Smi::FromInt(scope()->start_position()));
2101 2098
2102 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); 2099 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5);
2103 } 2100 }
2104 2101
2105 2102
2106 void FullCodeGenerator::VisitCall(Call* expr) { 2103 void FullCodeGenerator::VisitCall(Call* expr) {
2107 #ifdef DEBUG 2104 #ifdef DEBUG
(...skipping 1522 matching lines...) Expand 10 before | Expand all | Expand 10 after
3630 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 3627 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
3631 switch (expr->op()) { 3628 switch (expr->op()) {
3632 case Token::DELETE: { 3629 case Token::DELETE: {
3633 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); 3630 Comment cmnt(masm_, "[ UnaryOperation (DELETE)");
3634 Property* property = expr->expression()->AsProperty(); 3631 Property* property = expr->expression()->AsProperty();
3635 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 3632 VariableProxy* proxy = expr->expression()->AsVariableProxy();
3636 3633
3637 if (property != NULL) { 3634 if (property != NULL) {
3638 VisitForStackValue(property->obj()); 3635 VisitForStackValue(property->obj());
3639 VisitForStackValue(property->key()); 3636 VisitForStackValue(property->key());
3640 __ Push(Smi::FromInt(strict_mode_flag())); 3637 StrictModeFlag strict_mode_flag = (language_mode() == CLASSIC_MODE)
3638 ? kNonStrictMode : kStrictMode;
3639 __ Push(Smi::FromInt(strict_mode_flag));
3641 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); 3640 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
3642 context()->Plug(rax); 3641 context()->Plug(rax);
3643 } else if (proxy != NULL) { 3642 } else if (proxy != NULL) {
3644 Variable* var = proxy->var(); 3643 Variable* var = proxy->var();
3645 // Delete of an unqualified identifier is disallowed in strict mode 3644 // Delete of an unqualified identifier is disallowed in strict mode
3646 // but "delete this" is allowed. 3645 // but "delete this" is allowed.
3647 ASSERT(strict_mode_flag() == kNonStrictMode || var->is_this()); 3646 ASSERT(language_mode() == CLASSIC_MODE || var->is_this());
3648 if (var->IsUnallocated()) { 3647 if (var->IsUnallocated()) {
3649 __ push(GlobalObjectOperand()); 3648 __ push(GlobalObjectOperand());
3650 __ Push(var->name()); 3649 __ Push(var->name());
3651 __ Push(Smi::FromInt(kNonStrictMode)); 3650 __ Push(Smi::FromInt(kNonStrictMode));
3652 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); 3651 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
3653 context()->Plug(rax); 3652 context()->Plug(rax);
3654 } else if (var->IsStackAllocated() || var->IsContextSlot()) { 3653 } else if (var->IsStackAllocated() || var->IsContextSlot()) {
3655 // Result of deleting non-global variables is false. 'this' is 3654 // Result of deleting non-global variables is false. 'this' is
3656 // not really a variable, though we implement it as one. The 3655 // not really a variable, though we implement it as one. The
3657 // subexpression does not have side effects. 3656 // subexpression does not have side effects.
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
3918 // Perform the assignment as if via '='. 3917 // Perform the assignment as if via '='.
3919 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 3918 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3920 Token::ASSIGN); 3919 Token::ASSIGN);
3921 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3920 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3922 context()->Plug(rax); 3921 context()->Plug(rax);
3923 } 3922 }
3924 break; 3923 break;
3925 case NAMED_PROPERTY: { 3924 case NAMED_PROPERTY: {
3926 __ Move(rcx, prop->key()->AsLiteral()->handle()); 3925 __ Move(rcx, prop->key()->AsLiteral()->handle());
3927 __ pop(rdx); 3926 __ pop(rdx);
3928 Handle<Code> ic = is_strict_mode() 3927 Handle<Code> ic = is_classic_mode()
3929 ? isolate()->builtins()->StoreIC_Initialize_Strict() 3928 ? isolate()->builtins()->StoreIC_Initialize()
3930 : isolate()->builtins()->StoreIC_Initialize(); 3929 : isolate()->builtins()->StoreIC_Initialize_Strict();
3931 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); 3930 __ call(ic, RelocInfo::CODE_TARGET, expr->id());
3932 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3931 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3933 if (expr->is_postfix()) { 3932 if (expr->is_postfix()) {
3934 if (!context()->IsEffect()) { 3933 if (!context()->IsEffect()) {
3935 context()->PlugTOS(); 3934 context()->PlugTOS();
3936 } 3935 }
3937 } else { 3936 } else {
3938 context()->Plug(rax); 3937 context()->Plug(rax);
3939 } 3938 }
3940 break; 3939 break;
3941 } 3940 }
3942 case KEYED_PROPERTY: { 3941 case KEYED_PROPERTY: {
3943 __ pop(rcx); 3942 __ pop(rcx);
3944 __ pop(rdx); 3943 __ pop(rdx);
3945 Handle<Code> ic = is_strict_mode() 3944 Handle<Code> ic = is_classic_mode()
3946 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 3945 ? isolate()->builtins()->KeyedStoreIC_Initialize()
3947 : isolate()->builtins()->KeyedStoreIC_Initialize(); 3946 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
3948 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); 3947 __ call(ic, RelocInfo::CODE_TARGET, expr->id());
3949 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3948 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3950 if (expr->is_postfix()) { 3949 if (expr->is_postfix()) {
3951 if (!context()->IsEffect()) { 3950 if (!context()->IsEffect()) {
3952 context()->PlugTOS(); 3951 context()->PlugTOS();
3953 } 3952 }
3954 } else { 3953 } else {
3955 context()->Plug(rax); 3954 context()->Plug(rax);
3956 } 3955 }
3957 break; 3956 break;
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after
4307 *context_length = 0; 4306 *context_length = 0;
4308 return previous_; 4307 return previous_;
4309 } 4308 }
4310 4309
4311 4310
4312 #undef __ 4311 #undef __
4313 4312
4314 } } // namespace v8::internal 4313 } } // namespace v8::internal
4315 4314
4316 #endif // V8_TARGET_ARCH_X64 4315 #endif // V8_TARGET_ARCH_X64
OLDNEW
« src/scopes.h ('K') | « src/x64/code-stubs-x64.cc ('k') | src/x64/lithium-codegen-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698