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-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 837 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
848 // Note: For variables we must not push an initial value (such as | 848 // Note: For variables we must not push an initial value (such as |
849 // 'undefined') because we may have a (legal) redeclaration and we | 849 // 'undefined') because we may have a (legal) redeclaration and we |
850 // must not destroy the current value. | 850 // must not destroy the current value. |
851 if (hole_init) { | 851 if (hole_init) { |
852 __ LoadRoot(r0, Heap::kTheHoleValueRootIndex); | 852 __ LoadRoot(r0, Heap::kTheHoleValueRootIndex); |
853 __ Push(cp, r2, r1, r0); | 853 __ Push(cp, r2, r1, r0); |
854 } else { | 854 } else { |
855 __ mov(r0, Operand(Smi::FromInt(0))); // Indicates no initial value. | 855 __ mov(r0, Operand(Smi::FromInt(0))); // Indicates no initial value. |
856 __ Push(cp, r2, r1, r0); | 856 __ Push(cp, r2, r1, r0); |
857 } | 857 } |
858 __ CallRuntime(Runtime::kDeclareContextSlot, 4); | 858 __ CallRuntime(Runtime::kDeclareLookupSlot, 4); |
859 break; | 859 break; |
860 } | 860 } |
861 } | 861 } |
862 } | 862 } |
863 | 863 |
864 | 864 |
865 void FullCodeGenerator::VisitFunctionDeclaration( | 865 void FullCodeGenerator::VisitFunctionDeclaration( |
866 FunctionDeclaration* declaration) { | 866 FunctionDeclaration* declaration) { |
867 VariableProxy* proxy = declaration->proxy(); | 867 VariableProxy* proxy = declaration->proxy(); |
868 Variable* variable = proxy->var(); | 868 Variable* variable = proxy->var(); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
904 break; | 904 break; |
905 } | 905 } |
906 | 906 |
907 case Variable::LOOKUP: { | 907 case Variable::LOOKUP: { |
908 Comment cmnt(masm_, "[ FunctionDeclaration"); | 908 Comment cmnt(masm_, "[ FunctionDeclaration"); |
909 __ mov(r2, Operand(variable->name())); | 909 __ mov(r2, Operand(variable->name())); |
910 __ mov(r1, Operand(Smi::FromInt(NONE))); | 910 __ mov(r1, Operand(Smi::FromInt(NONE))); |
911 __ Push(cp, r2, r1); | 911 __ Push(cp, r2, r1); |
912 // Push initial value for function declaration. | 912 // Push initial value for function declaration. |
913 VisitForStackValue(declaration->fun()); | 913 VisitForStackValue(declaration->fun()); |
914 __ CallRuntime(Runtime::kDeclareContextSlot, 4); | 914 __ CallRuntime(Runtime::kDeclareLookupSlot, 4); |
915 break; | 915 break; |
916 } | 916 } |
917 } | 917 } |
918 } | 918 } |
919 | 919 |
920 | 920 |
921 void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) { | 921 void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) { |
922 Variable* variable = declaration->proxy()->var(); | 922 Variable* variable = declaration->proxy()->var(); |
923 ASSERT(variable->location() == Variable::CONTEXT); | 923 ASSERT(variable->location() == Variable::CONTEXT); |
924 ASSERT(variable->interface()->IsFrozen()); | 924 ASSERT(variable->interface()->IsFrozen()); |
(...skipping 1524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2449 if (var->IsContextSlot()) { | 2449 if (var->IsContextSlot()) { |
2450 // RecordWrite may destroy all its register arguments. | 2450 // RecordWrite may destroy all its register arguments. |
2451 __ mov(r3, result_register()); | 2451 __ mov(r3, result_register()); |
2452 int offset = Context::SlotOffset(var->index()); | 2452 int offset = Context::SlotOffset(var->index()); |
2453 __ RecordWriteContextSlot( | 2453 __ RecordWriteContextSlot( |
2454 r1, offset, r3, r2, kLRHasBeenSaved, kDontSaveFPRegs); | 2454 r1, offset, r3, r2, kLRHasBeenSaved, kDontSaveFPRegs); |
2455 } | 2455 } |
2456 } | 2456 } |
2457 | 2457 |
2458 | 2458 |
2459 void FullCodeGenerator::EmitCallStoreContextSlot( | |
2460 Handle<String> name, StrictMode strict_mode) { | |
2461 __ push(r0); // Value. | |
2462 __ mov(r1, Operand(name)); | |
2463 __ mov(r0, Operand(Smi::FromInt(strict_mode))); | |
2464 __ Push(cp, r1, r0); // Context, name, strict mode. | |
2465 __ CallRuntime(Runtime::kStoreContextSlot, 4); | |
2466 } | |
2467 | |
2468 | |
2469 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op) { | 2459 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op) { |
2470 if (var->IsUnallocated()) { | 2460 if (var->IsUnallocated()) { |
2471 // Global var, const, or let. | 2461 // Global var, const, or let. |
2472 __ mov(r2, Operand(var->name())); | 2462 __ mov(r2, Operand(var->name())); |
2473 __ ldr(r1, GlobalObjectOperand()); | 2463 __ ldr(r1, GlobalObjectOperand()); |
2474 CallStoreIC(); | 2464 CallStoreIC(); |
2475 | 2465 |
2476 } else if (op == Token::INIT_CONST_LEGACY) { | 2466 } else if (op == Token::INIT_CONST_LEGACY) { |
2477 // Const initializers need a write barrier. | 2467 // Const initializers need a write barrier. |
2478 ASSERT(!var->IsParameter()); // No const parameters. | 2468 ASSERT(!var->IsParameter()); // No const parameters. |
2479 if (var->IsLookupSlot()) { | 2469 if (var->IsLookupSlot()) { |
2480 __ push(r0); | 2470 __ push(r0); |
2481 __ mov(r0, Operand(var->name())); | 2471 __ mov(r0, Operand(var->name())); |
2482 __ Push(cp, r0); // Context and name. | 2472 __ Push(cp, r0); // Context and name. |
2483 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3); | 2473 __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, 3); |
2484 } else { | 2474 } else { |
2485 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); | 2475 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); |
2486 Label skip; | 2476 Label skip; |
2487 MemOperand location = VarOperand(var, r1); | 2477 MemOperand location = VarOperand(var, r1); |
2488 __ ldr(r2, location); | 2478 __ ldr(r2, location); |
2489 __ CompareRoot(r2, Heap::kTheHoleValueRootIndex); | 2479 __ CompareRoot(r2, Heap::kTheHoleValueRootIndex); |
2490 __ b(ne, &skip); | 2480 __ b(ne, &skip); |
2491 EmitStoreToStackLocalOrContextSlot(var, location); | 2481 EmitStoreToStackLocalOrContextSlot(var, location); |
2492 __ bind(&skip); | 2482 __ bind(&skip); |
2493 } | 2483 } |
2494 | 2484 |
2495 } else if (var->mode() == LET && op != Token::INIT_LET) { | 2485 } else if (var->mode() == LET && op != Token::INIT_LET) { |
2496 // Non-initializing assignment to let variable needs a write barrier. | 2486 // Non-initializing assignment to let variable needs a write barrier. |
2497 if (var->IsLookupSlot()) { | 2487 ASSERT(!var->IsLookupSlot()); |
2498 EmitCallStoreContextSlot(var->name(), strict_mode()); | 2488 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); |
2499 } else { | 2489 Label assign; |
2500 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); | 2490 MemOperand location = VarOperand(var, r1); |
2501 Label assign; | 2491 __ ldr(r3, location); |
2502 MemOperand location = VarOperand(var, r1); | 2492 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex); |
2503 __ ldr(r3, location); | 2493 __ b(ne, &assign); |
2504 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex); | 2494 __ mov(r3, Operand(var->name())); |
2505 __ b(ne, &assign); | 2495 __ push(r3); |
2506 __ mov(r3, Operand(var->name())); | 2496 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
2507 __ push(r3); | 2497 // Perform the assignment. |
2508 __ CallRuntime(Runtime::kThrowReferenceError, 1); | 2498 __ bind(&assign); |
2509 // Perform the assignment. | 2499 EmitStoreToStackLocalOrContextSlot(var, location); |
2510 __ bind(&assign); | |
2511 EmitStoreToStackLocalOrContextSlot(var, location); | |
2512 } | |
2513 | 2500 |
2514 } else if (!var->is_const_mode() || op == Token::INIT_CONST) { | 2501 } else if (!var->is_const_mode() || op == Token::INIT_CONST) { |
2515 // Assignment to var or initializing assignment to let/const | |
2516 // in harmony mode. | |
2517 if (var->IsLookupSlot()) { | 2502 if (var->IsLookupSlot()) { |
2518 EmitCallStoreContextSlot(var->name(), strict_mode()); | 2503 ASSERT(op == Token::ASSIGN || op == Token::INIT_VAR || |
| 2504 op == Token::ASSIGN_ADD); |
| 2505 // Assignment to var. |
| 2506 __ push(r0); // Value. |
| 2507 __ mov(r1, Operand(var->name())); |
| 2508 __ mov(r0, Operand(Smi::FromInt(strict_mode()))); |
| 2509 __ Push(cp, r1, r0); // Context, name, strict mode. |
| 2510 __ CallRuntime(Runtime::kStoreLookupSlot, 4); |
2519 } else { | 2511 } else { |
| 2512 // Assignment to var or initializing assignment to let/const in harmony |
| 2513 // mode. |
2520 ASSERT((var->IsStackAllocated() || var->IsContextSlot())); | 2514 ASSERT((var->IsStackAllocated() || var->IsContextSlot())); |
2521 MemOperand location = VarOperand(var, r1); | 2515 MemOperand location = VarOperand(var, r1); |
2522 if (generate_debug_code_ && op == Token::INIT_LET) { | 2516 if (generate_debug_code_ && op == Token::INIT_LET) { |
2523 // Check for an uninitialized let binding. | 2517 // Check for an uninitialized let binding. |
2524 __ ldr(r2, location); | 2518 __ ldr(r2, location); |
2525 __ CompareRoot(r2, Heap::kTheHoleValueRootIndex); | 2519 __ CompareRoot(r2, Heap::kTheHoleValueRootIndex); |
2526 __ Check(eq, kLetBindingReInitialization); | 2520 __ Check(eq, kLetBindingReInitialization); |
2527 } | 2521 } |
2528 EmitStoreToStackLocalOrContextSlot(var, location); | 2522 EmitStoreToStackLocalOrContextSlot(var, location); |
2529 } | 2523 } |
(...skipping 2329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4859 | 4853 |
4860 ASSERT(interrupt_address == | 4854 ASSERT(interrupt_address == |
4861 isolate->builtins()->OsrAfterStackCheck()->entry()); | 4855 isolate->builtins()->OsrAfterStackCheck()->entry()); |
4862 return OSR_AFTER_STACK_CHECK; | 4856 return OSR_AFTER_STACK_CHECK; |
4863 } | 4857 } |
4864 | 4858 |
4865 | 4859 |
4866 } } // namespace v8::internal | 4860 } } // namespace v8::internal |
4867 | 4861 |
4868 #endif // V8_TARGET_ARCH_ARM | 4862 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |