  v8::Local<v8::Promise> ExecuteJavaScript(gin::Arguments* gin_args,
                                           const std::u16string& code) {
    gin_helper::Arguments* args = static_cast<gin_helper::Arguments*>(gin_args);

    v8::Isolate* isolate = args->isolate();
    gin_helper::Promise<v8::Local<v8::Value>> promise(isolate);
    v8::Local<v8::Promise> handle = promise.GetHandle();

    content::RenderFrame* render_frame;
    std::string error_msg;
    if (!MaybeGetRenderFrame(&error_msg, "executeJavaScript", &render_frame)) {
      promise.RejectWithErrorMessage(error_msg);
      return handle;
    }

    const blink::WebScriptSource source{blink::WebString::FromUTF16(code)};

    bool has_user_gesture = false;
    args->GetNext(&has_user_gesture);

    ScriptExecutionCallback::CompletionCallback completion_callback;
    args->GetNext(&completion_callback);

    render_frame->GetWebFrame()->RequestExecuteScript(
        blink::DOMWrapperWorld::kMainWorldId, base::make_span(&source, 1),
        has_user_gesture, blink::WebLocalFrame::kSynchronous,
        new ScriptExecutionCallback(std::move(promise),
                                    std::move(completion_callback)),
        blink::BackForwardCacheAware::kAllow,
        blink::WebLocalFrame::PromiseBehavior::kDontWait);

    return handle;
  }
  v8::Local<v8::Promise> ExecuteJavaScript(gin::Arguments* gin_args,
                                           const std::u16string& code) {
    gin_helper::Arguments* args = static_cast<gin_helper::Arguments*>(gin_args);

    v8::Isolate* isolate = args->isolate();
    gin_helper::Promise<v8::Local<v8::Value>> promise(isolate);
    v8::Local<v8::Promise> handle = promise.GetHandle();

    content::RenderFrame* render_frame;
    std::string error_msg;
    if (!MaybeGetRenderFrame(&error_msg, "executeJavaScript", &render_frame)) {
      promise.RejectWithErrorMessage(error_msg);
      return handle;
    }

    const blink::WebScriptSource source{blink::WebString::FromUTF16(code)};

    bool has_user_gesture = false;
    args->GetNext(&has_user_gesture);

    ScriptExecutionCallback::CompletionCallback completion_callback;
    args->GetNext(&completion_callback);

    render_frame->GetWebFrame()->RequestExecuteScript(
        blink::DOMWrapperWorld::kMainWorldId, base::make_span(&source, 1),
        has_user_gesture, blink::WebLocalFrame::kSynchronous,
        new ScriptExecutionCallback(std::move(promise),
                                    std::move(completion_callback)),
        blink::BackForwardCacheAware::kAllow,
        blink::WebLocalFrame::PromiseBehavior::kDontWait);

    return handle;
  }