| 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 |