| 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 |