OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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/isolate.h" | 5 #include "src/isolate.h" |
6 | 6 |
7 #include <stdlib.h> | 7 #include <stdlib.h> |
8 | 8 |
9 #include <fstream> // NOLINT(readability/streams) | 9 #include <fstream> // NOLINT(readability/streams) |
10 #include <sstream> | 10 #include <sstream> |
(...skipping 2950 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2961 if (promise_reject_callback_ == NULL) return; | 2961 if (promise_reject_callback_ == NULL) return; |
2962 Handle<JSArray> stack_trace; | 2962 Handle<JSArray> stack_trace; |
2963 if (event == v8::kPromiseRejectWithNoHandler && value->IsJSObject()) { | 2963 if (event == v8::kPromiseRejectWithNoHandler && value->IsJSObject()) { |
2964 stack_trace = GetDetailedStackTrace(Handle<JSObject>::cast(value)); | 2964 stack_trace = GetDetailedStackTrace(Handle<JSObject>::cast(value)); |
2965 } | 2965 } |
2966 promise_reject_callback_(v8::PromiseRejectMessage( | 2966 promise_reject_callback_(v8::PromiseRejectMessage( |
2967 v8::Utils::PromiseToLocal(promise), event, v8::Utils::ToLocal(value), | 2967 v8::Utils::PromiseToLocal(promise), event, v8::Utils::ToLocal(value), |
2968 v8::Utils::StackTraceToLocal(stack_trace))); | 2968 v8::Utils::StackTraceToLocal(stack_trace))); |
2969 } | 2969 } |
2970 | 2970 |
| 2971 void Isolate::PromiseResolveThenableJob(Handle<PromiseContainer> container, |
| 2972 MaybeHandle<Object>* result, |
| 2973 MaybeHandle<Object>* maybe_exception) { |
| 2974 if (debug()->is_active()) { |
| 2975 Handle<Object> before_debug_event(container->before_debug_event(), this); |
| 2976 if (before_debug_event->IsJSObject()) { |
| 2977 debug()->OnAsyncTaskEvent(Handle<JSObject>::cast(before_debug_event)); |
| 2978 } |
| 2979 } |
| 2980 |
| 2981 Handle<JSReceiver> thenable(container->thenable(), this); |
| 2982 Handle<JSFunction> resolve(container->resolve(), this); |
| 2983 Handle<JSFunction> reject(container->reject(), this); |
| 2984 Handle<JSFunction> then(container->then(), this); |
| 2985 Handle<Object> argv[] = {resolve, reject}; |
| 2986 *result = Execution::TryCall(this, then, thenable, arraysize(argv), argv, |
| 2987 maybe_exception); |
| 2988 |
| 2989 Handle<Object> reason; |
| 2990 if (maybe_exception->ToHandle(&reason)) { |
| 2991 DCHECK(result->is_null()); |
| 2992 Handle<Object> reason_arg[] = {reason}; |
| 2993 *result = |
| 2994 Execution::TryCall(this, reject, factory()->undefined_value(), |
| 2995 arraysize(reason_arg), reason_arg, maybe_exception); |
| 2996 } |
| 2997 |
| 2998 if (debug()->is_active()) { |
| 2999 Handle<Object> after_debug_event(container->after_debug_event(), this); |
| 3000 if (after_debug_event->IsJSObject()) { |
| 3001 debug()->OnAsyncTaskEvent(Handle<JSObject>::cast(after_debug_event)); |
| 3002 } |
| 3003 } |
| 3004 } |
2971 | 3005 |
2972 void Isolate::EnqueueMicrotask(Handle<Object> microtask) { | 3006 void Isolate::EnqueueMicrotask(Handle<Object> microtask) { |
2973 DCHECK(microtask->IsJSFunction() || microtask->IsCallHandlerInfo()); | 3007 DCHECK(microtask->IsJSFunction() || microtask->IsCallHandlerInfo() || |
| 3008 microtask->IsPromiseContainer()); |
2974 Handle<FixedArray> queue(heap()->microtask_queue(), this); | 3009 Handle<FixedArray> queue(heap()->microtask_queue(), this); |
2975 int num_tasks = pending_microtask_count(); | 3010 int num_tasks = pending_microtask_count(); |
2976 DCHECK(num_tasks <= queue->length()); | 3011 DCHECK(num_tasks <= queue->length()); |
2977 if (num_tasks == 0) { | 3012 if (num_tasks == 0) { |
2978 queue = factory()->NewFixedArray(8); | 3013 queue = factory()->NewFixedArray(8); |
2979 heap()->set_microtask_queue(*queue); | 3014 heap()->set_microtask_queue(*queue); |
2980 } else if (num_tasks == queue->length()) { | 3015 } else if (num_tasks == queue->length()) { |
2981 queue = factory()->CopyFixedArrayAndGrow(queue, num_tasks); | 3016 queue = factory()->CopyFixedArrayAndGrow(queue, num_tasks); |
2982 heap()->set_microtask_queue(*queue); | 3017 heap()->set_microtask_queue(*queue); |
2983 } | 3018 } |
(...skipping 21 matching lines...) Expand all Loading... |
3005 HandleScope scope(this); | 3040 HandleScope scope(this); |
3006 int num_tasks = pending_microtask_count(); | 3041 int num_tasks = pending_microtask_count(); |
3007 Handle<FixedArray> queue(heap()->microtask_queue(), this); | 3042 Handle<FixedArray> queue(heap()->microtask_queue(), this); |
3008 DCHECK(num_tasks <= queue->length()); | 3043 DCHECK(num_tasks <= queue->length()); |
3009 set_pending_microtask_count(0); | 3044 set_pending_microtask_count(0); |
3010 heap()->set_microtask_queue(heap()->empty_fixed_array()); | 3045 heap()->set_microtask_queue(heap()->empty_fixed_array()); |
3011 | 3046 |
3012 Isolate* isolate = this; | 3047 Isolate* isolate = this; |
3013 FOR_WITH_HANDLE_SCOPE(isolate, int, i = 0, i, i < num_tasks, i++, { | 3048 FOR_WITH_HANDLE_SCOPE(isolate, int, i = 0, i, i < num_tasks, i++, { |
3014 Handle<Object> microtask(queue->get(i), this); | 3049 Handle<Object> microtask(queue->get(i), this); |
3015 if (microtask->IsJSFunction()) { | 3050 |
3016 Handle<JSFunction> microtask_function = | 3051 if (microtask->IsCallHandlerInfo()) { |
3017 Handle<JSFunction>::cast(microtask); | 3052 Handle<CallHandlerInfo> callback_info = |
| 3053 Handle<CallHandlerInfo>::cast(microtask); |
| 3054 v8::MicrotaskCallback callback = |
| 3055 v8::ToCData<v8::MicrotaskCallback>(callback_info->callback()); |
| 3056 void* data = v8::ToCData<void*>(callback_info->data()); |
| 3057 callback(data); |
| 3058 } else { |
3018 SaveContext save(this); | 3059 SaveContext save(this); |
3019 set_context(microtask_function->context()->native_context()); | 3060 Context* context = |
| 3061 microtask->IsJSFunction() |
| 3062 ? Handle<JSFunction>::cast(microtask)->context() |
| 3063 : Handle<PromiseContainer>::cast(microtask)->then()->context(); |
| 3064 set_context(context->native_context()); |
3020 handle_scope_implementer_->EnterMicrotaskContext( | 3065 handle_scope_implementer_->EnterMicrotaskContext( |
3021 handle(microtask_function->context(), this)); | 3066 Handle<Context>(context, this)); |
| 3067 |
| 3068 MaybeHandle<Object> result; |
3022 MaybeHandle<Object> maybe_exception; | 3069 MaybeHandle<Object> maybe_exception; |
3023 MaybeHandle<Object> result = Execution::TryCall( | 3070 |
3024 this, microtask_function, factory()->undefined_value(), 0, NULL, | 3071 if (microtask->IsJSFunction()) { |
3025 &maybe_exception); | 3072 Handle<JSFunction> microtask_function = |
| 3073 Handle<JSFunction>::cast(microtask); |
| 3074 result = Execution::TryCall(this, microtask_function, |
| 3075 factory()->undefined_value(), 0, NULL, |
| 3076 &maybe_exception); |
| 3077 } else { |
| 3078 PromiseResolveThenableJob(Handle<PromiseContainer>::cast(microtask), |
| 3079 &result, &maybe_exception); |
| 3080 } |
| 3081 |
3026 handle_scope_implementer_->LeaveMicrotaskContext(); | 3082 handle_scope_implementer_->LeaveMicrotaskContext(); |
| 3083 |
3027 // If execution is terminating, just bail out. | 3084 // If execution is terminating, just bail out. |
3028 if (result.is_null() && maybe_exception.is_null()) { | 3085 if (result.is_null() && maybe_exception.is_null()) { |
3029 // Clear out any remaining callbacks in the queue. | 3086 // Clear out any remaining callbacks in the queue. |
3030 heap()->set_microtask_queue(heap()->empty_fixed_array()); | 3087 heap()->set_microtask_queue(heap()->empty_fixed_array()); |
3031 set_pending_microtask_count(0); | 3088 set_pending_microtask_count(0); |
3032 return; | 3089 return; |
3033 } | 3090 } |
3034 } else { | |
3035 Handle<CallHandlerInfo> callback_info = | |
3036 Handle<CallHandlerInfo>::cast(microtask); | |
3037 v8::MicrotaskCallback callback = | |
3038 v8::ToCData<v8::MicrotaskCallback>(callback_info->callback()); | |
3039 void* data = v8::ToCData<void*>(callback_info->data()); | |
3040 callback(data); | |
3041 } | 3091 } |
3042 }); | 3092 }); |
3043 } | 3093 } |
3044 } | 3094 } |
3045 | 3095 |
3046 | 3096 |
3047 void Isolate::AddMicrotasksCompletedCallback( | 3097 void Isolate::AddMicrotasksCompletedCallback( |
3048 MicrotasksCompletedCallback callback) { | 3098 MicrotasksCompletedCallback callback) { |
3049 for (int i = 0; i < microtasks_completed_callbacks_.length(); i++) { | 3099 for (int i = 0; i < microtasks_completed_callbacks_.length(); i++) { |
3050 if (callback == microtasks_completed_callbacks_.at(i)) return; | 3100 if (callback == microtasks_completed_callbacks_.at(i)) return; |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3217 // Then check whether this scope intercepts. | 3267 // Then check whether this scope intercepts. |
3218 if ((flag & intercept_mask_)) { | 3268 if ((flag & intercept_mask_)) { |
3219 intercepted_flags_ |= flag; | 3269 intercepted_flags_ |= flag; |
3220 return true; | 3270 return true; |
3221 } | 3271 } |
3222 return false; | 3272 return false; |
3223 } | 3273 } |
3224 | 3274 |
3225 } // namespace internal | 3275 } // namespace internal |
3226 } // namespace v8 | 3276 } // namespace v8 |
OLD | NEW |