OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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_ARM64 | 7 #if V8_TARGET_ARCH_ARM64 |
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 2397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2408 | 2408 |
2409 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 2409 void FullCodeGenerator::EmitVariableAssignment(Variable* var, |
2410 Token::Value op) { | 2410 Token::Value op) { |
2411 ASM_LOCATION("FullCodeGenerator::EmitVariableAssignment"); | 2411 ASM_LOCATION("FullCodeGenerator::EmitVariableAssignment"); |
2412 if (var->IsUnallocated()) { | 2412 if (var->IsUnallocated()) { |
2413 // Global var, const, or let. | 2413 // Global var, const, or let. |
2414 __ Mov(StoreDescriptor::NameRegister(), Operand(var->name())); | 2414 __ Mov(StoreDescriptor::NameRegister(), Operand(var->name())); |
2415 __ Ldr(StoreDescriptor::ReceiverRegister(), GlobalObjectMemOperand()); | 2415 __ Ldr(StoreDescriptor::ReceiverRegister(), GlobalObjectMemOperand()); |
2416 CallStoreIC(); | 2416 CallStoreIC(); |
2417 | 2417 |
2418 } else if (op == Token::INIT_CONST_LEGACY) { | |
2419 // Const initializers need a write barrier. | |
2420 DCHECK(!var->IsParameter()); // No const parameters. | |
2421 if (var->IsLookupSlot()) { | |
2422 __ Mov(x1, Operand(var->name())); | |
2423 __ Push(x0, cp, x1); | |
2424 __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, 3); | |
2425 } else { | |
2426 DCHECK(var->IsStackLocal() || var->IsContextSlot()); | |
2427 Label skip; | |
2428 MemOperand location = VarOperand(var, x1); | |
2429 __ Ldr(x10, location); | |
2430 __ JumpIfNotRoot(x10, Heap::kTheHoleValueRootIndex, &skip); | |
2431 EmitStoreToStackLocalOrContextSlot(var, location); | |
2432 __ Bind(&skip); | |
2433 } | |
2434 | |
2435 } else if (var->mode() == LET && op != Token::INIT_LET) { | 2418 } else if (var->mode() == LET && op != Token::INIT_LET) { |
2436 // Non-initializing assignment to let variable needs a write barrier. | 2419 // Non-initializing assignment to let variable needs a write barrier. |
2437 DCHECK(!var->IsLookupSlot()); | 2420 DCHECK(!var->IsLookupSlot()); |
2438 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 2421 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
2439 Label assign; | 2422 Label assign; |
2440 MemOperand location = VarOperand(var, x1); | 2423 MemOperand location = VarOperand(var, x1); |
2441 __ Ldr(x10, location); | 2424 __ Ldr(x10, location); |
2442 __ JumpIfNotRoot(x10, Heap::kTheHoleValueRootIndex, &assign); | 2425 __ JumpIfNotRoot(x10, Heap::kTheHoleValueRootIndex, &assign); |
2443 __ Mov(x10, Operand(var->name())); | 2426 __ Mov(x10, Operand(var->name())); |
2444 __ Push(x10); | 2427 __ Push(x10); |
2445 __ CallRuntime(Runtime::kThrowReferenceError, 1); | 2428 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
2446 // Perform the assignment. | 2429 // Perform the assignment. |
2447 __ Bind(&assign); | 2430 __ Bind(&assign); |
2448 EmitStoreToStackLocalOrContextSlot(var, location); | 2431 EmitStoreToStackLocalOrContextSlot(var, location); |
2449 | 2432 |
| 2433 } else if (var->mode() == CONST && op != Token::INIT_CONST) { |
| 2434 // Assignment to const variable needs a write barrier. |
| 2435 DCHECK(!var->IsLookupSlot()); |
| 2436 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| 2437 Label const_error; |
| 2438 MemOperand location = VarOperand(var, x1); |
| 2439 __ Ldr(x10, location); |
| 2440 __ JumpIfNotRoot(x10, Heap::kTheHoleValueRootIndex, &const_error); |
| 2441 __ Mov(x10, Operand(var->name())); |
| 2442 __ Push(x10); |
| 2443 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
| 2444 __ Bind(&const_error); |
| 2445 __ CallRuntime(Runtime::kThrowConstAssignError, 0); |
| 2446 |
2450 } else if (!var->is_const_mode() || op == Token::INIT_CONST) { | 2447 } else if (!var->is_const_mode() || op == Token::INIT_CONST) { |
2451 if (var->IsLookupSlot()) { | 2448 if (var->IsLookupSlot()) { |
2452 // Assignment to var. | 2449 // Assignment to var. |
2453 __ Mov(x11, Operand(var->name())); | 2450 __ Mov(x11, Operand(var->name())); |
2454 __ Mov(x10, Smi::FromInt(language_mode())); | 2451 __ Mov(x10, Smi::FromInt(language_mode())); |
2455 // jssp[0] : mode. | 2452 // jssp[0] : mode. |
2456 // jssp[8] : name. | 2453 // jssp[8] : name. |
2457 // jssp[16] : context. | 2454 // jssp[16] : context. |
2458 // jssp[24] : value. | 2455 // jssp[24] : value. |
2459 __ Push(x0, cp, x11, x10); | 2456 __ Push(x0, cp, x11, x10); |
2460 __ CallRuntime(Runtime::kStoreLookupSlot, 4); | 2457 __ CallRuntime(Runtime::kStoreLookupSlot, 4); |
2461 } else { | 2458 } else { |
2462 // Assignment to var or initializing assignment to let/const in harmony | 2459 // Assignment to var or initializing assignment to let/const in harmony |
2463 // mode. | 2460 // mode. |
2464 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 2461 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
2465 MemOperand location = VarOperand(var, x1); | 2462 MemOperand location = VarOperand(var, x1); |
2466 if (FLAG_debug_code && op == Token::INIT_LET) { | 2463 if (FLAG_debug_code && op == Token::INIT_LET) { |
2467 __ Ldr(x10, location); | 2464 __ Ldr(x10, location); |
2468 __ CompareRoot(x10, Heap::kTheHoleValueRootIndex); | 2465 __ CompareRoot(x10, Heap::kTheHoleValueRootIndex); |
2469 __ Check(eq, kLetBindingReInitialization); | 2466 __ Check(eq, kLetBindingReInitialization); |
2470 } | 2467 } |
2471 EmitStoreToStackLocalOrContextSlot(var, location); | 2468 EmitStoreToStackLocalOrContextSlot(var, location); |
2472 } | 2469 } |
2473 } else if (IsSignallingAssignmentToConst(var, op, language_mode())) { | 2470 |
2474 __ CallRuntime(Runtime::kThrowConstAssignError, 0); | 2471 } else if (op == Token::INIT_CONST_LEGACY) { |
| 2472 // Const initializers need a write barrier. |
| 2473 DCHECK(var->mode() == CONST_LEGACY); |
| 2474 DCHECK(!var->IsParameter()); // No const parameters. |
| 2475 if (var->IsLookupSlot()) { |
| 2476 __ Mov(x1, Operand(var->name())); |
| 2477 __ Push(x0, cp, x1); |
| 2478 __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, 3); |
| 2479 } else { |
| 2480 DCHECK(var->IsStackLocal() || var->IsContextSlot()); |
| 2481 Label skip; |
| 2482 MemOperand location = VarOperand(var, x1); |
| 2483 __ Ldr(x10, location); |
| 2484 __ JumpIfNotRoot(x10, Heap::kTheHoleValueRootIndex, &skip); |
| 2485 EmitStoreToStackLocalOrContextSlot(var, location); |
| 2486 __ Bind(&skip); |
| 2487 } |
| 2488 |
| 2489 } else { |
| 2490 DCHECK(var->mode() == CONST_LEGACY && op != Token::INIT_CONST_LEGACY); |
| 2491 if (is_strict(language_mode())) { |
| 2492 __ CallRuntime(Runtime::kThrowConstAssignError, 0); |
| 2493 } |
| 2494 // Silently ignore store in sloppy mode. |
2475 } | 2495 } |
2476 } | 2496 } |
2477 | 2497 |
2478 | 2498 |
2479 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { | 2499 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { |
2480 ASM_LOCATION("FullCodeGenerator::EmitNamedPropertyAssignment"); | 2500 ASM_LOCATION("FullCodeGenerator::EmitNamedPropertyAssignment"); |
2481 // Assignment to a property, using a named store IC. | 2501 // Assignment to a property, using a named store IC. |
2482 Property* prop = expr->target()->AsProperty(); | 2502 Property* prop = expr->target()->AsProperty(); |
2483 DCHECK(prop != NULL); | 2503 DCHECK(prop != NULL); |
2484 DCHECK(prop->key()->IsLiteral()); | 2504 DCHECK(prop->key()->IsLiteral()); |
(...skipping 2995 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5480 return previous_; | 5500 return previous_; |
5481 } | 5501 } |
5482 | 5502 |
5483 | 5503 |
5484 #undef __ | 5504 #undef __ |
5485 | 5505 |
5486 | 5506 |
5487 } } // namespace v8::internal | 5507 } } // namespace v8::internal |
5488 | 5508 |
5489 #endif // V8_TARGET_ARCH_ARM64 | 5509 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |