Get rid of ScriptPromise::script_state_

It's used for two things:
* A comparison in IsAssociatedWith(ScriptState*) - this is only
  needed for ScriptPromiseProperty, which can store the state on
  its own.
* Then() uses it extensively - but the ScriptFunction inputs have
  the ScriptState, too.

This also changes the ScriptPromise constructor to take a
v8::Isolate*, making it look more like ScriptValue. The static
Resolve/Reject helpers still need a ScriptState, though.

Change-Id: Icc874958744145afb1dcc070f0ab773bcc938614
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5463609
Reviewed-by: Andrey Kosyakov <caseq@chromium.org>
Commit-Queue: Nate Chapin <japhet@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1292767}
diff --git a/third_party/blink/renderer/bindings/core/v8/rejected_promises.cc b/third_party/blink/renderer/bindings/core/v8/rejected_promises.cc
index dbf72583..6fca7cb 100644
--- a/third_party/blink/renderer/bindings/core/v8/rejected_promises.cc
+++ b/third_party/blink/renderer/bindings/core/v8/rejected_promises.cc
@@ -73,7 +73,8 @@
     if (target &&
         sanitize_script_errors_ == SanitizeScriptErrors::kDoNotSanitize) {
       PromiseRejectionEventInit* init = PromiseRejectionEventInit::Create();
-      init->setPromise(ScriptPromiseUntyped(script_state_, value));
+      init->setPromise(
+          ScriptPromiseUntyped(script_state_->GetIsolate(), value));
       init->setReason(ScriptValue(script_state_->GetIsolate(), reason));
       init->setCancelable(true);
       PromiseRejectionEvent* event = PromiseRejectionEvent::Create(
@@ -118,7 +119,8 @@
     if (target &&
         sanitize_script_errors_ == SanitizeScriptErrors::kDoNotSanitize) {
       PromiseRejectionEventInit* init = PromiseRejectionEventInit::Create();
-      init->setPromise(ScriptPromiseUntyped(script_state_, value));
+      init->setPromise(
+          ScriptPromiseUntyped(script_state_->GetIsolate(), value));
       init->setReason(ScriptValue(script_state_->GetIsolate(), reason));
       PromiseRejectionEvent* event = PromiseRejectionEvent::Create(
           script_state_, event_type_names::kRejectionhandled, init);
diff --git a/third_party/blink/renderer/bindings/core/v8/script_evaluation_result.cc b/third_party/blink/renderer/bindings/core/v8/script_evaluation_result.cc
index 2430de56..baf760f 100644
--- a/third_party/blink/renderer/bindings/core/v8/script_evaluation_result.cc
+++ b/third_party/blink/renderer/bindings/core/v8/script_evaluation_result.cc
@@ -138,7 +138,7 @@
   switch (result_type_) {
     case ResultType::kSuccess:
       return ScriptPromise<IDLAny>::FromV8Promise(
-          script_state, GetSuccessValue().As<v8::Promise>());
+          script_state->GetIsolate(), GetSuccessValue().As<v8::Promise>());
 
     case ResultType::kException:
       return ScriptPromise<IDLAny>::Reject(script_state,
diff --git a/third_party/blink/renderer/bindings/core/v8/script_function.h b/third_party/blink/renderer/bindings/core/v8/script_function.h
index 05341b82..aacc6028 100644
--- a/third_party/blink/renderer/bindings/core/v8/script_function.h
+++ b/third_party/blink/renderer/bindings/core/v8/script_function.h
@@ -92,6 +92,8 @@
     return function_.Get(script_state_->GetIsolate());
   }
 
+  ScriptState* GetScriptState() const { return script_state_; }
+
  private:
   Member<ScriptState> script_state_;
   TraceWrapperV8Reference<v8::Function> function_;
diff --git a/third_party/blink/renderer/bindings/core/v8/script_promise.cc b/third_party/blink/renderer/bindings/core/v8/script_promise.cc
index a72ff72..b54d1c4 100644
--- a/third_party/blink/renderer/bindings/core/v8/script_promise.cc
+++ b/third_party/blink/renderer/bindings/core/v8/script_promise.cc
@@ -158,57 +158,56 @@
 
 }  // namespace
 
-ScriptPromiseUntyped::ScriptPromiseUntyped(ScriptState* script_state,
-                                           v8::Local<v8::Value> value)
-    : script_state_(script_state) {
+ScriptPromiseUntyped::ScriptPromiseUntyped(v8::Isolate* isolate,
+                                           v8::Local<v8::Value> value) {
   if (value.IsEmpty())
     return;
 
   if (!value->IsPromise()) {
     promise_ = ScriptValue();
-    V8ThrowException::ThrowTypeError(script_state->GetIsolate(),
+    V8ThrowException::ThrowTypeError(isolate,
                                      "the given value is not a Promise");
     return;
   }
-  promise_ = ScriptValue(script_state->GetIsolate(), value);
+  promise_ = ScriptValue(isolate, value);
 }
 
 ScriptPromiseUntyped::ScriptPromiseUntyped(const ScriptPromiseUntyped& other) {
-  script_state_ = other.script_state_;
   promise_ = other.promise_;
 }
 
 ScriptPromise<IDLAny> ScriptPromiseUntyped::Then(ScriptFunction* on_fulfilled,
                                                  ScriptFunction* on_rejected) {
+  CHECK(on_fulfilled || on_rejected);
+  CHECK(!on_fulfilled || !on_rejected ||
+        on_fulfilled->GetScriptState() == on_rejected->GetScriptState());
   if (promise_.IsEmpty())
     return ScriptPromise<IDLAny>();
 
-  v8::Local<v8::Promise> promise = promise_.V8Value().As<v8::Promise>();
-
-  if (!on_fulfilled && !on_rejected) {
-    return ScriptPromise<IDLAny>::FromV8Promise(script_state_, promise);
-  }
-
+  v8::Local<v8::Promise> promise = V8Promise();
   v8::Local<v8::Promise> result_promise;
+  ScriptState* script_state = on_fulfilled ? on_fulfilled->GetScriptState()
+                                           : on_rejected->GetScriptState();
   if (!on_rejected) {
-    if (!promise->Then(script_state_->GetContext(), on_fulfilled->V8Function())
+    if (!promise->Then(script_state->GetContext(), on_fulfilled->V8Function())
              .ToLocal(&result_promise)) {
       return ScriptPromise<IDLAny>();
     }
   } else if (!on_fulfilled) {
-    if (!promise->Catch(script_state_->GetContext(), on_rejected->V8Function())
+    if (!promise->Catch(script_state->GetContext(), on_rejected->V8Function())
              .ToLocal(&result_promise)) {
       return ScriptPromise<IDLAny>();
     }
   } else {
     if (!promise
-             ->Then(script_state_->GetContext(), on_fulfilled->V8Function(),
+             ->Then(script_state->GetContext(), on_fulfilled->V8Function(),
                     on_rejected->V8Function())
              .ToLocal(&result_promise)) {
       return ScriptPromise<IDLAny>();
     }
   }
-  return ScriptPromise<IDLAny>::FromV8Promise(script_state_, result_promise);
+  return ScriptPromise<IDLAny>::FromV8Promise(script_state->GetIsolate(),
+                                              result_promise);
 }
 
 ScriptPromiseUntyped ScriptPromiseUntyped::CastUndefined(
@@ -223,9 +222,10 @@
   if (value.IsEmpty())
     return ScriptPromiseUntyped();
   if (value->IsPromise()) {
-    return ScriptPromiseUntyped(script_state, value);
+    return ScriptPromiseUntyped(script_state->GetIsolate(), value);
   }
-  return ScriptPromiseUntyped(script_state, ResolveRaw(script_state, value));
+  return ScriptPromiseUntyped(script_state->GetIsolate(),
+                              ResolveRaw(script_state, value));
 }
 
 ScriptPromiseUntyped ScriptPromiseUntyped::Reject(ScriptState* script_state,
@@ -235,7 +235,8 @@
 
 ScriptPromiseUntyped ScriptPromiseUntyped::Reject(ScriptState* script_state,
                                                   v8::Local<v8::Value> value) {
-  return ScriptPromiseUntyped(script_state, RejectRaw(script_state, value));
+  return ScriptPromiseUntyped(script_state->GetIsolate(),
+                              RejectRaw(script_state, value));
 }
 
 ScriptPromiseUntyped ScriptPromiseUntyped::Reject(
diff --git a/third_party/blink/renderer/bindings/core/v8/script_promise.h b/third_party/blink/renderer/bindings/core/v8/script_promise.h
index 446909bc..0dd6c5b68 100644
--- a/third_party/blink/renderer/bindings/core/v8/script_promise.h
+++ b/third_party/blink/renderer/bindings/core/v8/script_promise.h
@@ -72,7 +72,7 @@
 
   // Constructs a ScriptPromiseUntyped from |promise|.
   // If |promise| is not a Promise object, throws a v8 TypeError.
-  ScriptPromiseUntyped(ScriptState*, v8::Local<v8::Value> promise);
+  ScriptPromiseUntyped(v8::Isolate*, v8::Local<v8::Value> promise);
 
   ScriptPromiseUntyped(const ScriptPromiseUntyped&);
 
@@ -130,14 +130,7 @@
       ScriptState*,
       const HeapVector<ScriptPromiseUntyped>& promises);
 
-  void Trace(Visitor* visitor) const {
-    visitor->Trace(promise_);
-    visitor->Trace(script_state_);
-  }
-
-  bool IsAssociatedWith(ScriptState* script_state) const {
-    return script_state == script_state_;
-  }
+  void Trace(Visitor* visitor) const { visitor->Trace(promise_); }
 
  protected:
   template <typename IDLType, typename BlinkType>
@@ -147,7 +140,6 @@
   static v8::Local<v8::Promise> RejectRaw(ScriptState*, v8::Local<v8::Value>);
 
  private:
-  Member<ScriptState> script_state_;
   ScriptValue promise_;
 };
 
@@ -158,10 +150,10 @@
 
   template <typename T = IDLResolvedType>
   static ScriptPromise<T> FromV8Promise(
-      ScriptState* script_state,
+      v8::Isolate* isolate,
       v8::Local<v8::Promise> promise,
       typename std::enable_if<std::is_same_v<T, IDLAny>>::type* = 0) {
-    return ScriptPromise<T>(script_state, promise);
+    return ScriptPromise<T>(isolate, promise);
   }
 
   static ScriptPromise<IDLResolvedType> RejectWithDOMException(
@@ -181,7 +173,8 @@
       return ScriptPromise<IDLResolvedType>();
     }
     return ScriptPromise<IDLResolvedType>(
-        script_state, ScriptPromiseUntyped::RejectRaw(script_state, value));
+        script_state->GetIsolate(),
+        ScriptPromiseUntyped::RejectRaw(script_state, value));
   }
 
   static ScriptPromise<IDLResolvedType> Reject(
@@ -206,8 +199,8 @@
   template <typename IDLType, typename BlinkType>
   friend ScriptPromise<IDLType> ToResolvedPromise(ScriptState*, BlinkType);
 
-  ScriptPromise(ScriptState* script_state, v8::Local<v8::Promise> promise)
-      : ScriptPromiseUntyped(script_state, promise) {}
+  ScriptPromise(v8::Isolate* isolate, v8::Local<v8::Promise> promise)
+      : ScriptPromiseUntyped(isolate, promise) {}
 };
 
 // Defined in to_v8_traits.h due to circular dependency.
diff --git a/third_party/blink/renderer/bindings/core/v8/script_promise_property.h b/third_party/blink/renderer/bindings/core/v8/script_promise_property.h
index 571ac6e..9c8d160 100644
--- a/third_party/blink/renderer/bindings/core/v8/script_promise_property.h
+++ b/third_party/blink/renderer/bindings/core/v8/script_promise_property.h
@@ -48,8 +48,8 @@
     ScriptState* script_state = ToScriptState(execution_context_.Get(), world);
 
     for (auto& promise : promises_) {
-      if (promise.IsAssociatedWith(script_state)) {
-        return static_cast<ScriptPromise<IDLResolvedType>&>(promise);
+      if (promise.second == script_state) {
+        return static_cast<ScriptPromise<IDLResolvedType>&>(promise.first);
       }
     }
 
@@ -76,7 +76,7 @@
         resolver->template Reject<IDLRejectedType>(rejected_);
         break;
     }
-    promises_.push_back(promise);
+    promises_.emplace_back(promise, script_state);
     return promise;
   }
 
@@ -134,7 +134,7 @@
   void MarkAsHandled() {
     mark_as_handled_ = true;
     for (auto& promise : promises_) {
-      promise.MarkAsHandled();
+      promise.first.MarkAsHandled();
     }
   }
 
@@ -183,7 +183,7 @@
   // size by storing them as the untemplated base class and downcasting where
   // needed.
   HeapVector<Member<ScriptPromiseResolverBase>> resolvers_;
-  HeapVector<ScriptPromiseUntyped> promises_;
+  HeapVector<std::pair<ScriptPromiseUntyped, Member<ScriptState>>> promises_;
   WeakMember<ExecutionContext> const execution_context_;
 
   bool mark_as_handled_ = false;
diff --git a/third_party/blink/renderer/bindings/core/v8/script_promise_property_test.cc b/third_party/blink/renderer/bindings/core/v8/script_promise_property_test.cc
index 7cd00bf..0dc9278 100644
--- a/third_party/blink/renderer/bindings/core/v8/script_promise_property_test.cc
+++ b/third_party/blink/renderer/bindings/core/v8/script_promise_property_test.cc
@@ -106,12 +106,11 @@
 class ScriptPromisePropertyTestBase {
  public:
   ScriptPromisePropertyTestBase()
-      : page_(std::make_unique<DummyPageHolder>(gfx::Size(1, 1))) {
+      : page_(std::make_unique<DummyPageHolder>(gfx::Size(1, 1))),
+        other_world_(DOMWrapperWorld::EnsureIsolatedWorld(GetIsolate(), 1)) {
     v8::HandleScope handle_scope(GetIsolate());
-    other_script_state_ = ScriptState::Create(
-        v8::Context::New(GetIsolate()),
-        DOMWrapperWorld::EnsureIsolatedWorld(GetIsolate(), 1),
-        /* execution_context = */ nullptr);
+    // Force initialization of v8::Context and ScriptState for the other world.
+    page_->GetFrame().GetWindowProxy(OtherWorld());
   }
 
   virtual ~ScriptPromisePropertyTestBase() { DestroyContext(); }
@@ -122,8 +121,10 @@
     return ToScriptStateForMainWorld(&page_->GetFrame());
   }
   DOMWrapperWorld& MainWorld() { return MainScriptState()->World(); }
-  ScriptState* OtherScriptState() { return other_script_state_; }
-  DOMWrapperWorld& OtherWorld() { return other_script_state_->World(); }
+  ScriptState* OtherScriptState() {
+    return ToScriptState(&page_->GetFrame(), OtherWorld());
+  }
+  DOMWrapperWorld& OtherWorld() { return *other_world_; }
   ScriptState* CurrentScriptState() {
     return ScriptState::Current(GetIsolate());
   }
@@ -143,10 +144,7 @@
 
   void DestroyContext() {
     page_.reset();
-    if (other_script_state_) {
-      other_script_state_->DisposePerContextData();
-      other_script_state_ = nullptr;
-    }
+    other_world_ = nullptr;
   }
 
   void Gc() { ThreadState::Current()->CollectAllGarbageForTesting(); }
@@ -176,7 +174,7 @@
  private:
   test::TaskEnvironment task_environment_;
   std::unique_ptr<DummyPageHolder> page_;
-  Persistent<ScriptState> other_script_state_;
+  Persistent<DOMWrapperWorld> other_world_;
 };
 
 // This is the main test class.
diff --git a/third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h b/third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h
index d1b149c..7a23c5a 100644
--- a/third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h
+++ b/third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h
@@ -306,7 +306,7 @@
     // should not be accessed after 'Detach()`.
     CHECK(!resolver_.IsEmpty());
     return ScriptPromise<IDLResolvedType>(
-        script_state_,
+        script_state_->GetIsolate(),
         resolver_.Get(script_state_->GetIsolate())->GetPromise());
   }
 
diff --git a/third_party/blink/renderer/bindings/core/v8/script_promise_test.cc b/third_party/blink/renderer/bindings/core/v8/script_promise_test.cc
index 67d3d3c0..4f878a1 100644
--- a/third_party/blink/renderer/bindings/core/v8/script_promise_test.cc
+++ b/third_party/blink/renderer/bindings/core/v8/script_promise_test.cc
@@ -128,7 +128,7 @@
   test::TaskEnvironment task_environment;
   V8TestingScope scope;
   v8::TryCatch try_catch(scope.GetIsolate());
-  ScriptPromiseUntyped promise(scope.GetScriptState(),
+  ScriptPromiseUntyped promise(scope.GetIsolate(),
                                v8::Undefined(scope.GetIsolate()));
   ASSERT_TRUE(try_catch.HasCaught());
   ASSERT_TRUE(promise.IsEmpty());
@@ -448,7 +448,7 @@
   auto resolver = v8::Promise::Resolver::New(scope.GetContext());
   v8::Local<v8::Promise> promise = resolver.ToLocalChecked()->GetPromise();
   auto new_promise =
-      ScriptPromise<IDLAny>::FromV8Promise(scope.GetScriptState(), promise);
+      ScriptPromise<IDLAny>::FromV8Promise(scope.GetIsolate(), promise);
 
   ASSERT_FALSE(promise.IsEmpty());
   EXPECT_EQ(promise, new_promise.V8Value());
diff --git a/third_party/blink/renderer/bindings/core/v8/to_v8_traits.h b/third_party/blink/renderer/bindings/core/v8/to_v8_traits.h
index 08a284b..248a1d2 100644
--- a/third_party/blink/renderer/bindings/core/v8/to_v8_traits.h
+++ b/third_party/blink/renderer/bindings/core/v8/to_v8_traits.h
@@ -969,7 +969,8 @@
                                          BlinkType value) {
   auto v8_value = ToV8Traits<IDLType>::ToV8(script_state, value);
   return ScriptPromise<IDLType>(
-      script_state, ScriptPromiseUntyped::ResolveRaw(script_state, v8_value));
+      script_state->GetIsolate(),
+      ScriptPromiseUntyped::ResolveRaw(script_state, v8_value));
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/dom/document_test.cc b/third_party/blink/renderer/core/dom/document_test.cc
index 36a7f12..618de03c 100644
--- a/third_party/blink/renderer/core/dom/document_test.cc
+++ b/third_party/blink/renderer/core/dom/document_test.cc
@@ -1272,9 +1272,6 @@
       document.hasPrivateToken(scope.GetScriptState(), "https://issuer.example",
                                scope.GetExceptionState());
   DocumentTest::SimulateTrustTokenQueryAnswererConnectionError(&document);
-
-  ASSERT_TRUE(promise.IsAssociatedWith(scope.GetScriptState()));
-
   ScriptPromiseTester promise_tester(scope.GetScriptState(), promise);
   promise_tester.WaitUntilSettled();
   EXPECT_TRUE(promise_tester.IsRejected());
@@ -1662,9 +1659,6 @@
                                               "https://issuer.example",
                                               scope.GetExceptionState());
   DocumentTest::SimulateTrustTokenQueryAnswererConnectionError(&document);
-
-  ASSERT_TRUE(promise.IsAssociatedWith(scope.GetScriptState()));
-
   ScriptPromiseTester promise_tester(scope.GetScriptState(), promise);
   promise_tester.WaitUntilSettled();
   EXPECT_TRUE(promise_tester.IsRejected());
diff --git a/third_party/blink/renderer/core/dom/observable.cc b/third_party/blink/renderer/core/dom/observable.cc
index 0b8e683..6e9e7dce 100644
--- a/third_party/blink/renderer/core/dom/observable.cc
+++ b/third_party/blink/renderer/core/dom/observable.cc
@@ -1826,7 +1826,7 @@
 
   // 4. Try to convert to a Promise.
   if (v8_value->IsPromise()) {
-    ScriptPromiseUntyped promise(script_state, v8_value);
+    ScriptPromiseUntyped promise(script_state->GetIsolate(), v8_value);
     return MakeGarbageCollected<Observable>(
         ExecutionContext::From(script_state),
         MakeGarbageCollected<OperatorFromPromiseSubscribeDelegate>(promise));
diff --git a/third_party/blink/renderer/core/events/promise_rejection_event.cc b/third_party/blink/renderer/core/events/promise_rejection_event.cc
index 6b463a7b..6cbb5c6 100644
--- a/third_party/blink/renderer/core/events/promise_rejection_event.cc
+++ b/third_party/blink/renderer/core/events/promise_rejection_event.cc
@@ -34,7 +34,7 @@
     return ScriptPromise<IDLAny>();
   }
   return ScriptPromise<IDLAny>::FromV8Promise(
-      script_state, promise_.Get(script_state->GetIsolate()));
+      script_state->GetIsolate(), promise_.Get(script_state->GetIsolate()));
 }
 
 ScriptValue PromiseRejectionEvent::reason(ScriptState* script_state) const {
diff --git a/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc b/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc
index 9e7ce36..e9cf232 100644
--- a/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc
+++ b/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc
@@ -899,7 +899,7 @@
       v8::Local<v8::Value> value = result.GetSuccessValue();
       if (resolve_promises && !value.IsEmpty() && value->IsPromise()) {
         auto promise = ScriptPromise<IDLAny>::FromV8Promise(
-            script_state, value.As<v8::Promise>());
+            script_state->GetIsolate(), value.As<v8::Promise>());
         promise.Then(handler->CreateResolveCallback(script_state, frame_),
                      handler->CreateRejectCallback(script_state, frame_));
       } else {
diff --git a/third_party/blink/renderer/core/streams/pipe_to_engine.cc b/third_party/blink/renderer/core/streams/pipe_to_engine.cc
index fc6352b45..b6b2265 100644
--- a/third_party/blink/renderer/core/streams/pipe_to_engine.cc
+++ b/third_party/blink/renderer/core/streams/pipe_to_engine.cc
@@ -268,7 +268,7 @@
   //      2. Otherwise, return a promise resolved with undefined.
   if (!pipe_options_->PreventAbort() && Destination()->IsWritable()) {
     actions.push_back(ScriptPromiseUntyped(
-        script_state_,
+        script_state_->GetIsolate(),
         WritableStream::Abort(script_state_, Destination(), error)));
   }
 
diff --git a/third_party/blink/renderer/core/streams/stream_promise_resolver.cc b/third_party/blink/renderer/core/streams/stream_promise_resolver.cc
index 174b1a1..6fd76ab3 100644
--- a/third_party/blink/renderer/core/streams/stream_promise_resolver.cc
+++ b/third_party/blink/renderer/core/streams/stream_promise_resolver.cc
@@ -128,7 +128,7 @@
 
 ScriptPromiseUntyped StreamPromiseResolver::GetScriptPromiseUntyped(
     ScriptState* script_state) const {
-  return ScriptPromiseUntyped(script_state,
+  return ScriptPromiseUntyped(script_state->GetIsolate(),
                               V8Promise(script_state->GetIsolate()));
 }
 
diff --git a/third_party/blink/renderer/core/streams/writable_stream.cc b/third_party/blink/renderer/core/streams/writable_stream.cc
index a73d694db..ab5d3c61 100644
--- a/third_party/blink/renderer/core/streams/writable_stream.cc
+++ b/third_party/blink/renderer/core/streams/writable_stream.cc
@@ -122,7 +122,7 @@
   }
 
   //  3. Return ! WritableStreamAbort(this, reason).
-  return ScriptPromiseUntyped(script_state,
+  return ScriptPromiseUntyped(script_state->GetIsolate(),
                               Abort(script_state, this, reason.V8Value()));
 }
 
@@ -143,7 +143,8 @@
     return ScriptPromiseUntyped();
   }
 
-  return ScriptPromiseUntyped(script_state, Close(script_state, this));
+  return ScriptPromiseUntyped(script_state->GetIsolate(),
+                              Close(script_state, this));
 }
 
 WritableStreamDefaultWriter* WritableStream::getWriter(
diff --git a/third_party/blink/renderer/core/streams/writable_stream_default_writer.cc b/third_party/blink/renderer/core/streams/writable_stream_default_writer.cc
index f992c0b2..5030946 100644
--- a/third_party/blink/renderer/core/streams/writable_stream_default_writer.cc
+++ b/third_party/blink/renderer/core/streams/writable_stream_default_writer.cc
@@ -200,7 +200,7 @@
   }
 
   //  3. Return ! WritableStreamDefaultWriterAbort(this, reason).
-  return ScriptPromiseUntyped(script_state,
+  return ScriptPromiseUntyped(script_state->GetIsolate(),
                               Abort(script_state, this, reason.V8Value()));
 }
 
@@ -228,7 +228,8 @@
   }
 
   //  5. Return ! WritableStreamDefaultWriterClose(this).
-  return ScriptPromiseUntyped(script_state, Close(script_state, this));
+  return ScriptPromiseUntyped(script_state->GetIsolate(),
+                              Close(script_state, this));
 }
 
 void WritableStreamDefaultWriter::releaseLock(ScriptState* script_state) {
@@ -272,7 +273,7 @@
 
   //  3. Return ! WritableStreamDefaultWriterWrite(this, chunk).
   return ScriptPromiseUntyped(
-      script_state,
+      script_state->GetIsolate(),
       Write(script_state, this, chunk.V8Value(), exception_state));
 }
 
diff --git a/third_party/blink/renderer/core/view_transition/view_transition_test.cc b/third_party/blink/renderer/core/view_transition/view_transition_test.cc
index f097474..6d10c09 100644
--- a/third_party/blink/renderer/core/view_transition/view_transition_test.cc
+++ b/third_party/blink/renderer/core/view_transition/view_transition_test.cc
@@ -70,6 +70,11 @@
 
   void TearDown() override { web_view_helper_.reset(); }
 
+  ScriptState* GetScriptState() {
+    return ToScriptStateForMainWorld(
+        web_view_helper_->GetWebView()->MainFrameImpl()->GetFrame());
+  }
+
   Document& GetDocument() {
     return *web_view_helper_->GetWebView()
                 ->MainFrameImpl()
@@ -212,16 +217,16 @@
     <div id=target class=shared></div>
   )HTML");
 
-  V8TestingScope v8_scope;
-  ScriptState* script_state = v8_scope.GetScriptState();
-  ExceptionState& exception_state = v8_scope.GetExceptionState();
+  ScriptState* script_state = GetScriptState();
+  ScriptState::Scope scope(script_state);
 
   MockFunctionScope funcs(script_state);
   auto* view_transition_callback =
       V8ViewTransitionCallback::Create(funcs.ExpectCall()->V8Function());
 
   auto* transition = ViewTransitionSupplement::startViewTransition(
-      script_state, GetDocument(), view_transition_callback, exception_state);
+      script_state, GetDocument(), view_transition_callback,
+      IGNORE_EXCEPTION_FOR_TESTING);
 
   ScriptPromiseTester finished_tester(script_state,
                                       transition->finished(script_state));
