OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
140 | 140 |
141 ProfileEntryHookStub::MaybeCallEntryHook(masm_); | 141 ProfileEntryHookStub::MaybeCallEntryHook(masm_); |
142 | 142 |
143 #ifdef DEBUG | 143 #ifdef DEBUG |
144 if (strlen(FLAG_stop_at) > 0 && | 144 if (strlen(FLAG_stop_at) > 0 && |
145 info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { | 145 info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { |
146 __ stop("stop-at"); | 146 __ stop("stop-at"); |
147 } | 147 } |
148 #endif | 148 #endif |
149 | 149 |
150 // Classic mode functions and builtins need to replace the receiver with the | 150 // Sloppy mode functions and builtins need to replace the receiver with the |
151 // global proxy when called as functions (without an explicit receiver | 151 // global proxy when called as functions (without an explicit receiver |
152 // object). | 152 // object). |
153 if (info->is_classic_mode() && !info->is_native()) { | 153 if (info->is_sloppy_mode() && !info->is_native()) { |
154 Label ok; | 154 Label ok; |
155 int receiver_offset = info->scope()->num_parameters() * kPointerSize; | 155 int receiver_offset = info->scope()->num_parameters() * kPointerSize; |
156 __ ldr(r2, MemOperand(sp, receiver_offset)); | 156 __ ldr(r2, MemOperand(sp, receiver_offset)); |
157 __ CompareRoot(r2, Heap::kUndefinedValueRootIndex); | 157 __ CompareRoot(r2, Heap::kUndefinedValueRootIndex); |
158 __ b(ne, &ok); | 158 __ b(ne, &ok); |
159 | 159 |
160 __ ldr(r2, GlobalObjectOperand()); | 160 __ ldr(r2, GlobalObjectOperand()); |
161 __ ldr(r2, FieldMemOperand(r2, GlobalObject::kGlobalReceiverOffset)); | 161 __ ldr(r2, FieldMemOperand(r2, GlobalObject::kGlobalReceiverOffset)); |
162 | 162 |
163 __ str(r2, MemOperand(sp, receiver_offset)); | 163 __ str(r2, MemOperand(sp, receiver_offset)); |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
257 __ add(r2, fp, | 257 __ add(r2, fp, |
258 Operand(StandardFrameConstants::kCallerSPOffset + offset)); | 258 Operand(StandardFrameConstants::kCallerSPOffset + offset)); |
259 __ mov(r1, Operand(Smi::FromInt(num_parameters))); | 259 __ mov(r1, Operand(Smi::FromInt(num_parameters))); |
260 __ Push(r3, r2, r1); | 260 __ Push(r3, r2, r1); |
261 | 261 |
262 // Arguments to ArgumentsAccessStub: | 262 // Arguments to ArgumentsAccessStub: |
263 // function, receiver address, parameter count. | 263 // function, receiver address, parameter count. |
264 // The stub will rewrite receiever and parameter count if the previous | 264 // The stub will rewrite receiever and parameter count if the previous |
265 // stack frame was an arguments adapter frame. | 265 // stack frame was an arguments adapter frame. |
266 ArgumentsAccessStub::Type type; | 266 ArgumentsAccessStub::Type type; |
267 if (!is_classic_mode()) { | 267 if (!is_sloppy_mode()) { |
268 type = ArgumentsAccessStub::NEW_STRICT; | 268 type = ArgumentsAccessStub::NEW_STRICT; |
269 } else if (function()->has_duplicate_parameters()) { | 269 } else if (function()->has_duplicate_parameters()) { |
270 type = ArgumentsAccessStub::NEW_NON_STRICT_SLOW; | 270 type = ArgumentsAccessStub::NEW_SLOPPY_SLOW; |
271 } else { | 271 } else { |
272 type = ArgumentsAccessStub::NEW_NON_STRICT_FAST; | 272 type = ArgumentsAccessStub::NEW_SLOPPY_FAST; |
273 } | 273 } |
274 ArgumentsAccessStub stub(type); | 274 ArgumentsAccessStub stub(type); |
275 __ CallStub(&stub); | 275 __ CallStub(&stub); |
276 | 276 |
277 SetVar(arguments, r0, r1, r2); | 277 SetVar(arguments, r0, r1, r2); |
278 } | 278 } |
279 | 279 |
280 if (FLAG_trace) { | 280 if (FLAG_trace) { |
281 __ CallRuntime(Runtime::kTraceEnter, 0); | 281 __ CallRuntime(Runtime::kTraceEnter, 0); |
282 } | 282 } |
(...skipping 1071 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1354 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(Variable* var, | 1354 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(Variable* var, |
1355 TypeofState typeof_state, | 1355 TypeofState typeof_state, |
1356 Label* slow) { | 1356 Label* slow) { |
1357 Register current = cp; | 1357 Register current = cp; |
1358 Register next = r1; | 1358 Register next = r1; |
1359 Register temp = r2; | 1359 Register temp = r2; |
1360 | 1360 |
1361 Scope* s = scope(); | 1361 Scope* s = scope(); |
1362 while (s != NULL) { | 1362 while (s != NULL) { |
1363 if (s->num_heap_slots() > 0) { | 1363 if (s->num_heap_slots() > 0) { |
1364 if (s->calls_non_strict_eval()) { | 1364 if (s->calls_sloppy_eval()) { |
1365 // Check that extension is NULL. | 1365 // Check that extension is NULL. |
1366 __ ldr(temp, ContextOperand(current, Context::EXTENSION_INDEX)); | 1366 __ ldr(temp, ContextOperand(current, Context::EXTENSION_INDEX)); |
1367 __ tst(temp, temp); | 1367 __ tst(temp, temp); |
1368 __ b(ne, slow); | 1368 __ b(ne, slow); |
1369 } | 1369 } |
1370 // Load next context in chain. | 1370 // Load next context in chain. |
1371 __ ldr(next, ContextOperand(current, Context::PREVIOUS_INDEX)); | 1371 __ ldr(next, ContextOperand(current, Context::PREVIOUS_INDEX)); |
1372 // Walk the rest of the chain without clobbering cp. | 1372 // Walk the rest of the chain without clobbering cp. |
1373 current = next; | 1373 current = next; |
1374 } | 1374 } |
1375 // If no outer scope calls eval, we do not need to check more | 1375 // If no outer scope calls eval, we do not need to check more |
1376 // context extensions. | 1376 // context extensions. |
1377 if (!s->outer_scope_calls_non_strict_eval() || s->is_eval_scope()) break; | 1377 if (!s->outer_scope_calls_sloppy_eval() || s->is_eval_scope()) break; |
1378 s = s->outer_scope(); | 1378 s = s->outer_scope(); |
1379 } | 1379 } |
1380 | 1380 |
1381 if (s->is_eval_scope()) { | 1381 if (s->is_eval_scope()) { |
1382 Label loop, fast; | 1382 Label loop, fast; |
1383 if (!current.is(next)) { | 1383 if (!current.is(next)) { |
1384 __ Move(next, current); | 1384 __ Move(next, current); |
1385 } | 1385 } |
1386 __ bind(&loop); | 1386 __ bind(&loop); |
1387 // Terminate at native context. | 1387 // Terminate at native context. |
(...skipping 22 matching lines...) Expand all Loading... |
1410 | 1410 |
1411 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, | 1411 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, |
1412 Label* slow) { | 1412 Label* slow) { |
1413 ASSERT(var->IsContextSlot()); | 1413 ASSERT(var->IsContextSlot()); |
1414 Register context = cp; | 1414 Register context = cp; |
1415 Register next = r3; | 1415 Register next = r3; |
1416 Register temp = r4; | 1416 Register temp = r4; |
1417 | 1417 |
1418 for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) { | 1418 for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) { |
1419 if (s->num_heap_slots() > 0) { | 1419 if (s->num_heap_slots() > 0) { |
1420 if (s->calls_non_strict_eval()) { | 1420 if (s->calls_sloppy_eval()) { |
1421 // Check that extension is NULL. | 1421 // Check that extension is NULL. |
1422 __ ldr(temp, ContextOperand(context, Context::EXTENSION_INDEX)); | 1422 __ ldr(temp, ContextOperand(context, Context::EXTENSION_INDEX)); |
1423 __ tst(temp, temp); | 1423 __ tst(temp, temp); |
1424 __ b(ne, slow); | 1424 __ b(ne, slow); |
1425 } | 1425 } |
1426 __ ldr(next, ContextOperand(context, Context::PREVIOUS_INDEX)); | 1426 __ ldr(next, ContextOperand(context, Context::PREVIOUS_INDEX)); |
1427 // Walk the rest of the chain without clobbering cp. | 1427 // Walk the rest of the chain without clobbering cp. |
1428 context = next; | 1428 context = next; |
1429 } | 1429 } |
1430 } | 1430 } |
(...skipping 1007 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2438 __ mov(r2, Operand(prop->key()->AsLiteral()->value())); | 2438 __ mov(r2, Operand(prop->key()->AsLiteral()->value())); |
2439 CallStoreIC(); | 2439 CallStoreIC(); |
2440 break; | 2440 break; |
2441 } | 2441 } |
2442 case KEYED_PROPERTY: { | 2442 case KEYED_PROPERTY: { |
2443 __ push(r0); // Preserve value. | 2443 __ push(r0); // Preserve value. |
2444 VisitForStackValue(prop->obj()); | 2444 VisitForStackValue(prop->obj()); |
2445 VisitForAccumulatorValue(prop->key()); | 2445 VisitForAccumulatorValue(prop->key()); |
2446 __ mov(r1, r0); | 2446 __ mov(r1, r0); |
2447 __ Pop(r0, r2); // r0 = restored value. | 2447 __ Pop(r0, r2); // r0 = restored value. |
2448 Handle<Code> ic = is_classic_mode() | 2448 Handle<Code> ic = is_sloppy_mode() |
2449 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 2449 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
2450 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 2450 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
2451 CallIC(ic); | 2451 CallIC(ic); |
2452 break; | 2452 break; |
2453 } | 2453 } |
2454 } | 2454 } |
2455 context()->Plug(r0); | 2455 context()->Plug(r0); |
2456 } | 2456 } |
2457 | 2457 |
2458 | 2458 |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2564 } | 2564 } |
2565 | 2565 |
2566 | 2566 |
2567 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 2567 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
2568 // Assignment to a property, using a keyed store IC. | 2568 // Assignment to a property, using a keyed store IC. |
2569 | 2569 |
2570 // Record source code position before IC call. | 2570 // Record source code position before IC call. |
2571 SetSourcePosition(expr->position()); | 2571 SetSourcePosition(expr->position()); |
2572 __ Pop(r2, r1); // r1 = key. | 2572 __ Pop(r2, r1); // r1 = key. |
2573 | 2573 |
2574 Handle<Code> ic = is_classic_mode() | 2574 Handle<Code> ic = is_sloppy_mode() |
2575 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 2575 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
2576 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 2576 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
2577 CallIC(ic, expr->AssignmentFeedbackId()); | 2577 CallIC(ic, expr->AssignmentFeedbackId()); |
2578 | 2578 |
2579 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2579 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2580 context()->Plug(r0); | 2580 context()->Plug(r0); |
2581 } | 2581 } |
2582 | 2582 |
2583 | 2583 |
2584 void FullCodeGenerator::VisitProperty(Property* expr) { | 2584 void FullCodeGenerator::VisitProperty(Property* expr) { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2617 int arg_count = args->length(); | 2617 int arg_count = args->length(); |
2618 | 2618 |
2619 CallFunctionFlags flags; | 2619 CallFunctionFlags flags; |
2620 // Get the target function. | 2620 // Get the target function. |
2621 if (callee->IsVariableProxy()) { | 2621 if (callee->IsVariableProxy()) { |
2622 { StackValueContext context(this); | 2622 { StackValueContext context(this); |
2623 EmitVariableLoad(callee->AsVariableProxy()); | 2623 EmitVariableLoad(callee->AsVariableProxy()); |
2624 PrepareForBailout(callee, NO_REGISTERS); | 2624 PrepareForBailout(callee, NO_REGISTERS); |
2625 } | 2625 } |
2626 // Push undefined as receiver. This is patched in the method prologue if it | 2626 // Push undefined as receiver. This is patched in the method prologue if it |
2627 // is a classic mode method. | 2627 // is a sloppy mode method. |
2628 __ Push(isolate()->factory()->undefined_value()); | 2628 __ Push(isolate()->factory()->undefined_value()); |
2629 flags = NO_CALL_FUNCTION_FLAGS; | 2629 flags = NO_CALL_FUNCTION_FLAGS; |
2630 } else { | 2630 } else { |
2631 // Load the function from the receiver. | 2631 // Load the function from the receiver. |
2632 ASSERT(callee->IsProperty()); | 2632 ASSERT(callee->IsProperty()); |
2633 __ ldr(r0, MemOperand(sp, 0)); | 2633 __ ldr(r0, MemOperand(sp, 0)); |
2634 EmitNamedPropertyLoad(callee->AsProperty()); | 2634 EmitNamedPropertyLoad(callee->AsProperty()); |
2635 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2635 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
2636 // Push the target function under the receiver. | 2636 // Push the target function under the receiver. |
2637 __ ldr(ip, MemOperand(sp, 0)); | 2637 __ ldr(ip, MemOperand(sp, 0)); |
(...skipping 1540 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4178 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { | 4178 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { |
4179 switch (expr->op()) { | 4179 switch (expr->op()) { |
4180 case Token::DELETE: { | 4180 case Token::DELETE: { |
4181 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); | 4181 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); |
4182 Property* property = expr->expression()->AsProperty(); | 4182 Property* property = expr->expression()->AsProperty(); |
4183 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 4183 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
4184 | 4184 |
4185 if (property != NULL) { | 4185 if (property != NULL) { |
4186 VisitForStackValue(property->obj()); | 4186 VisitForStackValue(property->obj()); |
4187 VisitForStackValue(property->key()); | 4187 VisitForStackValue(property->key()); |
4188 StrictModeFlag strict_mode_flag = (language_mode() == CLASSIC_MODE) | 4188 StrictModeFlag strict_mode_flag = (language_mode() == SLOPPY_MODE) |
4189 ? kNonStrictMode : kStrictMode; | 4189 ? kSloppyMode : kStrictMode; |
4190 __ mov(r1, Operand(Smi::FromInt(strict_mode_flag))); | 4190 __ mov(r1, Operand(Smi::FromInt(strict_mode_flag))); |
4191 __ push(r1); | 4191 __ push(r1); |
4192 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); | 4192 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); |
4193 context()->Plug(r0); | 4193 context()->Plug(r0); |
4194 } else if (proxy != NULL) { | 4194 } else if (proxy != NULL) { |
4195 Variable* var = proxy->var(); | 4195 Variable* var = proxy->var(); |
4196 // Delete of an unqualified identifier is disallowed in strict mode | 4196 // Delete of an unqualified identifier is disallowed in strict mode |
4197 // but "delete this" is allowed. | 4197 // but "delete this" is allowed. |
4198 ASSERT(language_mode() == CLASSIC_MODE || var->is_this()); | 4198 ASSERT(language_mode() == SLOPPY_MODE || var->is_this()); |
4199 if (var->IsUnallocated()) { | 4199 if (var->IsUnallocated()) { |
4200 __ ldr(r2, GlobalObjectOperand()); | 4200 __ ldr(r2, GlobalObjectOperand()); |
4201 __ mov(r1, Operand(var->name())); | 4201 __ mov(r1, Operand(var->name())); |
4202 __ mov(r0, Operand(Smi::FromInt(kNonStrictMode))); | 4202 __ mov(r0, Operand(Smi::FromInt(kSloppyMode))); |
4203 __ Push(r2, r1, r0); | 4203 __ Push(r2, r1, r0); |
4204 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); | 4204 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); |
4205 context()->Plug(r0); | 4205 context()->Plug(r0); |
4206 } else if (var->IsStackAllocated() || var->IsContextSlot()) { | 4206 } else if (var->IsStackAllocated() || var->IsContextSlot()) { |
4207 // Result of deleting non-global, non-dynamic variables is false. | 4207 // Result of deleting non-global, non-dynamic variables is false. |
4208 // The subexpression does not have side effects. | 4208 // The subexpression does not have side effects. |
4209 context()->Plug(var->is_this()); | 4209 context()->Plug(var->is_this()); |
4210 } else { | 4210 } else { |
4211 // Non-global variable. Call the runtime to try to delete from the | 4211 // Non-global variable. Call the runtime to try to delete from the |
4212 // context where the variable was introduced. | 4212 // context where the variable was introduced. |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4446 if (!context()->IsEffect()) { | 4446 if (!context()->IsEffect()) { |
4447 context()->PlugTOS(); | 4447 context()->PlugTOS(); |
4448 } | 4448 } |
4449 } else { | 4449 } else { |
4450 context()->Plug(r0); | 4450 context()->Plug(r0); |
4451 } | 4451 } |
4452 break; | 4452 break; |
4453 } | 4453 } |
4454 case KEYED_PROPERTY: { | 4454 case KEYED_PROPERTY: { |
4455 __ Pop(r2, r1); // r1 = key. r2 = receiver. | 4455 __ Pop(r2, r1); // r1 = key. r2 = receiver. |
4456 Handle<Code> ic = is_classic_mode() | 4456 Handle<Code> ic = is_sloppy_mode() |
4457 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 4457 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
4458 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 4458 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
4459 CallIC(ic, expr->CountStoreFeedbackId()); | 4459 CallIC(ic, expr->CountStoreFeedbackId()); |
4460 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4460 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
4461 if (expr->is_postfix()) { | 4461 if (expr->is_postfix()) { |
4462 if (!context()->IsEffect()) { | 4462 if (!context()->IsEffect()) { |
4463 context()->PlugTOS(); | 4463 context()->PlugTOS(); |
4464 } | 4464 } |
4465 } else { | 4465 } else { |
4466 context()->Plug(r0); | 4466 context()->Plug(r0); |
(...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4918 ASSERT(Memory::uint32_at(interrupt_address_pointer) == | 4918 ASSERT(Memory::uint32_at(interrupt_address_pointer) == |
4919 reinterpret_cast<uint32_t>( | 4919 reinterpret_cast<uint32_t>( |
4920 isolate->builtins()->OsrAfterStackCheck()->entry())); | 4920 isolate->builtins()->OsrAfterStackCheck()->entry())); |
4921 return OSR_AFTER_STACK_CHECK; | 4921 return OSR_AFTER_STACK_CHECK; |
4922 } | 4922 } |
4923 | 4923 |
4924 | 4924 |
4925 } } // namespace v8::internal | 4925 } } // namespace v8::internal |
4926 | 4926 |
4927 #endif // V8_TARGET_ARCH_ARM | 4927 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |