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 |