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