From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dave Tapuska <dtapuska@chromium.org>
Date: Tue, 8 Feb 2022 15:58:40 +0000
Subject: Cleanup PausablecriptExecutor usage.

Improve performance of API so we don't have to go from
WTF::String->WebString->WTF::String for execution.

Ensure the Executor is traced via the PausableScriptExecutor.

BUG=1289384

(cherry picked from commit c8231f9a89460fd8336e6c0d8e10347f52f540ec)

Change-Id: If9badab91222c49c08a983c60132ce71b183e951
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3407654
Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Commit-Queue: Dave Tapuska <dtapuska@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#963010}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3443262
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/branch-heads/4758@{#1109}
Cr-Branched-From: 4a2cf4baf90326df19c3ee70ff987960d59a386e-refs/heads/main@{#950365}

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 71653584749ef80143f3312a85a9537edd35f014..60377e12f05d298aa512a2eda5358c8bea49d114 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
@@ -211,15 +211,16 @@ v8::MaybeLocal<v8::Value> CallMethodOnFrame(LocalFrame* local_frame,
 
 // A wrapper class used as the callback for JavaScript executed
 // in an isolated world.
-class JavaScriptIsolatedWorldRequest
-    : public GarbageCollected<JavaScriptIsolatedWorldRequest>,
-      public WebScriptExecutionCallback {
+class JavaScriptIsolatedWorldRequest : public PausableScriptExecutor::Executor,
+                                       public WebScriptExecutionCallback {
   using JavaScriptExecuteRequestInIsolatedWorldCallback =
       mojom::blink::LocalFrame::JavaScriptExecuteRequestInIsolatedWorldCallback;
 
  public:
   JavaScriptIsolatedWorldRequest(
       LocalFrame* local_frame,
+      int32_t world_id,
+      const String& script,
       bool wants_result,
       mojom::blink::LocalFrame::JavaScriptExecuteRequestInIsolatedWorldCallback
           callback);
@@ -229,27 +230,53 @@ class JavaScriptIsolatedWorldRequest
       const JavaScriptIsolatedWorldRequest&) = delete;
   ~JavaScriptIsolatedWorldRequest() override;
 
-  // WebScriptExecutionCallback:
-  void Completed(const WebVector<v8::Local<v8::Value>>& result) override;
+  // PausableScriptExecutor::Executor overrides.
+  Vector<v8::Local<v8::Value>> Execute(LocalDOMWindow*) override;
+
+  void Trace(Visitor* visitor) const override;
 
-  void Trace(Visitor* visitor) const { visitor->Trace(local_frame_); }
+  // WebScriptExecutionCallback overrides.
+  void Completed(const WebVector<v8::Local<v8::Value>>& result) override;
 
  private:
   Member<LocalFrame> local_frame_;
+  int32_t world_id_;
+  String script_;
   bool wants_result_;
   JavaScriptExecuteRequestInIsolatedWorldCallback callback_;
 };
 
 JavaScriptIsolatedWorldRequest::JavaScriptIsolatedWorldRequest(
     LocalFrame* local_frame,
+    int32_t world_id,
+    const String& script,
     bool wants_result,
     JavaScriptExecuteRequestInIsolatedWorldCallback callback)
     : local_frame_(local_frame),
+      world_id_(world_id),
+      script_(script),
       wants_result_(wants_result),
-      callback_(std::move(callback)) {}
+      callback_(std::move(callback)) {
+  DCHECK_GT(world_id, DOMWrapperWorld::kMainWorldId);
+}
 
 JavaScriptIsolatedWorldRequest::~JavaScriptIsolatedWorldRequest() = default;
 
+void JavaScriptIsolatedWorldRequest::Trace(Visitor* visitor) const {
+  PausableScriptExecutor::Executor::Trace(visitor);
+  visitor->Trace(local_frame_);
+}
+
+Vector<v8::Local<v8::Value>> JavaScriptIsolatedWorldRequest::Execute(
+    LocalDOMWindow* window) {
+  // Note: An error event in an isolated world will never be dispatched to
+  // a foreign world.
+  ClassicScript* classic_script = ClassicScript::CreateUnspecifiedScript(
+      script_, SanitizeScriptErrors::kDoNotSanitize);
+  return {classic_script->RunScriptInIsolatedWorldAndReturnValue(window,
+                                                                 world_id_)};
+}
+
 void JavaScriptIsolatedWorldRequest::Completed(
     const WebVector<v8::Local<v8::Value>>& result) {
   base::Value value;
@@ -269,7 +296,6 @@ void JavaScriptIsolatedWorldRequest::Completed(
     if (new_value)
       value = base::Value::FromUniquePtrValue(std::move(new_value));
   }
-
   std::move(callback_).Run(std::move(value));
 }
 
@@ -927,13 +953,16 @@ void LocalFrameMojoHandler::JavaScriptExecuteRequestInIsolatedWorld(
   v8::HandleScope handle_scope(v8::Isolate::GetCurrent());
   scoped_refptr<DOMWrapperWorld> isolated_world =
       DOMWrapperWorld::EnsureIsolatedWorld(ToIsolate(frame_), world_id);
-  ScriptSourceCode source_code = ScriptSourceCode(javascript);
-  HeapVector<ScriptSourceCode> sources;
-  sources.Append(&source_code, 1);
-  auto* executor = MakeGarbageCollected<PausableScriptExecutor>(
-      DomWindow(), std::move(isolated_world), sources, false /* user_gesture */,
+
+  // This member will be traced as the |executor| on the PausableScriptExector.
+  auto* execution_request =
       MakeGarbageCollected<JavaScriptIsolatedWorldRequest>(
-          frame_, wants_result, std::move(callback)));
+          frame_, world_id, javascript, wants_result, std::move(callback));
+
+  auto* executor = MakeGarbageCollected<PausableScriptExecutor>(
+      DomWindow(), ToScriptState(frame_, *isolated_world),
+      /*callback=*/execution_request,
+      /*executor=*/execution_request);
   executor->Run();
 }
 