@@ -259,9 +264,8 @@
 }
 
 TEST_P(ViewTransitionTest, TransitionCreatesNewObject) {
-  V8TestingScope v8_scope;
-  ScriptState* script_state = v8_scope.GetScriptState();
-  ExceptionState& exception_state = v8_scope.GetExceptionState();
+  ScriptState* script_state = GetScriptState();
+  ScriptState::Scope scope(script_state);
 
   MockFunctionScope funcs(script_state);
   auto* first_callback =
@@ -270,9 +274,11 @@
       V8ViewTransitionCallback::Create(funcs.ExpectCall()->V8Function());
 
   auto* first_transition = ViewTransitionSupplement::startViewTransition(
-      script_state, GetDocument(), first_callback, exception_state);
+      script_state, GetDocument(), first_callback,
+      IGNORE_EXCEPTION_FOR_TESTING);
   auto* second_transition = ViewTransitionSupplement::startViewTransition(
-      script_state, GetDocument(), second_callback, exception_state);
+      script_state, GetDocument(), second_callback,
+      IGNORE_EXCEPTION_FOR_TESTING);
 
   EXPECT_TRUE(first_transition);
   EXPECT_EQ(GetState(first_transition), State::kAborted);
@@ -284,16 +290,16 @@
 }
 
 TEST_P(ViewTransitionTest, TransitionReadyPromiseResolves) {
-  V8TestingScope v8_scope;
-  ScriptState* script_state = v8_scope.GetScriptState();
-  ExceptionState& exception_state = v8_scope.GetExceptionState();
+  ScriptState* script_state = GetScriptState();
+  ScriptState::Scope scope(script_state);
 
   MockFunctionScope funcs(script_state);
   auto* view_transition_callback =
       V8ViewTransitionCallback::Create(funcs.ExpectCall()->V8Function());
 
   auto* transition = ViewTransitionSupplement::startViewTransition(
-      script_state, GetDocument(), view_transition_callback, exception_state);
+      script_state, GetDocument(), view_transition_callback,
+      IGNORE_EXCEPTION_FOR_TESTING);
 
   ScriptPromiseTester promise_tester(script_state,
                                      transition->ready(script_state));
