OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 2035 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2046 shadows.Add(new ShadowTarget(node->escaping_targets()->at(i))); | 2046 shadows.Add(new ShadowTarget(node->escaping_targets()->at(i))); |
2047 } | 2047 } |
2048 | 2048 |
2049 // Generate code for the statements in the try block. | 2049 // Generate code for the statements in the try block. |
2050 VisitStatementsAndSpill(node->try_block()->statements()); | 2050 VisitStatementsAndSpill(node->try_block()->statements()); |
2051 | 2051 |
2052 // Stop the introduced shadowing and count the number of required unlinks. | 2052 // Stop the introduced shadowing and count the number of required unlinks. |
2053 // After shadowing stops, the original labels are unshadowed and the | 2053 // After shadowing stops, the original labels are unshadowed and the |
2054 // LabelShadows represent the formerly shadowing labels. | 2054 // LabelShadows represent the formerly shadowing labels. |
2055 bool has_unlinks = false; | 2055 bool has_unlinks = false; |
2056 for (int i = 0; i <= nof_escapes; i++) { | 2056 for (int i = 0; i < shadows.length(); i++) { |
2057 shadows[i]->StopShadowing(); | 2057 shadows[i]->StopShadowing(); |
2058 has_unlinks = has_unlinks || shadows[i]->is_linked(); | 2058 has_unlinks = has_unlinks || shadows[i]->is_linked(); |
2059 } | 2059 } |
2060 function_return_is_shadowed_ = function_return_was_shadowed; | 2060 function_return_is_shadowed_ = function_return_was_shadowed; |
2061 | 2061 |
2062 // Get an external reference to the handler address. | 2062 // Get an external reference to the handler address. |
2063 ExternalReference handler_address(Top::k_handler_address); | 2063 ExternalReference handler_address(Top::k_handler_address); |
2064 | 2064 |
2065 // The next handler address is at kNextIndex in the stack. | 2065 // The next handler address is at kNextIndex in the stack. |
2066 const int kNextIndex = StackHandlerConstants::kNextOffset / kPointerSize; | 2066 const int kNextIndex = StackHandlerConstants::kNextOffset / kPointerSize; |
2067 // If we can fall off the end of the try block, unlink from try chain. | 2067 // If we can fall off the end of the try block, unlink from try chain. |
2068 if (has_valid_frame()) { | 2068 if (has_valid_frame()) { |
2069 __ ldr(r1, frame_->ElementAt(kNextIndex)); | 2069 __ ldr(r1, frame_->ElementAt(kNextIndex)); |
2070 __ mov(r3, Operand(handler_address)); | 2070 __ mov(r3, Operand(handler_address)); |
2071 __ str(r1, MemOperand(r3)); | 2071 __ str(r1, MemOperand(r3)); |
2072 frame_->Drop(StackHandlerConstants::kSize / kPointerSize); | 2072 frame_->Drop(StackHandlerConstants::kSize / kPointerSize); |
2073 if (has_unlinks) { | 2073 if (has_unlinks) { |
2074 exit.Jump(); | 2074 exit.Jump(); |
2075 } | 2075 } |
2076 } | 2076 } |
2077 | 2077 |
2078 // Generate unlink code for the (formerly) shadowing labels that have been | 2078 // Generate unlink code for the (formerly) shadowing labels that have been |
2079 // jumped to. | 2079 // jumped to. Deallocate each shadow target. |
2080 for (int i = 0; i <= nof_escapes; i++) { | 2080 for (int i = 0; i < shadows.length(); i++) { |
2081 if (shadows[i]->is_linked()) { | 2081 if (shadows[i]->is_linked()) { |
2082 // Unlink from try chain; | 2082 // Unlink from try chain; |
2083 shadows[i]->Bind(); | 2083 shadows[i]->Bind(); |
2084 // Because we can be jumping here (to spilled code) from unspilled | 2084 // Because we can be jumping here (to spilled code) from unspilled |
2085 // code, we need to reestablish a spilled frame at this block. | 2085 // code, we need to reestablish a spilled frame at this block. |
2086 frame_->SpillAll(); | 2086 frame_->SpillAll(); |
2087 | 2087 |
2088 // Reload sp from the top handler, because some statements that we | 2088 // Reload sp from the top handler, because some statements that we |
2089 // break from (eg, for...in) may have left stuff on the stack. | 2089 // break from (eg, for...in) may have left stuff on the stack. |
2090 __ mov(r3, Operand(handler_address)); | 2090 __ mov(r3, Operand(handler_address)); |
2091 __ ldr(sp, MemOperand(r3)); | 2091 __ ldr(sp, MemOperand(r3)); |
2092 // The stack pointer was restored to just below the code slot | 2092 // The stack pointer was restored to just below the code slot |
2093 // (the topmost slot) in the handler. | 2093 // (the topmost slot) in the handler. |
2094 frame_->Forget(frame_->height() - handler_height + 1); | 2094 frame_->Forget(frame_->height() - handler_height + 1); |
2095 | 2095 |
2096 // kNextIndex is off by one because the code slot has already | 2096 // kNextIndex is off by one because the code slot has already |
2097 // been dropped. | 2097 // been dropped. |
2098 __ ldr(r1, frame_->ElementAt(kNextIndex - 1)); | 2098 __ ldr(r1, frame_->ElementAt(kNextIndex - 1)); |
2099 __ str(r1, MemOperand(r3)); | 2099 __ str(r1, MemOperand(r3)); |
2100 // The code slot has already been dropped from the handler. | 2100 // The code slot has already been dropped from the handler. |
2101 frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1); | 2101 frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1); |
2102 | 2102 |
2103 if (!function_return_is_shadowed_ && i == kReturnShadowIndex) { | 2103 if (!function_return_is_shadowed_ && i == kReturnShadowIndex) { |
2104 frame_->PrepareForReturn(); | 2104 frame_->PrepareForReturn(); |
2105 } | 2105 } |
2106 shadows[i]->other_target()->Jump(); | 2106 shadows[i]->other_target()->Jump(); |
2107 } | 2107 } |
| 2108 delete shadows[i]; |
2108 } | 2109 } |
2109 | 2110 |
2110 exit.Bind(); | 2111 exit.Bind(); |
2111 ASSERT(!has_valid_frame() || frame_->height() == original_height); | 2112 ASSERT(!has_valid_frame() || frame_->height() == original_height); |
2112 } | 2113 } |
2113 | 2114 |
2114 | 2115 |
2115 void CodeGenerator::VisitTryFinally(TryFinally* node) { | 2116 void CodeGenerator::VisitTryFinally(TryFinally* node) { |
2116 #ifdef DEBUG | 2117 #ifdef DEBUG |
2117 int original_height = frame_->height(); | 2118 int original_height = frame_->height(); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2162 shadows.Add(new ShadowTarget(node->escaping_targets()->at(i))); | 2163 shadows.Add(new ShadowTarget(node->escaping_targets()->at(i))); |
2163 } | 2164 } |
2164 | 2165 |
2165 // Generate code for the statements in the try block. | 2166 // Generate code for the statements in the try block. |
2166 VisitStatementsAndSpill(node->try_block()->statements()); | 2167 VisitStatementsAndSpill(node->try_block()->statements()); |
2167 | 2168 |
2168 // Stop the introduced shadowing and count the number of required unlinks. | 2169 // Stop the introduced shadowing and count the number of required unlinks. |
2169 // After shadowing stops, the original labels are unshadowed and the | 2170 // After shadowing stops, the original labels are unshadowed and the |
2170 // LabelShadows represent the formerly shadowing labels. | 2171 // LabelShadows represent the formerly shadowing labels. |
2171 int nof_unlinks = 0; | 2172 int nof_unlinks = 0; |
2172 for (int i = 0; i <= nof_escapes; i++) { | 2173 for (int i = 0; i < shadows.length(); i++) { |
2173 shadows[i]->StopShadowing(); | 2174 shadows[i]->StopShadowing(); |
2174 if (shadows[i]->is_linked()) nof_unlinks++; | 2175 if (shadows[i]->is_linked()) nof_unlinks++; |
2175 } | 2176 } |
2176 function_return_is_shadowed_ = function_return_was_shadowed; | 2177 function_return_is_shadowed_ = function_return_was_shadowed; |
2177 | 2178 |
2178 // Get an external reference to the handler address. | 2179 // Get an external reference to the handler address. |
2179 ExternalReference handler_address(Top::k_handler_address); | 2180 ExternalReference handler_address(Top::k_handler_address); |
2180 | 2181 |
2181 // The next handler address is at kNextIndex in the stack. | 2182 // The next handler address is at kNextIndex in the stack. |
2182 const int kNextIndex = StackHandlerConstants::kNextOffset / kPointerSize; | 2183 const int kNextIndex = StackHandlerConstants::kNextOffset / kPointerSize; |
2183 // If we can fall off the end of the try block, unlink from the try | 2184 // If we can fall off the end of the try block, unlink from the try |
2184 // chain and set the state on the frame to FALLING. | 2185 // chain and set the state on the frame to FALLING. |
2185 if (has_valid_frame()) { | 2186 if (has_valid_frame()) { |
2186 __ ldr(r1, frame_->ElementAt(kNextIndex)); | 2187 __ ldr(r1, frame_->ElementAt(kNextIndex)); |
2187 __ mov(r3, Operand(handler_address)); | 2188 __ mov(r3, Operand(handler_address)); |
2188 __ str(r1, MemOperand(r3)); | 2189 __ str(r1, MemOperand(r3)); |
2189 frame_->Drop(StackHandlerConstants::kSize / kPointerSize); | 2190 frame_->Drop(StackHandlerConstants::kSize / kPointerSize); |
2190 | 2191 |
2191 // Fake a top of stack value (unneeded when FALLING) and set the | 2192 // Fake a top of stack value (unneeded when FALLING) and set the |
2192 // state in r2, then jump around the unlink blocks if any. | 2193 // state in r2, then jump around the unlink blocks if any. |
2193 __ mov(r0, Operand(Factory::undefined_value())); | 2194 __ mov(r0, Operand(Factory::undefined_value())); |
2194 frame_->EmitPush(r0); | 2195 frame_->EmitPush(r0); |
2195 __ mov(r2, Operand(Smi::FromInt(FALLING))); | 2196 __ mov(r2, Operand(Smi::FromInt(FALLING))); |
2196 if (nof_unlinks > 0) { | 2197 if (nof_unlinks > 0) { |
2197 finally_block.Jump(); | 2198 finally_block.Jump(); |
2198 } | 2199 } |
2199 } | 2200 } |
2200 | 2201 |
2201 // Generate code to unlink and set the state for the (formerly) | 2202 // Generate code to unlink and set the state for the (formerly) |
2202 // shadowing labels that have been jumped to. | 2203 // shadowing targets that have been jumped to. |
2203 for (int i = 0; i <= nof_escapes; i++) { | 2204 for (int i = 0; i < shadows.length(); i++) { |
2204 if (shadows[i]->is_linked()) { | 2205 if (shadows[i]->is_linked()) { |
2205 // If we have come from the shadowed return, the return value is | 2206 // If we have come from the shadowed return, the return value is |
2206 // in (a non-refcounted reference to) r0. We must preserve it | 2207 // in (a non-refcounted reference to) r0. We must preserve it |
2207 // until it is pushed. | 2208 // until it is pushed. |
2208 // | 2209 // |
2209 // Because we can be jumping here (to spilled code) from | 2210 // Because we can be jumping here (to spilled code) from |
2210 // unspilled code, we need to reestablish a spilled frame at | 2211 // unspilled code, we need to reestablish a spilled frame at |
2211 // this block. | 2212 // this block. |
2212 shadows[i]->Bind(); | 2213 shadows[i]->Bind(); |
2213 frame_->SpillAll(); | 2214 frame_->SpillAll(); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2257 // | 2258 // |
2258 // Generate code for the statements in the finally block. | 2259 // Generate code for the statements in the finally block. |
2259 VisitStatementsAndSpill(node->finally_block()->statements()); | 2260 VisitStatementsAndSpill(node->finally_block()->statements()); |
2260 | 2261 |
2261 if (has_valid_frame()) { | 2262 if (has_valid_frame()) { |
2262 JumpTarget exit(this); | 2263 JumpTarget exit(this); |
2263 // Restore state and return value or faked TOS. | 2264 // Restore state and return value or faked TOS. |
2264 frame_->EmitPop(r2); | 2265 frame_->EmitPop(r2); |
2265 frame_->EmitPop(r0); | 2266 frame_->EmitPop(r0); |
2266 | 2267 |
2267 // Generate code to jump to the right destination for all used (formerly) | 2268 // Generate code to jump to the right destination for all used |
2268 // shadowing labels. | 2269 // formerly shadowing targets. Deallocate each shadow target. |
2269 for (int i = 0; i <= nof_escapes; i++) { | 2270 for (int i = 0; i < shadows.length(); i++) { |
2270 if (shadows[i]->is_bound()) { | 2271 if (shadows[i]->is_bound()) { |
2271 JumpTarget* original = shadows[i]->other_target(); | 2272 JumpTarget* original = shadows[i]->other_target(); |
2272 __ cmp(r2, Operand(Smi::FromInt(JUMPING + i))); | 2273 __ cmp(r2, Operand(Smi::FromInt(JUMPING + i))); |
2273 if (!function_return_is_shadowed_ && i == kReturnShadowIndex) { | 2274 if (!function_return_is_shadowed_ && i == kReturnShadowIndex) { |
2274 JumpTarget skip(this); | 2275 JumpTarget skip(this); |
2275 skip.Branch(ne); | 2276 skip.Branch(ne); |
2276 frame_->PrepareForReturn(); | 2277 frame_->PrepareForReturn(); |
2277 original->Jump(); | 2278 original->Jump(); |
2278 skip.Bind(); | 2279 skip.Bind(); |
2279 } else { | 2280 } else { |
2280 original->Branch(eq); | 2281 original->Branch(eq); |
2281 } | 2282 } |
2282 } | 2283 } |
| 2284 delete shadows[i]; |
2283 } | 2285 } |
2284 | 2286 |
2285 // Check if we need to rethrow the exception. | 2287 // Check if we need to rethrow the exception. |
2286 __ cmp(r2, Operand(Smi::FromInt(THROWING))); | 2288 __ cmp(r2, Operand(Smi::FromInt(THROWING))); |
2287 exit.Branch(ne); | 2289 exit.Branch(ne); |
2288 | 2290 |
2289 // Rethrow exception. | 2291 // Rethrow exception. |
2290 frame_->EmitPush(r0); | 2292 frame_->EmitPush(r0); |
2291 frame_->CallRuntime(Runtime::kReThrow, 1); | 2293 frame_->CallRuntime(Runtime::kReThrow, 1); |
2292 | 2294 |
(...skipping 2853 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5146 __ mov(r2, Operand(0)); | 5148 __ mov(r2, Operand(0)); |
5147 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); | 5149 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); |
5148 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)), | 5150 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)), |
5149 RelocInfo::CODE_TARGET); | 5151 RelocInfo::CODE_TARGET); |
5150 } | 5152 } |
5151 | 5153 |
5152 | 5154 |
5153 #undef __ | 5155 #undef __ |
5154 | 5156 |
5155 } } // namespace v8::internal | 5157 } } // namespace v8::internal |
OLD | NEW |