| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/execution.h" | 5 #include "src/execution.h" |
| 6 | 6 |
| 7 #include "src/bootstrapper.h" | 7 #include "src/bootstrapper.h" |
| 8 #include "src/codegen.h" | 8 #include "src/codegen.h" |
| 9 #include "src/compiler-dispatcher/optimizing-compile-dispatcher.h" | 9 #include "src/compiler-dispatcher/optimizing-compile-dispatcher.h" |
| 10 #include "src/isolate-inl.h" | 10 #include "src/isolate-inl.h" |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 47 PrintF(": %s", String::cast(name)->ToCString().get()); | 47 PrintF(": %s", String::cast(name)->ToCString().get()); |
| 48 } | 48 } |
| 49 } | 49 } |
| 50 PrintF("]\n"); | 50 PrintF("]\n"); |
| 51 } | 51 } |
| 52 } | 52 } |
| 53 | 53 |
| 54 | 54 |
| 55 namespace { | 55 namespace { |
| 56 | 56 |
| 57 enum class MessageHandling { kReport, kKeep }; |
| 58 |
| 57 MUST_USE_RESULT MaybeHandle<Object> Invoke(Isolate* isolate, bool is_construct, | 59 MUST_USE_RESULT MaybeHandle<Object> Invoke(Isolate* isolate, bool is_construct, |
| 58 Handle<Object> target, | 60 Handle<Object> target, |
| 59 Handle<Object> receiver, int argc, | 61 Handle<Object> receiver, int argc, |
| 60 Handle<Object> args[], | 62 Handle<Object> args[], |
| 61 Handle<Object> new_target) { | 63 Handle<Object> new_target, |
| 64 MessageHandling message_handling) { |
| 62 DCHECK(!receiver->IsJSGlobalObject()); | 65 DCHECK(!receiver->IsJSGlobalObject()); |
| 63 | 66 |
| 64 #ifdef USE_SIMULATOR | 67 #ifdef USE_SIMULATOR |
| 65 // Simulators use separate stacks for C++ and JS. JS stack overflow checks | 68 // Simulators use separate stacks for C++ and JS. JS stack overflow checks |
| 66 // are performed whenever a JS function is called. However, it can be the case | 69 // are performed whenever a JS function is called. However, it can be the case |
| 67 // that the C++ stack grows faster than the JS stack, resulting in an overflow | 70 // that the C++ stack grows faster than the JS stack, resulting in an overflow |
| 68 // there. Add a check here to make that less likely. | 71 // there. Add a check here to make that less likely. |
| 69 StackLimitCheck check(isolate); | 72 StackLimitCheck check(isolate); |
| 70 if (check.HasOverflowed()) { | 73 if (check.HasOverflowed()) { |
| 71 isolate->StackOverflow(); | 74 isolate->StackOverflow(); |
| 72 isolate->ReportPendingMessages(); | 75 if (message_handling == MessageHandling::kReport) { |
| 76 isolate->ReportPendingMessages(); |
| 77 } |
| 73 return MaybeHandle<Object>(); | 78 return MaybeHandle<Object>(); |
| 74 } | 79 } |
| 75 #endif | 80 #endif |
| 76 | 81 |
| 77 // api callbacks can be called directly. | 82 // api callbacks can be called directly. |
| 78 if (target->IsJSFunction()) { | 83 if (target->IsJSFunction()) { |
| 79 Handle<JSFunction> function = Handle<JSFunction>::cast(target); | 84 Handle<JSFunction> function = Handle<JSFunction>::cast(target); |
| 80 if ((!is_construct || function->IsConstructor()) && | 85 if ((!is_construct || function->IsConstructor()) && |
| 81 function->shared()->IsApiFunction()) { | 86 function->shared()->IsApiFunction()) { |
| 82 SaveContext save(isolate); | 87 SaveContext save(isolate); |
| 83 isolate->set_context(function->context()); | 88 isolate->set_context(function->context()); |
| 84 DCHECK(function->context()->global_object()->IsJSGlobalObject()); | 89 DCHECK(function->context()->global_object()->IsJSGlobalObject()); |
| 85 if (is_construct) receiver = isolate->factory()->the_hole_value(); | 90 if (is_construct) receiver = isolate->factory()->the_hole_value(); |
| 86 auto value = Builtins::InvokeApiFunction( | 91 auto value = Builtins::InvokeApiFunction( |
| 87 isolate, is_construct, function, receiver, argc, args, | 92 isolate, is_construct, function, receiver, argc, args, |
| 88 Handle<HeapObject>::cast(new_target)); | 93 Handle<HeapObject>::cast(new_target)); |
| 89 bool has_exception = value.is_null(); | 94 bool has_exception = value.is_null(); |
| 90 DCHECK(has_exception == isolate->has_pending_exception()); | 95 DCHECK(has_exception == isolate->has_pending_exception()); |
| 91 if (has_exception) { | 96 if (has_exception) { |
| 92 isolate->ReportPendingMessages(); | 97 if (message_handling == MessageHandling::kReport) { |
| 98 isolate->ReportPendingMessages(); |
| 99 } |
| 93 return MaybeHandle<Object>(); | 100 return MaybeHandle<Object>(); |
| 94 } else { | 101 } else { |
| 95 isolate->clear_pending_message(); | 102 isolate->clear_pending_message(); |
| 96 } | 103 } |
| 97 return value; | 104 return value; |
| 98 } | 105 } |
| 99 } | 106 } |
| 100 | 107 |
| 101 // Entering JavaScript. | 108 // Entering JavaScript. |
| 102 VMState<JS> state(isolate); | 109 VMState<JS> state(isolate); |
| 103 CHECK(AllowJavascriptExecution::IsAllowed(isolate)); | 110 CHECK(AllowJavascriptExecution::IsAllowed(isolate)); |
| 104 if (!ThrowOnJavascriptExecution::IsAllowed(isolate)) { | 111 if (!ThrowOnJavascriptExecution::IsAllowed(isolate)) { |
| 105 isolate->ThrowIllegalOperation(); | 112 isolate->ThrowIllegalOperation(); |
| 106 isolate->ReportPendingMessages(); | 113 if (message_handling == MessageHandling::kReport) { |
| 114 isolate->ReportPendingMessages(); |
| 115 } |
| 107 return MaybeHandle<Object>(); | 116 return MaybeHandle<Object>(); |
| 108 } | 117 } |
| 109 | 118 |
| 110 // Placeholder for return value. | 119 // Placeholder for return value. |
| 111 Object* value = NULL; | 120 Object* value = NULL; |
| 112 | 121 |
| 113 typedef Object* (*JSEntryFunction)(Object* new_target, Object* target, | 122 typedef Object* (*JSEntryFunction)(Object* new_target, Object* target, |
| 114 Object* receiver, int argc, | 123 Object* receiver, int argc, |
| 115 Object*** args); | 124 Object*** args); |
| 116 | 125 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 143 #ifdef VERIFY_HEAP | 152 #ifdef VERIFY_HEAP |
| 144 if (FLAG_verify_heap) { | 153 if (FLAG_verify_heap) { |
| 145 value->ObjectVerify(); | 154 value->ObjectVerify(); |
| 146 } | 155 } |
| 147 #endif | 156 #endif |
| 148 | 157 |
| 149 // Update the pending exception flag and return the value. | 158 // Update the pending exception flag and return the value. |
| 150 bool has_exception = value->IsException(isolate); | 159 bool has_exception = value->IsException(isolate); |
| 151 DCHECK(has_exception == isolate->has_pending_exception()); | 160 DCHECK(has_exception == isolate->has_pending_exception()); |
| 152 if (has_exception) { | 161 if (has_exception) { |
| 153 isolate->ReportPendingMessages(); | 162 if (message_handling == MessageHandling::kReport) { |
| 163 isolate->ReportPendingMessages(); |
| 164 } |
| 154 return MaybeHandle<Object>(); | 165 return MaybeHandle<Object>(); |
| 155 } else { | 166 } else { |
| 156 isolate->clear_pending_message(); | 167 isolate->clear_pending_message(); |
| 157 } | 168 } |
| 158 | 169 |
| 159 return Handle<Object>(value, isolate); | 170 return Handle<Object>(value, isolate); |
| 160 } | 171 } |
| 161 | 172 |
| 162 } // namespace | 173 MaybeHandle<Object> CallInternal(Isolate* isolate, Handle<Object> callable, |
| 163 | 174 Handle<Object> receiver, int argc, |
| 164 | 175 Handle<Object> argv[], |
| 165 // static | 176 MessageHandling message_handling) { |
| 166 MaybeHandle<Object> Execution::Call(Isolate* isolate, Handle<Object> callable, | |
| 167 Handle<Object> receiver, int argc, | |
| 168 Handle<Object> argv[]) { | |
| 169 // Convert calls on global objects to be calls on the global | 177 // Convert calls on global objects to be calls on the global |
| 170 // receiver instead to avoid having a 'this' pointer which refers | 178 // receiver instead to avoid having a 'this' pointer which refers |
| 171 // directly to a global object. | 179 // directly to a global object. |
| 172 if (receiver->IsJSGlobalObject()) { | 180 if (receiver->IsJSGlobalObject()) { |
| 173 receiver = | 181 receiver = |
| 174 handle(Handle<JSGlobalObject>::cast(receiver)->global_proxy(), isolate); | 182 handle(Handle<JSGlobalObject>::cast(receiver)->global_proxy(), isolate); |
| 175 } | 183 } |
| 176 return Invoke(isolate, false, callable, receiver, argc, argv, | 184 return Invoke(isolate, false, callable, receiver, argc, argv, |
| 177 isolate->factory()->undefined_value()); | 185 isolate->factory()->undefined_value(), message_handling); |
| 186 } |
| 187 |
| 188 } // namespace |
| 189 |
| 190 // static |
| 191 MaybeHandle<Object> Execution::Call(Isolate* isolate, Handle<Object> callable, |
| 192 Handle<Object> receiver, int argc, |
| 193 Handle<Object> argv[]) { |
| 194 return CallInternal(isolate, callable, receiver, argc, argv, |
| 195 MessageHandling::kReport); |
| 178 } | 196 } |
| 179 | 197 |
| 180 | 198 |
| 181 // static | 199 // static |
| 182 MaybeHandle<Object> Execution::New(Handle<JSFunction> constructor, int argc, | 200 MaybeHandle<Object> Execution::New(Handle<JSFunction> constructor, int argc, |
| 183 Handle<Object> argv[]) { | 201 Handle<Object> argv[]) { |
| 184 return New(constructor->GetIsolate(), constructor, constructor, argc, argv); | 202 return New(constructor->GetIsolate(), constructor, constructor, argc, argv); |
| 185 } | 203 } |
| 186 | 204 |
| 187 | 205 |
| 188 // static | 206 // static |
| 189 MaybeHandle<Object> Execution::New(Isolate* isolate, Handle<Object> constructor, | 207 MaybeHandle<Object> Execution::New(Isolate* isolate, Handle<Object> constructor, |
| 190 Handle<Object> new_target, int argc, | 208 Handle<Object> new_target, int argc, |
| 191 Handle<Object> argv[]) { | 209 Handle<Object> argv[]) { |
| 192 return Invoke(isolate, true, constructor, | 210 return Invoke(isolate, true, constructor, |
| 193 isolate->factory()->undefined_value(), argc, argv, new_target); | 211 isolate->factory()->undefined_value(), argc, argv, new_target, |
| 212 MessageHandling::kReport); |
| 194 } | 213 } |
| 195 | 214 |
| 196 | 215 |
| 197 MaybeHandle<Object> Execution::TryCall(Isolate* isolate, | 216 MaybeHandle<Object> Execution::TryCall(Isolate* isolate, |
| 198 Handle<Object> callable, | 217 Handle<Object> callable, |
| 199 Handle<Object> receiver, int argc, | 218 Handle<Object> receiver, int argc, |
| 200 Handle<Object> args[], | 219 Handle<Object> args[], |
| 201 MaybeHandle<Object>* exception_out) { | 220 MaybeHandle<Object>* exception_out) { |
| 202 bool is_termination = false; | 221 bool is_termination = false; |
| 203 MaybeHandle<Object> maybe_result; | 222 MaybeHandle<Object> maybe_result; |
| 204 if (exception_out != NULL) *exception_out = MaybeHandle<Object>(); | 223 if (exception_out != NULL) *exception_out = MaybeHandle<Object>(); |
| 205 // Enter a try-block while executing the JavaScript code. To avoid | 224 // Enter a try-block while executing the JavaScript code. To avoid |
| 206 // duplicate error printing it must be non-verbose. Also, to avoid | 225 // duplicate error printing it must be non-verbose. Also, to avoid |
| 207 // creating message objects during stack overflow we shouldn't | 226 // creating message objects during stack overflow we shouldn't |
| 208 // capture messages. | 227 // capture messages. |
| 209 { | 228 { |
| 210 v8::TryCatch catcher(reinterpret_cast<v8::Isolate*>(isolate)); | 229 v8::TryCatch catcher(reinterpret_cast<v8::Isolate*>(isolate)); |
| 211 catcher.SetVerbose(false); | 230 catcher.SetVerbose(false); |
| 212 catcher.SetCaptureMessage(false); | 231 catcher.SetCaptureMessage(false); |
| 213 | 232 |
| 214 maybe_result = Call(isolate, callable, receiver, argc, args); | 233 maybe_result = |
| 234 CallInternal(isolate, callable, receiver, argc, args, |
| 235 exception_out != nullptr ? MessageHandling::kReport |
| 236 : MessageHandling::kKeep); |
| 215 | 237 |
| 216 if (maybe_result.is_null()) { | 238 if (maybe_result.is_null()) { |
| 217 DCHECK(catcher.HasCaught()); | |
| 218 DCHECK(isolate->has_pending_exception()); | 239 DCHECK(isolate->has_pending_exception()); |
| 219 DCHECK(isolate->external_caught_exception()); | |
| 220 if (isolate->pending_exception() == | 240 if (isolate->pending_exception() == |
| 221 isolate->heap()->termination_exception()) { | 241 isolate->heap()->termination_exception()) { |
| 222 is_termination = true; | 242 is_termination = true; |
| 223 } else { | 243 } else { |
| 224 if (exception_out != NULL) { | 244 if (exception_out != nullptr) { |
| 245 DCHECK(catcher.HasCaught()); |
| 246 DCHECK(isolate->external_caught_exception()); |
| 225 *exception_out = v8::Utils::OpenHandle(*catcher.Exception()); | 247 *exception_out = v8::Utils::OpenHandle(*catcher.Exception()); |
| 226 } | 248 } |
| 227 } | 249 } |
| 228 isolate->OptionalRescheduleException(true); | 250 if (exception_out != nullptr) { |
| 251 isolate->OptionalRescheduleException(true); |
| 252 } |
| 229 } | 253 } |
| 230 | |
| 231 DCHECK(!isolate->has_pending_exception()); | |
| 232 } | 254 } |
| 233 | 255 |
| 234 // Re-request terminate execution interrupt to trigger later. | 256 // Re-request terminate execution interrupt to trigger later. |
| 235 if (is_termination) isolate->stack_guard()->RequestTerminateExecution(); | 257 if (is_termination) isolate->stack_guard()->RequestTerminateExecution(); |
| 236 | 258 |
| 237 return maybe_result; | 259 return maybe_result; |
| 238 } | 260 } |
| 239 | 261 |
| 240 | 262 |
| 241 void StackGuard::SetStackLimit(uintptr_t limit) { | 263 void StackGuard::SetStackLimit(uintptr_t limit) { |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 475 | 497 |
| 476 isolate_->counters()->stack_interrupts()->Increment(); | 498 isolate_->counters()->stack_interrupts()->Increment(); |
| 477 isolate_->counters()->runtime_profiler_ticks()->Increment(); | 499 isolate_->counters()->runtime_profiler_ticks()->Increment(); |
| 478 isolate_->runtime_profiler()->MarkCandidatesForOptimization(); | 500 isolate_->runtime_profiler()->MarkCandidatesForOptimization(); |
| 479 | 501 |
| 480 return isolate_->heap()->undefined_value(); | 502 return isolate_->heap()->undefined_value(); |
| 481 } | 503 } |
| 482 | 504 |
| 483 } // namespace internal | 505 } // namespace internal |
| 484 } // namespace v8 | 506 } // namespace v8 |
| OLD | NEW |