OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_ARM | 7 #if V8_TARGET_ARCH_ARM |
8 | 8 |
9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 1985 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1996 case VARIABLE: | 1996 case VARIABLE: |
1997 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), | 1997 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), |
1998 expr->op()); | 1998 expr->op()); |
1999 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 1999 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2000 context()->Plug(r0); | 2000 context()->Plug(r0); |
2001 break; | 2001 break; |
2002 case NAMED_PROPERTY: | 2002 case NAMED_PROPERTY: |
2003 EmitNamedPropertyAssignment(expr); | 2003 EmitNamedPropertyAssignment(expr); |
2004 break; | 2004 break; |
2005 case NAMED_SUPER_PROPERTY: | 2005 case NAMED_SUPER_PROPERTY: |
2006 EmitNamedSuperPropertyAssignment(expr); | 2006 EmitNamedSuperPropertyStore(property); |
| 2007 context()->Plug(r0); |
2007 break; | 2008 break; |
2008 case KEYED_PROPERTY: | 2009 case KEYED_PROPERTY: |
2009 EmitKeyedPropertyAssignment(expr); | 2010 EmitKeyedPropertyAssignment(expr); |
2010 break; | 2011 break; |
2011 } | 2012 } |
2012 } | 2013 } |
2013 | 2014 |
2014 | 2015 |
2015 void FullCodeGenerator::VisitYield(Yield* expr) { | 2016 void FullCodeGenerator::VisitYield(Yield* expr) { |
2016 Comment cmnt(masm_, "[ Yield"); | 2017 Comment cmnt(masm_, "[ Yield"); |
(...skipping 610 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2627 __ mov(StoreDescriptor::NameRegister(), | 2628 __ mov(StoreDescriptor::NameRegister(), |
2628 Operand(prop->key()->AsLiteral()->value())); | 2629 Operand(prop->key()->AsLiteral()->value())); |
2629 __ pop(StoreDescriptor::ReceiverRegister()); | 2630 __ pop(StoreDescriptor::ReceiverRegister()); |
2630 CallStoreIC(expr->AssignmentFeedbackId()); | 2631 CallStoreIC(expr->AssignmentFeedbackId()); |
2631 | 2632 |
2632 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2633 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2633 context()->Plug(r0); | 2634 context()->Plug(r0); |
2634 } | 2635 } |
2635 | 2636 |
2636 | 2637 |
2637 void FullCodeGenerator::EmitNamedSuperPropertyAssignment(Assignment* expr) { | 2638 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { |
2638 // Assignment to named property of super. | 2639 // Assignment to named property of super. |
2639 // r0 : value | 2640 // r0 : value |
2640 // stack : receiver ('this'), home_object | 2641 // stack : receiver ('this'), home_object |
2641 Property* prop = expr->target()->AsProperty(); | |
2642 DCHECK(prop != NULL); | 2642 DCHECK(prop != NULL); |
2643 Literal* key = prop->key()->AsLiteral(); | 2643 Literal* key = prop->key()->AsLiteral(); |
2644 DCHECK(key != NULL); | 2644 DCHECK(key != NULL); |
2645 | 2645 |
2646 __ Push(r0); | 2646 __ Push(r0); |
2647 __ Push(key->value()); | 2647 __ Push(key->value()); |
2648 __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreToSuper_Strict | 2648 __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreToSuper_Strict |
2649 : Runtime::kStoreToSuper_Sloppy), | 2649 : Runtime::kStoreToSuper_Sloppy), |
2650 4); | 2650 4); |
2651 context()->Plug(r0); | |
2652 } | 2651 } |
2653 | 2652 |
2654 | 2653 |
2655 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 2654 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
2656 // Assignment to a property, using a keyed store IC. | 2655 // Assignment to a property, using a keyed store IC. |
2657 | 2656 |
2658 // Record source code position before IC call. | 2657 // Record source code position before IC call. |
2659 SetSourcePosition(expr->position()); | 2658 SetSourcePosition(expr->position()); |
2660 __ Pop(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister()); | 2659 __ Pop(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister()); |
2661 DCHECK(StoreDescriptor::ValueRegister().is(r0)); | 2660 DCHECK(StoreDescriptor::ValueRegister().is(r0)); |
(...skipping 1705 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4367 | 4366 |
4368 | 4367 |
4369 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { | 4368 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { |
4370 DCHECK(expr->expression()->IsValidReferenceExpression()); | 4369 DCHECK(expr->expression()->IsValidReferenceExpression()); |
4371 | 4370 |
4372 Comment cmnt(masm_, "[ CountOperation"); | 4371 Comment cmnt(masm_, "[ CountOperation"); |
4373 SetSourcePosition(expr->position()); | 4372 SetSourcePosition(expr->position()); |
4374 | 4373 |
4375 // Expression can only be a property, a global or a (parameter or local) | 4374 // Expression can only be a property, a global or a (parameter or local) |
4376 // slot. | 4375 // slot. |
4377 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; | 4376 enum LhsKind { |
| 4377 VARIABLE, |
| 4378 NAMED_PROPERTY, |
| 4379 KEYED_PROPERTY, |
| 4380 NAMED_SUPER_PROPERTY |
| 4381 }; |
4378 LhsKind assign_type = VARIABLE; | 4382 LhsKind assign_type = VARIABLE; |
4379 Property* prop = expr->expression()->AsProperty(); | 4383 Property* prop = expr->expression()->AsProperty(); |
4380 // In case of a property we use the uninitialized expression context | 4384 // In case of a property we use the uninitialized expression context |
4381 // of the key to detect a named property. | 4385 // of the key to detect a named property. |
4382 if (prop != NULL) { | 4386 if (prop != NULL) { |
4383 assign_type = | 4387 assign_type = |
4384 (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY; | 4388 (prop->key()->IsPropertyName()) |
4385 if (prop->IsSuperAccess()) { | 4389 ? (prop->IsSuperAccess() ? NAMED_SUPER_PROPERTY : NAMED_PROPERTY) |
4386 // throw exception. | 4390 : KEYED_PROPERTY; |
4387 VisitSuperReference(prop->obj()->AsSuperReference()); | |
4388 return; | |
4389 } | |
4390 } | 4391 } |
4391 | 4392 |
4392 // Evaluate expression and get value. | 4393 // Evaluate expression and get value. |
4393 if (assign_type == VARIABLE) { | 4394 if (assign_type == VARIABLE) { |
4394 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); | 4395 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); |
4395 AccumulatorValueContext context(this); | 4396 AccumulatorValueContext context(this); |
4396 EmitVariableLoad(expr->expression()->AsVariableProxy()); | 4397 EmitVariableLoad(expr->expression()->AsVariableProxy()); |
4397 } else { | 4398 } else { |
4398 // Reserve space for result of postfix operation. | 4399 // Reserve space for result of postfix operation. |
4399 if (expr->is_postfix() && !context()->IsEffect()) { | 4400 if (expr->is_postfix() && !context()->IsEffect()) { |
4400 __ mov(ip, Operand(Smi::FromInt(0))); | 4401 __ mov(ip, Operand(Smi::FromInt(0))); |
4401 __ push(ip); | 4402 __ push(ip); |
4402 } | 4403 } |
4403 if (assign_type == NAMED_PROPERTY) { | 4404 if (assign_type == NAMED_PROPERTY) { |
4404 // Put the object both on the stack and in the register. | 4405 // Put the object both on the stack and in the register. |
4405 VisitForStackValue(prop->obj()); | 4406 VisitForStackValue(prop->obj()); |
4406 __ ldr(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); | 4407 __ ldr(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); |
4407 EmitNamedPropertyLoad(prop); | 4408 EmitNamedPropertyLoad(prop); |
| 4409 } else if (assign_type == NAMED_SUPER_PROPERTY) { |
| 4410 VisitForStackValue(prop->obj()->AsSuperReference()->this_var()); |
| 4411 EmitLoadHomeObject(prop->obj()->AsSuperReference()); |
| 4412 __ Push(result_register()); |
| 4413 const Register scratch = r1; |
| 4414 __ ldr(scratch, MemOperand(sp, kPointerSize)); |
| 4415 __ Push(scratch); |
| 4416 __ Push(result_register()); |
| 4417 EmitNamedSuperPropertyLoad(prop); |
4408 } else { | 4418 } else { |
4409 VisitForStackValue(prop->obj()); | 4419 VisitForStackValue(prop->obj()); |
4410 VisitForStackValue(prop->key()); | 4420 VisitForStackValue(prop->key()); |
4411 __ ldr(LoadDescriptor::ReceiverRegister(), | 4421 __ ldr(LoadDescriptor::ReceiverRegister(), |
4412 MemOperand(sp, 1 * kPointerSize)); | 4422 MemOperand(sp, 1 * kPointerSize)); |
4413 __ ldr(LoadDescriptor::NameRegister(), MemOperand(sp, 0)); | 4423 __ ldr(LoadDescriptor::NameRegister(), MemOperand(sp, 0)); |
4414 EmitKeyedPropertyLoad(prop); | 4424 EmitKeyedPropertyLoad(prop); |
4415 } | 4425 } |
4416 } | 4426 } |
4417 | 4427 |
(...skipping 20 matching lines...) Expand all Loading... |
4438 // Save the result on the stack. If we have a named or keyed property | 4448 // Save the result on the stack. If we have a named or keyed property |
4439 // we store the result under the receiver that is currently on top | 4449 // we store the result under the receiver that is currently on top |
4440 // of the stack. | 4450 // of the stack. |
4441 switch (assign_type) { | 4451 switch (assign_type) { |
4442 case VARIABLE: | 4452 case VARIABLE: |
4443 __ push(r0); | 4453 __ push(r0); |
4444 break; | 4454 break; |
4445 case NAMED_PROPERTY: | 4455 case NAMED_PROPERTY: |
4446 __ str(r0, MemOperand(sp, kPointerSize)); | 4456 __ str(r0, MemOperand(sp, kPointerSize)); |
4447 break; | 4457 break; |
| 4458 case NAMED_SUPER_PROPERTY: |
| 4459 __ str(r0, MemOperand(sp, 2 * kPointerSize)); |
| 4460 break; |
4448 case KEYED_PROPERTY: | 4461 case KEYED_PROPERTY: |
4449 __ str(r0, MemOperand(sp, 2 * kPointerSize)); | 4462 __ str(r0, MemOperand(sp, 2 * kPointerSize)); |
4450 break; | 4463 break; |
4451 } | 4464 } |
4452 } | 4465 } |
4453 } | 4466 } |
4454 | 4467 |
4455 __ add(r0, r0, Operand(Smi::FromInt(count_value)), SetCC); | 4468 __ add(r0, r0, Operand(Smi::FromInt(count_value)), SetCC); |
4456 __ b(vc, &done); | 4469 __ b(vc, &done); |
4457 // Call stub. Undo operation first. | 4470 // Call stub. Undo operation first. |
(...skipping 10 matching lines...) Expand all Loading... |
4468 // Save the result on the stack. If we have a named or keyed property | 4481 // Save the result on the stack. If we have a named or keyed property |
4469 // we store the result under the receiver that is currently on top | 4482 // we store the result under the receiver that is currently on top |
4470 // of the stack. | 4483 // of the stack. |
4471 switch (assign_type) { | 4484 switch (assign_type) { |
4472 case VARIABLE: | 4485 case VARIABLE: |
4473 __ push(r0); | 4486 __ push(r0); |
4474 break; | 4487 break; |
4475 case NAMED_PROPERTY: | 4488 case NAMED_PROPERTY: |
4476 __ str(r0, MemOperand(sp, kPointerSize)); | 4489 __ str(r0, MemOperand(sp, kPointerSize)); |
4477 break; | 4490 break; |
| 4491 case NAMED_SUPER_PROPERTY: |
| 4492 __ str(r0, MemOperand(sp, 2 * kPointerSize)); |
| 4493 break; |
4478 case KEYED_PROPERTY: | 4494 case KEYED_PROPERTY: |
4479 __ str(r0, MemOperand(sp, 2 * kPointerSize)); | 4495 __ str(r0, MemOperand(sp, 2 * kPointerSize)); |
4480 break; | 4496 break; |
4481 } | 4497 } |
4482 } | 4498 } |
4483 } | 4499 } |
4484 | 4500 |
4485 | 4501 |
4486 __ bind(&stub_call); | 4502 __ bind(&stub_call); |
4487 __ mov(r1, r0); | 4503 __ mov(r1, r0); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4526 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4542 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
4527 if (expr->is_postfix()) { | 4543 if (expr->is_postfix()) { |
4528 if (!context()->IsEffect()) { | 4544 if (!context()->IsEffect()) { |
4529 context()->PlugTOS(); | 4545 context()->PlugTOS(); |
4530 } | 4546 } |
4531 } else { | 4547 } else { |
4532 context()->Plug(r0); | 4548 context()->Plug(r0); |
4533 } | 4549 } |
4534 break; | 4550 break; |
4535 } | 4551 } |
| 4552 case NAMED_SUPER_PROPERTY: { |
| 4553 EmitNamedSuperPropertyStore(prop); |
| 4554 if (expr->is_postfix()) { |
| 4555 if (!context()->IsEffect()) { |
| 4556 context()->PlugTOS(); |
| 4557 } |
| 4558 } else { |
| 4559 context()->Plug(r0); |
| 4560 } |
| 4561 break; |
| 4562 } |
4536 case KEYED_PROPERTY: { | 4563 case KEYED_PROPERTY: { |
4537 __ Pop(StoreDescriptor::ReceiverRegister(), | 4564 __ Pop(StoreDescriptor::ReceiverRegister(), |
4538 StoreDescriptor::NameRegister()); | 4565 StoreDescriptor::NameRegister()); |
4539 Handle<Code> ic = | 4566 Handle<Code> ic = |
4540 CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code(); | 4567 CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code(); |
4541 CallIC(ic, expr->CountStoreFeedbackId()); | 4568 CallIC(ic, expr->CountStoreFeedbackId()); |
4542 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4569 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
4543 if (expr->is_postfix()) { | 4570 if (expr->is_postfix()) { |
4544 if (!context()->IsEffect()) { | 4571 if (!context()->IsEffect()) { |
4545 context()->PlugTOS(); | 4572 context()->PlugTOS(); |
(...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5056 | 5083 |
5057 DCHECK(interrupt_address == | 5084 DCHECK(interrupt_address == |
5058 isolate->builtins()->OsrAfterStackCheck()->entry()); | 5085 isolate->builtins()->OsrAfterStackCheck()->entry()); |
5059 return OSR_AFTER_STACK_CHECK; | 5086 return OSR_AFTER_STACK_CHECK; |
5060 } | 5087 } |
5061 | 5088 |
5062 | 5089 |
5063 } } // namespace v8::internal | 5090 } } // namespace v8::internal |
5064 | 5091 |
5065 #endif // V8_TARGET_ARCH_ARM | 5092 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |