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

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

Issue 8417035: Introduce extended mode. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments. 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 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 if (strlen(FLAG_stop_at) > 0 && 124 if (strlen(FLAG_stop_at) > 0 &&
125 info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { 125 info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
126 __ int3(); 126 __ int3();
127 } 127 }
128 #endif 128 #endif
129 129
130 // Strict mode functions and builtins need to replace the receiver 130 // Strict mode functions and builtins need to replace the receiver
131 // with undefined when called as functions (without an explicit 131 // with undefined when called as functions (without an explicit
132 // receiver object). ecx is zero for method calls and non-zero for 132 // receiver object). ecx is zero for method calls and non-zero for
133 // function calls. 133 // function calls.
134 if (info->is_strict_mode() || info->is_native()) { 134 if (!info->is_classic_mode() || info->is_native()) {
135 Label ok; 135 Label ok;
136 __ test(ecx, ecx); 136 __ test(ecx, ecx);
137 __ j(zero, &ok, Label::kNear); 137 __ j(zero, &ok, Label::kNear);
138 // +1 for return address. 138 // +1 for return address.
139 int receiver_offset = (info->scope()->num_parameters() + 1) * kPointerSize; 139 int receiver_offset = (info->scope()->num_parameters() + 1) * kPointerSize;
140 __ mov(Operand(esp, receiver_offset), 140 __ mov(Operand(esp, receiver_offset),
141 Immediate(isolate()->factory()->undefined_value())); 141 Immediate(isolate()->factory()->undefined_value()));
142 __ bind(&ok); 142 __ bind(&ok);
143 } 143 }
144 144
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 int offset = num_parameters * kPointerSize; 219 int offset = num_parameters * kPointerSize;
220 __ lea(edx, 220 __ lea(edx,
221 Operand(ebp, StandardFrameConstants::kCallerSPOffset + offset)); 221 Operand(ebp, StandardFrameConstants::kCallerSPOffset + offset));
222 __ push(edx); 222 __ push(edx);
223 __ SafePush(Immediate(Smi::FromInt(num_parameters))); 223 __ SafePush(Immediate(Smi::FromInt(num_parameters)));
224 // Arguments to ArgumentsAccessStub and/or New...: 224 // Arguments to ArgumentsAccessStub and/or New...:
225 // function, receiver address, parameter count. 225 // function, receiver address, parameter count.
226 // The stub will rewrite receiver and parameter count if the previous 226 // The stub will rewrite receiver and parameter count if the previous
227 // stack frame was an arguments adapter frame. 227 // stack frame was an arguments adapter frame.
228 ArgumentsAccessStub::Type type; 228 ArgumentsAccessStub::Type type;
229 if (is_strict_mode()) { 229 if (!is_classic_mode()) {
230 type = ArgumentsAccessStub::NEW_STRICT; 230 type = ArgumentsAccessStub::NEW_STRICT;
231 } else if (function()->has_duplicate_parameters()) { 231 } else if (function()->has_duplicate_parameters()) {
232 type = ArgumentsAccessStub::NEW_NON_STRICT_SLOW; 232 type = ArgumentsAccessStub::NEW_NON_STRICT_SLOW;
233 } else { 233 } else {
234 type = ArgumentsAccessStub::NEW_NON_STRICT_FAST; 234 type = ArgumentsAccessStub::NEW_NON_STRICT_FAST;
235 } 235 }
236 ArgumentsAccessStub stub(type); 236 ArgumentsAccessStub stub(type);
237 __ CallStub(&stub); 237 __ CallStub(&stub);
238 238
239 SetVar(arguments, eax, ebx, edx); 239 SetVar(arguments, eax, ebx, edx);
(...skipping 818 matching lines...) Expand 10 before | Expand all | Expand 10 after
1058 // space for nested functions that don't need literals cloning. If 1058 // space for nested functions that don't need literals cloning. If
1059 // we're running with the --always-opt or the --prepare-always-opt 1059 // we're running with the --always-opt or the --prepare-always-opt
1060 // flag, we need to use the runtime function so that the new function 1060 // flag, we need to use the runtime function so that the new function
1061 // we are creating here gets a chance to have its code optimized and 1061 // we are creating here gets a chance to have its code optimized and
1062 // doesn't just get a copy of the existing unoptimized code. 1062 // doesn't just get a copy of the existing unoptimized code.
1063 if (!FLAG_always_opt && 1063 if (!FLAG_always_opt &&
1064 !FLAG_prepare_always_opt && 1064 !FLAG_prepare_always_opt &&
1065 !pretenure && 1065 !pretenure &&
1066 scope()->is_function_scope() && 1066 scope()->is_function_scope() &&
1067 info->num_literals() == 0) { 1067 info->num_literals() == 0) {
1068 FastNewClosureStub stub(info->strict_mode_flag()); 1068 FastNewClosureStub stub(info->language_mode());
1069 __ push(Immediate(info)); 1069 __ push(Immediate(info));
1070 __ CallStub(&stub); 1070 __ CallStub(&stub);
1071 } else { 1071 } else {
1072 __ push(esi); 1072 __ push(esi);
1073 __ push(Immediate(info)); 1073 __ push(Immediate(info));
1074 __ push(Immediate(pretenure 1074 __ push(Immediate(pretenure
1075 ? isolate()->factory()->true_value() 1075 ? isolate()->factory()->true_value()
1076 : isolate()->factory()->false_value())); 1076 : isolate()->factory()->false_value()));
1077 __ CallRuntime(Runtime::kNewClosure, 3); 1077 __ CallRuntime(Runtime::kNewClosure, 3);
1078 } 1078 }
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
1403 switch (property->kind()) { 1403 switch (property->kind()) {
1404 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1404 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1405 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); 1405 ASSERT(!CompileTimeValue::IsCompileTimeValue(value));
1406 // Fall through. 1406 // Fall through.
1407 case ObjectLiteral::Property::COMPUTED: 1407 case ObjectLiteral::Property::COMPUTED:
1408 if (key->handle()->IsSymbol()) { 1408 if (key->handle()->IsSymbol()) {
1409 if (property->emit_store()) { 1409 if (property->emit_store()) {
1410 VisitForAccumulatorValue(value); 1410 VisitForAccumulatorValue(value);
1411 __ mov(ecx, Immediate(key->handle())); 1411 __ mov(ecx, Immediate(key->handle()));
1412 __ mov(edx, Operand(esp, 0)); 1412 __ mov(edx, Operand(esp, 0));
1413 Handle<Code> ic = is_strict_mode() 1413 Handle<Code> ic = is_classic_mode()
1414 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1414 ? isolate()->builtins()->StoreIC_Initialize()
1415 : isolate()->builtins()->StoreIC_Initialize(); 1415 : isolate()->builtins()->StoreIC_Initialize_Strict();
1416 __ call(ic, RelocInfo::CODE_TARGET, key->id()); 1416 __ call(ic, RelocInfo::CODE_TARGET, key->id());
1417 PrepareForBailoutForId(key->id(), NO_REGISTERS); 1417 PrepareForBailoutForId(key->id(), NO_REGISTERS);
1418 } else { 1418 } else {
1419 VisitForEffect(value); 1419 VisitForEffect(value);
1420 } 1420 }
1421 break; 1421 break;
1422 } 1422 }
1423 // Fall through. 1423 // Fall through.
1424 case ObjectLiteral::Property::PROTOTYPE: 1424 case ObjectLiteral::Property::PROTOTYPE:
1425 __ push(Operand(esp, 0)); // Duplicate receiver. 1425 __ push(Operand(esp, 0)); // Duplicate receiver.
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after
1801 EffectContext context(this); 1801 EffectContext context(this);
1802 EmitVariableAssignment(var, Token::ASSIGN); 1802 EmitVariableAssignment(var, Token::ASSIGN);
1803 break; 1803 break;
1804 } 1804 }
1805 case NAMED_PROPERTY: { 1805 case NAMED_PROPERTY: {
1806 __ push(eax); // Preserve value. 1806 __ push(eax); // Preserve value.
1807 VisitForAccumulatorValue(prop->obj()); 1807 VisitForAccumulatorValue(prop->obj());
1808 __ mov(edx, eax); 1808 __ mov(edx, eax);
1809 __ pop(eax); // Restore value. 1809 __ pop(eax); // Restore value.
1810 __ mov(ecx, prop->key()->AsLiteral()->handle()); 1810 __ mov(ecx, prop->key()->AsLiteral()->handle());
1811 Handle<Code> ic = is_strict_mode() 1811 Handle<Code> ic = is_classic_mode()
1812 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1812 ? isolate()->builtins()->StoreIC_Initialize()
1813 : isolate()->builtins()->StoreIC_Initialize(); 1813 : isolate()->builtins()->StoreIC_Initialize_Strict();
1814 __ call(ic); 1814 __ call(ic);
1815 break; 1815 break;
1816 } 1816 }
1817 case KEYED_PROPERTY: { 1817 case KEYED_PROPERTY: {
1818 __ push(eax); // Preserve value. 1818 __ push(eax); // Preserve value.
1819 VisitForStackValue(prop->obj()); 1819 VisitForStackValue(prop->obj());
1820 VisitForAccumulatorValue(prop->key()); 1820 VisitForAccumulatorValue(prop->key());
1821 __ mov(ecx, eax); 1821 __ mov(ecx, eax);
1822 __ pop(edx); 1822 __ pop(edx);
1823 __ pop(eax); // Restore value. 1823 __ pop(eax); // Restore value.
1824 Handle<Code> ic = is_strict_mode() 1824 Handle<Code> ic = is_classic_mode()
1825 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 1825 ? isolate()->builtins()->KeyedStoreIC_Initialize()
1826 : isolate()->builtins()->KeyedStoreIC_Initialize(); 1826 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
1827 __ call(ic); 1827 __ call(ic);
1828 break; 1828 break;
1829 } 1829 }
1830 } 1830 }
1831 PrepareForBailoutForId(bailout_ast_id, TOS_REG); 1831 PrepareForBailoutForId(bailout_ast_id, TOS_REG);
1832 context()->Plug(eax); 1832 context()->Plug(eax);
1833 } 1833 }
1834 1834
1835 1835
1836 void FullCodeGenerator::EmitVariableAssignment(Variable* var, 1836 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
1837 Token::Value op) { 1837 Token::Value op) {
1838 if (var->IsUnallocated()) { 1838 if (var->IsUnallocated()) {
1839 // Global var, const, or let. 1839 // Global var, const, or let.
1840 __ mov(ecx, var->name()); 1840 __ mov(ecx, var->name());
1841 __ mov(edx, GlobalObjectOperand()); 1841 __ mov(edx, GlobalObjectOperand());
1842 Handle<Code> ic = is_strict_mode() 1842 Handle<Code> ic = is_classic_mode()
1843 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1843 ? isolate()->builtins()->StoreIC_Initialize()
1844 : isolate()->builtins()->StoreIC_Initialize(); 1844 : isolate()->builtins()->StoreIC_Initialize_Strict();
1845 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); 1845 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT);
1846 1846
1847 } else if (op == Token::INIT_CONST) { 1847 } else if (op == Token::INIT_CONST) {
1848 // Const initializers need a write barrier. 1848 // Const initializers need a write barrier.
1849 ASSERT(!var->IsParameter()); // No const parameters. 1849 ASSERT(!var->IsParameter()); // No const parameters.
1850 if (var->IsStackLocal()) { 1850 if (var->IsStackLocal()) {
1851 Label skip; 1851 Label skip;
1852 __ mov(edx, StackOperand(var)); 1852 __ mov(edx, StackOperand(var));
1853 __ cmp(edx, isolate()->factory()->the_hole_value()); 1853 __ cmp(edx, isolate()->factory()->the_hole_value());
1854 __ j(not_equal, &skip); 1854 __ j(not_equal, &skip);
(...skipping 11 matching lines...) Expand all
1866 __ push(Immediate(var->name())); 1866 __ push(Immediate(var->name()));
1867 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3); 1867 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3);
1868 } 1868 }
1869 1869
1870 } else if (var->mode() == LET && op != Token::INIT_LET) { 1870 } else if (var->mode() == LET && op != Token::INIT_LET) {
1871 // Non-initializing assignment to let variable needs a write barrier. 1871 // Non-initializing assignment to let variable needs a write barrier.
1872 if (var->IsLookupSlot()) { 1872 if (var->IsLookupSlot()) {
1873 __ push(eax); // Value. 1873 __ push(eax); // Value.
1874 __ push(esi); // Context. 1874 __ push(esi); // Context.
1875 __ push(Immediate(var->name())); 1875 __ push(Immediate(var->name()));
1876 __ push(Immediate(Smi::FromInt(strict_mode_flag()))); 1876 __ push(Immediate(Smi::FromInt(language_mode())));
1877 __ CallRuntime(Runtime::kStoreContextSlot, 4); 1877 __ CallRuntime(Runtime::kStoreContextSlot, 4);
1878 } else { 1878 } else {
1879 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); 1879 ASSERT(var->IsStackAllocated() || var->IsContextSlot());
1880 Label assign; 1880 Label assign;
1881 MemOperand location = VarOperand(var, ecx); 1881 MemOperand location = VarOperand(var, ecx);
1882 __ mov(edx, location); 1882 __ mov(edx, location);
1883 __ cmp(edx, isolate()->factory()->the_hole_value()); 1883 __ cmp(edx, isolate()->factory()->the_hole_value());
1884 __ j(not_equal, &assign, Label::kNear); 1884 __ j(not_equal, &assign, Label::kNear);
1885 __ push(Immediate(var->name())); 1885 __ push(Immediate(var->name()));
1886 __ CallRuntime(Runtime::kThrowReferenceError, 1); 1886 __ CallRuntime(Runtime::kThrowReferenceError, 1);
(...skipping 22 matching lines...) Expand all
1909 if (var->IsContextSlot()) { 1909 if (var->IsContextSlot()) {
1910 __ mov(edx, eax); 1910 __ mov(edx, eax);
1911 int offset = Context::SlotOffset(var->index()); 1911 int offset = Context::SlotOffset(var->index());
1912 __ RecordWriteContextSlot(ecx, offset, edx, ebx, kDontSaveFPRegs); 1912 __ RecordWriteContextSlot(ecx, offset, edx, ebx, kDontSaveFPRegs);
1913 } 1913 }
1914 } else { 1914 } else {
1915 ASSERT(var->IsLookupSlot()); 1915 ASSERT(var->IsLookupSlot());
1916 __ push(eax); // Value. 1916 __ push(eax); // Value.
1917 __ push(esi); // Context. 1917 __ push(esi); // Context.
1918 __ push(Immediate(var->name())); 1918 __ push(Immediate(var->name()));
1919 __ push(Immediate(Smi::FromInt(strict_mode_flag()))); 1919 __ push(Immediate(Smi::FromInt(language_mode())));
1920 __ CallRuntime(Runtime::kStoreContextSlot, 4); 1920 __ CallRuntime(Runtime::kStoreContextSlot, 4);
1921 } 1921 }
1922 } 1922 }
1923 // Non-initializing assignments to consts are ignored. 1923 // Non-initializing assignments to consts are ignored.
1924 } 1924 }
1925 1925
1926 1926
1927 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 1927 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
1928 // Assignment to a property, using a named store IC. 1928 // Assignment to a property, using a named store IC.
1929 Property* prop = expr->target()->AsProperty(); 1929 Property* prop = expr->target()->AsProperty();
(...skipping 11 matching lines...) Expand all
1941 } 1941 }
1942 1942
1943 // Record source code position before IC call. 1943 // Record source code position before IC call.
1944 SetSourcePosition(expr->position()); 1944 SetSourcePosition(expr->position());
1945 __ mov(ecx, prop->key()->AsLiteral()->handle()); 1945 __ mov(ecx, prop->key()->AsLiteral()->handle());
1946 if (expr->ends_initialization_block()) { 1946 if (expr->ends_initialization_block()) {
1947 __ mov(edx, Operand(esp, 0)); 1947 __ mov(edx, Operand(esp, 0));
1948 } else { 1948 } else {
1949 __ pop(edx); 1949 __ pop(edx);
1950 } 1950 }
1951 Handle<Code> ic = is_strict_mode() 1951 Handle<Code> ic = is_classic_mode()
1952 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1952 ? isolate()->builtins()->StoreIC_Initialize()
1953 : isolate()->builtins()->StoreIC_Initialize(); 1953 : isolate()->builtins()->StoreIC_Initialize_Strict();
1954 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); 1954 __ call(ic, RelocInfo::CODE_TARGET, expr->id());
1955 1955
1956 // If the assignment ends an initialization block, revert to fast case. 1956 // If the assignment ends an initialization block, revert to fast case.
1957 if (expr->ends_initialization_block()) { 1957 if (expr->ends_initialization_block()) {
1958 __ push(eax); // Result of assignment, saved even if not needed. 1958 __ push(eax); // Result of assignment, saved even if not needed.
1959 __ push(Operand(esp, kPointerSize)); // Receiver is under value. 1959 __ push(Operand(esp, kPointerSize)); // Receiver is under value.
1960 __ CallRuntime(Runtime::kToFastProperties, 1); 1960 __ CallRuntime(Runtime::kToFastProperties, 1);
1961 __ pop(eax); 1961 __ pop(eax);
1962 __ Drop(1); 1962 __ Drop(1);
1963 } 1963 }
(...skipping 17 matching lines...) Expand all
1981 } 1981 }
1982 1982
1983 __ pop(ecx); 1983 __ pop(ecx);
1984 if (expr->ends_initialization_block()) { 1984 if (expr->ends_initialization_block()) {
1985 __ mov(edx, Operand(esp, 0)); // Leave receiver on the stack for later. 1985 __ mov(edx, Operand(esp, 0)); // Leave receiver on the stack for later.
1986 } else { 1986 } else {
1987 __ pop(edx); 1987 __ pop(edx);
1988 } 1988 }
1989 // Record source code position before IC call. 1989 // Record source code position before IC call.
1990 SetSourcePosition(expr->position()); 1990 SetSourcePosition(expr->position());
1991 Handle<Code> ic = is_strict_mode() 1991 Handle<Code> ic = is_classic_mode()
1992 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 1992 ? isolate()->builtins()->KeyedStoreIC_Initialize()
1993 : isolate()->builtins()->KeyedStoreIC_Initialize(); 1993 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
1994 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); 1994 __ call(ic, RelocInfo::CODE_TARGET, expr->id());
1995 1995
1996 // If the assignment ends an initialization block, revert to fast case. 1996 // If the assignment ends an initialization block, revert to fast case.
1997 if (expr->ends_initialization_block()) { 1997 if (expr->ends_initialization_block()) {
1998 __ pop(edx); 1998 __ pop(edx);
1999 __ push(eax); // Result of assignment, saved even if not needed. 1999 __ push(eax); // Result of assignment, saved even if not needed.
2000 __ push(edx); 2000 __ push(edx);
2001 __ CallRuntime(Runtime::kToFastProperties, 1); 2001 __ CallRuntime(Runtime::kToFastProperties, 1);
2002 __ pop(eax); 2002 __ pop(eax);
2003 } 2003 }
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
2127 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { 2127 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
2128 // Push copy of the first argument or undefined if it doesn't exist. 2128 // Push copy of the first argument or undefined if it doesn't exist.
2129 if (arg_count > 0) { 2129 if (arg_count > 0) {
2130 __ push(Operand(esp, arg_count * kPointerSize)); 2130 __ push(Operand(esp, arg_count * kPointerSize));
2131 } else { 2131 } else {
2132 __ push(Immediate(isolate()->factory()->undefined_value())); 2132 __ push(Immediate(isolate()->factory()->undefined_value()));
2133 } 2133 }
2134 2134
2135 // Push the receiver of the enclosing function. 2135 // Push the receiver of the enclosing function.
2136 __ push(Operand(ebp, (2 + info_->scope()->num_parameters()) * kPointerSize)); 2136 __ push(Operand(ebp, (2 + info_->scope()->num_parameters()) * kPointerSize));
2137 2137 // Push the language mode.
2138 // Push the strict mode flag. In harmony mode every eval call 2138 __ push(Immediate(Smi::FromInt(language_mode())));
2139 // is a strict mode eval call.
2140 StrictModeFlag strict_mode =
2141 FLAG_harmony_scoping ? kStrictMode : strict_mode_flag();
2142 __ push(Immediate(Smi::FromInt(strict_mode)));
2143 2139
2144 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 4); 2140 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 4);
2145 } 2141 }
2146 2142
2147 2143
2148 void FullCodeGenerator::VisitCall(Call* expr) { 2144 void FullCodeGenerator::VisitCall(Call* expr) {
2149 #ifdef DEBUG 2145 #ifdef DEBUG
2150 // We want to verify that RecordJSReturnSite gets called on all paths 2146 // We want to verify that RecordJSReturnSite gets called on all paths
2151 // through this function. Avoid early returns. 2147 // through this function. Avoid early returns.
2152 expr->return_is_recorded_ = false; 2148 expr->return_is_recorded_ = false;
(...skipping 1496 matching lines...) Expand 10 before | Expand all | Expand 10 after
3649 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 3645 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
3650 switch (expr->op()) { 3646 switch (expr->op()) {
3651 case Token::DELETE: { 3647 case Token::DELETE: {
3652 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); 3648 Comment cmnt(masm_, "[ UnaryOperation (DELETE)");
3653 Property* property = expr->expression()->AsProperty(); 3649 Property* property = expr->expression()->AsProperty();
3654 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 3650 VariableProxy* proxy = expr->expression()->AsVariableProxy();
3655 3651
3656 if (property != NULL) { 3652 if (property != NULL) {
3657 VisitForStackValue(property->obj()); 3653 VisitForStackValue(property->obj());
3658 VisitForStackValue(property->key()); 3654 VisitForStackValue(property->key());
3659 __ push(Immediate(Smi::FromInt(strict_mode_flag()))); 3655 StrictModeFlag strict_mode_flag = (language_mode() == CLASSIC_MODE)
3656 ? kNonStrictMode : kStrictMode;
3657 __ push(Immediate(Smi::FromInt(strict_mode_flag)));
3660 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); 3658 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
3661 context()->Plug(eax); 3659 context()->Plug(eax);
3662 } else if (proxy != NULL) { 3660 } else if (proxy != NULL) {
3663 Variable* var = proxy->var(); 3661 Variable* var = proxy->var();
3664 // Delete of an unqualified identifier is disallowed in strict mode 3662 // Delete of an unqualified identifier is disallowed in strict mode
3665 // but "delete this" is allowed. 3663 // but "delete this" is allowed.
3666 ASSERT(strict_mode_flag() == kNonStrictMode || var->is_this()); 3664 ASSERT(language_mode() == CLASSIC_MODE || var->is_this());
3667 if (var->IsUnallocated()) { 3665 if (var->IsUnallocated()) {
3668 __ push(GlobalObjectOperand()); 3666 __ push(GlobalObjectOperand());
3669 __ push(Immediate(var->name())); 3667 __ push(Immediate(var->name()));
3670 __ push(Immediate(Smi::FromInt(kNonStrictMode))); 3668 __ push(Immediate(Smi::FromInt(kNonStrictMode)));
3671 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); 3669 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
3672 context()->Plug(eax); 3670 context()->Plug(eax);
3673 } else if (var->IsStackAllocated() || var->IsContextSlot()) { 3671 } else if (var->IsStackAllocated() || var->IsContextSlot()) {
3674 // Result of deleting non-global variables is false. 'this' is 3672 // Result of deleting non-global variables is false. 'this' is
3675 // not really a variable, though we implement it as one. The 3673 // not really a variable, though we implement it as one. The
3676 // subexpression does not have side effects. 3674 // subexpression does not have side effects.
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
3935 // Perform the assignment as if via '='. 3933 // Perform the assignment as if via '='.
3936 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 3934 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3937 Token::ASSIGN); 3935 Token::ASSIGN);
3938 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3936 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3939 context()->Plug(eax); 3937 context()->Plug(eax);
3940 } 3938 }
3941 break; 3939 break;
3942 case NAMED_PROPERTY: { 3940 case NAMED_PROPERTY: {
3943 __ mov(ecx, prop->key()->AsLiteral()->handle()); 3941 __ mov(ecx, prop->key()->AsLiteral()->handle());
3944 __ pop(edx); 3942 __ pop(edx);
3945 Handle<Code> ic = is_strict_mode() 3943 Handle<Code> ic = is_classic_mode()
3946 ? isolate()->builtins()->StoreIC_Initialize_Strict() 3944 ? isolate()->builtins()->StoreIC_Initialize()
3947 : isolate()->builtins()->StoreIC_Initialize(); 3945 : isolate()->builtins()->StoreIC_Initialize_Strict();
3948 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); 3946 __ call(ic, RelocInfo::CODE_TARGET, expr->id());
3949 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3947 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3950 if (expr->is_postfix()) { 3948 if (expr->is_postfix()) {
3951 if (!context()->IsEffect()) { 3949 if (!context()->IsEffect()) {
3952 context()->PlugTOS(); 3950 context()->PlugTOS();
3953 } 3951 }
3954 } else { 3952 } else {
3955 context()->Plug(eax); 3953 context()->Plug(eax);
3956 } 3954 }
3957 break; 3955 break;
3958 } 3956 }
3959 case KEYED_PROPERTY: { 3957 case KEYED_PROPERTY: {
3960 __ pop(ecx); 3958 __ pop(ecx);
3961 __ pop(edx); 3959 __ pop(edx);
3962 Handle<Code> ic = is_strict_mode() 3960 Handle<Code> ic = is_classic_mode()
3963 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 3961 ? isolate()->builtins()->KeyedStoreIC_Initialize()
3964 : isolate()->builtins()->KeyedStoreIC_Initialize(); 3962 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
3965 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); 3963 __ call(ic, RelocInfo::CODE_TARGET, expr->id());
3966 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3964 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3967 if (expr->is_postfix()) { 3965 if (expr->is_postfix()) {
3968 // Result is on the stack 3966 // Result is on the stack
3969 if (!context()->IsEffect()) { 3967 if (!context()->IsEffect()) {
3970 context()->PlugTOS(); 3968 context()->PlugTOS();
3971 } 3969 }
3972 } else { 3970 } else {
3973 context()->Plug(eax); 3971 context()->Plug(eax);
3974 } 3972 }
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after
4322 *context_length = 0; 4320 *context_length = 0;
4323 return previous_; 4321 return previous_;
4324 } 4322 }
4325 4323
4326 4324
4327 #undef __ 4325 #undef __
4328 4326
4329 } } // namespace v8::internal 4327 } } // namespace v8::internal
4330 4328
4331 #endif // V8_TARGET_ARCH_IA32 4329 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/code-stubs-ia32.cc ('k') | src/ia32/lithium-codegen-ia32.h » ('j') | src/objects.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698