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

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 more 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
« no previous file with comments | « src/ia32/code-stubs-ia32.cc ('k') | src/ia32/lithium-codegen-ia32.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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). ecx is zero for method calls and non-zero for 134 // receiver object). ecx 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 __ test(ecx, ecx); 138 __ test(ecx, ecx);
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 __ mov(ecx, Operand(esp, receiver_offset)); 142 __ mov(ecx, Operand(esp, receiver_offset));
143 __ JumpIfSmi(ecx, &ok); 143 __ JumpIfSmi(ecx, &ok);
144 __ CmpObjectType(ecx, JS_GLOBAL_PROXY_TYPE, ecx); 144 __ CmpObjectType(ecx, JS_GLOBAL_PROXY_TYPE, ecx);
145 __ j(not_equal, &ok, Label::kNear); 145 __ j(not_equal, &ok, Label::kNear);
146 __ mov(Operand(esp, receiver_offset), 146 __ mov(Operand(esp, receiver_offset),
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 int offset = num_parameters * kPointerSize; 225 int offset = num_parameters * kPointerSize;
226 __ lea(edx, 226 __ lea(edx,
227 Operand(ebp, StandardFrameConstants::kCallerSPOffset + offset)); 227 Operand(ebp, StandardFrameConstants::kCallerSPOffset + offset));
228 __ push(edx); 228 __ push(edx);
229 __ SafePush(Immediate(Smi::FromInt(num_parameters))); 229 __ SafePush(Immediate(Smi::FromInt(num_parameters)));
230 // Arguments to ArgumentsAccessStub and/or New...: 230 // Arguments to ArgumentsAccessStub and/or New...:
231 // function, receiver address, parameter count. 231 // function, receiver address, parameter count.
232 // The stub will rewrite receiver and parameter count if the previous 232 // The stub will rewrite receiver and parameter count if the previous
233 // stack frame was an arguments adapter frame. 233 // stack frame was an arguments adapter frame.
234 ArgumentsAccessStub::Type type; 234 ArgumentsAccessStub::Type type;
235 if (is_strict_mode()) { 235 if (!is_classic_mode()) {
236 type = ArgumentsAccessStub::NEW_STRICT; 236 type = ArgumentsAccessStub::NEW_STRICT;
237 } else if (function()->has_duplicate_parameters()) { 237 } else if (function()->has_duplicate_parameters()) {
238 type = ArgumentsAccessStub::NEW_NON_STRICT_SLOW; 238 type = ArgumentsAccessStub::NEW_NON_STRICT_SLOW;
239 } else { 239 } else {
240 type = ArgumentsAccessStub::NEW_NON_STRICT_FAST; 240 type = ArgumentsAccessStub::NEW_NON_STRICT_FAST;
241 } 241 }
242 ArgumentsAccessStub stub(type); 242 ArgumentsAccessStub stub(type);
243 __ CallStub(&stub); 243 __ CallStub(&stub);
244 244
245 SetVar(arguments, eax, ebx, edx); 245 SetVar(arguments, eax, ebx, edx);
(...skipping 818 matching lines...) Expand 10 before | Expand all | Expand 10 after
1064 // space for nested functions that don't need literals cloning. If 1064 // space for nested functions that don't need literals cloning. If
1065 // we're running with the --always-opt or the --prepare-always-opt 1065 // we're running with the --always-opt or the --prepare-always-opt
1066 // flag, we need to use the runtime function so that the new function 1066 // flag, we need to use the runtime function so that the new function
1067 // we are creating here gets a chance to have its code optimized and 1067 // we are creating here gets a chance to have its code optimized and
1068 // doesn't just get a copy of the existing unoptimized code. 1068 // doesn't just get a copy of the existing unoptimized code.
1069 if (!FLAG_always_opt && 1069 if (!FLAG_always_opt &&
1070 !FLAG_prepare_always_opt && 1070 !FLAG_prepare_always_opt &&
1071 !pretenure && 1071 !pretenure &&
1072 scope()->is_function_scope() && 1072 scope()->is_function_scope() &&
1073 info->num_literals() == 0) { 1073 info->num_literals() == 0) {
1074 FastNewClosureStub stub(info->strict_mode_flag()); 1074 FastNewClosureStub stub(info->language_mode());
1075 __ push(Immediate(info)); 1075 __ push(Immediate(info));
1076 __ CallStub(&stub); 1076 __ CallStub(&stub);
1077 } else { 1077 } else {
1078 __ push(esi); 1078 __ push(esi);
1079 __ push(Immediate(info)); 1079 __ push(Immediate(info));
1080 __ push(Immediate(pretenure 1080 __ push(Immediate(pretenure
1081 ? isolate()->factory()->true_value() 1081 ? isolate()->factory()->true_value()
1082 : isolate()->factory()->false_value())); 1082 : isolate()->factory()->false_value()));
1083 __ CallRuntime(Runtime::kNewClosure, 3); 1083 __ CallRuntime(Runtime::kNewClosure, 3);
1084 } 1084 }
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
1413 switch (property->kind()) { 1413 switch (property->kind()) {
1414 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1414 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1415 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); 1415 ASSERT(!CompileTimeValue::IsCompileTimeValue(value));
1416 // Fall through. 1416 // Fall through.
1417 case ObjectLiteral::Property::COMPUTED: 1417 case ObjectLiteral::Property::COMPUTED:
1418 if (key->handle()->IsSymbol()) { 1418 if (key->handle()->IsSymbol()) {
1419 if (property->emit_store()) { 1419 if (property->emit_store()) {
1420 VisitForAccumulatorValue(value); 1420 VisitForAccumulatorValue(value);
1421 __ mov(ecx, Immediate(key->handle())); 1421 __ mov(ecx, Immediate(key->handle()));
1422 __ mov(edx, Operand(esp, 0)); 1422 __ mov(edx, Operand(esp, 0));
1423 Handle<Code> ic = is_strict_mode() 1423 Handle<Code> ic = is_classic_mode()
1424 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1424 ? isolate()->builtins()->StoreIC_Initialize()
1425 : isolate()->builtins()->StoreIC_Initialize(); 1425 : isolate()->builtins()->StoreIC_Initialize_Strict();
1426 __ call(ic, RelocInfo::CODE_TARGET, key->id()); 1426 __ call(ic, RelocInfo::CODE_TARGET, key->id());
1427 PrepareForBailoutForId(key->id(), NO_REGISTERS); 1427 PrepareForBailoutForId(key->id(), NO_REGISTERS);
1428 } else { 1428 } else {
1429 VisitForEffect(value); 1429 VisitForEffect(value);
1430 } 1430 }
1431 break; 1431 break;
1432 } 1432 }
1433 // Fall through. 1433 // Fall through.
1434 case ObjectLiteral::Property::PROTOTYPE: 1434 case ObjectLiteral::Property::PROTOTYPE:
1435 __ push(Operand(esp, 0)); // Duplicate receiver. 1435 __ push(Operand(esp, 0)); // Duplicate receiver.
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after
1811 EffectContext context(this); 1811 EffectContext context(this);
1812 EmitVariableAssignment(var, Token::ASSIGN); 1812 EmitVariableAssignment(var, Token::ASSIGN);
1813 break; 1813 break;
1814 } 1814 }
1815 case NAMED_PROPERTY: { 1815 case NAMED_PROPERTY: {
1816 __ push(eax); // Preserve value. 1816 __ push(eax); // Preserve value.
1817 VisitForAccumulatorValue(prop->obj()); 1817 VisitForAccumulatorValue(prop->obj());
1818 __ mov(edx, eax); 1818 __ mov(edx, eax);
1819 __ pop(eax); // Restore value. 1819 __ pop(eax); // Restore value.
1820 __ mov(ecx, prop->key()->AsLiteral()->handle()); 1820 __ mov(ecx, prop->key()->AsLiteral()->handle());
1821 Handle<Code> ic = is_strict_mode() 1821 Handle<Code> ic = is_classic_mode()
1822 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1822 ? isolate()->builtins()->StoreIC_Initialize()
1823 : isolate()->builtins()->StoreIC_Initialize(); 1823 : isolate()->builtins()->StoreIC_Initialize_Strict();
1824 __ call(ic); 1824 __ call(ic);
1825 break; 1825 break;
1826 } 1826 }
1827 case KEYED_PROPERTY: { 1827 case KEYED_PROPERTY: {
1828 __ push(eax); // Preserve value. 1828 __ push(eax); // Preserve value.
1829 VisitForStackValue(prop->obj()); 1829 VisitForStackValue(prop->obj());
1830 VisitForAccumulatorValue(prop->key()); 1830 VisitForAccumulatorValue(prop->key());
1831 __ mov(ecx, eax); 1831 __ mov(ecx, eax);
1832 __ pop(edx); 1832 __ pop(edx);
1833 __ pop(eax); // Restore value. 1833 __ pop(eax); // Restore value.
1834 Handle<Code> ic = is_strict_mode() 1834 Handle<Code> ic = is_classic_mode()
1835 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 1835 ? isolate()->builtins()->KeyedStoreIC_Initialize()
1836 : isolate()->builtins()->KeyedStoreIC_Initialize(); 1836 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
1837 __ call(ic); 1837 __ call(ic);
1838 break; 1838 break;
1839 } 1839 }
1840 } 1840 }
1841 PrepareForBailoutForId(bailout_ast_id, TOS_REG); 1841 PrepareForBailoutForId(bailout_ast_id, TOS_REG);
1842 context()->Plug(eax); 1842 context()->Plug(eax);
1843 } 1843 }
1844 1844
1845 1845
1846 void FullCodeGenerator::EmitVariableAssignment(Variable* var, 1846 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
1847 Token::Value op) { 1847 Token::Value op) {
1848 if (var->IsUnallocated()) { 1848 if (var->IsUnallocated()) {
1849 // Global var, const, or let. 1849 // Global var, const, or let.
1850 __ mov(ecx, var->name()); 1850 __ mov(ecx, var->name());
1851 __ mov(edx, GlobalObjectOperand()); 1851 __ mov(edx, GlobalObjectOperand());
1852 Handle<Code> ic = is_strict_mode() 1852 Handle<Code> ic = is_classic_mode()
1853 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1853 ? isolate()->builtins()->StoreIC_Initialize()
1854 : isolate()->builtins()->StoreIC_Initialize(); 1854 : isolate()->builtins()->StoreIC_Initialize_Strict();
1855 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); 1855 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT);
1856 1856
1857 } else if (op == Token::INIT_CONST) { 1857 } else if (op == Token::INIT_CONST) {
1858 // Const initializers need a write barrier. 1858 // Const initializers need a write barrier.
1859 ASSERT(!var->IsParameter()); // No const parameters. 1859 ASSERT(!var->IsParameter()); // No const parameters.
1860 if (var->IsStackLocal()) { 1860 if (var->IsStackLocal()) {
1861 Label skip; 1861 Label skip;
1862 __ mov(edx, StackOperand(var)); 1862 __ mov(edx, StackOperand(var));
1863 __ cmp(edx, isolate()->factory()->the_hole_value()); 1863 __ cmp(edx, isolate()->factory()->the_hole_value());
1864 __ j(not_equal, &skip); 1864 __ j(not_equal, &skip);
(...skipping 11 matching lines...) Expand all
1876 __ push(Immediate(var->name())); 1876 __ push(Immediate(var->name()));
1877 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3); 1877 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3);
1878 } 1878 }
1879 1879
1880 } else if (var->mode() == LET && op != Token::INIT_LET) { 1880 } else if (var->mode() == LET && op != Token::INIT_LET) {
1881 // Non-initializing assignment to let variable needs a write barrier. 1881 // Non-initializing assignment to let variable needs a write barrier.
1882 if (var->IsLookupSlot()) { 1882 if (var->IsLookupSlot()) {
1883 __ push(eax); // Value. 1883 __ push(eax); // Value.
1884 __ push(esi); // Context. 1884 __ push(esi); // Context.
1885 __ push(Immediate(var->name())); 1885 __ push(Immediate(var->name()));
1886 __ push(Immediate(Smi::FromInt(strict_mode_flag()))); 1886 __ push(Immediate(Smi::FromInt(language_mode())));
1887 __ CallRuntime(Runtime::kStoreContextSlot, 4); 1887 __ CallRuntime(Runtime::kStoreContextSlot, 4);
1888 } else { 1888 } else {
1889 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); 1889 ASSERT(var->IsStackAllocated() || var->IsContextSlot());
1890 Label assign; 1890 Label assign;
1891 MemOperand location = VarOperand(var, ecx); 1891 MemOperand location = VarOperand(var, ecx);
1892 __ mov(edx, location); 1892 __ mov(edx, location);
1893 __ cmp(edx, isolate()->factory()->the_hole_value()); 1893 __ cmp(edx, isolate()->factory()->the_hole_value());
1894 __ j(not_equal, &assign, Label::kNear); 1894 __ j(not_equal, &assign, Label::kNear);
1895 __ push(Immediate(var->name())); 1895 __ push(Immediate(var->name()));
1896 __ CallRuntime(Runtime::kThrowReferenceError, 1); 1896 __ CallRuntime(Runtime::kThrowReferenceError, 1);
(...skipping 22 matching lines...) Expand all
1919 if (var->IsContextSlot()) { 1919 if (var->IsContextSlot()) {
1920 __ mov(edx, eax); 1920 __ mov(edx, eax);
1921 int offset = Context::SlotOffset(var->index()); 1921 int offset = Context::SlotOffset(var->index());
1922 __ RecordWriteContextSlot(ecx, offset, edx, ebx, kDontSaveFPRegs); 1922 __ RecordWriteContextSlot(ecx, offset, edx, ebx, kDontSaveFPRegs);
1923 } 1923 }
1924 } else { 1924 } else {
1925 ASSERT(var->IsLookupSlot()); 1925 ASSERT(var->IsLookupSlot());
1926 __ push(eax); // Value. 1926 __ push(eax); // Value.
1927 __ push(esi); // Context. 1927 __ push(esi); // Context.
1928 __ push(Immediate(var->name())); 1928 __ push(Immediate(var->name()));
1929 __ push(Immediate(Smi::FromInt(strict_mode_flag()))); 1929 __ push(Immediate(Smi::FromInt(language_mode())));
1930 __ CallRuntime(Runtime::kStoreContextSlot, 4); 1930 __ CallRuntime(Runtime::kStoreContextSlot, 4);
1931 } 1931 }
1932 } 1932 }
1933 // Non-initializing assignments to consts are ignored. 1933 // Non-initializing assignments to consts are ignored.
1934 } 1934 }
1935 1935
1936 1936
1937 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 1937 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
1938 // Assignment to a property, using a named store IC. 1938 // Assignment to a property, using a named store IC.
1939 Property* prop = expr->target()->AsProperty(); 1939 Property* prop = expr->target()->AsProperty();
(...skipping 11 matching lines...) Expand all
1951 } 1951 }
1952 1952
1953 // Record source code position before IC call. 1953 // Record source code position before IC call.
1954 SetSourcePosition(expr->position()); 1954 SetSourcePosition(expr->position());
1955 __ mov(ecx, prop->key()->AsLiteral()->handle()); 1955 __ mov(ecx, prop->key()->AsLiteral()->handle());
1956 if (expr->ends_initialization_block()) { 1956 if (expr->ends_initialization_block()) {
1957 __ mov(edx, Operand(esp, 0)); 1957 __ mov(edx, Operand(esp, 0));
1958 } else { 1958 } else {
1959 __ pop(edx); 1959 __ pop(edx);
1960 } 1960 }
1961 Handle<Code> ic = is_strict_mode() 1961 Handle<Code> ic = is_classic_mode()
1962 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1962 ? isolate()->builtins()->StoreIC_Initialize()
1963 : isolate()->builtins()->StoreIC_Initialize(); 1963 : isolate()->builtins()->StoreIC_Initialize_Strict();
1964 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); 1964 __ call(ic, RelocInfo::CODE_TARGET, expr->id());
1965 1965
1966 // If the assignment ends an initialization block, revert to fast case. 1966 // If the assignment ends an initialization block, revert to fast case.
1967 if (expr->ends_initialization_block()) { 1967 if (expr->ends_initialization_block()) {
1968 __ push(eax); // Result of assignment, saved even if not needed. 1968 __ push(eax); // Result of assignment, saved even if not needed.
1969 __ push(Operand(esp, kPointerSize)); // Receiver is under value. 1969 __ push(Operand(esp, kPointerSize)); // Receiver is under value.
1970 __ CallRuntime(Runtime::kToFastProperties, 1); 1970 __ CallRuntime(Runtime::kToFastProperties, 1);
1971 __ pop(eax); 1971 __ pop(eax);
1972 __ Drop(1); 1972 __ Drop(1);
1973 } 1973 }
(...skipping 17 matching lines...) Expand all
1991 } 1991 }
1992 1992
1993 __ pop(ecx); 1993 __ pop(ecx);
1994 if (expr->ends_initialization_block()) { 1994 if (expr->ends_initialization_block()) {
1995 __ mov(edx, Operand(esp, 0)); // Leave receiver on the stack for later. 1995 __ mov(edx, Operand(esp, 0)); // Leave receiver on the stack for later.
1996 } else { 1996 } else {
1997 __ pop(edx); 1997 __ pop(edx);
1998 } 1998 }
1999 // Record source code position before IC call. 1999 // Record source code position before IC call.
2000 SetSourcePosition(expr->position()); 2000 SetSourcePosition(expr->position());
2001 Handle<Code> ic = is_strict_mode() 2001 Handle<Code> ic = is_classic_mode()
2002 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 2002 ? isolate()->builtins()->KeyedStoreIC_Initialize()
2003 : isolate()->builtins()->KeyedStoreIC_Initialize(); 2003 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
2004 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); 2004 __ call(ic, RelocInfo::CODE_TARGET, expr->id());
2005 2005
2006 // If the assignment ends an initialization block, revert to fast case. 2006 // If the assignment ends an initialization block, revert to fast case.
2007 if (expr->ends_initialization_block()) { 2007 if (expr->ends_initialization_block()) {
2008 __ pop(edx); 2008 __ pop(edx);
2009 __ push(eax); // Result of assignment, saved even if not needed. 2009 __ push(eax); // Result of assignment, saved even if not needed.
2010 __ push(edx); 2010 __ push(edx);
2011 __ CallRuntime(Runtime::kToFastProperties, 1); 2011 __ CallRuntime(Runtime::kToFastProperties, 1);
2012 __ pop(eax); 2012 __ pop(eax);
2013 } 2013 }
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
2138 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { 2138 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
2139 // Push copy of the first argument or undefined if it doesn't exist. 2139 // Push copy of the first argument or undefined if it doesn't exist.
2140 if (arg_count > 0) { 2140 if (arg_count > 0) {
2141 __ push(Operand(esp, arg_count * kPointerSize)); 2141 __ push(Operand(esp, arg_count * kPointerSize));
2142 } else { 2142 } else {
2143 __ push(Immediate(isolate()->factory()->undefined_value())); 2143 __ push(Immediate(isolate()->factory()->undefined_value()));
2144 } 2144 }
2145 2145
2146 // Push the receiver of the enclosing function. 2146 // Push the receiver of the enclosing function.
2147 __ push(Operand(ebp, (2 + info_->scope()->num_parameters()) * kPointerSize)); 2147 __ push(Operand(ebp, (2 + info_->scope()->num_parameters()) * kPointerSize));
2148 2148 // Push the language mode.
2149 // Push the strict mode flag. In harmony mode every eval call 2149 __ push(Immediate(Smi::FromInt(language_mode())));
2150 // is a strict mode eval call.
2151 StrictModeFlag strict_mode =
2152 FLAG_harmony_scoping ? kStrictMode : strict_mode_flag();
2153 __ push(Immediate(Smi::FromInt(strict_mode)));
2154 2150
2155 // Push the start position of the scope the calls resides in. 2151 // Push the start position of the scope the calls resides in.
2156 __ push(Immediate(Smi::FromInt(scope()->start_position()))); 2152 __ push(Immediate(Smi::FromInt(scope()->start_position())));
2157 2153
2154 // Do the runtime call.
2158 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); 2155 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5);
2159 } 2156 }
2160 2157
2161 2158
2162 void FullCodeGenerator::VisitCall(Call* expr) { 2159 void FullCodeGenerator::VisitCall(Call* expr) {
2163 #ifdef DEBUG 2160 #ifdef DEBUG
2164 // We want to verify that RecordJSReturnSite gets called on all paths 2161 // We want to verify that RecordJSReturnSite gets called on all paths
2165 // through this function. Avoid early returns. 2162 // through this function. Avoid early returns.
2166 expr->return_is_recorded_ = false; 2163 expr->return_is_recorded_ = false;
2167 #endif 2164 #endif
(...skipping 1504 matching lines...) Expand 10 before | Expand all | Expand 10 after
3672 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 3669 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
3673 switch (expr->op()) { 3670 switch (expr->op()) {
3674 case Token::DELETE: { 3671 case Token::DELETE: {
3675 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); 3672 Comment cmnt(masm_, "[ UnaryOperation (DELETE)");
3676 Property* property = expr->expression()->AsProperty(); 3673 Property* property = expr->expression()->AsProperty();
3677 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 3674 VariableProxy* proxy = expr->expression()->AsVariableProxy();
3678 3675
3679 if (property != NULL) { 3676 if (property != NULL) {
3680 VisitForStackValue(property->obj()); 3677 VisitForStackValue(property->obj());
3681 VisitForStackValue(property->key()); 3678 VisitForStackValue(property->key());
3682 __ push(Immediate(Smi::FromInt(strict_mode_flag()))); 3679 StrictModeFlag strict_mode_flag = (language_mode() == CLASSIC_MODE)
3680 ? kNonStrictMode : kStrictMode;
3681 __ push(Immediate(Smi::FromInt(strict_mode_flag)));
3683 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); 3682 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
3684 context()->Plug(eax); 3683 context()->Plug(eax);
3685 } else if (proxy != NULL) { 3684 } else if (proxy != NULL) {
3686 Variable* var = proxy->var(); 3685 Variable* var = proxy->var();
3687 // Delete of an unqualified identifier is disallowed in strict mode 3686 // Delete of an unqualified identifier is disallowed in strict mode
3688 // but "delete this" is allowed. 3687 // but "delete this" is allowed.
3689 ASSERT(strict_mode_flag() == kNonStrictMode || var->is_this()); 3688 ASSERT(language_mode() == CLASSIC_MODE || var->is_this());
3690 if (var->IsUnallocated()) { 3689 if (var->IsUnallocated()) {
3691 __ push(GlobalObjectOperand()); 3690 __ push(GlobalObjectOperand());
3692 __ push(Immediate(var->name())); 3691 __ push(Immediate(var->name()));
3693 __ push(Immediate(Smi::FromInt(kNonStrictMode))); 3692 __ push(Immediate(Smi::FromInt(kNonStrictMode)));
3694 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); 3693 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
3695 context()->Plug(eax); 3694 context()->Plug(eax);
3696 } else if (var->IsStackAllocated() || var->IsContextSlot()) { 3695 } else if (var->IsStackAllocated() || var->IsContextSlot()) {
3697 // Result of deleting non-global variables is false. 'this' is 3696 // Result of deleting non-global variables is false. 'this' is
3698 // not really a variable, though we implement it as one. The 3697 // not really a variable, though we implement it as one. The
3699 // subexpression does not have side effects. 3698 // subexpression does not have side effects.
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
3958 // Perform the assignment as if via '='. 3957 // Perform the assignment as if via '='.
3959 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 3958 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3960 Token::ASSIGN); 3959 Token::ASSIGN);
3961 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3960 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3962 context()->Plug(eax); 3961 context()->Plug(eax);
3963 } 3962 }
3964 break; 3963 break;
3965 case NAMED_PROPERTY: { 3964 case NAMED_PROPERTY: {
3966 __ mov(ecx, prop->key()->AsLiteral()->handle()); 3965 __ mov(ecx, prop->key()->AsLiteral()->handle());
3967 __ pop(edx); 3966 __ pop(edx);
3968 Handle<Code> ic = is_strict_mode() 3967 Handle<Code> ic = is_classic_mode()
3969 ? isolate()->builtins()->StoreIC_Initialize_Strict() 3968 ? isolate()->builtins()->StoreIC_Initialize()
3970 : isolate()->builtins()->StoreIC_Initialize(); 3969 : isolate()->builtins()->StoreIC_Initialize_Strict();
3971 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); 3970 __ call(ic, RelocInfo::CODE_TARGET, expr->id());
3972 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3971 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3973 if (expr->is_postfix()) { 3972 if (expr->is_postfix()) {
3974 if (!context()->IsEffect()) { 3973 if (!context()->IsEffect()) {
3975 context()->PlugTOS(); 3974 context()->PlugTOS();
3976 } 3975 }
3977 } else { 3976 } else {
3978 context()->Plug(eax); 3977 context()->Plug(eax);
3979 } 3978 }
3980 break; 3979 break;
3981 } 3980 }
3982 case KEYED_PROPERTY: { 3981 case KEYED_PROPERTY: {
3983 __ pop(ecx); 3982 __ pop(ecx);
3984 __ pop(edx); 3983 __ pop(edx);
3985 Handle<Code> ic = is_strict_mode() 3984 Handle<Code> ic = is_classic_mode()
3986 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 3985 ? isolate()->builtins()->KeyedStoreIC_Initialize()
3987 : isolate()->builtins()->KeyedStoreIC_Initialize(); 3986 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
3988 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); 3987 __ call(ic, RelocInfo::CODE_TARGET, expr->id());
3989 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3988 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3990 if (expr->is_postfix()) { 3989 if (expr->is_postfix()) {
3991 // Result is on the stack 3990 // Result is on the stack
3992 if (!context()->IsEffect()) { 3991 if (!context()->IsEffect()) {
3993 context()->PlugTOS(); 3992 context()->PlugTOS();
3994 } 3993 }
3995 } else { 3994 } else {
3996 context()->Plug(eax); 3995 context()->Plug(eax);
3997 } 3996 }
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after
4345 *context_length = 0; 4344 *context_length = 0;
4346 return previous_; 4345 return previous_;
4347 } 4346 }
4348 4347
4349 4348
4350 #undef __ 4349 #undef __
4351 4350
4352 } } // namespace v8::internal 4351 } } // namespace v8::internal
4353 4352
4354 #endif // V8_TARGET_ARCH_IA32 4353 #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') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698