OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/interpreter/bytecode-generator.h" | 5 #include "src/interpreter/bytecode-generator.h" |
6 | 6 |
7 #include "src/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
8 #include "src/compiler.h" | 8 #include "src/compiler.h" |
9 #include "src/interpreter/bytecode-register-allocator.h" | 9 #include "src/interpreter/bytecode-register-allocator.h" |
10 #include "src/interpreter/control-flow-builders.h" | 10 #include "src/interpreter/control-flow-builders.h" |
(...skipping 841 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
852 } | 852 } |
853 | 853 |
854 | 854 |
855 void BytecodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { | 855 void BytecodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { |
856 VisitForAccumulatorValue(stmt->expression()); | 856 VisitForAccumulatorValue(stmt->expression()); |
857 execution_control()->ReturnAccumulator(); | 857 execution_control()->ReturnAccumulator(); |
858 } | 858 } |
859 | 859 |
860 | 860 |
861 void BytecodeGenerator::VisitWithStatement(WithStatement* stmt) { | 861 void BytecodeGenerator::VisitWithStatement(WithStatement* stmt) { |
862 UNIMPLEMENTED(); | 862 VisitForAccumulatorValue(stmt->expression()); |
| 863 builder()->CastAccumulatorToJSObject(); |
| 864 VisitNewLocalWithContext(); |
| 865 VisitInScope(stmt->statement(), stmt->scope()); |
863 } | 866 } |
864 | 867 |
865 | 868 |
866 void BytecodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { | 869 void BytecodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { |
867 // We need this scope because we visit for register values. We have to | 870 // We need this scope because we visit for register values. We have to |
868 // maintain a execution result scope where registers can be allocated. | 871 // maintain a execution result scope where registers can be allocated. |
869 ZoneList<CaseClause*>* clauses = stmt->cases(); | 872 ZoneList<CaseClause*>* clauses = stmt->cases(); |
870 SwitchBuilder switch_builder(builder(), clauses->length()); | 873 SwitchBuilder switch_builder(builder(), clauses->length()); |
871 ControlScopeForBreakable scope(this, stmt, &switch_builder); | 874 ControlScopeForBreakable scope(this, stmt, &switch_builder); |
872 int default_index = -1; | 875 int default_index = -1; |
(...skipping 1483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2356 builder() | 2359 builder() |
2357 ->LoadLiteral(scope->GetScopeInfo(isolate())) | 2360 ->LoadLiteral(scope->GetScopeInfo(isolate())) |
2358 .StoreAccumulatorInRegister(scope_info); | 2361 .StoreAccumulatorInRegister(scope_info); |
2359 VisitFunctionClosureForContext(); | 2362 VisitFunctionClosureForContext(); |
2360 builder() | 2363 builder() |
2361 ->StoreAccumulatorInRegister(closure) | 2364 ->StoreAccumulatorInRegister(closure) |
2362 .CallRuntime(Runtime::kPushBlockContext, scope_info, 2); | 2365 .CallRuntime(Runtime::kPushBlockContext, scope_info, 2); |
2363 execution_result()->SetResultInAccumulator(); | 2366 execution_result()->SetResultInAccumulator(); |
2364 } | 2367 } |
2365 | 2368 |
| 2369 void BytecodeGenerator::VisitNewLocalWithContext() { |
| 2370 AccumulatorResultScope accumulator_execution_result(this); |
| 2371 |
| 2372 register_allocator()->PrepareForConsecutiveAllocations(2); |
| 2373 Register extension_object = register_allocator()->NextConsecutiveRegister(); |
| 2374 Register closure = register_allocator()->NextConsecutiveRegister(); |
| 2375 |
| 2376 builder()->StoreAccumulatorInRegister(extension_object); |
| 2377 VisitFunctionClosureForContext(); |
| 2378 builder()->StoreAccumulatorInRegister(closure).CallRuntime( |
| 2379 Runtime::kPushWithContext, extension_object, 2); |
| 2380 execution_result()->SetResultInAccumulator(); |
| 2381 } |
2366 | 2382 |
2367 void BytecodeGenerator::VisitNewLocalCatchContext(Variable* variable) { | 2383 void BytecodeGenerator::VisitNewLocalCatchContext(Variable* variable) { |
2368 AccumulatorResultScope accumulator_execution_result(this); | 2384 AccumulatorResultScope accumulator_execution_result(this); |
2369 DCHECK(variable->IsContextSlot()); | 2385 DCHECK(variable->IsContextSlot()); |
2370 | 2386 |
2371 // Allocate a new local block context. | 2387 // Allocate a new local block context. |
2372 register_allocator()->PrepareForConsecutiveAllocations(3); | 2388 register_allocator()->PrepareForConsecutiveAllocations(3); |
2373 Register name = register_allocator()->NextConsecutiveRegister(); | 2389 Register name = register_allocator()->NextConsecutiveRegister(); |
2374 Register exception = register_allocator()->NextConsecutiveRegister(); | 2390 Register exception = register_allocator()->NextConsecutiveRegister(); |
2375 Register closure = register_allocator()->NextConsecutiveRegister(); | 2391 Register closure = register_allocator()->NextConsecutiveRegister(); |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2451 if (closure_scope->is_script_scope() || | 2467 if (closure_scope->is_script_scope() || |
2452 closure_scope->is_module_scope()) { | 2468 closure_scope->is_module_scope()) { |
2453 // Contexts nested in the native context have a canonical empty function as | 2469 // Contexts nested in the native context have a canonical empty function as |
2454 // their closure, not the anonymous closure containing the global code. | 2470 // their closure, not the anonymous closure containing the global code. |
2455 Register native_context = register_allocator()->NewRegister(); | 2471 Register native_context = register_allocator()->NewRegister(); |
2456 builder() | 2472 builder() |
2457 ->LoadContextSlot(execution_context()->reg(), | 2473 ->LoadContextSlot(execution_context()->reg(), |
2458 Context::NATIVE_CONTEXT_INDEX) | 2474 Context::NATIVE_CONTEXT_INDEX) |
2459 .StoreAccumulatorInRegister(native_context) | 2475 .StoreAccumulatorInRegister(native_context) |
2460 .LoadContextSlot(native_context, Context::CLOSURE_INDEX); | 2476 .LoadContextSlot(native_context, Context::CLOSURE_INDEX); |
| 2477 } else if (closure_scope->is_eval_scope()) { |
| 2478 // Contexts created by a call to eval have the same closure as the |
| 2479 // context calling eval, not the anonymous closure containing the eval |
| 2480 // code. Fetch it from the context. |
| 2481 builder()->LoadContextSlot(execution_context()->reg(), |
| 2482 Context::CLOSURE_INDEX); |
2461 } else { | 2483 } else { |
2462 DCHECK(closure_scope->is_function_scope()); | 2484 DCHECK(closure_scope->is_function_scope()); |
2463 builder()->LoadAccumulatorWithRegister(Register::function_closure()); | 2485 builder()->LoadAccumulatorWithRegister(Register::function_closure()); |
2464 } | 2486 } |
2465 execution_result()->SetResultInAccumulator(); | 2487 execution_result()->SetResultInAccumulator(); |
2466 } | 2488 } |
2467 | 2489 |
2468 | 2490 |
2469 // Visits the expression |expr| and places the result in the accumulator. | 2491 // Visits the expression |expr| and places the result in the accumulator. |
2470 void BytecodeGenerator::VisitForAccumulatorValue(Expression* expr) { | 2492 void BytecodeGenerator::VisitForAccumulatorValue(Expression* expr) { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2506 } | 2528 } |
2507 | 2529 |
2508 | 2530 |
2509 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { | 2531 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { |
2510 return info()->feedback_vector()->GetIndex(slot); | 2532 return info()->feedback_vector()->GetIndex(slot); |
2511 } | 2533 } |
2512 | 2534 |
2513 } // namespace interpreter | 2535 } // namespace interpreter |
2514 } // namespace internal | 2536 } // namespace internal |
2515 } // namespace v8 | 2537 } // namespace v8 |
OLD | NEW |