| OLD | NEW | 
|---|
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 844 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 855       StoreToFrameField(StandardFrameConstants::kContextOffset, | 855       StoreToFrameField(StandardFrameConstants::kContextOffset, | 
| 856                         context_register()); | 856                         context_register()); | 
| 857     } | 857     } | 
| 858     { Comment cmnt(masm_, "[ Declarations"); | 858     { Comment cmnt(masm_, "[ Declarations"); | 
| 859       VisitDeclarations(scope_->declarations()); | 859       VisitDeclarations(scope_->declarations()); | 
| 860     } | 860     } | 
| 861   } | 861   } | 
| 862   PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); | 862   PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); | 
| 863   VisitStatements(stmt->statements()); | 863   VisitStatements(stmt->statements()); | 
| 864   scope_ = saved_scope; | 864   scope_ = saved_scope; | 
| 865   __ bind(nested_statement.break_target()); | 865   __ bind(nested_statement.break_label()); | 
| 866   PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); | 866   PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); | 
| 867 } | 867 } | 
| 868 | 868 | 
| 869 | 869 | 
| 870 void FullCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) { | 870 void FullCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) { | 
| 871   Comment cmnt(masm_, "[ ExpressionStatement"); | 871   Comment cmnt(masm_, "[ ExpressionStatement"); | 
| 872   SetStatementPosition(stmt); | 872   SetStatementPosition(stmt); | 
| 873   VisitForEffect(stmt->expression()); | 873   VisitForEffect(stmt->expression()); | 
| 874 } | 874 } | 
| 875 | 875 | 
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 925   __ Drop(stack_depth); | 925   __ Drop(stack_depth); | 
| 926   if (context_length > 0) { | 926   if (context_length > 0) { | 
| 927     while (context_length > 0) { | 927     while (context_length > 0) { | 
| 928       LoadContextField(context_register(), Context::PREVIOUS_INDEX); | 928       LoadContextField(context_register(), Context::PREVIOUS_INDEX); | 
| 929       --context_length; | 929       --context_length; | 
| 930     } | 930     } | 
| 931     StoreToFrameField(StandardFrameConstants::kContextOffset, | 931     StoreToFrameField(StandardFrameConstants::kContextOffset, | 
| 932                       context_register()); | 932                       context_register()); | 
| 933   } | 933   } | 
| 934 | 934 | 
| 935   Iteration* loop = current->AsIteration(); | 935   __ jmp(current->AsIteration()->continue_label()); | 
| 936   __ jmp(loop->continue_target()); |  | 
| 937 } | 936 } | 
| 938 | 937 | 
| 939 | 938 | 
| 940 void FullCodeGenerator::VisitBreakStatement(BreakStatement* stmt) { | 939 void FullCodeGenerator::VisitBreakStatement(BreakStatement* stmt) { | 
| 941   Comment cmnt(masm_,  "[ BreakStatement"); | 940   Comment cmnt(masm_,  "[ BreakStatement"); | 
| 942   SetStatementPosition(stmt); | 941   SetStatementPosition(stmt); | 
| 943   NestedStatement* current = nesting_stack_; | 942   NestedStatement* current = nesting_stack_; | 
| 944   int stack_depth = 0; | 943   int stack_depth = 0; | 
| 945   int context_length = 0; | 944   int context_length = 0; | 
| 946   // When breaking, we clobber the unpredictable value in the accumulator | 945   // When breaking, we clobber the unpredictable value in the accumulator | 
| 947   // with one that's safe for GC.  If we hit an exit from the try block of | 946   // with one that's safe for GC.  If we hit an exit from the try block of | 
| 948   // try...finally on our way out, we will unconditionally preserve the | 947   // try...finally on our way out, we will unconditionally preserve the | 
| 949   // accumulator on the stack. | 948   // accumulator on the stack. | 
| 950   ClearAccumulator(); | 949   ClearAccumulator(); | 
| 951   while (!current->IsBreakTarget(stmt->target())) { | 950   while (!current->IsBreakTarget(stmt->target())) { | 
| 952     current = current->Exit(&stack_depth, &context_length); | 951     current = current->Exit(&stack_depth, &context_length); | 
| 953   } | 952   } | 
| 954   __ Drop(stack_depth); | 953   __ Drop(stack_depth); | 
| 955   if (context_length > 0) { | 954   if (context_length > 0) { | 
| 956     while (context_length > 0) { | 955     while (context_length > 0) { | 
| 957       LoadContextField(context_register(), Context::PREVIOUS_INDEX); | 956       LoadContextField(context_register(), Context::PREVIOUS_INDEX); | 
| 958       --context_length; | 957       --context_length; | 
| 959     } | 958     } | 
| 960     StoreToFrameField(StandardFrameConstants::kContextOffset, | 959     StoreToFrameField(StandardFrameConstants::kContextOffset, | 
| 961                       context_register()); | 960                       context_register()); | 
| 962   } | 961   } | 
| 963 | 962 | 
| 964   Breakable* target = current->AsBreakable(); | 963   __ jmp(current->AsBreakable()->break_label()); | 
| 965   __ jmp(target->break_target()); |  | 
| 966 } | 964 } | 
| 967 | 965 | 
| 968 | 966 | 
| 969 void FullCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { | 967 void FullCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { | 
| 970   Comment cmnt(masm_, "[ ReturnStatement"); | 968   Comment cmnt(masm_, "[ ReturnStatement"); | 
| 971   SetStatementPosition(stmt); | 969   SetStatementPosition(stmt); | 
| 972   Expression* expr = stmt->expression(); | 970   Expression* expr = stmt->expression(); | 
| 973   VisitForAccumulatorValue(expr); | 971   VisitForAccumulatorValue(expr); | 
| 974 | 972 | 
| 975   // Exit all nested statements. | 973   // Exit all nested statements. | 
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1023   Label body, stack_check; | 1021   Label body, stack_check; | 
| 1024 | 1022 | 
| 1025   Iteration loop_statement(this, stmt); | 1023   Iteration loop_statement(this, stmt); | 
| 1026   increment_loop_depth(); | 1024   increment_loop_depth(); | 
| 1027 | 1025 | 
| 1028   __ bind(&body); | 1026   __ bind(&body); | 
| 1029   Visit(stmt->body()); | 1027   Visit(stmt->body()); | 
| 1030 | 1028 | 
| 1031   // Record the position of the do while condition and make sure it is | 1029   // Record the position of the do while condition and make sure it is | 
| 1032   // possible to break on the condition. | 1030   // possible to break on the condition. | 
| 1033   __ bind(loop_statement.continue_target()); | 1031   __ bind(loop_statement.continue_label()); | 
| 1034   PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS); | 1032   PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS); | 
| 1035   SetExpressionPosition(stmt->cond(), stmt->condition_position()); | 1033   SetExpressionPosition(stmt->cond(), stmt->condition_position()); | 
| 1036   VisitForControl(stmt->cond(), | 1034   VisitForControl(stmt->cond(), | 
| 1037                   &stack_check, | 1035                   &stack_check, | 
| 1038                   loop_statement.break_target(), | 1036                   loop_statement.break_label(), | 
| 1039                   &stack_check); | 1037                   &stack_check); | 
| 1040 | 1038 | 
| 1041   // Check stack before looping. | 1039   // Check stack before looping. | 
| 1042   PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS); | 1040   PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS); | 
| 1043   __ bind(&stack_check); | 1041   __ bind(&stack_check); | 
| 1044   EmitStackCheck(stmt); | 1042   EmitStackCheck(stmt); | 
| 1045   __ jmp(&body); | 1043   __ jmp(&body); | 
| 1046 | 1044 | 
| 1047   PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); | 1045   PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); | 
| 1048   __ bind(loop_statement.break_target()); | 1046   __ bind(loop_statement.break_label()); | 
| 1049   decrement_loop_depth(); | 1047   decrement_loop_depth(); | 
| 1050 } | 1048 } | 
| 1051 | 1049 | 
| 1052 | 1050 | 
| 1053 void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) { | 1051 void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) { | 
| 1054   Comment cmnt(masm_, "[ WhileStatement"); | 1052   Comment cmnt(masm_, "[ WhileStatement"); | 
| 1055   Label test, body; | 1053   Label test, body; | 
| 1056 | 1054 | 
| 1057   Iteration loop_statement(this, stmt); | 1055   Iteration loop_statement(this, stmt); | 
| 1058   increment_loop_depth(); | 1056   increment_loop_depth(); | 
| 1059 | 1057 | 
| 1060   // Emit the test at the bottom of the loop. | 1058   // Emit the test at the bottom of the loop. | 
| 1061   __ jmp(&test); | 1059   __ jmp(&test); | 
| 1062 | 1060 | 
| 1063   PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); | 1061   PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); | 
| 1064   __ bind(&body); | 1062   __ bind(&body); | 
| 1065   Visit(stmt->body()); | 1063   Visit(stmt->body()); | 
| 1066 | 1064 | 
| 1067   // Emit the statement position here as this is where the while | 1065   // Emit the statement position here as this is where the while | 
| 1068   // statement code starts. | 1066   // statement code starts. | 
| 1069   __ bind(loop_statement.continue_target()); | 1067   __ bind(loop_statement.continue_label()); | 
| 1070   SetStatementPosition(stmt); | 1068   SetStatementPosition(stmt); | 
| 1071 | 1069 | 
| 1072   // Check stack before looping. | 1070   // Check stack before looping. | 
| 1073   EmitStackCheck(stmt); | 1071   EmitStackCheck(stmt); | 
| 1074 | 1072 | 
| 1075   __ bind(&test); | 1073   __ bind(&test); | 
| 1076   VisitForControl(stmt->cond(), | 1074   VisitForControl(stmt->cond(), | 
| 1077                   &body, | 1075                   &body, | 
| 1078                   loop_statement.break_target(), | 1076                   loop_statement.break_label(), | 
| 1079                   loop_statement.break_target()); | 1077                   loop_statement.break_label()); | 
| 1080 | 1078 | 
| 1081   PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); | 1079   PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); | 
| 1082   __ bind(loop_statement.break_target()); | 1080   __ bind(loop_statement.break_label()); | 
| 1083   decrement_loop_depth(); | 1081   decrement_loop_depth(); | 
| 1084 } | 1082 } | 
| 1085 | 1083 | 
| 1086 | 1084 | 
| 1087 void FullCodeGenerator::VisitForStatement(ForStatement* stmt) { | 1085 void FullCodeGenerator::VisitForStatement(ForStatement* stmt) { | 
| 1088   Comment cmnt(masm_, "[ ForStatement"); | 1086   Comment cmnt(masm_, "[ ForStatement"); | 
| 1089   Label test, body; | 1087   Label test, body; | 
| 1090 | 1088 | 
| 1091   Iteration loop_statement(this, stmt); | 1089   Iteration loop_statement(this, stmt); | 
| 1092   if (stmt->init() != NULL) { | 1090   if (stmt->init() != NULL) { | 
| 1093     Visit(stmt->init()); | 1091     Visit(stmt->init()); | 
| 1094   } | 1092   } | 
| 1095 | 1093 | 
| 1096   increment_loop_depth(); | 1094   increment_loop_depth(); | 
| 1097   // Emit the test at the bottom of the loop (even if empty). | 1095   // Emit the test at the bottom of the loop (even if empty). | 
| 1098   __ jmp(&test); | 1096   __ jmp(&test); | 
| 1099 | 1097 | 
| 1100   PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); | 1098   PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); | 
| 1101   __ bind(&body); | 1099   __ bind(&body); | 
| 1102   Visit(stmt->body()); | 1100   Visit(stmt->body()); | 
| 1103 | 1101 | 
| 1104   PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS); | 1102   PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS); | 
| 1105   __ bind(loop_statement.continue_target()); | 1103   __ bind(loop_statement.continue_label()); | 
| 1106   SetStatementPosition(stmt); | 1104   SetStatementPosition(stmt); | 
| 1107   if (stmt->next() != NULL) { | 1105   if (stmt->next() != NULL) { | 
| 1108     Visit(stmt->next()); | 1106     Visit(stmt->next()); | 
| 1109   } | 1107   } | 
| 1110 | 1108 | 
| 1111   // Emit the statement position here as this is where the for | 1109   // Emit the statement position here as this is where the for | 
| 1112   // statement code starts. | 1110   // statement code starts. | 
| 1113   SetStatementPosition(stmt); | 1111   SetStatementPosition(stmt); | 
| 1114 | 1112 | 
| 1115   // Check stack before looping. | 1113   // Check stack before looping. | 
| 1116   EmitStackCheck(stmt); | 1114   EmitStackCheck(stmt); | 
| 1117 | 1115 | 
| 1118   __ bind(&test); | 1116   __ bind(&test); | 
| 1119   if (stmt->cond() != NULL) { | 1117   if (stmt->cond() != NULL) { | 
| 1120     VisitForControl(stmt->cond(), | 1118     VisitForControl(stmt->cond(), | 
| 1121                     &body, | 1119                     &body, | 
| 1122                     loop_statement.break_target(), | 1120                     loop_statement.break_label(), | 
| 1123                     loop_statement.break_target()); | 1121                     loop_statement.break_label()); | 
| 1124   } else { | 1122   } else { | 
| 1125     __ jmp(&body); | 1123     __ jmp(&body); | 
| 1126   } | 1124   } | 
| 1127 | 1125 | 
| 1128   PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); | 1126   PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); | 
| 1129   __ bind(loop_statement.break_target()); | 1127   __ bind(loop_statement.break_label()); | 
| 1130   decrement_loop_depth(); | 1128   decrement_loop_depth(); | 
| 1131 } | 1129 } | 
| 1132 | 1130 | 
| 1133 | 1131 | 
| 1134 void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { | 1132 void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { | 
| 1135   Comment cmnt(masm_, "[ TryCatchStatement"); | 1133   Comment cmnt(masm_, "[ TryCatchStatement"); | 
| 1136   SetStatementPosition(stmt); | 1134   SetStatementPosition(stmt); | 
| 1137   // The try block adds a handler to the exception handler chain | 1135   // The try block adds a handler to the exception handler chain | 
| 1138   // before entering, and removes it again when exiting normally. | 1136   // before entering, and removes it again when exiting normally. | 
| 1139   // If an exception is thrown during execution of the try block, | 1137   // If an exception is thrown during execution of the try block, | 
| 1140   // control is passed to the handler, which also consumes the handler. | 1138   // control is passed to the handler, which also consumes the handler. | 
| 1141   // At this point, the exception is in a register, and store it in | 1139   // At this point, the exception is in a register, and store it in | 
| 1142   // the temporary local variable (prints as ".catch-var") before | 1140   // the temporary local variable (prints as ".catch-var") before | 
| 1143   // executing the catch block. The catch block has been rewritten | 1141   // executing the catch block. The catch block has been rewritten | 
| 1144   // to introduce a new scope to bind the catch variable and to remove | 1142   // to introduce a new scope to bind the catch variable and to remove | 
| 1145   // that scope again afterwards. | 1143   // that scope again afterwards. | 
| 1146 | 1144 | 
| 1147   Label try_handler_setup, catch_entry, done; | 1145   Label try_handler_setup, done; | 
| 1148   __ Call(&try_handler_setup); | 1146   __ Call(&try_handler_setup); | 
| 1149   // Try handler code, exception in result register. | 1147   // Try handler code, exception in result register. | 
| 1150 | 1148 | 
| 1151   // Extend the context before executing the catch block. | 1149   // Extend the context before executing the catch block. | 
| 1152   { Comment cmnt(masm_, "[ Extend catch context"); | 1150   { Comment cmnt(masm_, "[ Extend catch context"); | 
| 1153     __ Push(stmt->variable()->name()); | 1151     __ Push(stmt->variable()->name()); | 
| 1154     __ push(result_register()); | 1152     __ push(result_register()); | 
| 1155     PushFunctionArgumentForContextAllocation(); | 1153     PushFunctionArgumentForContextAllocation(); | 
| 1156     __ CallRuntime(Runtime::kPushCatchContext, 3); | 1154     __ CallRuntime(Runtime::kPushCatchContext, 3); | 
| 1157     StoreToFrameField(StandardFrameConstants::kContextOffset, | 1155     StoreToFrameField(StandardFrameConstants::kContextOffset, | 
| 1158                       context_register()); | 1156                       context_register()); | 
| 1159   } | 1157   } | 
| 1160 | 1158 | 
| 1161   Scope* saved_scope = scope(); | 1159   Scope* saved_scope = scope(); | 
| 1162   scope_ = stmt->scope(); | 1160   scope_ = stmt->scope(); | 
| 1163   ASSERT(scope_->declarations()->is_empty()); | 1161   ASSERT(scope_->declarations()->is_empty()); | 
| 1164   { WithOrCatch body(this); | 1162   { WithOrCatch body(this); | 
| 1165     Visit(stmt->catch_block()); | 1163     Visit(stmt->catch_block()); | 
| 1166   } | 1164   } | 
| 1167   scope_ = saved_scope; | 1165   scope_ = saved_scope; | 
| 1168   __ jmp(&done); | 1166   __ jmp(&done); | 
| 1169 | 1167 | 
| 1170   // Try block code. Sets up the exception handler chain. | 1168   // Try block code. Sets up the exception handler chain. | 
| 1171   __ bind(&try_handler_setup); | 1169   __ bind(&try_handler_setup); | 
| 1172   { | 1170   { | 
| 1173     TryCatch try_block(this, &catch_entry); | 1171     const int delta = StackHandlerConstants::kSize / kPointerSize; | 
|  | 1172     TryCatch try_block(this); | 
| 1174     __ PushTryHandler(IN_JAVASCRIPT, TRY_CATCH_HANDLER); | 1173     __ PushTryHandler(IN_JAVASCRIPT, TRY_CATCH_HANDLER); | 
| 1175     increment_stack_height(StackHandlerConstants::kSize / kPointerSize); | 1174     increment_stack_height(delta); | 
| 1176     Visit(stmt->try_block()); | 1175     Visit(stmt->try_block()); | 
| 1177     __ PopTryHandler(); | 1176     __ PopTryHandler(); | 
| 1178     decrement_stack_height(StackHandlerConstants::kSize / kPointerSize); | 1177     decrement_stack_height(delta); | 
| 1179   } | 1178   } | 
| 1180   __ bind(&done); | 1179   __ bind(&done); | 
| 1181 } | 1180 } | 
| 1182 | 1181 | 
| 1183 | 1182 | 
| 1184 void FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) { | 1183 void FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) { | 
| 1185   Comment cmnt(masm_, "[ TryFinallyStatement"); | 1184   Comment cmnt(masm_, "[ TryFinallyStatement"); | 
| 1186   SetStatementPosition(stmt); | 1185   SetStatementPosition(stmt); | 
| 1187   // Try finally is compiled by setting up a try-handler on the stack while | 1186   // Try finally is compiled by setting up a try-handler on the stack while | 
| 1188   // executing the try body, and removing it again afterwards. | 1187   // executing the try body, and removing it again afterwards. | 
| (...skipping 12 matching lines...) Expand all  Loading... | 
| 1201   //    rethrowing the exception. | 1200   //    rethrowing the exception. | 
| 1202   // | 1201   // | 
| 1203   // The finally block must assume a return address on top of the stack | 1202   // The finally block must assume a return address on top of the stack | 
| 1204   // (or in the link register on ARM chips) and a value (return value or | 1203   // (or in the link register on ARM chips) and a value (return value or | 
| 1205   // exception) in the result register (rax/eax/r0), both of which must | 1204   // exception) in the result register (rax/eax/r0), both of which must | 
| 1206   // be preserved. The return address isn't GC-safe, so it should be | 1205   // be preserved. The return address isn't GC-safe, so it should be | 
| 1207   // cooked before GC. | 1206   // cooked before GC. | 
| 1208   Label finally_entry; | 1207   Label finally_entry; | 
| 1209   Label try_handler_setup; | 1208   Label try_handler_setup; | 
| 1210   const int original_stack_height = stack_height(); | 1209   const int original_stack_height = stack_height(); | 
| 1211   const int finally_block_stack_height = original_stack_height + 2; |  | 
| 1212   const int try_block_stack_height = original_stack_height + 5; |  | 
| 1213   STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize); |  | 
| 1214 | 1210 | 
| 1215   // Setup the try-handler chain. Use a call to | 1211   // Setup the try-handler chain. Use a call to | 
| 1216   // Jump to try-handler setup and try-block code. Use call to put try-handler | 1212   // Jump to try-handler setup and try-block code. Use call to put try-handler | 
| 1217   // address on stack. | 1213   // address on stack. | 
| 1218   __ Call(&try_handler_setup); | 1214   __ Call(&try_handler_setup); | 
| 1219   // Try handler code. Return address of call is pushed on handler stack. | 1215   // Try handler code. Return address of call is pushed on handler stack. | 
| 1220   { | 1216   { | 
| 1221     // This code is only executed during stack-handler traversal when an | 1217     // This code is only executed during stack-handler traversal when an | 
| 1222     // exception is thrown. The execption is in the result register, which | 1218     // exception is thrown. The exception is in the result register, which | 
| 1223     // is retained by the finally block. | 1219     // is retained by the finally block. | 
| 1224     // Call the finally block and then rethrow the exception. | 1220     // Call the finally block and then rethrow the exception if it returns. | 
| 1225     __ Call(&finally_entry); | 1221     __ Call(&finally_entry); | 
| 1226     __ push(result_register()); | 1222     __ push(result_register()); | 
| 1227     __ CallRuntime(Runtime::kReThrow, 1); | 1223     __ CallRuntime(Runtime::kReThrow, 1); | 
| 1228   } | 1224   } | 
| 1229 | 1225 | 
| 1230   __ bind(&finally_entry); | 1226   __ bind(&finally_entry); | 
| 1231   { | 1227   { | 
| 1232     // Finally block implementation. | 1228     // Finally block implementation. | 
| 1233     Finally finally_block(this); | 1229     Finally finally_block(this); | 
| 1234     EnterFinallyBlock(); | 1230     EnterFinallyBlock(); | 
| 1235     set_stack_height(finally_block_stack_height); | 1231     set_stack_height(original_stack_height + Finally::kElementCount); | 
| 1236     Visit(stmt->finally_block()); | 1232     Visit(stmt->finally_block()); | 
| 1237     ExitFinallyBlock();  // Return to the calling code. | 1233     ExitFinallyBlock();  // Return to the calling code. | 
| 1238   } | 1234   } | 
| 1239 | 1235 | 
| 1240   __ bind(&try_handler_setup); | 1236   __ bind(&try_handler_setup); | 
| 1241   { | 1237   { | 
| 1242     // Setup try handler (stack pointer registers). | 1238     // Setup try handler (stack pointer registers). | 
|  | 1239     const int delta = StackHandlerConstants::kSize / kPointerSize; | 
| 1243     TryFinally try_block(this, &finally_entry); | 1240     TryFinally try_block(this, &finally_entry); | 
| 1244     __ PushTryHandler(IN_JAVASCRIPT, TRY_FINALLY_HANDLER); | 1241     __ PushTryHandler(IN_JAVASCRIPT, TRY_FINALLY_HANDLER); | 
| 1245     set_stack_height(try_block_stack_height); | 1242     set_stack_height(original_stack_height + delta); | 
| 1246     Visit(stmt->try_block()); | 1243     Visit(stmt->try_block()); | 
| 1247     __ PopTryHandler(); | 1244     __ PopTryHandler(); | 
| 1248     set_stack_height(original_stack_height); | 1245     set_stack_height(original_stack_height); | 
| 1249   } | 1246   } | 
| 1250   // Execute the finally block on the way out.  Clobber the unpredictable | 1247   // Execute the finally block on the way out.  Clobber the unpredictable | 
| 1251   // value in the accumulator with one that's safe for GC.  The finally | 1248   // value in the accumulator with one that's safe for GC.  The finally | 
| 1252   // block will unconditionally preserve the accumulator on the stack. | 1249   // block will unconditionally preserve the accumulator on the stack. | 
| 1253   ClearAccumulator(); | 1250   ClearAccumulator(); | 
| 1254   __ Call(&finally_entry); | 1251   __ Call(&finally_entry); | 
| 1255 } | 1252 } | 
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1386   } | 1383   } | 
| 1387 | 1384 | 
| 1388   return false; | 1385   return false; | 
| 1389 } | 1386 } | 
| 1390 | 1387 | 
| 1391 | 1388 | 
| 1392 #undef __ | 1389 #undef __ | 
| 1393 | 1390 | 
| 1394 | 1391 | 
| 1395 } }  // namespace v8::internal | 1392 } }  // namespace v8::internal | 
| OLD | NEW | 
|---|