OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
136 if (strlen(FLAG_stop_at) > 0 && | 136 if (strlen(FLAG_stop_at) > 0 && |
137 info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { | 137 info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { |
138 __ stop("stop-at"); | 138 __ stop("stop-at"); |
139 } | 139 } |
140 #endif | 140 #endif |
141 | 141 |
142 // Strict mode functions and builtins need to replace the receiver | 142 // Strict mode functions and builtins need to replace the receiver |
143 // with undefined when called as functions (without an explicit | 143 // with undefined when called as functions (without an explicit |
144 // receiver object). r5 is zero for method calls and non-zero for | 144 // receiver object). r5 is zero for method calls and non-zero for |
145 // function calls. | 145 // function calls. |
146 if (info->is_strict_mode() || info->is_native()) { | 146 if (!info->is_classic_mode() || info->is_native()) { |
147 Label ok; | 147 Label ok; |
148 __ cmp(r5, Operand(0)); | 148 __ cmp(r5, Operand(0)); |
149 __ b(eq, &ok); | 149 __ b(eq, &ok); |
150 int receiver_offset = info->scope()->num_parameters() * kPointerSize; | 150 int receiver_offset = info->scope()->num_parameters() * kPointerSize; |
151 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); | 151 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); |
152 __ str(r2, MemOperand(sp, receiver_offset)); | 152 __ str(r2, MemOperand(sp, receiver_offset)); |
153 __ bind(&ok); | 153 __ bind(&ok); |
154 } | 154 } |
155 | 155 |
156 // Open a frame scope to indicate that there is a frame on the stack. The | 156 // Open a frame scope to indicate that there is a frame on the stack. The |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
229 __ add(r2, fp, | 229 __ add(r2, fp, |
230 Operand(StandardFrameConstants::kCallerSPOffset + offset)); | 230 Operand(StandardFrameConstants::kCallerSPOffset + offset)); |
231 __ mov(r1, Operand(Smi::FromInt(num_parameters))); | 231 __ mov(r1, Operand(Smi::FromInt(num_parameters))); |
232 __ Push(r3, r2, r1); | 232 __ Push(r3, r2, r1); |
233 | 233 |
234 // Arguments to ArgumentsAccessStub: | 234 // Arguments to ArgumentsAccessStub: |
235 // function, receiver address, parameter count. | 235 // function, receiver address, parameter count. |
236 // The stub will rewrite receiever and parameter count if the previous | 236 // The stub will rewrite receiever and parameter count if the previous |
237 // stack frame was an arguments adapter frame. | 237 // stack frame was an arguments adapter frame. |
238 ArgumentsAccessStub::Type type; | 238 ArgumentsAccessStub::Type type; |
239 if (is_strict_mode()) { | 239 if (!is_classic_mode()) { |
240 type = ArgumentsAccessStub::NEW_STRICT; | 240 type = ArgumentsAccessStub::NEW_STRICT; |
241 } else if (function()->has_duplicate_parameters()) { | 241 } else if (function()->has_duplicate_parameters()) { |
242 type = ArgumentsAccessStub::NEW_NON_STRICT_SLOW; | 242 type = ArgumentsAccessStub::NEW_NON_STRICT_SLOW; |
243 } else { | 243 } else { |
244 type = ArgumentsAccessStub::NEW_NON_STRICT_FAST; | 244 type = ArgumentsAccessStub::NEW_NON_STRICT_FAST; |
245 } | 245 } |
246 ArgumentsAccessStub stub(type); | 246 ArgumentsAccessStub stub(type); |
247 __ CallStub(&stub); | 247 __ CallStub(&stub); |
248 | 248 |
249 SetVar(arguments, r0, r1, r2); | 249 SetVar(arguments, r0, r1, r2); |
(...skipping 858 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1108 // space for nested functions that don't need literals cloning. If | 1108 // space for nested functions that don't need literals cloning. If |
1109 // we're running with the --always-opt or the --prepare-always-opt | 1109 // we're running with the --always-opt or the --prepare-always-opt |
1110 // flag, we need to use the runtime function so that the new function | 1110 // flag, we need to use the runtime function so that the new function |
1111 // we are creating here gets a chance to have its code optimized and | 1111 // we are creating here gets a chance to have its code optimized and |
1112 // doesn't just get a copy of the existing unoptimized code. | 1112 // doesn't just get a copy of the existing unoptimized code. |
1113 if (!FLAG_always_opt && | 1113 if (!FLAG_always_opt && |
1114 !FLAG_prepare_always_opt && | 1114 !FLAG_prepare_always_opt && |
1115 !pretenure && | 1115 !pretenure && |
1116 scope()->is_function_scope() && | 1116 scope()->is_function_scope() && |
1117 info->num_literals() == 0) { | 1117 info->num_literals() == 0) { |
1118 FastNewClosureStub stub(info->strict_mode_flag()); | 1118 FastNewClosureStub stub(info->language_mode()); |
1119 __ mov(r0, Operand(info)); | 1119 __ mov(r0, Operand(info)); |
1120 __ push(r0); | 1120 __ push(r0); |
1121 __ CallStub(&stub); | 1121 __ CallStub(&stub); |
1122 } else { | 1122 } else { |
1123 __ mov(r0, Operand(info)); | 1123 __ mov(r0, Operand(info)); |
1124 __ LoadRoot(r1, pretenure ? Heap::kTrueValueRootIndex | 1124 __ LoadRoot(r1, pretenure ? Heap::kTrueValueRootIndex |
1125 : Heap::kFalseValueRootIndex); | 1125 : Heap::kFalseValueRootIndex); |
1126 __ Push(cp, r0, r1); | 1126 __ Push(cp, r0, r1); |
1127 __ CallRuntime(Runtime::kNewClosure, 3); | 1127 __ CallRuntime(Runtime::kNewClosure, 3); |
1128 } | 1128 } |
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1458 UNREACHABLE(); | 1458 UNREACHABLE(); |
1459 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1459 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
1460 ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value())); | 1460 ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value())); |
1461 // Fall through. | 1461 // Fall through. |
1462 case ObjectLiteral::Property::COMPUTED: | 1462 case ObjectLiteral::Property::COMPUTED: |
1463 if (key->handle()->IsSymbol()) { | 1463 if (key->handle()->IsSymbol()) { |
1464 if (property->emit_store()) { | 1464 if (property->emit_store()) { |
1465 VisitForAccumulatorValue(value); | 1465 VisitForAccumulatorValue(value); |
1466 __ mov(r2, Operand(key->handle())); | 1466 __ mov(r2, Operand(key->handle())); |
1467 __ ldr(r1, MemOperand(sp)); | 1467 __ ldr(r1, MemOperand(sp)); |
1468 Handle<Code> ic = is_strict_mode() | 1468 Handle<Code> ic = is_classic_mode() |
1469 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 1469 ? isolate()->builtins()->StoreIC_Initialize() |
1470 : isolate()->builtins()->StoreIC_Initialize(); | 1470 : isolate()->builtins()->StoreIC_Initialize_Strict(); |
1471 __ Call(ic, RelocInfo::CODE_TARGET, key->id()); | 1471 __ Call(ic, RelocInfo::CODE_TARGET, key->id()); |
1472 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1472 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
1473 } else { | 1473 } else { |
1474 VisitForEffect(value); | 1474 VisitForEffect(value); |
1475 } | 1475 } |
1476 break; | 1476 break; |
1477 } | 1477 } |
1478 // Fall through. | 1478 // Fall through. |
1479 case ObjectLiteral::Property::PROTOTYPE: | 1479 case ObjectLiteral::Property::PROTOTYPE: |
1480 // Duplicate receiver on stack. | 1480 // Duplicate receiver on stack. |
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1866 EffectContext context(this); | 1866 EffectContext context(this); |
1867 EmitVariableAssignment(var, Token::ASSIGN); | 1867 EmitVariableAssignment(var, Token::ASSIGN); |
1868 break; | 1868 break; |
1869 } | 1869 } |
1870 case NAMED_PROPERTY: { | 1870 case NAMED_PROPERTY: { |
1871 __ push(r0); // Preserve value. | 1871 __ push(r0); // Preserve value. |
1872 VisitForAccumulatorValue(prop->obj()); | 1872 VisitForAccumulatorValue(prop->obj()); |
1873 __ mov(r1, r0); | 1873 __ mov(r1, r0); |
1874 __ pop(r0); // Restore value. | 1874 __ pop(r0); // Restore value. |
1875 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); | 1875 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); |
1876 Handle<Code> ic = is_strict_mode() | 1876 Handle<Code> ic = is_classic_mode() |
1877 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 1877 ? isolate()->builtins()->StoreIC_Initialize() |
1878 : isolate()->builtins()->StoreIC_Initialize(); | 1878 : isolate()->builtins()->StoreIC_Initialize_Strict(); |
1879 __ Call(ic); | 1879 __ Call(ic); |
1880 break; | 1880 break; |
1881 } | 1881 } |
1882 case KEYED_PROPERTY: { | 1882 case KEYED_PROPERTY: { |
1883 __ push(r0); // Preserve value. | 1883 __ push(r0); // Preserve value. |
1884 VisitForStackValue(prop->obj()); | 1884 VisitForStackValue(prop->obj()); |
1885 VisitForAccumulatorValue(prop->key()); | 1885 VisitForAccumulatorValue(prop->key()); |
1886 __ mov(r1, r0); | 1886 __ mov(r1, r0); |
1887 __ pop(r2); | 1887 __ pop(r2); |
1888 __ pop(r0); // Restore value. | 1888 __ pop(r0); // Restore value. |
1889 Handle<Code> ic = is_strict_mode() | 1889 Handle<Code> ic = is_classic_mode() |
1890 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() | 1890 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
1891 : isolate()->builtins()->KeyedStoreIC_Initialize(); | 1891 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
1892 __ Call(ic); | 1892 __ Call(ic); |
1893 break; | 1893 break; |
1894 } | 1894 } |
1895 } | 1895 } |
1896 PrepareForBailoutForId(bailout_ast_id, TOS_REG); | 1896 PrepareForBailoutForId(bailout_ast_id, TOS_REG); |
1897 context()->Plug(r0); | 1897 context()->Plug(r0); |
1898 } | 1898 } |
1899 | 1899 |
1900 | 1900 |
1901 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 1901 void FullCodeGenerator::EmitVariableAssignment(Variable* var, |
1902 Token::Value op) { | 1902 Token::Value op) { |
1903 if (var->IsUnallocated()) { | 1903 if (var->IsUnallocated()) { |
1904 // Global var, const, or let. | 1904 // Global var, const, or let. |
1905 __ mov(r2, Operand(var->name())); | 1905 __ mov(r2, Operand(var->name())); |
1906 __ ldr(r1, GlobalObjectOperand()); | 1906 __ ldr(r1, GlobalObjectOperand()); |
1907 Handle<Code> ic = is_strict_mode() | 1907 Handle<Code> ic = is_classic_mode() |
1908 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 1908 ? isolate()->builtins()->StoreIC_Initialize() |
1909 : isolate()->builtins()->StoreIC_Initialize(); | 1909 : isolate()->builtins()->StoreIC_Initialize_Strict(); |
1910 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT); | 1910 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT); |
1911 | 1911 |
1912 } else if (op == Token::INIT_CONST) { | 1912 } else if (op == Token::INIT_CONST) { |
1913 // Const initializers need a write barrier. | 1913 // Const initializers need a write barrier. |
1914 ASSERT(!var->IsParameter()); // No const parameters. | 1914 ASSERT(!var->IsParameter()); // No const parameters. |
1915 if (var->IsStackLocal()) { | 1915 if (var->IsStackLocal()) { |
1916 Label skip; | 1916 Label skip; |
1917 __ ldr(r1, StackOperand(var)); | 1917 __ ldr(r1, StackOperand(var)); |
1918 __ CompareRoot(r1, Heap::kTheHoleValueRootIndex); | 1918 __ CompareRoot(r1, Heap::kTheHoleValueRootIndex); |
1919 __ b(ne, &skip); | 1919 __ b(ne, &skip); |
(...skipping 10 matching lines...) Expand all Loading... |
1930 __ mov(r0, Operand(var->name())); | 1930 __ mov(r0, Operand(var->name())); |
1931 __ Push(cp, r0); // Context and name. | 1931 __ Push(cp, r0); // Context and name. |
1932 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3); | 1932 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3); |
1933 } | 1933 } |
1934 | 1934 |
1935 } else if (var->mode() == LET && op != Token::INIT_LET) { | 1935 } else if (var->mode() == LET && op != Token::INIT_LET) { |
1936 // Non-initializing assignment to let variable needs a write barrier. | 1936 // Non-initializing assignment to let variable needs a write barrier. |
1937 if (var->IsLookupSlot()) { | 1937 if (var->IsLookupSlot()) { |
1938 __ push(r0); // Value. | 1938 __ push(r0); // Value. |
1939 __ mov(r1, Operand(var->name())); | 1939 __ mov(r1, Operand(var->name())); |
1940 __ mov(r0, Operand(Smi::FromInt(strict_mode_flag()))); | 1940 __ mov(r0, Operand(Smi::FromInt(language_mode()))); |
1941 __ Push(cp, r1, r0); // Context, name, strict mode. | 1941 __ Push(cp, r1, r0); // Context, name, strict mode. |
1942 __ CallRuntime(Runtime::kStoreContextSlot, 4); | 1942 __ CallRuntime(Runtime::kStoreContextSlot, 4); |
1943 } else { | 1943 } else { |
1944 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); | 1944 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); |
1945 Label assign; | 1945 Label assign; |
1946 MemOperand location = VarOperand(var, r1); | 1946 MemOperand location = VarOperand(var, r1); |
1947 __ ldr(r3, location); | 1947 __ ldr(r3, location); |
1948 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex); | 1948 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex); |
1949 __ b(ne, &assign); | 1949 __ b(ne, &assign); |
1950 __ mov(r3, Operand(var->name())); | 1950 __ mov(r3, Operand(var->name())); |
(...skipping 27 matching lines...) Expand all Loading... |
1978 if (var->IsContextSlot()) { | 1978 if (var->IsContextSlot()) { |
1979 __ mov(r3, r0); | 1979 __ mov(r3, r0); |
1980 int offset = Context::SlotOffset(var->index()); | 1980 int offset = Context::SlotOffset(var->index()); |
1981 __ RecordWriteContextSlot( | 1981 __ RecordWriteContextSlot( |
1982 r1, offset, r3, r2, kLRHasBeenSaved, kDontSaveFPRegs); | 1982 r1, offset, r3, r2, kLRHasBeenSaved, kDontSaveFPRegs); |
1983 } | 1983 } |
1984 } else { | 1984 } else { |
1985 ASSERT(var->IsLookupSlot()); | 1985 ASSERT(var->IsLookupSlot()); |
1986 __ push(r0); // Value. | 1986 __ push(r0); // Value. |
1987 __ mov(r1, Operand(var->name())); | 1987 __ mov(r1, Operand(var->name())); |
1988 __ mov(r0, Operand(Smi::FromInt(strict_mode_flag()))); | 1988 __ mov(r0, Operand(Smi::FromInt(language_mode()))); |
1989 __ Push(cp, r1, r0); // Context, name, strict mode. | 1989 __ Push(cp, r1, r0); // Context, name, strict mode. |
1990 __ CallRuntime(Runtime::kStoreContextSlot, 4); | 1990 __ CallRuntime(Runtime::kStoreContextSlot, 4); |
1991 } | 1991 } |
1992 } | 1992 } |
1993 // Non-initializing assignments to consts are ignored. | 1993 // Non-initializing assignments to consts are ignored. |
1994 } | 1994 } |
1995 | 1995 |
1996 | 1996 |
1997 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { | 1997 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { |
1998 // Assignment to a property, using a named store IC. | 1998 // Assignment to a property, using a named store IC. |
(...skipping 16 matching lines...) Expand all Loading... |
2015 SetSourcePosition(expr->position()); | 2015 SetSourcePosition(expr->position()); |
2016 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); | 2016 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); |
2017 // Load receiver to r1. Leave a copy in the stack if needed for turning the | 2017 // Load receiver to r1. Leave a copy in the stack if needed for turning the |
2018 // receiver into fast case. | 2018 // receiver into fast case. |
2019 if (expr->ends_initialization_block()) { | 2019 if (expr->ends_initialization_block()) { |
2020 __ ldr(r1, MemOperand(sp)); | 2020 __ ldr(r1, MemOperand(sp)); |
2021 } else { | 2021 } else { |
2022 __ pop(r1); | 2022 __ pop(r1); |
2023 } | 2023 } |
2024 | 2024 |
2025 Handle<Code> ic = is_strict_mode() | 2025 Handle<Code> ic = is_classic_mode() |
2026 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 2026 ? isolate()->builtins()->StoreIC_Initialize() |
2027 : isolate()->builtins()->StoreIC_Initialize(); | 2027 : isolate()->builtins()->StoreIC_Initialize_Strict(); |
2028 __ Call(ic, RelocInfo::CODE_TARGET, expr->id()); | 2028 __ Call(ic, RelocInfo::CODE_TARGET, expr->id()); |
2029 | 2029 |
2030 // If the assignment ends an initialization block, revert to fast case. | 2030 // If the assignment ends an initialization block, revert to fast case. |
2031 if (expr->ends_initialization_block()) { | 2031 if (expr->ends_initialization_block()) { |
2032 __ push(r0); // Result of assignment, saved even if not needed. | 2032 __ push(r0); // Result of assignment, saved even if not needed. |
2033 // Receiver is under the result value. | 2033 // Receiver is under the result value. |
2034 __ ldr(ip, MemOperand(sp, kPointerSize)); | 2034 __ ldr(ip, MemOperand(sp, kPointerSize)); |
2035 __ push(ip); | 2035 __ push(ip); |
2036 __ CallRuntime(Runtime::kToFastProperties, 1); | 2036 __ CallRuntime(Runtime::kToFastProperties, 1); |
2037 __ pop(r0); | 2037 __ pop(r0); |
(...skipping 23 matching lines...) Expand all Loading... |
2061 SetSourcePosition(expr->position()); | 2061 SetSourcePosition(expr->position()); |
2062 __ pop(r1); // Key. | 2062 __ pop(r1); // Key. |
2063 // Load receiver to r2. Leave a copy in the stack if needed for turning the | 2063 // Load receiver to r2. Leave a copy in the stack if needed for turning the |
2064 // receiver into fast case. | 2064 // receiver into fast case. |
2065 if (expr->ends_initialization_block()) { | 2065 if (expr->ends_initialization_block()) { |
2066 __ ldr(r2, MemOperand(sp)); | 2066 __ ldr(r2, MemOperand(sp)); |
2067 } else { | 2067 } else { |
2068 __ pop(r2); | 2068 __ pop(r2); |
2069 } | 2069 } |
2070 | 2070 |
2071 Handle<Code> ic = is_strict_mode() | 2071 Handle<Code> ic = is_classic_mode() |
2072 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() | 2072 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
2073 : isolate()->builtins()->KeyedStoreIC_Initialize(); | 2073 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
2074 __ Call(ic, RelocInfo::CODE_TARGET, expr->id()); | 2074 __ Call(ic, RelocInfo::CODE_TARGET, expr->id()); |
2075 | 2075 |
2076 // If the assignment ends an initialization block, revert to fast case. | 2076 // If the assignment ends an initialization block, revert to fast case. |
2077 if (expr->ends_initialization_block()) { | 2077 if (expr->ends_initialization_block()) { |
2078 __ push(r0); // Result of assignment, saved even if not needed. | 2078 __ push(r0); // Result of assignment, saved even if not needed. |
2079 // Receiver is under the result value. | 2079 // Receiver is under the result value. |
2080 __ ldr(ip, MemOperand(sp, kPointerSize)); | 2080 __ ldr(ip, MemOperand(sp, kPointerSize)); |
2081 __ push(ip); | 2081 __ push(ip); |
2082 __ CallRuntime(Runtime::kToFastProperties, 1); | 2082 __ CallRuntime(Runtime::kToFastProperties, 1); |
2083 __ pop(r0); | 2083 __ pop(r0); |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2186 | 2186 |
2187 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { | 2187 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { |
2188 // Push copy of the first argument or undefined if it doesn't exist. | 2188 // Push copy of the first argument or undefined if it doesn't exist. |
2189 if (arg_count > 0) { | 2189 if (arg_count > 0) { |
2190 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize)); | 2190 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize)); |
2191 } else { | 2191 } else { |
2192 __ LoadRoot(r1, Heap::kUndefinedValueRootIndex); | 2192 __ LoadRoot(r1, Heap::kUndefinedValueRootIndex); |
2193 } | 2193 } |
2194 __ push(r1); | 2194 __ push(r1); |
2195 | 2195 |
2196 // Push the receiver of the enclosing function and do runtime call. | 2196 // Push the receiver of the enclosing function. |
2197 int receiver_offset = 2 + info_->scope()->num_parameters(); | 2197 int receiver_offset = 2 + info_->scope()->num_parameters(); |
2198 __ ldr(r1, MemOperand(fp, receiver_offset * kPointerSize)); | 2198 __ ldr(r1, MemOperand(fp, receiver_offset * kPointerSize)); |
2199 __ push(r1); | 2199 __ push(r1); |
2200 // Push the strict mode flag. In harmony mode every eval call | 2200 // Push the language mode. |
2201 // is a strict mode eval call. | 2201 __ mov(r1, Operand(Smi::FromInt(language_mode()))); |
2202 StrictModeFlag strict_mode = | |
2203 FLAG_harmony_scoping ? kStrictMode : strict_mode_flag(); | |
2204 __ mov(r1, Operand(Smi::FromInt(strict_mode))); | |
2205 __ push(r1); | 2202 __ push(r1); |
2206 | 2203 |
2207 // Push the start position of the scope the calls resides in. | 2204 // Push the start position of the scope the calls resides in. |
2208 __ mov(r1, Operand(Smi::FromInt(scope()->start_position()))); | 2205 __ mov(r1, Operand(Smi::FromInt(scope()->start_position()))); |
2209 __ push(r1); | 2206 __ push(r1); |
2210 | 2207 |
| 2208 // Do the runtime call. |
2211 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); | 2209 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); |
2212 } | 2210 } |
2213 | 2211 |
2214 | 2212 |
2215 void FullCodeGenerator::VisitCall(Call* expr) { | 2213 void FullCodeGenerator::VisitCall(Call* expr) { |
2216 #ifdef DEBUG | 2214 #ifdef DEBUG |
2217 // We want to verify that RecordJSReturnSite gets called on all paths | 2215 // We want to verify that RecordJSReturnSite gets called on all paths |
2218 // through this function. Avoid early returns. | 2216 // through this function. Avoid early returns. |
2219 expr->return_is_recorded_ = false; | 2217 expr->return_is_recorded_ = false; |
2220 #endif | 2218 #endif |
(...skipping 1473 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3694 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { | 3692 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { |
3695 switch (expr->op()) { | 3693 switch (expr->op()) { |
3696 case Token::DELETE: { | 3694 case Token::DELETE: { |
3697 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); | 3695 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); |
3698 Property* property = expr->expression()->AsProperty(); | 3696 Property* property = expr->expression()->AsProperty(); |
3699 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 3697 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
3700 | 3698 |
3701 if (property != NULL) { | 3699 if (property != NULL) { |
3702 VisitForStackValue(property->obj()); | 3700 VisitForStackValue(property->obj()); |
3703 VisitForStackValue(property->key()); | 3701 VisitForStackValue(property->key()); |
3704 __ mov(r1, Operand(Smi::FromInt(strict_mode_flag()))); | 3702 StrictModeFlag strict_mode_flag = (language_mode() == CLASSIC_MODE) |
| 3703 ? kNonStrictMode : kStrictMode; |
| 3704 __ mov(r1, Operand(Smi::FromInt(strict_mode_flag))); |
3705 __ push(r1); | 3705 __ push(r1); |
3706 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); | 3706 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); |
3707 context()->Plug(r0); | 3707 context()->Plug(r0); |
3708 } else if (proxy != NULL) { | 3708 } else if (proxy != NULL) { |
3709 Variable* var = proxy->var(); | 3709 Variable* var = proxy->var(); |
3710 // Delete of an unqualified identifier is disallowed in strict mode | 3710 // Delete of an unqualified identifier is disallowed in strict mode |
3711 // but "delete this" is allowed. | 3711 // but "delete this" is allowed. |
3712 ASSERT(strict_mode_flag() == kNonStrictMode || var->is_this()); | 3712 ASSERT(language_mode() == CLASSIC_MODE || var->is_this()); |
3713 if (var->IsUnallocated()) { | 3713 if (var->IsUnallocated()) { |
3714 __ ldr(r2, GlobalObjectOperand()); | 3714 __ ldr(r2, GlobalObjectOperand()); |
3715 __ mov(r1, Operand(var->name())); | 3715 __ mov(r1, Operand(var->name())); |
3716 __ mov(r0, Operand(Smi::FromInt(kNonStrictMode))); | 3716 __ mov(r0, Operand(Smi::FromInt(kNonStrictMode))); |
3717 __ Push(r2, r1, r0); | 3717 __ Push(r2, r1, r0); |
3718 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); | 3718 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); |
3719 context()->Plug(r0); | 3719 context()->Plug(r0); |
3720 } else if (var->IsStackAllocated() || var->IsContextSlot()) { | 3720 } else if (var->IsStackAllocated() || var->IsContextSlot()) { |
3721 // Result of deleting non-global, non-dynamic variables is false. | 3721 // Result of deleting non-global, non-dynamic variables is false. |
3722 // The subexpression does not have side effects. | 3722 // The subexpression does not have side effects. |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3966 } else { | 3966 } else { |
3967 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 3967 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
3968 Token::ASSIGN); | 3968 Token::ASSIGN); |
3969 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3969 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
3970 context()->Plug(r0); | 3970 context()->Plug(r0); |
3971 } | 3971 } |
3972 break; | 3972 break; |
3973 case NAMED_PROPERTY: { | 3973 case NAMED_PROPERTY: { |
3974 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); | 3974 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); |
3975 __ pop(r1); | 3975 __ pop(r1); |
3976 Handle<Code> ic = is_strict_mode() | 3976 Handle<Code> ic = is_classic_mode() |
3977 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 3977 ? isolate()->builtins()->StoreIC_Initialize() |
3978 : isolate()->builtins()->StoreIC_Initialize(); | 3978 : isolate()->builtins()->StoreIC_Initialize_Strict(); |
3979 __ Call(ic, RelocInfo::CODE_TARGET, expr->id()); | 3979 __ Call(ic, RelocInfo::CODE_TARGET, expr->id()); |
3980 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3980 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
3981 if (expr->is_postfix()) { | 3981 if (expr->is_postfix()) { |
3982 if (!context()->IsEffect()) { | 3982 if (!context()->IsEffect()) { |
3983 context()->PlugTOS(); | 3983 context()->PlugTOS(); |
3984 } | 3984 } |
3985 } else { | 3985 } else { |
3986 context()->Plug(r0); | 3986 context()->Plug(r0); |
3987 } | 3987 } |
3988 break; | 3988 break; |
3989 } | 3989 } |
3990 case KEYED_PROPERTY: { | 3990 case KEYED_PROPERTY: { |
3991 __ pop(r1); // Key. | 3991 __ pop(r1); // Key. |
3992 __ pop(r2); // Receiver. | 3992 __ pop(r2); // Receiver. |
3993 Handle<Code> ic = is_strict_mode() | 3993 Handle<Code> ic = is_classic_mode() |
3994 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() | 3994 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
3995 : isolate()->builtins()->KeyedStoreIC_Initialize(); | 3995 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
3996 __ Call(ic, RelocInfo::CODE_TARGET, expr->id()); | 3996 __ Call(ic, RelocInfo::CODE_TARGET, expr->id()); |
3997 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3997 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
3998 if (expr->is_postfix()) { | 3998 if (expr->is_postfix()) { |
3999 if (!context()->IsEffect()) { | 3999 if (!context()->IsEffect()) { |
4000 context()->PlugTOS(); | 4000 context()->PlugTOS(); |
4001 } | 4001 } |
4002 } else { | 4002 } else { |
4003 context()->Plug(r0); | 4003 context()->Plug(r0); |
4004 } | 4004 } |
4005 break; | 4005 break; |
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4357 *context_length = 0; | 4357 *context_length = 0; |
4358 return previous_; | 4358 return previous_; |
4359 } | 4359 } |
4360 | 4360 |
4361 | 4361 |
4362 #undef __ | 4362 #undef __ |
4363 | 4363 |
4364 } } // namespace v8::internal | 4364 } } // namespace v8::internal |
4365 | 4365 |
4366 #endif // V8_TARGET_ARCH_ARM | 4366 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |