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_MIPS64 | 7 #if V8_TARGET_ARCH_MIPS64 |
8 | 8 |
9 // Note on Mips implementation: | 9 // Note on Mips implementation: |
10 // | 10 // |
(...skipping 834 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
845 // 'undefined') because we may have a (legal) redeclaration and we | 845 // 'undefined') because we may have a (legal) redeclaration and we |
846 // must not destroy the current value. | 846 // must not destroy the current value. |
847 if (hole_init) { | 847 if (hole_init) { |
848 __ LoadRoot(a0, Heap::kTheHoleValueRootIndex); | 848 __ LoadRoot(a0, Heap::kTheHoleValueRootIndex); |
849 __ Push(cp, a2, a1, a0); | 849 __ Push(cp, a2, a1, a0); |
850 } else { | 850 } else { |
851 ASSERT(Smi::FromInt(0) == 0); | 851 ASSERT(Smi::FromInt(0) == 0); |
852 __ mov(a0, zero_reg); // Smi::FromInt(0) indicates no initial value. | 852 __ mov(a0, zero_reg); // Smi::FromInt(0) indicates no initial value. |
853 __ Push(cp, a2, a1, a0); | 853 __ Push(cp, a2, a1, a0); |
854 } | 854 } |
855 __ CallRuntime(Runtime::kDeclareContextSlot, 4); | 855 __ CallRuntime(Runtime::kDeclareLookupSlot, 4); |
856 break; | 856 break; |
857 } | 857 } |
858 } | 858 } |
859 } | 859 } |
860 | 860 |
861 | 861 |
862 void FullCodeGenerator::VisitFunctionDeclaration( | 862 void FullCodeGenerator::VisitFunctionDeclaration( |
863 FunctionDeclaration* declaration) { | 863 FunctionDeclaration* declaration) { |
864 VariableProxy* proxy = declaration->proxy(); | 864 VariableProxy* proxy = declaration->proxy(); |
865 Variable* variable = proxy->var(); | 865 Variable* variable = proxy->var(); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
901 break; | 901 break; |
902 } | 902 } |
903 | 903 |
904 case Variable::LOOKUP: { | 904 case Variable::LOOKUP: { |
905 Comment cmnt(masm_, "[ FunctionDeclaration"); | 905 Comment cmnt(masm_, "[ FunctionDeclaration"); |
906 __ li(a2, Operand(variable->name())); | 906 __ li(a2, Operand(variable->name())); |
907 __ li(a1, Operand(Smi::FromInt(NONE))); | 907 __ li(a1, Operand(Smi::FromInt(NONE))); |
908 __ Push(cp, a2, a1); | 908 __ Push(cp, a2, a1); |
909 // Push initial value for function declaration. | 909 // Push initial value for function declaration. |
910 VisitForStackValue(declaration->fun()); | 910 VisitForStackValue(declaration->fun()); |
911 __ CallRuntime(Runtime::kDeclareContextSlot, 4); | 911 __ CallRuntime(Runtime::kDeclareLookupSlot, 4); |
912 break; | 912 break; |
913 } | 913 } |
914 } | 914 } |
915 } | 915 } |
916 | 916 |
917 | 917 |
918 void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) { | 918 void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) { |
919 Variable* variable = declaration->proxy()->var(); | 919 Variable* variable = declaration->proxy()->var(); |
920 ASSERT(variable->location() == Variable::CONTEXT); | 920 ASSERT(variable->location() == Variable::CONTEXT); |
921 ASSERT(variable->interface()->IsFrozen()); | 921 ASSERT(variable->interface()->IsFrozen()); |
(...skipping 1518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2440 if (var->IsContextSlot()) { | 2440 if (var->IsContextSlot()) { |
2441 // RecordWrite may destroy all its register arguments. | 2441 // RecordWrite may destroy all its register arguments. |
2442 __ Move(a3, result_register()); | 2442 __ Move(a3, result_register()); |
2443 int offset = Context::SlotOffset(var->index()); | 2443 int offset = Context::SlotOffset(var->index()); |
2444 __ RecordWriteContextSlot( | 2444 __ RecordWriteContextSlot( |
2445 a1, offset, a3, a2, kRAHasBeenSaved, kDontSaveFPRegs); | 2445 a1, offset, a3, a2, kRAHasBeenSaved, kDontSaveFPRegs); |
2446 } | 2446 } |
2447 } | 2447 } |
2448 | 2448 |
2449 | 2449 |
2450 void FullCodeGenerator::EmitCallStoreContextSlot( | |
2451 Handle<String> name, StrictMode strict_mode) { | |
2452 __ li(a1, Operand(name)); | |
2453 __ li(a0, Operand(Smi::FromInt(strict_mode))); | |
2454 __ Push(v0, cp, a1, a0); // Value, context, name, strict mode. | |
2455 __ CallRuntime(Runtime::kStoreContextSlot, 4); | |
2456 } | |
2457 | |
2458 | |
2459 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op) { | 2450 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op) { |
2460 if (var->IsUnallocated()) { | 2451 if (var->IsUnallocated()) { |
2461 // Global var, const, or let. | 2452 // Global var, const, or let. |
2462 __ mov(StoreIC::ValueRegister(), result_register()); | 2453 __ mov(StoreIC::ValueRegister(), result_register()); |
2463 __ li(StoreIC::NameRegister(), Operand(var->name())); | 2454 __ li(StoreIC::NameRegister(), Operand(var->name())); |
2464 __ ld(StoreIC::ReceiverRegister(), GlobalObjectOperand()); | 2455 __ ld(StoreIC::ReceiverRegister(), GlobalObjectOperand()); |
2465 CallStoreIC(); | 2456 CallStoreIC(); |
2466 } else if (op == Token::INIT_CONST_LEGACY) { | 2457 } else if (op == Token::INIT_CONST_LEGACY) { |
2467 // Const initializers need a write barrier. | 2458 // Const initializers need a write barrier. |
2468 ASSERT(!var->IsParameter()); // No const parameters. | 2459 ASSERT(!var->IsParameter()); // No const parameters. |
2469 if (var->IsLookupSlot()) { | 2460 if (var->IsLookupSlot()) { |
2470 __ li(a0, Operand(var->name())); | 2461 __ li(a0, Operand(var->name())); |
2471 __ Push(v0, cp, a0); // Context and name. | 2462 __ Push(v0, cp, a0); // Context and name. |
2472 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3); | 2463 __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, 3); |
2473 } else { | 2464 } else { |
2474 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); | 2465 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); |
2475 Label skip; | 2466 Label skip; |
2476 MemOperand location = VarOperand(var, a1); | 2467 MemOperand location = VarOperand(var, a1); |
2477 __ ld(a2, location); | 2468 __ ld(a2, location); |
2478 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); | 2469 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); |
2479 __ Branch(&skip, ne, a2, Operand(at)); | 2470 __ Branch(&skip, ne, a2, Operand(at)); |
2480 EmitStoreToStackLocalOrContextSlot(var, location); | 2471 EmitStoreToStackLocalOrContextSlot(var, location); |
2481 __ bind(&skip); | 2472 __ bind(&skip); |
2482 } | 2473 } |
2483 | 2474 |
2484 } else if (var->mode() == LET && op != Token::INIT_LET) { | 2475 } else if (var->mode() == LET && op != Token::INIT_LET) { |
2485 // Non-initializing assignment to let variable needs a write barrier. | 2476 // Non-initializing assignment to let variable needs a write barrier. |
2486 if (var->IsLookupSlot()) { | 2477 ASSERT(!var->IsLookupSlot()); |
2487 EmitCallStoreContextSlot(var->name(), strict_mode()); | 2478 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); |
2488 } else { | 2479 Label assign; |
2489 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); | 2480 MemOperand location = VarOperand(var, a1); |
2490 Label assign; | 2481 __ ld(a3, location); |
2491 MemOperand location = VarOperand(var, a1); | 2482 __ LoadRoot(a4, Heap::kTheHoleValueRootIndex); |
2492 __ ld(a3, location); | 2483 __ Branch(&assign, ne, a3, Operand(a4)); |
2493 __ LoadRoot(a4, Heap::kTheHoleValueRootIndex); | 2484 __ li(a3, Operand(var->name())); |
2494 __ Branch(&assign, ne, a3, Operand(a4)); | 2485 __ push(a3); |
2495 __ li(a3, Operand(var->name())); | 2486 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
2496 __ push(a3); | 2487 // Perform the assignment. |
2497 __ CallRuntime(Runtime::kThrowReferenceError, 1); | 2488 __ bind(&assign); |
2498 // Perform the assignment. | 2489 EmitStoreToStackLocalOrContextSlot(var, location); |
2499 __ bind(&assign); | |
2500 EmitStoreToStackLocalOrContextSlot(var, location); | |
2501 } | |
2502 | 2490 |
2503 } else if (!var->is_const_mode() || op == Token::INIT_CONST) { | 2491 } else if (!var->is_const_mode() || op == Token::INIT_CONST) { |
2504 // Assignment to var or initializing assignment to let/const | |
2505 // in harmony mode. | |
2506 if (var->IsLookupSlot()) { | 2492 if (var->IsLookupSlot()) { |
2507 EmitCallStoreContextSlot(var->name(), strict_mode()); | 2493 ASSERT(op == Token::ASSIGN || op == Token::INIT_VAR || |
| 2494 op == Token::ASSIGN_ADD); |
| 2495 // Assignment to var. |
| 2496 __ li(a4, Operand(var->name())); |
| 2497 __ li(a3, Operand(Smi::FromInt(strict_mode()))); |
| 2498 // jssp[0] : mode. |
| 2499 // jssp[8] : name. |
| 2500 // jssp[16] : context. |
| 2501 // jssp[24] : value. |
| 2502 __ Push(v0, cp, a4, a3); |
| 2503 __ CallRuntime(Runtime::kStoreLookupSlot, 4); |
2508 } else { | 2504 } else { |
| 2505 // Assignment to var or initializing assignment to let/const in harmony |
| 2506 // mode. |
2509 ASSERT((var->IsStackAllocated() || var->IsContextSlot())); | 2507 ASSERT((var->IsStackAllocated() || var->IsContextSlot())); |
2510 MemOperand location = VarOperand(var, a1); | 2508 MemOperand location = VarOperand(var, a1); |
2511 if (generate_debug_code_ && op == Token::INIT_LET) { | 2509 if (generate_debug_code_ && op == Token::INIT_LET) { |
2512 // Check for an uninitialized let binding. | 2510 // Check for an uninitialized let binding. |
2513 __ ld(a2, location); | 2511 __ ld(a2, location); |
2514 __ LoadRoot(a4, Heap::kTheHoleValueRootIndex); | 2512 __ LoadRoot(a4, Heap::kTheHoleValueRootIndex); |
2515 __ Check(eq, kLetBindingReInitialization, a2, Operand(a4)); | 2513 __ Check(eq, kLetBindingReInitialization, a2, Operand(a4)); |
2516 } | 2514 } |
2517 EmitStoreToStackLocalOrContextSlot(var, location); | 2515 EmitStoreToStackLocalOrContextSlot(var, location); |
2518 } | 2516 } |
(...skipping 2340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4859 Assembler::target_address_at(pc_immediate_load_address)) == | 4857 Assembler::target_address_at(pc_immediate_load_address)) == |
4860 reinterpret_cast<uint64_t>( | 4858 reinterpret_cast<uint64_t>( |
4861 isolate->builtins()->OsrAfterStackCheck()->entry())); | 4859 isolate->builtins()->OsrAfterStackCheck()->entry())); |
4862 return OSR_AFTER_STACK_CHECK; | 4860 return OSR_AFTER_STACK_CHECK; |
4863 } | 4861 } |
4864 | 4862 |
4865 | 4863 |
4866 } } // namespace v8::internal | 4864 } } // namespace v8::internal |
4867 | 4865 |
4868 #endif // V8_TARGET_ARCH_MIPS64 | 4866 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |