| Index: src/api.cc
|
| diff --git a/src/api.cc b/src/api.cc
|
| index bf57a3aa14376ab17e6c42a8004561e72a2f80e6..0158d3ab56dc4706a9e6618a4b3a6af3f53d9acb 100644
|
| --- a/src/api.cc
|
| +++ b/src/api.cc
|
| @@ -157,6 +157,18 @@ class InternalEscapableScope : public v8::EscapableHandleScope {
|
| };
|
|
|
|
|
| +#ifdef V8_ENABLE_CHECKS
|
| +void CheckMicrotasksScopesConsistency(i::Isolate* isolate) {
|
| + auto handle_scope_implementer = isolate->handle_scope_implementer();
|
| + if (handle_scope_implementer->microtasks_policy() ==
|
| + v8::MicrotasksPolicy::kScoped) {
|
| + DCHECK(handle_scope_implementer->GetMicrotasksScopeDepth() ||
|
| + !handle_scope_implementer->DebugMicrotasksScopeDepthIsZero());
|
| + }
|
| +}
|
| +#endif
|
| +
|
| +
|
| class CallDepthScope {
|
| public:
|
| explicit CallDepthScope(i::Isolate* isolate, Local<Context> context,
|
| @@ -176,6 +188,9 @@ class CallDepthScope {
|
| if (!context_.IsEmpty()) context_->Exit();
|
| if (!escaped_) isolate_->handle_scope_implementer()->DecrementCallDepth();
|
| if (do_callback_) isolate_->FireCallCompletedCallback();
|
| +#ifdef V8_ENABLE_CHECKS
|
| + if (do_callback_) CheckMicrotasksScopesConsistency(isolate_);
|
| +#endif
|
| }
|
|
|
| void Escape() {
|
| @@ -7298,10 +7313,12 @@ Isolate::SuppressMicrotaskExecutionScope::SuppressMicrotaskExecutionScope(
|
| Isolate* isolate)
|
| : isolate_(reinterpret_cast<i::Isolate*>(isolate)) {
|
| isolate_->handle_scope_implementer()->IncrementCallDepth();
|
| + isolate_->handle_scope_implementer()->IncrementMicrotasksSuppressions();
|
| }
|
|
|
|
|
| Isolate::SuppressMicrotaskExecutionScope::~SuppressMicrotaskExecutionScope() {
|
| + isolate_->handle_scope_implementer()->DecrementMicrotasksSuppressions();
|
| isolate_->handle_scope_implementer()->DecrementCallDepth();
|
| }
|
|
|
| @@ -7443,6 +7460,7 @@ void Isolate::SetPromiseRejectCallback(PromiseRejectCallback callback) {
|
|
|
|
|
| void Isolate::RunMicrotasks() {
|
| + DCHECK(MicrotasksPolicy::kScoped != GetMicrotasksPolicy());
|
| reinterpret_cast<i::Isolate*>(this)->RunMicrotasks();
|
| }
|
|
|
| @@ -7466,12 +7484,26 @@ void Isolate::EnqueueMicrotask(MicrotaskCallback microtask, void* data) {
|
|
|
|
|
| void Isolate::SetAutorunMicrotasks(bool autorun) {
|
| - reinterpret_cast<i::Isolate*>(this)->set_autorun_microtasks(autorun);
|
| + SetMicrotasksPolicy(
|
| + autorun ? MicrotasksPolicy::kAuto : MicrotasksPolicy::kExplicit);
|
| }
|
|
|
|
|
| bool Isolate::WillAutorunMicrotasks() const {
|
| - return reinterpret_cast<const i::Isolate*>(this)->autorun_microtasks();
|
| + return GetMicrotasksPolicy() == MicrotasksPolicy::kAuto;
|
| +}
|
| +
|
| +
|
| +void Isolate::SetMicrotasksPolicy(MicrotasksPolicy policy) {
|
| + i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
|
| + isolate->handle_scope_implementer()->set_microtasks_policy(policy);
|
| +}
|
| +
|
| +
|
| +MicrotasksPolicy Isolate::GetMicrotasksPolicy() const {
|
| + i::Isolate* isolate =
|
| + reinterpret_cast<i::Isolate*>(const_cast<Isolate*>(this));
|
| + return isolate->handle_scope_implementer()->microtasks_policy();
|
| }
|
|
|
|
|
| @@ -7710,6 +7742,49 @@ void Isolate::VisitWeakHandles(PersistentHandleVisitor* visitor) {
|
| }
|
|
|
|
|
| +MicrotasksScope::MicrotasksScope(Isolate* isolate, MicrotasksScope::Type type)
|
| + : isolate_(reinterpret_cast<i::Isolate*>(isolate)),
|
| + run_(type == MicrotasksScope::kRunMicrotasks) {
|
| + auto handle_scope_implementer = isolate_->handle_scope_implementer();
|
| + if (run_) handle_scope_implementer->IncrementMicrotasksScopeDepth();
|
| +#ifdef V8_ENABLE_CHECKS
|
| + if (!run_) handle_scope_implementer->IncrementDebugMicrotasksScopeDepth();
|
| +#endif
|
| +}
|
| +
|
| +
|
| +MicrotasksScope::~MicrotasksScope() {
|
| + auto handle_scope_implementer = isolate_->handle_scope_implementer();
|
| + if (run_) {
|
| + handle_scope_implementer->DecrementMicrotasksScopeDepth();
|
| + if (MicrotasksPolicy::kScoped ==
|
| + handle_scope_implementer->microtasks_policy()) {
|
| + PerformCheckpoint(reinterpret_cast<Isolate*>(isolate_));
|
| + }
|
| + }
|
| +#ifdef V8_ENABLE_CHECKS
|
| + if (!run_) handle_scope_implementer->DecrementDebugMicrotasksScopeDepth();
|
| +#endif
|
| +}
|
| +
|
| +
|
| +void MicrotasksScope::PerformCheckpoint(Isolate* v8Isolate) {
|
| + i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8Isolate);
|
| + if (IsExecutionTerminatingCheck(isolate)) return;
|
| + auto handle_scope_implementer = isolate->handle_scope_implementer();
|
| + if (!handle_scope_implementer->GetMicrotasksScopeDepth() &&
|
| + !handle_scope_implementer->HasMicrotasksSuppressions()) {
|
| + isolate->RunMicrotasks();
|
| + }
|
| +}
|
| +
|
| +
|
| +int MicrotasksScope::GetCurrentDepth(Isolate* v8Isolate) {
|
| + i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8Isolate);
|
| + return isolate->handle_scope_implementer()->GetMicrotasksScopeDepth();
|
| +}
|
| +
|
| +
|
| String::Utf8Value::Utf8Value(v8::Local<v8::Value> obj)
|
| : str_(NULL), length_(0) {
|
| if (obj.IsEmpty()) return;
|
|
|