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 // Do a hard return as execution_control is the top level and will not | |
710 // issue a deferred return command. | |
711 DCHECK(execution_control() == &control); | |
709 builder()->LoadUndefined(); | 712 builder()->LoadUndefined(); |
710 BuildReturn(); | 713 BuildHardReturn(); |
Dan Ehrenberg
2017/02/09 06:40:00
Why is this a hard return? I would expect implicit
caitp
2017/02/09 12:53:07
This change is just too shrink bytecode a bit.
Th
Dan Ehrenberg
2017/02/09 13:23:36
I thought this would be reached in a case like "as
rmcilroy
2017/02/09 13:33:49
I didn't realize this was only a to optimize bytec
caitp
2017/02/09 13:38:47
My understanding is that this is needed to ensure
| |
711 } | 714 } |
712 DCHECK(!builder()->RequiresImplicitReturn()); | 715 DCHECK(!builder()->RequiresImplicitReturn()); |
713 } | 716 } |
714 | 717 |
715 void BytecodeGenerator::GenerateBytecodeBody() { | 718 void BytecodeGenerator::GenerateBytecodeBody() { |
716 // Build the arguments object if it is used. | 719 // Build the arguments object if it is used. |
717 VisitArgumentsObject(scope()->arguments()); | 720 VisitArgumentsObject(scope()->arguments()); |
718 | 721 |
719 // Build rest arguments array if it is used. | 722 // Build rest arguments array if it is used. |
720 Variable* rest_parameter = scope()->rest_parameter(); | 723 Variable* rest_parameter = scope()->rest_parameter(); |
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1051 } | 1054 } |
1052 | 1055 |
1053 void BytecodeGenerator::VisitBreakStatement(BreakStatement* stmt) { | 1056 void BytecodeGenerator::VisitBreakStatement(BreakStatement* stmt) { |
1054 builder()->SetStatementPosition(stmt); | 1057 builder()->SetStatementPosition(stmt); |
1055 execution_control()->Break(stmt->target()); | 1058 execution_control()->Break(stmt->target()); |
1056 } | 1059 } |
1057 | 1060 |
1058 void BytecodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { | 1061 void BytecodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { |
1059 builder()->SetStatementPosition(stmt); | 1062 builder()->SetStatementPosition(stmt); |
1060 VisitForAccumulatorValue(stmt->expression()); | 1063 VisitForAccumulatorValue(stmt->expression()); |
1064 | |
1065 if (stmt->is_hard_return()) { | |
1066 // TODO(caitp): remove hard_return handling and ReturnStatement AST node | |
1067 // flags once BytecodeGenerator performs all implicit control flow for | |
1068 // async functions. | |
1069 return BuildHardReturn(); | |
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 BuildHardReturn(); | |
2026 } | |
2027 | |
2028 void BytecodeGenerator::BuildHardReturn() { | |
1994 if (FLAG_trace) { | 2029 if (FLAG_trace) { |
1995 RegisterAllocationScope register_scope(this); | 2030 RegisterAllocationScope register_scope(this); |
1996 Register result = register_allocator()->NewRegister(); | 2031 Register result = register_allocator()->NewRegister(); |
1997 // Runtime returns {result} value, preserving accumulator. | 2032 // Runtime returns {result} value, preserving accumulator. |
1998 builder()->StoreAccumulatorInRegister(result).CallRuntime( | 2033 builder()->StoreAccumulatorInRegister(result).CallRuntime( |
1999 Runtime::kTraceExit, result); | 2034 Runtime::kTraceExit, result); |
2000 } | 2035 } |
2001 builder()->Return(); | 2036 builder()->Return(); |
2002 } | 2037 } |
2003 | 2038 |
(...skipping 1377 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 |