Chromium Code Reviews| 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/compile-time-value.h" | 7 #include "src/ast/compile-time-value.h" |
| 8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
| 9 #include "src/builtins/builtins-constructor.h" | 9 #include "src/builtins/builtins-constructor.h" |
| 10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
| (...skipping 688 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 699 // since we skip some obviously dead code. Hence the generated bytecode may | 699 // since we skip some obviously dead code. Hence the generated bytecode may |
| 700 // contain jumps to unbound labels (resume points that will never be used). | 700 // contain jumps to unbound labels (resume points that will never be used). |
| 701 // We bind these now. | 701 // We bind these now. |
| 702 for (auto& label : generator_resume_points_) { | 702 for (auto& label : generator_resume_points_) { |
| 703 if (!label.is_bound()) builder()->Bind(&label); | 703 if (!label.is_bound()) builder()->Bind(&label); |
| 704 } | 704 } |
| 705 | 705 |
| 706 // Emit an implicit return instruction in case control flow can fall off the | 706 // Emit an implicit return instruction in case control flow can fall off the |
| 707 // end of the function without an explicit return being present on all paths. | 707 // end of the function without an explicit return being present on all paths. |
| 708 if (builder()->RequiresImplicitReturn()) { | 708 if (builder()->RequiresImplicitReturn()) { |
| 709 DCHECK(execution_control() == &control); | |
|
rmcilroy
2017/02/08 12:21:56
nit - please add a comment here that we can do a h
caitp
2017/02/08 13:42:58
Done.
| |
| 709 builder()->LoadUndefined(); | 710 builder()->LoadUndefined(); |
| 710 BuildReturn(); | 711 BuildTraceExit(); |
| 712 builder()->Return(); | |
| 711 } | 713 } |
| 712 DCHECK(!builder()->RequiresImplicitReturn()); | 714 DCHECK(!builder()->RequiresImplicitReturn()); |
| 713 } | 715 } |
| 714 | 716 |
| 715 void BytecodeGenerator::GenerateBytecodeBody() { | 717 void BytecodeGenerator::GenerateBytecodeBody() { |
| 716 // Build the arguments object if it is used. | 718 // Build the arguments object if it is used. |
| 717 VisitArgumentsObject(scope()->arguments()); | 719 VisitArgumentsObject(scope()->arguments()); |
| 718 | 720 |
| 719 // Build rest arguments array if it is used. | 721 // Build rest arguments array if it is used. |
| 720 Variable* rest_parameter = scope()->rest_parameter(); | 722 Variable* rest_parameter = scope()->rest_parameter(); |
| (...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1051 } | 1053 } |
| 1052 | 1054 |
| 1053 void BytecodeGenerator::VisitBreakStatement(BreakStatement* stmt) { | 1055 void BytecodeGenerator::VisitBreakStatement(BreakStatement* stmt) { |
| 1054 builder()->SetStatementPosition(stmt); | 1056 builder()->SetStatementPosition(stmt); |
| 1055 execution_control()->Break(stmt->target()); | 1057 execution_control()->Break(stmt->target()); |
| 1056 } | 1058 } |
| 1057 | 1059 |
| 1058 void BytecodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { | 1060 void BytecodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { |
| 1059 builder()->SetStatementPosition(stmt); | 1061 builder()->SetStatementPosition(stmt); |
| 1060 VisitForAccumulatorValue(stmt->expression()); | 1062 VisitForAccumulatorValue(stmt->expression()); |
| 1063 | |
| 1064 if (stmt->is_hard_return()) { | |
| 1065 // TODO(caitp): remove hard_return handling and ReturnStatement AST node | |
| 1066 // flags once BytecodeGenerator performs all implicit control flow for | |
| 1067 // async functions. | |
| 1068 builder()->Return(); | |
|
rmcilroy
2017/02/08 12:21:56
BuildTraceExit here too? How about Creating a Bui
caitp
2017/02/08 13:42:58
That looks cleaner, nice. Done
| |
| 1069 return; | |
| 1070 } | |
| 1071 | |
| 1061 execution_control()->ReturnAccumulator(); | 1072 execution_control()->ReturnAccumulator(); |
| 1062 } | 1073 } |
| 1063 | 1074 |
| 1064 void BytecodeGenerator::VisitWithStatement(WithStatement* stmt) { | 1075 void BytecodeGenerator::VisitWithStatement(WithStatement* stmt) { |
| 1065 builder()->SetStatementPosition(stmt); | 1076 builder()->SetStatementPosition(stmt); |
| 1066 VisitForAccumulatorValue(stmt->expression()); | 1077 VisitForAccumulatorValue(stmt->expression()); |
| 1067 BuildNewLocalWithContext(stmt->scope()); | 1078 BuildNewLocalWithContext(stmt->scope()); |
| 1068 VisitInScope(stmt->statement(), stmt->scope()); | 1079 VisitInScope(stmt->statement(), stmt->scope()); |
| 1069 } | 1080 } |
| 1070 | 1081 |
| (...skipping 913 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1984 } | 1995 } |
| 1985 | 1996 |
| 1986 void BytecodeGenerator::BuildVariableLoadForAccumulatorValue( | 1997 void BytecodeGenerator::BuildVariableLoadForAccumulatorValue( |
| 1987 Variable* variable, FeedbackSlot slot, HoleCheckMode hole_check_mode, | 1998 Variable* variable, FeedbackSlot slot, HoleCheckMode hole_check_mode, |
| 1988 TypeofMode typeof_mode) { | 1999 TypeofMode typeof_mode) { |
| 1989 ValueResultScope accumulator_result(this); | 2000 ValueResultScope accumulator_result(this); |
| 1990 BuildVariableLoad(variable, slot, hole_check_mode, typeof_mode); | 2001 BuildVariableLoad(variable, slot, hole_check_mode, typeof_mode); |
| 1991 } | 2002 } |
| 1992 | 2003 |
| 1993 void BytecodeGenerator::BuildReturn() { | 2004 void BytecodeGenerator::BuildReturn() { |
| 2005 if (IsAsyncFunction(info()->literal()->kind())) { | |
| 2006 RegisterAllocationScope register_scope(this); | |
| 2007 RegisterList args = register_allocator()->NewRegisterList(3); | |
| 2008 Register receiver = args[0]; | |
| 2009 Register promise = args[1]; | |
| 2010 Register return_value = args[2]; | |
| 2011 builder()->StoreAccumulatorInRegister(return_value); | |
| 2012 | |
| 2013 Variable* var_promise = scope()->promise_var(); | |
| 2014 DCHECK_NOT_NULL(var_promise); | |
| 2015 BuildVariableLoad(var_promise, FeedbackSlot::Invalid(), | |
| 2016 HoleCheckMode::kElided); | |
| 2017 builder() | |
| 2018 ->StoreAccumulatorInRegister(promise) | |
| 2019 .LoadUndefined() | |
| 2020 .StoreAccumulatorInRegister(receiver) | |
| 2021 .CallJSRuntime(Context::PROMISE_RESOLVE_INDEX, args) | |
| 2022 .LoadAccumulatorWithRegister(promise); | |
| 2023 } | |
| 2024 | |
| 2025 BuildTraceExit(); | |
| 2026 builder()->Return(); | |
| 2027 } | |
| 2028 | |
| 2029 void BytecodeGenerator::BuildTraceExit() { | |
| 1994 if (FLAG_trace) { | 2030 if (FLAG_trace) { |
| 1995 RegisterAllocationScope register_scope(this); | 2031 RegisterAllocationScope register_scope(this); |
| 1996 Register result = register_allocator()->NewRegister(); | 2032 Register result = register_allocator()->NewRegister(); |
| 1997 // Runtime returns {result} value, preserving accumulator. | 2033 // Runtime returns {result} value, preserving accumulator. |
| 1998 builder()->StoreAccumulatorInRegister(result).CallRuntime( | 2034 builder()->StoreAccumulatorInRegister(result).CallRuntime( |
| 1999 Runtime::kTraceExit, result); | 2035 Runtime::kTraceExit, result); |
| 2000 } | 2036 } |
| 2001 builder()->Return(); | |
| 2002 } | 2037 } |
| 2003 | 2038 |
| 2004 void BytecodeGenerator::BuildReThrow() { builder()->ReThrow(); } | 2039 void BytecodeGenerator::BuildReThrow() { builder()->ReThrow(); } |
| 2005 | 2040 |
| 2006 void BytecodeGenerator::BuildAbort(BailoutReason bailout_reason) { | 2041 void BytecodeGenerator::BuildAbort(BailoutReason bailout_reason) { |
| 2007 RegisterAllocationScope register_scope(this); | 2042 RegisterAllocationScope register_scope(this); |
| 2008 Register reason = register_allocator()->NewRegister(); | 2043 Register reason = register_allocator()->NewRegister(); |
| 2009 builder() | 2044 builder() |
| 2010 ->LoadLiteral(Smi::FromInt(static_cast<int>(bailout_reason))) | 2045 ->LoadLiteral(Smi::FromInt(static_cast<int>(bailout_reason))) |
| 2011 .StoreAccumulatorInRegister(reason) | 2046 .StoreAccumulatorInRegister(reason) |
| (...skipping 1369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3381 } | 3416 } |
| 3382 | 3417 |
| 3383 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() { | 3418 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() { |
| 3384 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict | 3419 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict |
| 3385 : Runtime::kStoreKeyedToSuper_Sloppy; | 3420 : Runtime::kStoreKeyedToSuper_Sloppy; |
| 3386 } | 3421 } |
| 3387 | 3422 |
| 3388 } // namespace interpreter | 3423 } // namespace interpreter |
| 3389 } // namespace internal | 3424 } // namespace internal |
| 3390 } // namespace v8 | 3425 } // namespace v8 |
| OLD | NEW |