| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 653 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 664 const FullCodeGenerator::InlineFunctionGenerator | 664 const FullCodeGenerator::InlineFunctionGenerator |
| 665 FullCodeGenerator::kInlineFunctionGenerators[] = { | 665 FullCodeGenerator::kInlineFunctionGenerators[] = { |
| 666 INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS) | 666 INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS) |
| 667 INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS) | 667 INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS) |
| 668 }; | 668 }; |
| 669 #undef INLINE_FUNCTION_GENERATOR_ADDRESS | 669 #undef INLINE_FUNCTION_GENERATOR_ADDRESS |
| 670 | 670 |
| 671 | 671 |
| 672 FullCodeGenerator::InlineFunctionGenerator | 672 FullCodeGenerator::InlineFunctionGenerator |
| 673 FullCodeGenerator::FindInlineFunctionGenerator(Runtime::FunctionId id) { | 673 FullCodeGenerator::FindInlineFunctionGenerator(Runtime::FunctionId id) { |
| 674 return kInlineFunctionGenerators[ | 674 int lookup_index = |
| 675 static_cast<int>(id) - static_cast<int>(Runtime::kFirstInlineFunction)]; | 675 static_cast<int>(id) - static_cast<int>(Runtime::kFirstInlineFunction); |
| 676 ASSERT(lookup_index >= 0); |
| 677 ASSERT(static_cast<size_t>(lookup_index) < |
| 678 ARRAY_SIZE(kInlineFunctionGenerators)); |
| 679 return kInlineFunctionGenerators[lookup_index]; |
| 676 } | 680 } |
| 677 | 681 |
| 678 | 682 |
| 679 void FullCodeGenerator::EmitInlineRuntimeCall(CallRuntime* node) { | 683 void FullCodeGenerator::EmitInlineRuntimeCall(CallRuntime* node) { |
| 680 ZoneList<Expression*>* args = node->arguments(); | 684 ZoneList<Expression*>* args = node->arguments(); |
| 681 Handle<String> name = node->name(); | 685 Handle<String> name = node->name(); |
| 682 Runtime::Function* function = node->function(); | 686 Runtime::Function* function = node->function(); |
| 683 ASSERT(function != NULL); | 687 ASSERT(function != NULL); |
| 684 ASSERT(function->intrinsic_type == Runtime::INLINE); | 688 ASSERT(function->intrinsic_type == Runtime::INLINE); |
| 685 InlineFunctionGenerator generator = | 689 InlineFunctionGenerator generator = |
| 686 FindInlineFunctionGenerator(function->function_id); | 690 FindInlineFunctionGenerator(function->function_id); |
| 687 ASSERT(generator != NULL); | |
| 688 ((*this).*(generator))(args); | 691 ((*this).*(generator))(args); |
| 689 } | 692 } |
| 690 | 693 |
| 691 | 694 |
| 692 void FullCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { | 695 void FullCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { |
| 693 Comment cmnt(masm_, "[ BinaryOperation"); | 696 Comment cmnt(masm_, "[ BinaryOperation"); |
| 694 Token::Value op = expr->op(); | 697 Token::Value op = expr->op(); |
| 695 Expression* left = expr->left(); | 698 Expression* left = expr->left(); |
| 696 Expression* right = expr->right(); | 699 Expression* right = expr->right(); |
| 697 | 700 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 754 UNREACHABLE(); | 757 UNREACHABLE(); |
| 755 } | 758 } |
| 756 } | 759 } |
| 757 | 760 |
| 758 | 761 |
| 759 void FullCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) { | 762 void FullCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) { |
| 760 Label eval_right, done; | 763 Label eval_right, done; |
| 761 | 764 |
| 762 context()->EmitLogicalLeft(expr, &eval_right, &done); | 765 context()->EmitLogicalLeft(expr, &eval_right, &done); |
| 763 | 766 |
| 767 PrepareForBailoutForId(expr->RightId(), NO_REGISTERS); |
| 764 __ bind(&eval_right); | 768 __ bind(&eval_right); |
| 765 if (context()->IsTest()) ForwardBailoutToChild(expr); | 769 if (context()->IsTest()) ForwardBailoutToChild(expr); |
| 766 context()->HandleExpression(expr->right()); | 770 context()->HandleExpression(expr->right()); |
| 767 | 771 |
| 768 __ bind(&done); | 772 __ bind(&done); |
| 769 } | 773 } |
| 770 | 774 |
| 771 | 775 |
| 772 void FullCodeGenerator::EffectContext::EmitLogicalLeft(BinaryOperation* expr, | 776 void FullCodeGenerator::EffectContext::EmitLogicalLeft(BinaryOperation* expr, |
| 773 Label* eval_right, | 777 Label* eval_right, |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 918 } | 922 } |
| 919 | 923 |
| 920 | 924 |
| 921 void FullCodeGenerator::VisitIfStatement(IfStatement* stmt) { | 925 void FullCodeGenerator::VisitIfStatement(IfStatement* stmt) { |
| 922 Comment cmnt(masm_, "[ IfStatement"); | 926 Comment cmnt(masm_, "[ IfStatement"); |
| 923 SetStatementPosition(stmt); | 927 SetStatementPosition(stmt); |
| 924 Label then_part, else_part, done; | 928 Label then_part, else_part, done; |
| 925 | 929 |
| 926 if (stmt->HasElseStatement()) { | 930 if (stmt->HasElseStatement()) { |
| 927 VisitForControl(stmt->condition(), &then_part, &else_part, &then_part); | 931 VisitForControl(stmt->condition(), &then_part, &else_part, &then_part); |
| 932 PrepareForBailoutForId(stmt->ThenId(), NO_REGISTERS); |
| 928 __ bind(&then_part); | 933 __ bind(&then_part); |
| 929 Visit(stmt->then_statement()); | 934 Visit(stmt->then_statement()); |
| 930 __ jmp(&done); | 935 __ jmp(&done); |
| 931 | 936 |
| 937 PrepareForBailoutForId(stmt->ElseId(), NO_REGISTERS); |
| 932 __ bind(&else_part); | 938 __ bind(&else_part); |
| 933 Visit(stmt->else_statement()); | 939 Visit(stmt->else_statement()); |
| 934 } else { | 940 } else { |
| 935 VisitForControl(stmt->condition(), &then_part, &done, &then_part); | 941 VisitForControl(stmt->condition(), &then_part, &done, &then_part); |
| 942 PrepareForBailoutForId(stmt->ThenId(), NO_REGISTERS); |
| 936 __ bind(&then_part); | 943 __ bind(&then_part); |
| 937 Visit(stmt->then_statement()); | 944 Visit(stmt->then_statement()); |
| 945 |
| 946 PrepareForBailoutForId(stmt->ElseId(), NO_REGISTERS); |
| 938 } | 947 } |
| 939 __ bind(&done); | 948 __ bind(&done); |
| 940 PrepareForBailoutForId(stmt->id(), NO_REGISTERS); | 949 PrepareForBailoutForId(stmt->id(), NO_REGISTERS); |
| 941 } | 950 } |
| 942 | 951 |
| 943 | 952 |
| 944 void FullCodeGenerator::VisitContinueStatement(ContinueStatement* stmt) { | 953 void FullCodeGenerator::VisitContinueStatement(ContinueStatement* stmt) { |
| 945 Comment cmnt(masm_, "[ ContinueStatement"); | 954 Comment cmnt(masm_, "[ ContinueStatement"); |
| 946 SetStatementPosition(stmt); | 955 SetStatementPosition(stmt); |
| 947 NestedStatement* current = nesting_stack_; | 956 NestedStatement* current = nesting_stack_; |
| 948 int stack_depth = 0; | 957 int stack_depth = 0; |
| 958 // When continuing, we clobber the unpredictable value in the accumulator |
| 959 // with one that's safe for GC. If we hit an exit from the try block of |
| 960 // try...finally on our way out, we will unconditionally preserve the |
| 961 // accumulator on the stack. |
| 962 ClearAccumulator(); |
| 949 while (!current->IsContinueTarget(stmt->target())) { | 963 while (!current->IsContinueTarget(stmt->target())) { |
| 950 stack_depth = current->Exit(stack_depth); | 964 stack_depth = current->Exit(stack_depth); |
| 951 current = current->outer(); | 965 current = current->outer(); |
| 952 } | 966 } |
| 953 __ Drop(stack_depth); | 967 __ Drop(stack_depth); |
| 954 | 968 |
| 955 Iteration* loop = current->AsIteration(); | 969 Iteration* loop = current->AsIteration(); |
| 956 __ jmp(loop->continue_target()); | 970 __ jmp(loop->continue_target()); |
| 957 } | 971 } |
| 958 | 972 |
| 959 | 973 |
| 960 void FullCodeGenerator::VisitBreakStatement(BreakStatement* stmt) { | 974 void FullCodeGenerator::VisitBreakStatement(BreakStatement* stmt) { |
| 961 Comment cmnt(masm_, "[ BreakStatement"); | 975 Comment cmnt(masm_, "[ BreakStatement"); |
| 962 SetStatementPosition(stmt); | 976 SetStatementPosition(stmt); |
| 963 NestedStatement* current = nesting_stack_; | 977 NestedStatement* current = nesting_stack_; |
| 964 int stack_depth = 0; | 978 int stack_depth = 0; |
| 979 // When breaking, we clobber the unpredictable value in the accumulator |
| 980 // with one that's safe for GC. If we hit an exit from the try block of |
| 981 // try...finally on our way out, we will unconditionally preserve the |
| 982 // accumulator on the stack. |
| 983 ClearAccumulator(); |
| 965 while (!current->IsBreakTarget(stmt->target())) { | 984 while (!current->IsBreakTarget(stmt->target())) { |
| 966 stack_depth = current->Exit(stack_depth); | 985 stack_depth = current->Exit(stack_depth); |
| 967 current = current->outer(); | 986 current = current->outer(); |
| 968 } | 987 } |
| 969 __ Drop(stack_depth); | 988 __ Drop(stack_depth); |
| 970 | 989 |
| 971 Breakable* target = current->AsBreakable(); | 990 Breakable* target = current->AsBreakable(); |
| 972 __ jmp(target->break_target()); | 991 __ jmp(target->break_target()); |
| 973 } | 992 } |
| 974 | 993 |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1036 // possible to break on the condition. | 1055 // possible to break on the condition. |
| 1037 __ bind(loop_statement.continue_target()); | 1056 __ bind(loop_statement.continue_target()); |
| 1038 PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS); | 1057 PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS); |
| 1039 SetExpressionPosition(stmt->cond(), stmt->condition_position()); | 1058 SetExpressionPosition(stmt->cond(), stmt->condition_position()); |
| 1040 VisitForControl(stmt->cond(), | 1059 VisitForControl(stmt->cond(), |
| 1041 &stack_check, | 1060 &stack_check, |
| 1042 loop_statement.break_target(), | 1061 loop_statement.break_target(), |
| 1043 &stack_check); | 1062 &stack_check); |
| 1044 | 1063 |
| 1045 // Check stack before looping. | 1064 // Check stack before looping. |
| 1065 PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS); |
| 1046 __ bind(&stack_check); | 1066 __ bind(&stack_check); |
| 1047 EmitStackCheck(stmt); | 1067 EmitStackCheck(stmt); |
| 1048 __ jmp(&body); | 1068 __ jmp(&body); |
| 1049 | 1069 |
| 1070 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); |
| 1050 __ bind(loop_statement.break_target()); | 1071 __ bind(loop_statement.break_target()); |
| 1051 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); | |
| 1052 decrement_loop_depth(); | 1072 decrement_loop_depth(); |
| 1053 } | 1073 } |
| 1054 | 1074 |
| 1055 | 1075 |
| 1056 void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) { | 1076 void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) { |
| 1057 Comment cmnt(masm_, "[ WhileStatement"); | 1077 Comment cmnt(masm_, "[ WhileStatement"); |
| 1058 Label test, body; | 1078 Label test, body; |
| 1059 | 1079 |
| 1060 Iteration loop_statement(this, stmt); | 1080 Iteration loop_statement(this, stmt); |
| 1061 increment_loop_depth(); | 1081 increment_loop_depth(); |
| 1062 | 1082 |
| 1063 // Emit the test at the bottom of the loop. | 1083 // Emit the test at the bottom of the loop. |
| 1064 __ jmp(&test); | 1084 __ jmp(&test); |
| 1065 | 1085 |
| 1086 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); |
| 1066 __ bind(&body); | 1087 __ bind(&body); |
| 1067 Visit(stmt->body()); | 1088 Visit(stmt->body()); |
| 1068 | 1089 |
| 1069 // Emit the statement position here as this is where the while | 1090 // Emit the statement position here as this is where the while |
| 1070 // statement code starts. | 1091 // statement code starts. |
| 1071 __ bind(loop_statement.continue_target()); | 1092 __ bind(loop_statement.continue_target()); |
| 1072 SetStatementPosition(stmt); | 1093 SetStatementPosition(stmt); |
| 1073 | 1094 |
| 1074 // Check stack before looping. | 1095 // Check stack before looping. |
| 1075 EmitStackCheck(stmt); | 1096 EmitStackCheck(stmt); |
| 1076 | 1097 |
| 1077 __ bind(&test); | 1098 __ bind(&test); |
| 1078 VisitForControl(stmt->cond(), | 1099 VisitForControl(stmt->cond(), |
| 1079 &body, | 1100 &body, |
| 1080 loop_statement.break_target(), | 1101 loop_statement.break_target(), |
| 1081 loop_statement.break_target()); | 1102 loop_statement.break_target()); |
| 1082 | 1103 |
| 1104 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); |
| 1083 __ bind(loop_statement.break_target()); | 1105 __ bind(loop_statement.break_target()); |
| 1084 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); | |
| 1085 decrement_loop_depth(); | 1106 decrement_loop_depth(); |
| 1086 } | 1107 } |
| 1087 | 1108 |
| 1088 | 1109 |
| 1089 void FullCodeGenerator::VisitForStatement(ForStatement* stmt) { | 1110 void FullCodeGenerator::VisitForStatement(ForStatement* stmt) { |
| 1090 Comment cmnt(masm_, "[ ForStatement"); | 1111 Comment cmnt(masm_, "[ ForStatement"); |
| 1091 Label test, body; | 1112 Label test, body; |
| 1092 | 1113 |
| 1093 Iteration loop_statement(this, stmt); | 1114 Iteration loop_statement(this, stmt); |
| 1094 if (stmt->init() != NULL) { | 1115 if (stmt->init() != NULL) { |
| 1095 Visit(stmt->init()); | 1116 Visit(stmt->init()); |
| 1096 } | 1117 } |
| 1097 | 1118 |
| 1098 increment_loop_depth(); | 1119 increment_loop_depth(); |
| 1099 // Emit the test at the bottom of the loop (even if empty). | 1120 // Emit the test at the bottom of the loop (even if empty). |
| 1100 __ jmp(&test); | 1121 __ jmp(&test); |
| 1101 | 1122 |
| 1123 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); |
| 1102 __ bind(&body); | 1124 __ bind(&body); |
| 1103 Visit(stmt->body()); | 1125 Visit(stmt->body()); |
| 1104 | 1126 |
| 1127 PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS); |
| 1105 __ bind(loop_statement.continue_target()); | 1128 __ bind(loop_statement.continue_target()); |
| 1106 PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS); | |
| 1107 | |
| 1108 SetStatementPosition(stmt); | 1129 SetStatementPosition(stmt); |
| 1109 if (stmt->next() != NULL) { | 1130 if (stmt->next() != NULL) { |
| 1110 Visit(stmt->next()); | 1131 Visit(stmt->next()); |
| 1111 } | 1132 } |
| 1112 | 1133 |
| 1113 // Emit the statement position here as this is where the for | 1134 // Emit the statement position here as this is where the for |
| 1114 // statement code starts. | 1135 // statement code starts. |
| 1115 SetStatementPosition(stmt); | 1136 SetStatementPosition(stmt); |
| 1116 | 1137 |
| 1117 // Check stack before looping. | 1138 // Check stack before looping. |
| 1118 EmitStackCheck(stmt); | 1139 EmitStackCheck(stmt); |
| 1119 | 1140 |
| 1120 __ bind(&test); | 1141 __ bind(&test); |
| 1121 if (stmt->cond() != NULL) { | 1142 if (stmt->cond() != NULL) { |
| 1122 VisitForControl(stmt->cond(), | 1143 VisitForControl(stmt->cond(), |
| 1123 &body, | 1144 &body, |
| 1124 loop_statement.break_target(), | 1145 loop_statement.break_target(), |
| 1125 loop_statement.break_target()); | 1146 loop_statement.break_target()); |
| 1126 } else { | 1147 } else { |
| 1127 __ jmp(&body); | 1148 __ jmp(&body); |
| 1128 } | 1149 } |
| 1129 | 1150 |
| 1151 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); |
| 1130 __ bind(loop_statement.break_target()); | 1152 __ bind(loop_statement.break_target()); |
| 1131 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); | |
| 1132 decrement_loop_depth(); | 1153 decrement_loop_depth(); |
| 1133 } | 1154 } |
| 1134 | 1155 |
| 1135 | 1156 |
| 1136 void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { | 1157 void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { |
| 1137 Comment cmnt(masm_, "[ TryCatchStatement"); | 1158 Comment cmnt(masm_, "[ TryCatchStatement"); |
| 1138 SetStatementPosition(stmt); | 1159 SetStatementPosition(stmt); |
| 1139 // The try block adds a handler to the exception handler chain | 1160 // The try block adds a handler to the exception handler chain |
| 1140 // before entering, and removes it again when exiting normally. | 1161 // before entering, and removes it again when exiting normally. |
| 1141 // If an exception is thrown during execution of the try block, | 1162 // If an exception is thrown during execution of the try block, |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1228 } | 1249 } |
| 1229 | 1250 |
| 1230 __ bind(&try_handler_setup); | 1251 __ bind(&try_handler_setup); |
| 1231 { | 1252 { |
| 1232 // Setup try handler (stack pointer registers). | 1253 // Setup try handler (stack pointer registers). |
| 1233 TryFinally try_block(this, &finally_entry); | 1254 TryFinally try_block(this, &finally_entry); |
| 1234 __ PushTryHandler(IN_JAVASCRIPT, TRY_FINALLY_HANDLER); | 1255 __ PushTryHandler(IN_JAVASCRIPT, TRY_FINALLY_HANDLER); |
| 1235 Visit(stmt->try_block()); | 1256 Visit(stmt->try_block()); |
| 1236 __ PopTryHandler(); | 1257 __ PopTryHandler(); |
| 1237 } | 1258 } |
| 1238 // Execute the finally block on the way out. | 1259 // Execute the finally block on the way out. Clobber the unpredictable |
| 1260 // value in the accumulator with one that's safe for GC. The finally |
| 1261 // block will unconditionally preserve the accumulator on the stack. |
| 1262 ClearAccumulator(); |
| 1239 __ Call(&finally_entry); | 1263 __ Call(&finally_entry); |
| 1240 } | 1264 } |
| 1241 | 1265 |
| 1242 | 1266 |
| 1243 void FullCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) { | 1267 void FullCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) { |
| 1244 #ifdef ENABLE_DEBUGGER_SUPPORT | 1268 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 1245 Comment cmnt(masm_, "[ DebuggerStatement"); | 1269 Comment cmnt(masm_, "[ DebuggerStatement"); |
| 1246 SetStatementPosition(stmt); | 1270 SetStatementPosition(stmt); |
| 1247 | 1271 |
| 1248 __ DebugBreak(); | 1272 __ DebugBreak(); |
| 1249 // Ignore the return value. | 1273 // Ignore the return value. |
| 1250 #endif | 1274 #endif |
| 1251 } | 1275 } |
| 1252 | 1276 |
| 1253 | 1277 |
| 1254 void FullCodeGenerator::VisitConditional(Conditional* expr) { | 1278 void FullCodeGenerator::VisitConditional(Conditional* expr) { |
| 1255 Comment cmnt(masm_, "[ Conditional"); | 1279 Comment cmnt(masm_, "[ Conditional"); |
| 1256 Label true_case, false_case, done; | 1280 Label true_case, false_case, done; |
| 1257 VisitForControl(expr->condition(), &true_case, &false_case, &true_case); | 1281 VisitForControl(expr->condition(), &true_case, &false_case, &true_case); |
| 1258 | 1282 |
| 1283 PrepareForBailoutForId(expr->ThenId(), NO_REGISTERS); |
| 1259 __ bind(&true_case); | 1284 __ bind(&true_case); |
| 1260 SetExpressionPosition(expr->then_expression(), | 1285 SetExpressionPosition(expr->then_expression(), |
| 1261 expr->then_expression_position()); | 1286 expr->then_expression_position()); |
| 1262 if (context()->IsTest()) { | 1287 if (context()->IsTest()) { |
| 1263 const TestContext* for_test = TestContext::cast(context()); | 1288 const TestContext* for_test = TestContext::cast(context()); |
| 1264 VisitForControl(expr->then_expression(), | 1289 VisitForControl(expr->then_expression(), |
| 1265 for_test->true_label(), | 1290 for_test->true_label(), |
| 1266 for_test->false_label(), | 1291 for_test->false_label(), |
| 1267 NULL); | 1292 NULL); |
| 1268 } else { | 1293 } else { |
| 1269 context()->HandleExpression(expr->then_expression()); | 1294 context()->HandleExpression(expr->then_expression()); |
| 1270 __ jmp(&done); | 1295 __ jmp(&done); |
| 1271 } | 1296 } |
| 1272 | 1297 |
| 1298 PrepareForBailoutForId(expr->ElseId(), NO_REGISTERS); |
| 1273 __ bind(&false_case); | 1299 __ bind(&false_case); |
| 1274 if (context()->IsTest()) ForwardBailoutToChild(expr); | 1300 if (context()->IsTest()) ForwardBailoutToChild(expr); |
| 1275 SetExpressionPosition(expr->else_expression(), | 1301 SetExpressionPosition(expr->else_expression(), |
| 1276 expr->else_expression_position()); | 1302 expr->else_expression_position()); |
| 1277 context()->HandleExpression(expr->else_expression()); | 1303 context()->HandleExpression(expr->else_expression()); |
| 1278 // If control flow falls through Visit, merge it with true case here. | 1304 // If control flow falls through Visit, merge it with true case here. |
| 1279 if (!context()->IsTest()) { | 1305 if (!context()->IsTest()) { |
| 1280 __ bind(&done); | 1306 __ bind(&done); |
| 1281 } | 1307 } |
| 1282 } | 1308 } |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1348 __ Drop(stack_depth); | 1374 __ Drop(stack_depth); |
| 1349 __ PopTryHandler(); | 1375 __ PopTryHandler(); |
| 1350 return 0; | 1376 return 0; |
| 1351 } | 1377 } |
| 1352 | 1378 |
| 1353 | 1379 |
| 1354 #undef __ | 1380 #undef __ |
| 1355 | 1381 |
| 1356 | 1382 |
| 1357 } } // namespace v8::internal | 1383 } } // namespace v8::internal |
| OLD | NEW |