@@ -331,16 +337,16 @@
   auto* e2 = GetDocument().getElementById(AtomicString("e2"));
   auto* e3 = GetDocument().getElementById(AtomicString("e3"));
 
-  V8TestingScope v8_scope;
-  ScriptState* script_state = v8_scope.GetScriptState();
-  ExceptionState& exception_state = v8_scope.GetExceptionState();
+  ScriptState* script_state = GetScriptState();
+  ScriptState::Scope scope(script_state);
 
   MockFunctionScope funcs(script_state);
   auto* view_transition_callback =
       V8ViewTransitionCallback::Create(funcs.ExpectCall()->V8Function());
 
   auto* transition = ViewTransitionSupplement::startViewTransition(
-      script_state, GetDocument(), view_transition_callback, exception_state);
+      script_state, GetDocument(), view_transition_callback,
+      IGNORE_EXCEPTION_FOR_TESTING);
 
   EXPECT_EQ(GetState(transition), State::kCaptureTagDiscovery);
   EXPECT_FALSE(ShouldCompositeForViewTransition(e1));
@@ -393,9 +399,9 @@
   auto* e2 = GetDocument().getElementById(AtomicString("e2"));
   auto* e3 = GetDocument().getElementById(AtomicString("e3"));
 
-  V8TestingScope v8_scope;
-  ScriptState* script_state = v8_scope.GetScriptState();
-  ExceptionState& exception_state = v8_scope.GetExceptionState();
+  ScriptState* script_state = GetScriptState();
+  ScriptState::Scope scope(script_state);
+  DummyExceptionStateForTesting exception_state;
 
   // Set two of the elements to be shared.
   e1->setAttribute(html_names::kStyleAttr,
@@ -441,8 +447,8 @@
                                AtomicString("view-transition-name: e2"));
       };
   auto start_setup_callback =
-      v8::Function::New(v8_scope.GetContext(), start_setup_lambda,
-                        v8::External::New(v8_scope.GetIsolate(), &data))
+      v8::Function::New(script_state->GetContext(), start_setup_lambda,
+                        v8::External::New(script_state->GetIsolate(), &data))
           .ToLocalChecked();
 
   ViewTransitionSupplement::startViewTransition(
@@ -466,16 +472,16 @@
 }
 
 TEST_P(ViewTransitionTest, TransitionCleanedUpBeforePromiseResolution) {
-  V8TestingScope v8_scope;
-  ScriptState* script_state = v8_scope.GetScriptState();
-  ExceptionState& exception_state = v8_scope.GetExceptionState();
+  ScriptState* script_state = GetScriptState();
+  ScriptState::Scope scope(script_state);
 
   MockFunctionScope funcs(script_state);
   auto* view_transition_callback =
       V8ViewTransitionCallback::Create(funcs.ExpectCall()->V8Function());
 
   auto* transition = ViewTransitionSupplement::startViewTransition(
-      script_state, GetDocument(), view_transition_callback, exception_state);
+      script_state, GetDocument(), view_transition_callback,
+      IGNORE_EXCEPTION_FOR_TESTING);
   ScriptPromiseTester promise_tester(script_state,
                                      transition->finished(script_state));
 
@@ -497,16 +503,16 @@
 }
 
 TEST_P(ViewTransitionTest, RenderingPausedTest) {
-  V8TestingScope v8_scope;
-  ScriptState* script_state = v8_scope.GetScriptState();
-  ExceptionState& exception_state = v8_scope.GetExceptionState();
+  ScriptState* script_state = GetScriptState();
+  ScriptState::Scope scope(script_state);
 
   MockFunctionScope funcs(script_state);
   auto* view_transition_callback =
       V8ViewTransitionCallback::Create(funcs.ExpectCall()->V8Function());
 
   auto* transition = ViewTransitionSupplement::startViewTransition(
-      script_state, GetDocument(), view_transition_callback, exception_state);
+      script_state, GetDocument(), view_transition_callback,
+      IGNORE_EXCEPTION_FOR_TESTING);
 
   ScriptPromiseTester finished_tester(script_state,
                                       transition->finished(script_state));
@@ -537,16 +543,16 @@
 }
 
 TEST_P(ViewTransitionTest, Abandon) {
-  V8TestingScope v8_scope;
-  ScriptState* script_state = v8_scope.GetScriptState();
-  ExceptionState& exception_state = v8_scope.GetExceptionState();
+  ScriptState* script_state = GetScriptState();
+  ScriptState::Scope scope(script_state);
 
   MockFunctionScope funcs(script_state);
   auto* view_transition_callback =
       V8ViewTransitionCallback::Create(funcs.ExpectCall()->V8Function());
 
   auto* transition = ViewTransitionSupplement::startViewTransition(
-      script_state, GetDocument(), view_transition_callback, exception_state);
+      script_state, GetDocument(), view_transition_callback,
+      IGNORE_EXCEPTION_FOR_TESTING);
   ScriptPromiseTester finished_tester(script_state,
                                       transition->finished(script_state));
   EXPECT_EQ(GetState(transition), State::kCaptureTagDiscovery);
@@ -573,9 +579,9 @@
     <div id=e3 style="view-transition-name: e3"></div>
   )HTML");
 
-  V8TestingScope v8_scope;
-  ScriptState* script_state = v8_scope.GetScriptState();
-  ExceptionState& exception_state = v8_scope.GetExceptionState();
+  ScriptState* script_state = GetScriptState();
+  ScriptState::Scope scope(script_state);
+  DummyExceptionStateForTesting exception_state;
 
   struct Data {
     STACK_ALLOCATED();
@@ -598,15 +604,15 @@
   auto start_setup_lambda =
       [](const v8::FunctionCallbackInfo<v8::Value>& info) {};
   auto start_setup_callback =
-      v8::Function::New(v8_scope.GetContext(), start_setup_lambda,
-                        v8::External::New(v8_scope.GetIsolate(), &data))
+      v8::Function::New(script_state->GetContext(), start_setup_lambda,
+                        v8::External::New(script_state->GetIsolate(), &data))
           .ToLocalChecked();
 
   auto* transition = ViewTransitionSupplement::startViewTransition(
       script_state, GetDocument(),
-      V8ViewTransitionCallback::Create(start_setup_callback), exception_state);
+      V8ViewTransitionCallback::Create(start_setup_callback),
+      ASSERT_NO_EXCEPTION);
 
-  ASSERT_FALSE(exception_state.HadException());
   UpdateAllLifecyclePhasesForTest();
 
   // The prepare phase should generate the pseudo tree.
@@ -661,23 +667,22 @@
 
   auto* element = GetDocument().getElementById(AtomicString("element"));
 
-  V8TestingScope v8_scope;
-  ScriptState* script_state = v8_scope.GetScriptState();
-  ExceptionState& exception_state = v8_scope.GetExceptionState();
+  ScriptState* script_state = GetScriptState();
+  ScriptState::Scope scope(script_state);
 
   auto start_setup_lambda =
       [](const v8::FunctionCallbackInfo<v8::Value>& info) {};
 
   // This callback sets the elements for the start phase of the transition.
   auto start_setup_callback =
-      v8::Function::New(v8_scope.GetContext(), start_setup_lambda, {})
+      v8::Function::New(script_state->GetContext(), start_setup_lambda, {})
           .ToLocalChecked();
 
   auto* transition = ViewTransitionSupplement::startViewTransition(
       script_state, GetDocument(),
-      V8ViewTransitionCallback::Create(start_setup_callback), exception_state);
+      V8ViewTransitionCallback::Create(start_setup_callback),
+      ASSERT_NO_EXCEPTION);
 
-  ASSERT_FALSE(exception_state.HadException());
   UpdateAllLifecyclePhasesForTest();
 
   // Finish the prepare phase, mutate the DOM and start the animation.
@@ -729,23 +734,22 @@
     <div></div>
   )HTML");
 
-  V8TestingScope v8_scope;
-  ScriptState* script_state = v8_scope.GetScriptState();
-  ExceptionState& exception_state = v8_scope.GetExceptionState();
+  ScriptState* script_state = GetScriptState();
+  ScriptState::Scope scope(script_state);
 
   auto start_setup_lambda =
       [](const v8::FunctionCallbackInfo<v8::Value>& info) {};
 
   // This callback sets the elements for the start phase of the transition.
   auto start_setup_callback =
-      v8::Function::New(v8_scope.GetContext(), start_setup_lambda, {})
+      v8::Function::New(script_state->GetContext(), start_setup_lambda, {})
           .ToLocalChecked();
 
   auto* transition = ViewTransitionSupplement::startViewTransition(
       script_state, GetDocument(),
-      V8ViewTransitionCallback::Create(start_setup_callback), exception_state);
+      V8ViewTransitionCallback::Create(start_setup_callback),
+      ASSERT_NO_EXCEPTION);
 
-  ASSERT_FALSE(exception_state.HadException());
   UpdateAllLifecyclePhasesForTest();
 
   // Finish the prepare phase, mutate the DOM and start the animation.
@@ -849,23 +853,22 @@
 
   UpdateAllLifecyclePhasesForTest();
 
-  V8TestingScope v8_scope;
-  ScriptState* script_state = v8_scope.GetScriptState();
-  ExceptionState& exception_state = v8_scope.GetExceptionState();
+  ScriptState* script_state = GetScriptState();
+  ScriptState::Scope scope(script_state);
 
   auto start_setup_lambda =
       [](const v8::FunctionCallbackInfo<v8::Value>& info) {};
 
   // This callback sets the elements for the start phase of the transition.
   auto start_setup_callback =
-      v8::Function::New(v8_scope.GetContext(), start_setup_lambda, {})
+      v8::Function::New(script_state->GetContext(), start_setup_lambda, {})
           .ToLocalChecked();
 
   auto* transition = ViewTransitionSupplement::startViewTransition(
       script_state, GetDocument(),
-      V8ViewTransitionCallback::Create(start_setup_callback), exception_state);
+      V8ViewTransitionCallback::Create(start_setup_callback),
+      ASSERT_NO_EXCEPTION);
 
-  ASSERT_FALSE(exception_state.HadException());
   UpdateAllLifecyclePhasesForTest();
 
   // The snapshot rect should not have been shrunk by the virtual keyboard, even
@@ -915,21 +918,21 @@
       Document::CreateForTest(*GetDocument().GetExecutionContext());
   ASSERT_FALSE(document->documentElement());
 
-  V8TestingScope v8_scope;
-  ScriptState* script_state = v8_scope.GetScriptState();
-  ExceptionState& exception_state = v8_scope.GetExceptionState();
+  ScriptState* script_state = GetScriptState();
+  ScriptState::Scope scope(script_state);
 
   auto start_setup_lambda =
       [](const v8::FunctionCallbackInfo<v8::Value>& info) {};
 
   // This callback sets the elements for the start phase of the transition.
   auto start_setup_callback =
-      v8::Function::New(v8_scope.GetContext(), start_setup_lambda, {})
+      v8::Function::New(script_state->GetContext(), start_setup_lambda, {})
           .ToLocalChecked();
 
   DOMViewTransition* transition = ViewTransitionSupplement::startViewTransition(
       script_state, *document,
-      V8ViewTransitionCallback::Create(start_setup_callback), exception_state);
+      V8ViewTransitionCallback::Create(start_setup_callback),
+      IGNORE_EXCEPTION_FOR_TESTING);
   ASSERT_FALSE(transition);
 }
 
@@ -943,22 +946,21 @@
 
   UpdateAllLifecyclePhasesForTest();
 
-  V8TestingScope v8_scope;
-  ScriptState* script_state = v8_scope.GetScriptState();
-  ExceptionState& exception_state = v8_scope.GetExceptionState();
+  ScriptState* script_state = GetScriptState();
+  ScriptState::Scope scope(script_state);
 
   auto start_setup_lambda =
       [](const v8::FunctionCallbackInfo<v8::Value>& info) {};
 
   // This callback sets the elements for the start phase of the transition.
   auto start_setup_callback =
-      v8::Function::New(v8_scope.GetContext(), start_setup_lambda, {})
+      v8::Function::New(script_state->GetContext(), start_setup_lambda, {})
           .ToLocalChecked();
 
   auto* transition = ViewTransitionSupplement::startViewTransition(
       script_state, GetDocument(),
-      V8ViewTransitionCallback::Create(start_setup_callback), exception_state);
-  ASSERT_FALSE(exception_state.HadException());
+      V8ViewTransitionCallback::Create(start_setup_callback),
+      ASSERT_NO_EXCEPTION);
 
   EXPECT_TRUE(GetDocument().GetLayoutView()->NeedsPaintPropertyUpdate());
   EXPECT_TRUE(
@@ -991,9 +993,8 @@
 
   UpdateAllLifecyclePhasesForTest();
 
-  V8TestingScope v8_scope;
-  ScriptState* script_state = v8_scope.GetScriptState();
-  ExceptionState& exception_state = v8_scope.GetExceptionState();
+  ScriptState* script_state = GetScriptState();
+  ScriptState::Scope scope(script_state);
 
   auto start_setup_lambda =
       [](const v8::FunctionCallbackInfo<v8::Value>& info) {
@@ -1006,14 +1007,14 @@
   // This callback sets the elements for the start phase of the transition.
   auto start_setup_callback =
       v8::Function::New(
-          v8_scope.GetContext(), start_setup_lambda,
-          v8::External::New(v8_scope.GetIsolate(), &GetDocument()))
+          script_state->GetContext(), start_setup_lambda,
+          v8::External::New(script_state->GetIsolate(), &GetDocument()))
           .ToLocalChecked();
 
   ViewTransitionSupplement::startViewTransition(
       script_state, GetDocument(),
-      V8ViewTransitionCallback::Create(start_setup_callback), exception_state);
-  ASSERT_FALSE(exception_state.HadException());
+      V8ViewTransitionCallback::Create(start_setup_callback),
+      ASSERT_NO_EXCEPTION);
 
   UpdateAllLifecyclePhasesAndFinishDirectives();
   test::RunPendingTasks();
