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_IA32 | 7 #if V8_TARGET_ARCH_IA32 |
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 2366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2377 Variable* var, MemOperand location) { | 2377 Variable* var, MemOperand location) { |
2378 __ mov(location, eax); | 2378 __ mov(location, eax); |
2379 if (var->IsContextSlot()) { | 2379 if (var->IsContextSlot()) { |
2380 __ mov(edx, eax); | 2380 __ mov(edx, eax); |
2381 int offset = Context::SlotOffset(var->index()); | 2381 int offset = Context::SlotOffset(var->index()); |
2382 __ RecordWriteContextSlot(ecx, offset, edx, ebx, kDontSaveFPRegs); | 2382 __ RecordWriteContextSlot(ecx, offset, edx, ebx, kDontSaveFPRegs); |
2383 } | 2383 } |
2384 } | 2384 } |
2385 | 2385 |
2386 | 2386 |
2387 void FullCodeGenerator::EmitCallStoreContextSlot( | |
2388 Handle<String> name, StrictMode strict_mode) { | |
2389 __ push(eax); // Value. | |
2390 __ push(esi); // Context. | |
2391 __ push(Immediate(name)); | |
2392 __ push(Immediate(Smi::FromInt(strict_mode))); | |
2393 __ CallRuntime(Runtime::kStoreContextSlot, 4); | |
2394 } | |
2395 | |
2396 | |
2397 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 2387 void FullCodeGenerator::EmitVariableAssignment(Variable* var, |
2398 Token::Value op) { | 2388 Token::Value op) { |
2399 if (var->IsUnallocated()) { | 2389 if (var->IsUnallocated()) { |
2400 // Global var, const, or let. | 2390 // Global var, const, or let. |
2401 __ mov(ecx, var->name()); | 2391 __ mov(ecx, var->name()); |
2402 __ mov(edx, GlobalObjectOperand()); | 2392 __ mov(edx, GlobalObjectOperand()); |
2403 CallStoreIC(); | 2393 CallStoreIC(); |
2404 | 2394 |
2405 } else if (op == Token::INIT_CONST_LEGACY) { | 2395 } else if (op == Token::INIT_CONST_LEGACY) { |
2406 // Const initializers need a write barrier. | 2396 // Const initializers need a write barrier. |
2407 ASSERT(!var->IsParameter()); // No const parameters. | 2397 ASSERT(!var->IsParameter()); // No const parameters. |
2408 if (var->IsLookupSlot()) { | 2398 if (var->IsLookupSlot()) { |
2409 __ push(eax); | 2399 __ push(eax); |
2410 __ push(esi); | 2400 __ push(esi); |
2411 __ push(Immediate(var->name())); | 2401 __ push(Immediate(var->name())); |
2412 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3); | 2402 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3); |
2413 } else { | 2403 } else { |
2414 ASSERT(var->IsStackLocal() || var->IsContextSlot()); | 2404 ASSERT(var->IsStackLocal() || var->IsContextSlot()); |
2415 Label skip; | 2405 Label skip; |
2416 MemOperand location = VarOperand(var, ecx); | 2406 MemOperand location = VarOperand(var, ecx); |
2417 __ mov(edx, location); | 2407 __ mov(edx, location); |
2418 __ cmp(edx, isolate()->factory()->the_hole_value()); | 2408 __ cmp(edx, isolate()->factory()->the_hole_value()); |
2419 __ j(not_equal, &skip, Label::kNear); | 2409 __ j(not_equal, &skip, Label::kNear); |
2420 EmitStoreToStackLocalOrContextSlot(var, location); | 2410 EmitStoreToStackLocalOrContextSlot(var, location); |
2421 __ bind(&skip); | 2411 __ bind(&skip); |
2422 } | 2412 } |
2423 | 2413 |
2424 } else if (var->mode() == LET && op != Token::INIT_LET) { | 2414 } else if (var->mode() == LET && op != Token::INIT_LET) { |
2425 // Non-initializing assignment to let variable needs a write barrier. | 2415 // Non-initializing assignment to let variable needs a write barrier. |
2426 if (var->IsLookupSlot()) { | 2416 ASSERT(!var->IsLookupSlot()); |
2427 EmitCallStoreContextSlot(var->name(), strict_mode()); | 2417 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); |
2428 } else { | 2418 Label assign; |
2429 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); | 2419 MemOperand location = VarOperand(var, ecx); |
2430 Label assign; | 2420 __ mov(edx, location); |
2431 MemOperand location = VarOperand(var, ecx); | 2421 __ cmp(edx, isolate()->factory()->the_hole_value()); |
2432 __ mov(edx, location); | 2422 __ j(not_equal, &assign, Label::kNear); |
2433 __ cmp(edx, isolate()->factory()->the_hole_value()); | 2423 __ push(Immediate(var->name())); |
2434 __ j(not_equal, &assign, Label::kNear); | 2424 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
2435 __ push(Immediate(var->name())); | 2425 __ bind(&assign); |
2436 __ CallRuntime(Runtime::kThrowReferenceError, 1); | 2426 EmitStoreToStackLocalOrContextSlot(var, location); |
2437 __ bind(&assign); | |
2438 EmitStoreToStackLocalOrContextSlot(var, location); | |
2439 } | |
2440 | 2427 |
2441 } else if (!var->is_const_mode() || op == Token::INIT_CONST) { | 2428 } else if (!var->is_const_mode() || op == Token::INIT_CONST) { |
2442 // Assignment to var or initializing assignment to let/const | |
2443 // in harmony mode. | |
2444 if (var->IsLookupSlot()) { | 2429 if (var->IsLookupSlot()) { |
2445 EmitCallStoreContextSlot(var->name(), strict_mode()); | 2430 ASSERT(op == Token::ASSIGN || op == Token::INIT_VAR || |
| 2431 op == Token::ASSIGN_ADD); |
| 2432 // Assignment to var. |
| 2433 __ push(eax); // Value. |
| 2434 __ push(esi); // Context. |
| 2435 __ push(Immediate(var->name())); |
| 2436 __ push(Immediate(Smi::FromInt(strict_mode()))); |
| 2437 __ CallRuntime(Runtime::kStoreLookupSlot, 4); |
2446 } else { | 2438 } else { |
| 2439 // Assignment to var or initializing assignment to let/const in harmony |
| 2440 // mode. |
2447 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); | 2441 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); |
2448 MemOperand location = VarOperand(var, ecx); | 2442 MemOperand location = VarOperand(var, ecx); |
2449 if (generate_debug_code_ && op == Token::INIT_LET) { | 2443 if (generate_debug_code_ && op == Token::INIT_LET) { |
2450 // Check for an uninitialized let binding. | 2444 // Check for an uninitialized let binding. |
2451 __ mov(edx, location); | 2445 __ mov(edx, location); |
2452 __ cmp(edx, isolate()->factory()->the_hole_value()); | 2446 __ cmp(edx, isolate()->factory()->the_hole_value()); |
2453 __ Check(equal, kLetBindingReInitialization); | 2447 __ Check(equal, kLetBindingReInitialization); |
2454 } | 2448 } |
2455 EmitStoreToStackLocalOrContextSlot(var, location); | 2449 EmitStoreToStackLocalOrContextSlot(var, location); |
2456 } | 2450 } |
(...skipping 2345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4802 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 4796 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
4803 Assembler::target_address_at(call_target_address, | 4797 Assembler::target_address_at(call_target_address, |
4804 unoptimized_code)); | 4798 unoptimized_code)); |
4805 return OSR_AFTER_STACK_CHECK; | 4799 return OSR_AFTER_STACK_CHECK; |
4806 } | 4800 } |
4807 | 4801 |
4808 | 4802 |
4809 } } // namespace v8::internal | 4803 } } // namespace v8::internal |
4810 | 4804 |
4811 #endif // V8_TARGET_ARCH_IA32 | 4805 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |