Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(447)

Side by Side Diff: src/full-codegen/full-codegen.cc

Issue 1724753002: [fullcodegen] Implement control flow across do-expressions. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Disable verification. Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/full-codegen/full-codegen.h ('k') | src/full-codegen/ia32/full-codegen-ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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/full-codegen/full-codegen.h" 5 #include "src/full-codegen/full-codegen.h"
6 6
7 #include "src/ast/ast.h" 7 #include "src/ast/ast.h"
8 #include "src/ast/ast-numbering.h" 8 #include "src/ast/ast-numbering.h"
9 #include "src/ast/prettyprinter.h" 9 #include "src/ast/prettyprinter.h"
10 #include "src/ast/scopeinfo.h" 10 #include "src/ast/scopeinfo.h"
(...skipping 895 matching lines...) Expand 10 before | Expand all | Expand 10 after
906 Visit(stmt->then_statement()); 906 Visit(stmt->then_statement());
907 907
908 PrepareForBailoutForId(stmt->ElseId(), NO_REGISTERS); 908 PrepareForBailoutForId(stmt->ElseId(), NO_REGISTERS);
909 } 909 }
910 __ bind(&done); 910 __ bind(&done);
911 PrepareForBailoutForId(stmt->IfId(), NO_REGISTERS); 911 PrepareForBailoutForId(stmt->IfId(), NO_REGISTERS);
912 } 912 }
913 913
914 void FullCodeGenerator::EmitContinue(Statement* target) { 914 void FullCodeGenerator::EmitContinue(Statement* target) {
915 NestedStatement* current = nesting_stack_; 915 NestedStatement* current = nesting_stack_;
916 int stack_depth = 0;
917 int context_length = 0; 916 int context_length = 0;
918 // When continuing, we clobber the unpredictable value in the accumulator 917 // When continuing, we clobber the unpredictable value in the accumulator
919 // with one that's safe for GC. If we hit an exit from the try block of 918 // with one that's safe for GC. If we hit an exit from the try block of
920 // try...finally on our way out, we will unconditionally preserve the 919 // try...finally on our way out, we will unconditionally preserve the
921 // accumulator on the stack. 920 // accumulator on the stack.
922 ClearAccumulator(); 921 ClearAccumulator();
923 while (!current->IsContinueTarget(target)) { 922 while (!current->IsContinueTarget(target)) {
924 if (current->IsTryFinally()) { 923 if (current->IsTryFinally()) {
925 Comment cmnt(masm(), "[ Deferred continue through finally"); 924 Comment cmnt(masm(), "[ Deferred continue through finally");
926 current->Exit(&stack_depth, &context_length); 925 current->Exit(&context_length);
927 DCHECK_EQ(0, stack_depth); 926 DCHECK_EQ(-1, context_length);
928 DCHECK_EQ(0, context_length);
929 current->AsTryFinally()->deferred_commands()->RecordContinue(target); 927 current->AsTryFinally()->deferred_commands()->RecordContinue(target);
930 return; 928 return;
931 } 929 }
932 current = current->Exit(&stack_depth, &context_length); 930 current = current->Exit(&context_length);
933 } 931 }
934 __ Drop(stack_depth); 932 int stack_depth = current->GetStackDepthAtTarget();
933 int stack_drop = operand_stack_depth_ - stack_depth;
934 DCHECK_GE(stack_drop, 0);
935 __ Drop(stack_drop);
935 if (context_length > 0) { 936 if (context_length > 0) {
936 while (context_length > 0) { 937 while (context_length > 0) {
937 LoadContextField(context_register(), Context::PREVIOUS_INDEX); 938 LoadContextField(context_register(), Context::PREVIOUS_INDEX);
938 --context_length; 939 --context_length;
939 } 940 }
940 StoreToFrameField(StandardFrameConstants::kContextOffset, 941 StoreToFrameField(StandardFrameConstants::kContextOffset,
941 context_register()); 942 context_register());
942 } 943 }
943 944
944 __ jmp(current->AsIteration()->continue_label()); 945 __ jmp(current->AsIteration()->continue_label());
945 } 946 }
946 947
947 void FullCodeGenerator::VisitContinueStatement(ContinueStatement* stmt) { 948 void FullCodeGenerator::VisitContinueStatement(ContinueStatement* stmt) {
948 Comment cmnt(masm_, "[ ContinueStatement"); 949 Comment cmnt(masm_, "[ ContinueStatement");
949 SetStatementPosition(stmt); 950 SetStatementPosition(stmt);
950 EmitContinue(stmt->target()); 951 EmitContinue(stmt->target());
951 } 952 }
952 953
953 void FullCodeGenerator::EmitBreak(Statement* target) { 954 void FullCodeGenerator::EmitBreak(Statement* target) {
954 NestedStatement* current = nesting_stack_; 955 NestedStatement* current = nesting_stack_;
955 int stack_depth = 0;
956 int context_length = 0; 956 int context_length = 0;
957 // When breaking, we clobber the unpredictable value in the accumulator 957 // When breaking, we clobber the unpredictable value in the accumulator
958 // with one that's safe for GC. If we hit an exit from the try block of 958 // with one that's safe for GC. If we hit an exit from the try block of
959 // try...finally on our way out, we will unconditionally preserve the 959 // try...finally on our way out, we will unconditionally preserve the
960 // accumulator on the stack. 960 // accumulator on the stack.
961 ClearAccumulator(); 961 ClearAccumulator();
962 while (!current->IsBreakTarget(target)) { 962 while (!current->IsBreakTarget(target)) {
963 if (current->IsTryFinally()) { 963 if (current->IsTryFinally()) {
964 Comment cmnt(masm(), "[ Deferred break through finally"); 964 Comment cmnt(masm(), "[ Deferred break through finally");
965 current->Exit(&stack_depth, &context_length); 965 current->Exit(&context_length);
966 DCHECK_EQ(0, stack_depth); 966 DCHECK_EQ(-1, context_length);
967 DCHECK_EQ(0, context_length);
968 current->AsTryFinally()->deferred_commands()->RecordBreak(target); 967 current->AsTryFinally()->deferred_commands()->RecordBreak(target);
969 return; 968 return;
970 } 969 }
971 current = current->Exit(&stack_depth, &context_length); 970 current = current->Exit(&context_length);
972 } 971 }
973 __ Drop(stack_depth); 972 int stack_depth = current->GetStackDepthAtTarget();
973 int stack_drop = operand_stack_depth_ - stack_depth;
974 DCHECK_GE(stack_drop, 0);
975 __ Drop(stack_drop);
974 if (context_length > 0) { 976 if (context_length > 0) {
975 while (context_length > 0) { 977 while (context_length > 0) {
976 LoadContextField(context_register(), Context::PREVIOUS_INDEX); 978 LoadContextField(context_register(), Context::PREVIOUS_INDEX);
977 --context_length; 979 --context_length;
978 } 980 }
979 StoreToFrameField(StandardFrameConstants::kContextOffset, 981 StoreToFrameField(StandardFrameConstants::kContextOffset,
980 context_register()); 982 context_register());
981 } 983 }
982 984
983 __ jmp(current->AsBreakable()->break_label()); 985 __ jmp(current->AsBreakable()->break_label());
984 } 986 }
985 987
986 void FullCodeGenerator::VisitBreakStatement(BreakStatement* stmt) { 988 void FullCodeGenerator::VisitBreakStatement(BreakStatement* stmt) {
987 Comment cmnt(masm_, "[ BreakStatement"); 989 Comment cmnt(masm_, "[ BreakStatement");
988 SetStatementPosition(stmt); 990 SetStatementPosition(stmt);
989 EmitBreak(stmt->target()); 991 EmitBreak(stmt->target());
990 } 992 }
991 993
992 void FullCodeGenerator::EmitUnwindAndReturn() { 994 void FullCodeGenerator::EmitUnwindAndReturn() {
993 NestedStatement* current = nesting_stack_; 995 NestedStatement* current = nesting_stack_;
994 int stack_depth = 0;
995 int context_length = 0; 996 int context_length = 0;
996 while (current != NULL) { 997 while (current != NULL) {
997 if (current->IsTryFinally()) { 998 if (current->IsTryFinally()) {
998 Comment cmnt(masm(), "[ Deferred return through finally"); 999 Comment cmnt(masm(), "[ Deferred return through finally");
999 current->Exit(&stack_depth, &context_length); 1000 current->Exit(&context_length);
1000 DCHECK_EQ(0, stack_depth); 1001 DCHECK_EQ(-1, context_length);
1001 DCHECK_EQ(0, context_length);
1002 current->AsTryFinally()->deferred_commands()->RecordReturn(); 1002 current->AsTryFinally()->deferred_commands()->RecordReturn();
1003 return; 1003 return;
1004 } 1004 }
1005 current = current->Exit(&stack_depth, &context_length); 1005 current = current->Exit(&context_length);
1006 } 1006 }
1007 __ Drop(stack_depth);
1008 EmitReturnSequence(); 1007 EmitReturnSequence();
1009 } 1008 }
1010 1009
1011 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { 1010 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
1012 // Stack: receiver, home_object 1011 // Stack: receiver, home_object
1013 SetExpressionPosition(prop); 1012 SetExpressionPosition(prop);
1014 Literal* key = prop->key()->AsLiteral(); 1013 Literal* key = prop->key()->AsLiteral();
1015 DCHECK(!key->value()->IsSmi()); 1014 DCHECK(!key->value()->IsSmi());
1016 DCHECK(prop->IsSuperAccess()); 1015 DCHECK(prop->IsSuperAccess());
1017 1016
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
1274 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); 1273 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register());
1275 scope_ = saved_scope; 1274 scope_ = saved_scope;
1276 __ jmp(&exit); 1275 __ jmp(&exit);
1277 1276
1278 // Try block code. Sets up the exception handler chain. 1277 // Try block code. Sets up the exception handler chain.
1279 __ bind(&try_entry); 1278 __ bind(&try_entry);
1280 1279
1281 try_catch_depth_++; 1280 try_catch_depth_++;
1282 int handler_index = NewHandlerTableEntry(); 1281 int handler_index = NewHandlerTableEntry();
1283 EnterTryBlock(handler_index, &handler_entry); 1282 EnterTryBlock(handler_index, &handler_entry);
1284 { TryCatch try_body(this); 1283 {
1284 Comment cmnt_try(masm(), "[ Try block");
1285 Visit(stmt->try_block()); 1285 Visit(stmt->try_block());
1286 } 1286 }
1287 ExitTryBlock(handler_index); 1287 ExitTryBlock(handler_index);
1288 try_catch_depth_--; 1288 try_catch_depth_--;
1289 __ bind(&exit); 1289 __ bind(&exit);
1290 } 1290 }
1291 1291
1292 1292
1293 void FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) { 1293 void FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
1294 Comment cmnt(masm_, "[ TryFinallyStatement"); 1294 Comment cmnt(masm_, "[ TryFinallyStatement");
(...skipping 20 matching lines...) Expand all
1315 Label try_entry, handler_entry, finally_entry; 1315 Label try_entry, handler_entry, finally_entry;
1316 DeferredCommands deferred(this, &finally_entry); 1316 DeferredCommands deferred(this, &finally_entry);
1317 1317
1318 // Jump to try-handler setup and try-block code. 1318 // Jump to try-handler setup and try-block code.
1319 __ jmp(&try_entry); 1319 __ jmp(&try_entry);
1320 __ bind(&handler_entry); 1320 __ bind(&handler_entry);
1321 1321
1322 // Exception handler code. This code is only executed when an exception 1322 // Exception handler code. This code is only executed when an exception
1323 // is thrown. Record the continuation and jump to the finally block. 1323 // is thrown. Record the continuation and jump to the finally block.
1324 { 1324 {
1325 Comment cmt_handler(masm(), "[ Finally handler"); 1325 Comment cmnt_handler(masm(), "[ Finally handler");
1326 deferred.RecordThrow(); 1326 deferred.RecordThrow();
1327 } 1327 }
1328 1328
1329 // Set up try handler. 1329 // Set up try handler.
1330 __ bind(&try_entry); 1330 __ bind(&try_entry);
1331 int handler_index = NewHandlerTableEntry(); 1331 int handler_index = NewHandlerTableEntry();
1332 EnterTryBlock(handler_index, &handler_entry); 1332 EnterTryBlock(handler_index, &handler_entry);
1333 { 1333 {
1334 Comment cmnt_try(masm(), "[ Try block");
1334 TryFinally try_body(this, &deferred); 1335 TryFinally try_body(this, &deferred);
1335 Visit(stmt->try_block()); 1336 Visit(stmt->try_block());
1336 } 1337 }
1337 ExitTryBlock(handler_index); 1338 ExitTryBlock(handler_index);
1338 // Execute the finally block on the way out. Clobber the unpredictable 1339 // Execute the finally block on the way out. Clobber the unpredictable
1339 // value in the result register with one that's safe for GC because the 1340 // value in the result register with one that's safe for GC because the
1340 // finally block will unconditionally preserve the result register on the 1341 // finally block will unconditionally preserve the result register on the
1341 // stack. 1342 // stack.
1342 ClearAccumulator(); 1343 ClearAccumulator();
1343 deferred.EmitFallThrough(); 1344 deferred.EmitFallThrough();
1344 // Fall through to the finally block. 1345 // Fall through to the finally block.
1345 1346
1346 // Finally block implementation. 1347 // Finally block implementation.
1347 __ bind(&finally_entry); 1348 __ bind(&finally_entry);
1348 Comment cmnt_finally(masm(), "[ Finally block");
1349 OperandStackDepthIncrement(2); // Token and accumulator are on stack.
1350 EnterFinallyBlock();
1351 { 1349 {
1352 Finally finally_body(this); 1350 Comment cmnt_finally(masm(), "[ Finally block");
1351 OperandStackDepthIncrement(2); // Token and accumulator are on stack.
1352 EnterFinallyBlock();
1353 Visit(stmt->finally_block()); 1353 Visit(stmt->finally_block());
1354 ExitFinallyBlock();
1355 OperandStackDepthDecrement(2); // Token and accumulator were on stack.
1354 } 1356 }
1355 ExitFinallyBlock();
1356 OperandStackDepthDecrement(2); // Token and accumulator were on stack.
1357 1357
1358 { 1358 {
1359 Comment cmnt_deferred(masm(), "[ Post-finally dispatch"); 1359 Comment cmnt_deferred(masm(), "[ Post-finally dispatch");
1360 deferred.EmitCommands(); // Return to the calling code. 1360 deferred.EmitCommands(); // Return to the calling code.
1361 } 1361 }
1362 } 1362 }
1363 1363
1364 1364
1365 void FullCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) { 1365 void FullCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) {
1366 Comment cmnt(masm_, "[ DebuggerStatement"); 1366 Comment cmnt(masm_, "[ DebuggerStatement");
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
1592 1592
1593 void FullCodeGenerator::VisitEmptyParentheses(EmptyParentheses* expr) { 1593 void FullCodeGenerator::VisitEmptyParentheses(EmptyParentheses* expr) {
1594 UNREACHABLE(); 1594 UNREACHABLE();
1595 } 1595 }
1596 1596
1597 1597
1598 void FullCodeGenerator::VisitRewritableExpression(RewritableExpression* expr) { 1598 void FullCodeGenerator::VisitRewritableExpression(RewritableExpression* expr) {
1599 Visit(expr->expression()); 1599 Visit(expr->expression());
1600 } 1600 }
1601 1601
1602 FullCodeGenerator::NestedStatement* FullCodeGenerator::TryFinally::Exit(
1603 int* context_length) {
1604 // The macros used here must preserve the result register.
1602 1605
1603 FullCodeGenerator::NestedStatement* FullCodeGenerator::TryFinally::Exit( 1606 // Calculate how many operands to drop to get down to handler block.
1604 int* stack_depth, int* context_length) { 1607 int stack_drop = codegen_->operand_stack_depth_ - GetStackDepthAtTarget();
1605 // The macros used here must preserve the result register. 1608 DCHECK_GE(stack_drop, 0);
1606 1609
1607 // Because the handler block contains the context of the finally 1610 // Because the handler block contains the context of the finally
1608 // code, we can restore it directly from there for the finally code 1611 // code, we can restore it directly from there for the finally code
1609 // rather than iteratively unwinding contexts via their previous 1612 // rather than iteratively unwinding contexts via their previous
1610 // links. 1613 // links.
1611 if (*context_length > 0) { 1614 if (*context_length > 0) {
1612 __ Drop(*stack_depth); // Down to the handler block. 1615 __ Drop(stack_drop); // Down to the handler block.
1613 // Restore the context to its dedicated register and the stack. 1616 // Restore the context to its dedicated register and the stack.
1614 STATIC_ASSERT(TryFinally::kElementCount == 1); 1617 STATIC_ASSERT(TryBlockConstant::kElementCount == 1);
1615 __ Pop(codegen_->context_register()); 1618 __ Pop(codegen_->context_register());
1616 codegen_->StoreToFrameField(StandardFrameConstants::kContextOffset, 1619 codegen_->StoreToFrameField(StandardFrameConstants::kContextOffset,
1617 codegen_->context_register()); 1620 codegen_->context_register());
1618 } else { 1621 } else {
1619 // Down to the handler block and also drop context. 1622 // Down to the handler block and also drop context.
1620 __ Drop(*stack_depth + kElementCount); 1623 __ Drop(stack_drop + TryBlockConstant::kElementCount);
1621 } 1624 }
1622 *stack_depth = 0; 1625
1623 *context_length = 0; 1626 // The caller will ignore outputs.
1627 *context_length = -1;
1624 return previous_; 1628 return previous_;
1625 } 1629 }
1626 1630
1627 void FullCodeGenerator::DeferredCommands::RecordBreak(Statement* target) { 1631 void FullCodeGenerator::DeferredCommands::RecordBreak(Statement* target) {
1628 TokenId token = dispenser_.GetBreakContinueToken(); 1632 TokenId token = dispenser_.GetBreakContinueToken();
1629 commands_.push_back({kBreak, token, target}); 1633 commands_.push_back({kBreak, token, target});
1630 EmitJumpToFinally(token); 1634 EmitJumpToFinally(token);
1631 } 1635 }
1632 1636
1633 void FullCodeGenerator::DeferredCommands::RecordContinue(Statement* target) { 1637 void FullCodeGenerator::DeferredCommands::RecordContinue(Statement* target) {
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
1879 return var->mode() == CONST_LEGACY || var->scope()->is_nonlinear() || 1883 return var->mode() == CONST_LEGACY || var->scope()->is_nonlinear() ||
1880 var->initializer_position() >= proxy->position(); 1884 var->initializer_position() >= proxy->position();
1881 } 1885 }
1882 1886
1883 1887
1884 #undef __ 1888 #undef __
1885 1889
1886 1890
1887 } // namespace internal 1891 } // namespace internal
1888 } // namespace v8 1892 } // namespace v8
OLDNEW
« no previous file with comments | « src/full-codegen/full-codegen.h ('k') | src/full-codegen/ia32/full-codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698