@@ -1084,22 +1085,21 @@
 
   UpdateAllLifecyclePhasesForTest();
 
-  V8TestingScope v8_scope;
-  ScriptState* script_state = v8_scope.GetScriptState();
-  ExceptionState& exception_state = v8_scope.GetExceptionState();
+  ScriptState* script_state = GetScriptState();
+  ScriptState::Scope scope(script_state);
 
   auto start_setup_lambda =
       [](const v8::FunctionCallbackInfo<v8::Value>& info) {};
 
   // This callback sets the elements for the start phase of the transition.
   auto start_setup_callback =
-      v8::Function::New(v8_scope.GetContext(), start_setup_lambda, {})
+      v8::Function::New(script_state->GetContext(), start_setup_lambda, {})
           .ToLocalChecked();
 
   ViewTransitionSupplement::startViewTransition(
       script_state, GetDocument(),
-      V8ViewTransitionCallback::Create(start_setup_callback), exception_state);
-  ASSERT_FALSE(exception_state.HadException());
+      V8ViewTransitionCallback::Create(start_setup_callback),
+      ASSERT_NO_EXCEPTION);
 
   UpdateAllLifecyclePhasesAndFinishDirectives();
   test::RunPendingTasks();
@@ -1163,22 +1163,21 @@
 
   UpdateAllLifecyclePhasesForTest();
 
-  V8TestingScope v8_scope;
-  ScriptState* script_state = v8_scope.GetScriptState();
-  ExceptionState& exception_state = v8_scope.GetExceptionState();
+  ScriptState* script_state = GetScriptState();
+  ScriptState::Scope scope(script_state);
 
   auto start_setup_lambda =
       [](const v8::FunctionCallbackInfo<v8::Value>& info) {};
 
   // This callback sets the elements for the start phase of the transition.
   auto start_setup_callback =
-      v8::Function::New(v8_scope.GetContext(), start_setup_lambda, {})
+      v8::Function::New(script_state->GetContext(), start_setup_lambda, {})
           .ToLocalChecked();
 
   ViewTransitionSupplement::startViewTransition(
       script_state, GetDocument(),
-      V8ViewTransitionCallback::Create(start_setup_callback), exception_state);
-  ASSERT_FALSE(exception_state.HadException());
+      V8ViewTransitionCallback::Create(start_setup_callback),
+      ASSERT_NO_EXCEPTION);
 
   UpdateAllLifecyclePhasesAndFinishDirectives();
   test::RunPendingTasks();
@@ -1270,22 +1269,21 @@
 
   UpdateAllLifecyclePhasesForTest();
 
-  V8TestingScope v8_scope;
-  ScriptState* script_state = v8_scope.GetScriptState();
-  ExceptionState& exception_state = v8_scope.GetExceptionState();
+  ScriptState* script_state = GetScriptState();
+  ScriptState::Scope scope(script_state);
 
   auto start_setup_lambda =
       [](const v8::FunctionCallbackInfo<v8::Value>& info) {};
 
   // This callback sets the elements for the start phase of the transition.
   auto start_setup_callback =
-      v8::Function::New(v8_scope.GetContext(), start_setup_lambda, {})
+      v8::Function::New(script_state->GetContext(), start_setup_lambda, {})
           .ToLocalChecked();
 
   ViewTransitionSupplement::startViewTransition(
       script_state, GetDocument(),
-      V8ViewTransitionCallback::Create(start_setup_callback), exception_state);
-  ASSERT_FALSE(exception_state.HadException());
+      V8ViewTransitionCallback::Create(start_setup_callback),
+      ASSERT_NO_EXCEPTION);
 
   UpdateAllLifecyclePhasesAndFinishDirectives();
   test::RunPendingTasks();
@@ -1310,9 +1308,8 @@
   GetDocument().domWindow()->navigation()->UpdateCurrentEntryForTesting(
       *current_item);
 
-  V8TestingScope v8_scope;
-  ScriptState* script_state = v8_scope.GetScriptState();
-  ExceptionState& exception_state = v8_scope.GetExceptionState();
+  ScriptState* script_state = GetScriptState();
+  ScriptState::Scope scope(script_state);
 
   auto page_swap_params = mojom::blink::PageSwapEventParams::New();
   page_swap_params->url = KURL("http://test.com");
@@ -1335,14 +1332,14 @@
       };
   auto start_setup_callback =
       v8::Function::New(
-          v8_scope.GetContext(), start_setup_lambda,
-          v8::External::New(v8_scope.GetIsolate(), &callback_issued))
+          script_state->GetContext(), start_setup_lambda,
+          v8::External::New(script_state->GetIsolate(), &callback_issued))
           .ToLocalChecked();
   DOMViewTransition* script_transition =
       ViewTransitionSupplement::startViewTransition(
           script_state, GetDocument(),
           V8ViewTransitionCallback::Create(start_setup_callback),
-          exception_state);
+          IGNORE_EXCEPTION_FOR_TESTING);
 
   EXPECT_TRUE(script_transition);
 
diff --git a/third_party/blink/renderer/modules/webtransport/web_transport_test.cc b/third_party/blink/renderer/modules/webtransport/web_transport_test.cc
index 7a5adc2..12f412ec 100644
--- a/third_party/blink/renderer/modules/webtransport/web_transport_test.cc
+++ b/third_party/blink/renderer/modules/webtransport/web_transport_test.cc
@@ -1552,8 +1552,8 @@
   {
     v8::HandleScope handle_scope(isolate);
     ScriptPromiseTester tester(
-        script_state, ScriptPromiseUntyped(
-                          script_state, close_promise_persistent.Get(isolate)));
+        script_state,
+        ScriptPromiseUntyped(isolate, close_promise_persistent.Get(isolate)));
     close_promise_persistent.Reset();
     tester.WaitUntilSettled();
     EXPECT_TRUE(tester.IsFulfilled());