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