Browse Source

ci: auto-3way patches and detect changes (#22976)

Jeremy Apthorp 5 years ago
parent
commit
29f773e008

+ 23 - 1
.circleci/config.yml

@@ -231,7 +231,25 @@ step-gclient-sync: &step-gclient-sync
           $GCLIENT_EXTRA_ARGS \
           "$CIRCLE_REPOSITORY_URL"
 
-        gclient sync --with_branch_heads --with_tags
+        ELECTRON_USE_THREE_WAY_MERGE_FOR_PATCHES=1 gclient sync --with_branch_heads --with_tags
+        # Re-export all the patches to check if there were changes.
+        python src/electron/script/export_all_patches.py src/electron/patches/config.json
+        cd src/electron
+        git update-index --refresh
+        if ! git diff-index --quiet HEAD --; then
+          # There are changes to the patches. Make a git commit with the updated patches
+          git add patches
+          GIT_COMMITTER_NAME="Electron Bot" GIT_COMMITTER_EMAIL="[email protected]" git commit -m "update patches" --author="Electron Bot <[email protected]>"
+          # Export it
+          mkdir -p ../../patches
+          git format-patch -1 --stdout --keep-subject --no-stat --full-index > ../../patches/update-patches.patch
+          echo
+          echo "======================================================================"
+          echo "There were changes to the patches when applying."
+          echo "Check the CI artifacts for a patch you can apply to fix it."
+          echo "======================================================================"
+          exit 1
+        fi
       fi
 
 step-setup-env-for-build: &step-setup-env-for-build
@@ -981,6 +999,8 @@ steps-checkout-and-save-cache: &steps-checkout-and-save-cache
     - *step-set-git-cache-path
     # This sync call only runs if .circle-sync-done is an EMPTY file
     - *step-gclient-sync
+    - store_artifacts:
+        path: patches
     - *step-save-git-cache
     # These next few steps reset Electron to the correct commit regardless of which cache was restored
     - run:
@@ -1301,6 +1321,8 @@ commands:
             - *step-set-git-cache-path
             # This sync call only runs if .circle-sync-done is an EMPTY file
             - *step-gclient-sync
+            - store_artifacts:
+                path: patches
             # These next few steps reset Electron to the correct commit regardless of which cache was restored
             - when:
                 condition: << parameters.preserve-vendor-dirs >>

+ 1 - 1
patches/boringssl/fix_add_RSA-PSS_keygen_functions.patch

@@ -9,7 +9,7 @@ Refs https://github.com/nodejs/node/pull/26960.
 Upstreamed at https://boringssl-review.googlesource.com/c/boringssl/+/38524.
 
 diff --git a/include/openssl/evp.h b/include/openssl/evp.h
-index 19baa64ddba84c3dd59e65aef77d1ebbf49e43df..37217c49f7e05eb25562023bf356fdadae1bc66f 100644
+index fe6c8b6adb3ec1259f1d66d7b77da3577cbaf2dc..d15cbdc394fbd0944314375115e38380462d17f4 100644
 --- a/include/openssl/evp.h
 +++ b/include/openssl/evp.h
 @@ -723,6 +723,18 @@ OPENSSL_EXPORT int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int padding);

+ 1 - 1
patches/chromium/command-ismediakey.patch

@@ -91,7 +91,7 @@ index 85378bb565de617b1bd611d28c8714361747a357..d67d558b91b49835dfa9278930939480
    }
    return VKEY_UNKNOWN;
  }
-@@ -192,7 +199,10 @@ static CGEventRef EventTapCallback(CGEventTapProxy proxy,
+@@ -192,7 +199,10 @@ CGEventRef MediaKeysListenerImpl::EventTapCallback(CGEventTapProxy proxy,
    int key_code = (data1 & 0xFFFF0000) >> 16;
    if (key_code != NX_KEYTYPE_PLAY && key_code != NX_KEYTYPE_NEXT &&
        key_code != NX_KEYTYPE_PREVIOUS && key_code != NX_KEYTYPE_FAST &&

+ 1 - 1
patches/chromium/disable_compositor_recycling.patch

@@ -9,7 +9,7 @@ diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/cont
 index 7d70d057e10ccf3301e810c8a0521d644c8e907f..591305cb57a2f89067b25189b9c33d92858f01a0 100644
 --- a/content/browser/renderer_host/render_widget_host_view_mac.mm
 +++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
-@@ -472,7 +472,11 @@
+@@ -472,7 +472,11 @@ void RenderWidgetHostViewMac::WasOccluded() {
      return;
  
    host()->WasHidden();

+ 1 - 1
patches/chromium/fix_undo_redo_broken_in_webviews.patch

@@ -20,7 +20,7 @@ index 591305cb57a2f89067b25189b9c33d92858f01a0..a3112cb03bc73eb670631ff429f38414
  #include "content/common/text_input_state.h"
  #include "content/common/view_messages.h"
  #include "content/public/browser/browser_context.h"
-@@ -978,7 +979,12 @@ void CombineTextNodesAndMakeCallback(SpeechCallback callback,
+@@ -978,7 +979,12 @@ gfx::Range RenderWidgetHostViewMac::ConvertCharacterRangeToCompositionRange(
  }
  
  WebContents* RenderWidgetHostViewMac::GetWebContents() {

+ 1 - 1
patches/chromium/fix_use_the_new_mediaplaypause_key_listener_for_internal_chrome.patch

@@ -12,7 +12,7 @@ diff --git a/chrome/browser/extensions/global_shortcut_listener_mac.mm b/chrome/
 index befe726af9c10b1563a7fc0bb77cc55f65943d5c..bac51f33f35f96fe4ecc764cf5ca887176642f74 100644
 --- a/chrome/browser/extensions/global_shortcut_listener_mac.mm
 +++ b/chrome/browser/extensions/global_shortcut_listener_mac.mm
-@@ -39,7 +39,7 @@
+@@ -39,7 +39,7 @@ GlobalShortcutListenerMac::GlobalShortcutListenerMac()
    // global MediaKeysListener to receive media keys.
    if (!content::MediaKeysListenerManager::IsMediaKeysListenerManagerEnabled()) {
      media_keys_listener_ = ui::MediaKeysListener::Create(

+ 3 - 3
patches/chromium/mas-cfisobjc.patch

@@ -9,7 +9,7 @@ diff --git a/base/mac/foundation_util.mm b/base/mac/foundation_util.mm
 index 2a83d4d8158422c1056725679309c6ced1e531bd..f52934712f8de78193127c426d02982b36e9d422 100644
 --- a/base/mac/foundation_util.mm
 +++ b/base/mac/foundation_util.mm
-@@ -27,7 +27,6 @@
+@@ -27,7 +27,6 @@ CFTypeID SecKeyGetTypeID();
  #if !defined(OS_IOS)
  CFTypeID SecACLGetTypeID();
  CFTypeID SecTrustedApplicationGetTypeID();
@@ -17,7 +17,7 @@ index 2a83d4d8158422c1056725679309c6ced1e531bd..f52934712f8de78193127c426d02982b
  #endif
  }  // extern "C"
  
-@@ -316,8 +315,7 @@ void SetBaseBundleID(const char* new_base_bundle_id) {
+@@ -316,8 +315,7 @@ NSFont* CFToNSCast(CTFontRef cf_val) {
        const_cast<NSFont*>(reinterpret_cast<const NSFont*>(cf_val));
    DCHECK(!cf_val ||
           CTFontGetTypeID() == CFGetTypeID(cf_val) ||
@@ -27,7 +27,7 @@ index 2a83d4d8158422c1056725679309c6ced1e531bd..f52934712f8de78193127c426d02982b
    return ns_val;
  }
  
-@@ -385,9 +383,6 @@ CTFontRef NSToCFCast(NSFont* ns_val) {
+@@ -385,9 +383,6 @@ CFCast<CTFontRef>(const CFTypeRef& cf_val) {
      return (CTFontRef)(cf_val);
    }
  

+ 3 - 3
patches/chromium/mas_blink_no_private_api.patch

@@ -18,7 +18,7 @@ index 94afefcee81b87c05bf9b1199d90d3d4b5ea84a6..2ec7f04c71824b47de1ddbf1f0e8625d
  extern "C" {
  
  // Kill ring calls. Would be better to use NSKillRing.h, but that's not
-@@ -39,38 +40,53 @@
+@@ -39,38 +40,53 @@ NSString* _NSYankFromKillRing();
  void _NSNewKillRingSequence();
  void _NSSetKillRingToYankedState();
  }
@@ -92,7 +92,7 @@ index 8f4ae94bc1d8188d041654c50511f3346eee79de..fa06f47abbff3dcda937bf0b794f616e
  
  namespace blink {
  
-@@ -95,10 +97,12 @@ void _NSDrawCarbonThemeListBox(NSRect frame,
+@@ -95,10 +97,12 @@ bool ThemePainterMac::PaintTextField(const Node* node,
    // behavior change while remaining a fragile solution.
    // https://bugs.chromium.org/p/chromium/issues/detail?id=658085#c3
    if (!use_ns_text_field_cell) {
@@ -105,7 +105,7 @@ index 8f4ae94bc1d8188d041654c50511f3346eee79de..fa06f47abbff3dcda937bf0b794f616e
      return false;
    }
  
-@@ -186,10 +190,12 @@ void _NSDrawCarbonThemeListBox(NSRect frame,
+@@ -186,10 +190,12 @@ bool ThemePainterMac::PaintTextArea(const Node* node,
                                      const IntRect& r) {
    ScopedColorSchemeAppearance appearance(style.UsedColorScheme());
    LocalCurrentGraphicsContext local_context(paint_info.context, r);

+ 8 - 8
patches/chromium/mas_disable_custom_window_frame.patch

@@ -18,7 +18,7 @@ index cf88f696a46ff0ac84bcf466b44d1080438426c1..7672eee30a811001a0149edfa4eed9dc
  @interface NSWindow (PrivateBrowserNativeWidgetAPI)
  + (Class)frameViewClassForStyleMask:(NSUInteger)windowStyle;
  @end
-@@ -63,10 +64,13 @@ - (NSRect)_draggableFrame NS_DEPRECATED_MAC(10_10, 10_11) {
+@@ -63,10 +64,13 @@
  
  @end
  
@@ -32,7 +32,7 @@ index cf88f696a46ff0ac84bcf466b44d1080438426c1..7672eee30a811001a0149edfa4eed9dc
  + (Class)frameViewClassForStyleMask:(NSUInteger)windowStyle {
    // - NSThemeFrame and its subclasses will be nil if it's missing at runtime.
    if ([BrowserWindowFrame class])
-@@ -81,6 +85,8 @@ - (BOOL)_usesCustomDrawing {
+@@ -81,6 +85,8 @@
    return NO;
  }
  
@@ -54,7 +54,7 @@ index 8416c7c6e052dafb2aad61c0bd3224c36e945d23..cd356beda023ab2409b16d58ca38c70b
  @interface NSWindow (PrivateAPI)
  + (Class)frameViewClassForStyleMask:(NSUInteger)windowStyle;
  @end
-@@ -18,8 +20,12 @@ - (CGFloat)_titlebarHeight {
+@@ -18,8 +20,12 @@
  }
  @end
  
@@ -67,7 +67,7 @@ index 8416c7c6e052dafb2aad61c0bd3224c36e945d23..cd356beda023ab2409b16d58ca38c70b
  + (Class)frameViewClassForStyleMask:(NSUInteger)windowStyle {
    if ([NativeWidgetMacFramelessNSWindowFrame class]) {
      return [NativeWidgetMacFramelessNSWindowFrame class];
-@@ -27,4 +33,6 @@ + (Class)frameViewClassForStyleMask:(NSUInteger)windowStyle {
+@@ -27,4 +33,6 @@
    return [super frameViewClassForStyleMask:windowStyle];
  }
  
@@ -108,7 +108,7 @@ index c10c6633e7bc61cdc3ee41fc018786731177a948..09cc91eaab41e82165d550313579c9e1
  - (BOOL)hasKeyAppearance;
  - (long long)_resizeDirectionForMouseLocation:(CGPoint)location;
  - (BOOL)_isConsideredOpenForPersistentState;
-@@ -56,6 +58,8 @@ - (void)cr_mouseDownOnFrameView:(NSEvent*)event {
+@@ -56,6 +58,8 @@
  }
  @end
  
@@ -117,7 +117,7 @@ index c10c6633e7bc61cdc3ee41fc018786731177a948..09cc91eaab41e82165d550313579c9e1
  @implementation NativeWidgetMacNSWindowTitledFrame
  - (void)mouseDown:(NSEvent*)event {
    if (self.window.isMovable)
-@@ -82,6 +86,8 @@ - (BOOL)usesCustomDrawing {
+@@ -82,6 +86,8 @@
  }
  @end
  
@@ -126,7 +126,7 @@ index c10c6633e7bc61cdc3ee41fc018786731177a948..09cc91eaab41e82165d550313579c9e1
  @implementation NativeWidgetMacNSWindow {
   @private
    base::scoped_nsobject<CommandDispatcher> _commandDispatcher;
-@@ -163,6 +169,8 @@ - (BOOL)hasViewsMenuActive {
+@@ -163,6 +169,8 @@
  
  // NSWindow overrides.
  
@@ -135,7 +135,7 @@ index c10c6633e7bc61cdc3ee41fc018786731177a948..09cc91eaab41e82165d550313579c9e1
  + (Class)frameViewClassForStyleMask:(NSWindowStyleMask)windowStyle {
    if (windowStyle & NSWindowStyleMaskTitled) {
      if (Class customFrame = [NativeWidgetMacNSWindowTitledFrame class])
-@@ -174,6 +182,8 @@ + (Class)frameViewClassForStyleMask:(NSWindowStyleMask)windowStyle {
+@@ -174,6 +182,8 @@
    return [super frameViewClassForStyleMask:windowStyle];
  }
  

+ 13 - 13
patches/chromium/mas_disable_remote_accessibility.patch

@@ -17,7 +17,7 @@ diff --git a/components/remote_cocoa/app_shim/application_bridge.mm b/components
 index 9ddda9116e7284cbccde8a51e23ad7560dd06367..e846091ad99b0154636489e53491209ff3cbfaaa 100644
 --- a/components/remote_cocoa/app_shim/application_bridge.mm
 +++ b/components/remote_cocoa/app_shim/application_bridge.mm
-@@ -49,6 +49,7 @@
+@@ -49,6 +49,7 @@ class NativeWidgetBridgeOwner : public NativeWidgetNSWindowHostHelper {
  
    // NativeWidgetNSWindowHostHelper:
    id GetNativeViewAccessible() override {
@@ -25,7 +25,7 @@ index 9ddda9116e7284cbccde8a51e23ad7560dd06367..e846091ad99b0154636489e53491209f
      if (!remote_accessibility_element_) {
        int64_t browser_pid = 0;
        std::vector<uint8_t> element_token;
-@@ -59,6 +60,9 @@ id GetNativeViewAccessible() override {
+@@ -59,6 +60,9 @@ class NativeWidgetBridgeOwner : public NativeWidgetNSWindowHostHelper {
            ui::RemoteAccessibility::GetRemoteElementFromToken(element_token);
      }
      return remote_accessibility_element_.get();
@@ -35,7 +35,7 @@ index 9ddda9116e7284cbccde8a51e23ad7560dd06367..e846091ad99b0154636489e53491209f
    }
    void DispatchKeyEvent(ui::KeyEvent* event) override {
      bool event_handled = false;
-@@ -96,8 +100,10 @@ void GetWordAt(const gfx::Point& location_in_content,
+@@ -96,8 +100,10 @@ class NativeWidgetBridgeOwner : public NativeWidgetNSWindowHostHelper {
    mojo::AssociatedRemote<mojom::TextInputHost> text_input_host_remote_;
  
    std::unique_ptr<NativeWidgetNSWindowBridge> bridge_;
@@ -50,7 +50,7 @@ diff --git a/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.mm
 index 2ee45cb069ec5d78d9c7a3f61fdd1d444a590f41..badc4323b910f8e3957583e05af303472cb204f6 100644
 --- a/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.mm
 +++ b/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.mm
-@@ -543,10 +543,12 @@ NSUInteger CountBridgedWindows(NSArray* child_windows) {
+@@ -543,10 +543,12 @@ void NativeWidgetNSWindowBridge::CreateContentView(uint64_t ns_view_id,
    // this should be treated as an error and caught early.
    CHECK(bridged_view_);
  
@@ -67,7 +67,7 @@ diff --git a/content/app_shim_remote_cocoa/ns_view_bridge_factory_impl.mm b/cont
 index a8e5c8888cb7ea8a85de7c8e8c613cc2b3c5be15..d01468fe77703b2812865b0198b84b0b645283c4 100644
 --- a/content/app_shim_remote_cocoa/ns_view_bridge_factory_impl.mm
 +++ b/content/app_shim_remote_cocoa/ns_view_bridge_factory_impl.mm
-@@ -66,8 +66,10 @@ id GetFocusedBrowserAccessibilityElement() override {
+@@ -66,8 +66,10 @@ class RenderWidgetHostNSViewBridgeOwner
      return nil;
    }
    void SetAccessibilityWindow(NSWindow* window) override {
@@ -78,7 +78,7 @@ index a8e5c8888cb7ea8a85de7c8e8c613cc2b3c5be15..d01468fe77703b2812865b0198b84b0b
    }
  
    void ForwardKeyboardEvent(const content::NativeWebKeyboardEvent& key_event,
-@@ -126,8 +128,10 @@ void SmartMagnify(const blink::WebGestureEvent& web_event) override {
+@@ -126,8 +128,10 @@ class RenderWidgetHostNSViewBridgeOwner
  
    mojo::AssociatedRemote<mojom::RenderWidgetHostNSViewHost> host_;
    std::unique_ptr<RenderWidgetHostNSViewBridge> bridge_;
@@ -120,7 +120,7 @@ diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/cont
 index de6fb32e1ff930fbb1c778b59ba18402741c8b44..7d70d057e10ccf3301e810c8a0521d644c8e907f 100644
 --- a/content/browser/renderer_host/render_widget_host_view_mac.mm
 +++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
-@@ -231,8 +231,10 @@
+@@ -231,8 +231,10 @@ RenderWidgetHostViewMac::~RenderWidgetHostViewMac() {
  void RenderWidgetHostViewMac::MigrateNSViewBridge(
      remote_cocoa::mojom::Application* remote_cocoa_application,
      uint64_t parent_ns_view_id) {
@@ -131,7 +131,7 @@ index de6fb32e1ff930fbb1c778b59ba18402741c8b44..7d70d057e10ccf3301e810c8a0521d64
  
    // Disconnect from the previous bridge (this will have the effect of
    // destroying the associated bridge), and close the receiver (to allow it
-@@ -1348,8 +1350,10 @@ void CombineTextNodesAndMakeCallback(SpeechCallback callback,
+@@ -1348,8 +1350,10 @@ RenderWidgetHostViewMac::AccessibilityGetNativeViewAccessible() {
  
  gfx::NativeViewAccessible
  RenderWidgetHostViewMac::AccessibilityGetNativeViewAccessibleForWindow() {
@@ -142,7 +142,7 @@ index de6fb32e1ff930fbb1c778b59ba18402741c8b44..7d70d057e10ccf3301e810c8a0521d64
    return [GetInProcessNSView() window];
  }
  
-@@ -1381,9 +1385,11 @@ void CombineTextNodesAndMakeCallback(SpeechCallback callback,
+@@ -1381,9 +1385,11 @@ id RenderWidgetHostViewMac::GetFocusedBrowserAccessibilityElement() {
  }
  
  void RenderWidgetHostViewMac::SetAccessibilityWindow(NSWindow* window) {
@@ -154,7 +154,7 @@ index de6fb32e1ff930fbb1c778b59ba18402741c8b44..7d70d057e10ccf3301e810c8a0521d64
  }
  
  bool RenderWidgetHostViewMac::SyncIsWidgetForMainFrame(
-@@ -1866,12 +1872,14 @@ void CombineTextNodesAndMakeCallback(SpeechCallback callback,
+@@ -1866,12 +1872,14 @@ void RenderWidgetHostViewMac::StopSpeaking() {
  
  void RenderWidgetHostViewMac::SetRemoteAccessibilityWindowToken(
      const std::vector<uint8_t>& window_token) {
@@ -239,7 +239,7 @@ diff --git a/ui/views/cocoa/native_widget_mac_ns_window_host.mm b/ui/views/cocoa
 index 2256c365af5b1af79458fdcb0cb9d44c9ff641fd..f4949b071a177452b0074a2436669e9846558d1a 100644
 --- a/ui/views/cocoa/native_widget_mac_ns_window_host.mm
 +++ b/ui/views/cocoa/native_widget_mac_ns_window_host.mm
-@@ -282,14 +282,22 @@ void HandleAccelerator(const ui::Accelerator& accelerator,
+@@ -282,14 +282,22 @@ gfx::NativeViewAccessible
  NativeWidgetMacNSWindowHost::GetNativeViewAccessibleForNSView() const {
    if (in_process_ns_window_bridge_)
      return in_process_ns_window_bridge_->ns_view();
@@ -262,7 +262,7 @@ index 2256c365af5b1af79458fdcb0cb9d44c9ff641fd..f4949b071a177452b0074a2436669e98
  }
  
  remote_cocoa::mojom::NativeWidgetNSWindow*
-@@ -1118,6 +1126,7 @@ void HandleAccelerator(const ui::Accelerator& accelerator,
+@@ -1118,6 +1126,7 @@ void NativeWidgetMacNSWindowHost::OnFocusWindowToolbar() {
  void NativeWidgetMacNSWindowHost::SetRemoteAccessibilityTokens(
      const std::vector<uint8_t>& window_token,
      const std::vector<uint8_t>& view_token) {
@@ -270,7 +270,7 @@ index 2256c365af5b1af79458fdcb0cb9d44c9ff641fd..f4949b071a177452b0074a2436669e98
    remote_window_accessible_ =
        ui::RemoteAccessibility::GetRemoteElementFromToken(window_token);
    remote_view_accessible_ =
-@@ -1125,14 +1134,17 @@ void HandleAccelerator(const ui::Accelerator& accelerator,
+@@ -1125,14 +1134,17 @@ void NativeWidgetMacNSWindowHost::SetRemoteAccessibilityTokens(
    [remote_view_accessible_ setWindowUIElement:remote_window_accessible_.get()];
    [remote_view_accessible_
        setTopLevelUIElement:remote_window_accessible_.get()];

+ 5 - 5
patches/chromium/mas_disable_remote_layer.patch

@@ -44,7 +44,7 @@ diff --git a/gpu/ipc/service/image_transport_surface_overlay_mac.mm b/gpu/ipc/se
 index eb46993b8f40fdc7da35dae1b850dad637f6b47d..05a9ae47620d17b5a53f991c0b3a0a5c153b599c 100644
 --- a/gpu/ipc/service/image_transport_surface_overlay_mac.mm
 +++ b/gpu/ipc/service/image_transport_surface_overlay_mac.mm
-@@ -63,6 +63,7 @@
+@@ -63,6 +63,7 @@ ImageTransportSurfaceOverlayMacBase<
  template <typename BaseClass>
  bool ImageTransportSurfaceOverlayMacBase<BaseClass>::Initialize(
      gl::GLSurfaceFormat format) {
@@ -52,7 +52,7 @@ index eb46993b8f40fdc7da35dae1b850dad637f6b47d..05a9ae47620d17b5a53f991c0b3a0a5c
    // Create the CAContext to send this to the GPU process, and the layer for
    // the context.
    if (use_remote_layer_api_) {
-@@ -71,6 +72,7 @@
+@@ -71,6 +72,7 @@ bool ImageTransportSurfaceOverlayMacBase<BaseClass>::Initialize(
          [CAContext contextWithCGSConnection:connection_id options:@{}] retain]);
      [ca_context_ setLayer:ca_layer_tree_coordinator_->GetCALayerForDisplay()];
    }
@@ -60,7 +60,7 @@ index eb46993b8f40fdc7da35dae1b850dad637f6b47d..05a9ae47620d17b5a53f991c0b3a0a5c
    return true;
  }
  
-@@ -139,7 +141,9 @@
+@@ -139,7 +141,9 @@ ImageTransportSurfaceOverlayMacBase<BaseClass>::SwapBuffersInternal(
                           "GLImpl", static_cast<int>(gl::GetGLImplementation()),
                           "width", pixel_size_.width());
      if (use_remote_layer_api_) {
@@ -74,7 +74,7 @@ diff --git a/ui/accelerated_widget_mac/display_ca_layer_tree.mm b/ui/accelerated
 index 38f25d6314f653d7138d30c67c5ae49963863327..f2fda251ed975bd848a49b33830d329fc8954826 100644
 --- a/ui/accelerated_widget_mac/display_ca_layer_tree.mm
 +++ b/ui/accelerated_widget_mac/display_ca_layer_tree.mm
-@@ -97,6 +97,7 @@ - (void)setContentsChanged;
+@@ -97,6 +97,7 @@ void DisplayCALayerTree::UpdateCALayerTree(
  }
  
  void DisplayCALayerTree::GotCALayerFrame(uint32_t ca_context_id) {
@@ -82,7 +82,7 @@ index 38f25d6314f653d7138d30c67c5ae49963863327..f2fda251ed975bd848a49b33830d329f
    // Early-out if the remote layer has not changed.
    if ([remote_layer_ contextId] == ca_context_id)
      return;
-@@ -121,6 +122,9 @@ - (void)setContentsChanged;
+@@ -121,6 +122,9 @@ void DisplayCALayerTree::GotCALayerFrame(uint32_t ca_context_id) {
      [io_surface_layer_ removeFromSuperlayer];
      io_surface_layer_.reset();
    }

+ 27 - 27
patches/chromium/mas_no_private_api.patch

@@ -53,7 +53,7 @@ diff --git a/content/browser/accessibility/browser_accessibility_cocoa.mm b/cont
 index bd9fa917f7b5cabb5d2b21dfb9c8b427440ff067..bd573f2d0e39218f802f35e0e3bd4e5d5f902d3f 100644
 --- a/content/browser/accessibility/browser_accessibility_cocoa.mm
 +++ b/content/browser/accessibility/browser_accessibility_cocoa.mm
-@@ -206,6 +206,7 @@
+@@ -206,6 +206,7 @@ NSString* const
  NSString* const NSAccessibilityLengthForTextMarkerRangeParameterizedAttribute =
      @"AXLengthForTextMarkerRange";
  
@@ -61,7 +61,7 @@ index bd9fa917f7b5cabb5d2b21dfb9c8b427440ff067..bd573f2d0e39218f802f35e0e3bd4e5d
  // Private attributes that can be used for testing text markers, e.g. in dump
  // tree tests.
  NSString* const
-@@ -217,6 +218,7 @@
+@@ -217,6 +218,7 @@ NSString* const
  NSString* const
      NSAccessibilityTextMarkerNodeDebugDescriptionParameterizedAttribute =
          @"AXTextMarkerNodeDebugDescription";
@@ -69,7 +69,7 @@ index bd9fa917f7b5cabb5d2b21dfb9c8b427440ff067..bd573f2d0e39218f802f35e0e3bd4e5d
  
  // Other private attributes.
  NSString* const NSAccessibilitySelectTextWithCriteriaParameterizedAttribute =
-@@ -240,6 +242,7 @@
+@@ -240,6 +242,7 @@ NSDictionary* attributeToMethodNameMap = nil;
  // VoiceOver uses -1 to mean "no limit" for AXResultsLimit.
  const int kAXResultsLimitNoLimit = -1;
  
@@ -77,7 +77,7 @@ index bd9fa917f7b5cabb5d2b21dfb9c8b427440ff067..bd573f2d0e39218f802f35e0e3bd4e5d
  extern "C" {
  
  // The following are private accessibility APIs required for cursor navigation
-@@ -479,6 +482,7 @@ void AddMisspelledTextAttributes(const AXPlatformRange& ax_range,
+@@ -479,6 +482,7 @@ NSAttributedString* GetAttributedTextForTextMarkerRange(id marker_range) {
    AddMisspelledTextAttributes(ax_range, attributed_text);
    return attributed_text;
  }
@@ -85,7 +85,7 @@ index bd9fa917f7b5cabb5d2b21dfb9c8b427440ff067..bd573f2d0e39218f802f35e0e3bd4e5d
  
  // Returns an autoreleased copy of the AXNodeData's attribute.
  NSString* NSStringForStringAttribute(BrowserAccessibility* browserAccessibility,
-@@ -772,7 +776,9 @@ + (void)initialize {
+@@ -772,7 +776,9 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
        {NSAccessibilityEditableAncestorAttribute, @"editableAncestor"},
        {NSAccessibilityElementBusyAttribute, @"elementBusy"},
        {NSAccessibilityEnabledAttribute, @"enabled"},
@@ -95,7 +95,7 @@ index bd9fa917f7b5cabb5d2b21dfb9c8b427440ff067..bd573f2d0e39218f802f35e0e3bd4e5d
        {NSAccessibilityExpandedAttribute, @"expanded"},
        {NSAccessibilityFocusableAncestorAttribute, @"focusableAncestor"},
        {NSAccessibilityFocusedAttribute, @"focused"},
-@@ -784,8 +790,10 @@ + (void)initialize {
+@@ -784,8 +790,10 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
        {NSAccessibilityHighestEditableAncestorAttribute,
         @"highestEditableAncestor"},
        {NSAccessibilityIndexAttribute, @"index"},
@@ -106,7 +106,7 @@ index bd9fa917f7b5cabb5d2b21dfb9c8b427440ff067..bd573f2d0e39218f802f35e0e3bd4e5d
        {NSAccessibilityInvalidAttribute, @"invalid"},
        {NSAccessibilityIsMultiSelectableAttribute, @"isMultiSelectable"},
        {NSAccessibilityLanguageAttribute, @"language"},
-@@ -807,13 +815,17 @@ + (void)initialize {
+@@ -807,13 +815,17 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
        {NSAccessibilityRowsAttribute, @"rows"},
        // TODO(aboxhall): expose
        // NSAccessibilityServesAsTitleForUIElementsAttribute
@@ -124,7 +124,7 @@ index bd9fa917f7b5cabb5d2b21dfb9c8b427440ff067..bd573f2d0e39218f802f35e0e3bd4e5d
        {NSAccessibilitySizeAttribute, @"size"},
        {NSAccessibilitySortDirectionAttribute, @"sortDirection"},
        {NSAccessibilitySubroleAttribute, @"subrole"},
-@@ -1308,6 +1320,7 @@ - (NSNumber*)enabled {
+@@ -1308,6 +1320,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
                                    ax::mojom::Restriction::kDisabled];
  }
  
@@ -132,7 +132,7 @@ index bd9fa917f7b5cabb5d2b21dfb9c8b427440ff067..bd573f2d0e39218f802f35e0e3bd4e5d
  // Returns a text marker that points to the last character in the document that
  // can be selected with VoiceOver.
  - (id)endTextMarker {
-@@ -1318,6 +1331,7 @@ - (id)endTextMarker {
+@@ -1318,6 +1331,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
    BrowserAccessibilityPositionInstance position = root->CreatePositionAt(0);
    return CreateTextMarker(position->CreatePositionAtEndOfAnchor());
  }
@@ -140,7 +140,7 @@ index bd9fa917f7b5cabb5d2b21dfb9c8b427440ff067..bd573f2d0e39218f802f35e0e3bd4e5d
  
  - (NSNumber*)expanded {
    if (![self instanceActive])
-@@ -1467,6 +1481,8 @@ - (NSNumber*)index {
+@@ -1467,6 +1481,8 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
    return nil;
  }
  
@@ -149,7 +149,7 @@ index bd9fa917f7b5cabb5d2b21dfb9c8b427440ff067..bd573f2d0e39218f802f35e0e3bd4e5d
  - (NSNumber*)insertionPointLineNumber {
    if (![self instanceActive])
      return nil;
-@@ -1489,6 +1505,7 @@ - (NSNumber*)insertionPointLineNumber {
+@@ -1489,6 +1505,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
                         caretPosition->AsTextPosition()->text_offset());
    return @(std::distance(lineBreaks.begin(), iterator));
  }
@@ -157,7 +157,7 @@ index bd9fa917f7b5cabb5d2b21dfb9c8b427440ff067..bd573f2d0e39218f802f35e0e3bd4e5d
  
  // Returns whether or not this node should be ignored in the
  // accessibility tree.
-@@ -2166,6 +2183,7 @@ - (NSArray*)selectedChildren {
+@@ -2166,6 +2183,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
    return ret;
  }
  
@@ -165,7 +165,7 @@ index bd9fa917f7b5cabb5d2b21dfb9c8b427440ff067..bd573f2d0e39218f802f35e0e3bd4e5d
  - (NSString*)selectedText {
    if (![self instanceActive])
      return nil;
-@@ -2177,11 +2195,13 @@ - (NSString*)selectedText {
+@@ -2177,11 +2195,13 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
      return nil;
    return base::SysUTF16ToNSString(range.GetText());
  }
@@ -179,7 +179,7 @@ index bd9fa917f7b5cabb5d2b21dfb9c8b427440ff067..bd573f2d0e39218f802f35e0e3bd4e5d
  - (NSValue*)selectedTextRange {
    if (![self instanceActive])
      return nil;
-@@ -2202,12 +2222,15 @@ - (NSValue*)selectedTextRange {
+@@ -2202,12 +2222,15 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
    int selLength = range.GetText().length();
    return [NSValue valueWithRange:NSMakeRange(selStart, selLength)];
  }
@@ -195,7 +195,7 @@ index bd9fa917f7b5cabb5d2b21dfb9c8b427440ff067..bd573f2d0e39218f802f35e0e3bd4e5d
  
  - (NSValue*)size {
    if (![self instanceActive])
-@@ -2240,6 +2263,7 @@ - (NSString*)sortDirection {
+@@ -2240,6 +2263,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
    return nil;
  }
  
@@ -203,7 +203,7 @@ index bd9fa917f7b5cabb5d2b21dfb9c8b427440ff067..bd573f2d0e39218f802f35e0e3bd4e5d
  // Returns a text marker that points to the first character in the document that
  // can be selected with VoiceOver.
  - (id)startTextMarker {
-@@ -2250,6 +2274,7 @@ - (id)startTextMarker {
+@@ -2250,6 +2274,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
    BrowserAccessibilityPositionInstance position = root->CreatePositionAt(0);
    return CreateTextMarker(position->CreatePositionAtStartOfAnchor());
  }
@@ -211,7 +211,7 @@ index bd9fa917f7b5cabb5d2b21dfb9c8b427440ff067..bd573f2d0e39218f802f35e0e3bd4e5d
  
  // Returns a subrole based upon the role.
  - (NSString*)subrole {
-@@ -2570,11 +2595,13 @@ - (NSAttributedString*)attributedValueForRange:(NSRange)range {
+@@ -2570,11 +2595,13 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
    NSMutableAttributedString* attributedValue =
        [[[NSMutableAttributedString alloc] initWithString:value] autorelease];
  
@@ -225,7 +225,7 @@ index bd9fa917f7b5cabb5d2b21dfb9c8b427440ff067..bd573f2d0e39218f802f35e0e3bd4e5d
  
    return [attributedValue attributedSubstringFromRange:range];
  }
-@@ -2677,9 +2704,8 @@ - (id)accessibilityAttributeValue:(NSString*)attribute
+@@ -2677,9 +2704,8 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
        return ToBrowserAccessibilityCocoa(cell);
    }
  
@@ -237,7 +237,7 @@ index bd9fa917f7b5cabb5d2b21dfb9c8b427440ff067..bd573f2d0e39218f802f35e0e3bd4e5d
      BrowserAccessibilityPositionInstance position =
          CreatePositionFromTextMarker(parameter);
      if (!position->IsNullPosition())
-@@ -2990,6 +3016,7 @@ AXPlatformRange range(std::move(lineStartPosition),
+@@ -2990,6 +3016,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
  
      return CreateTextMarker(root->CreatePositionAt(index));
    }
@@ -245,7 +245,7 @@ index bd9fa917f7b5cabb5d2b21dfb9c8b427440ff067..bd573f2d0e39218f802f35e0e3bd4e5d
  
    if ([attribute isEqualToString:
                       NSAccessibilityBoundsForRangeParameterizedAttribute]) {
-@@ -3025,6 +3052,7 @@ AXPlatformRange range(std::move(lineStartPosition),
+@@ -3025,6 +3052,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
      return nil;
    }
  
@@ -253,7 +253,7 @@ index bd9fa917f7b5cabb5d2b21dfb9c8b427440ff067..bd573f2d0e39218f802f35e0e3bd4e5d
    if ([attribute
            isEqualToString:
                NSAccessibilityLineTextMarkerRangeForTextMarkerParameterizedAttribute]) {
-@@ -3139,6 +3167,7 @@ AXPlatformRange range(std::move(lineStartPosition),
+@@ -3139,6 +3167,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
  
      return @(child->GetIndexInParent());
    }
@@ -265,7 +265,7 @@ diff --git a/content/browser/accessibility/browser_accessibility_manager_mac.mm
 index 8e8b6b785ed6e2831f107e925c387f723f55a8fc..33324bbca5953f6f2f9d829e4c7b5d7daa3f49ea 100644
 --- a/content/browser/accessibility/browser_accessibility_manager_mac.mm
 +++ b/content/browser/accessibility/browser_accessibility_manager_mac.mm
-@@ -534,6 +534,7 @@ void PostAnnouncementNotification(NSString* announcement) {
+@@ -534,6 +534,7 @@ NSDictionary* BrowserAccessibilityManagerMac::
        [user_info setObject:native_focus_object
                      forKey:NSAccessibilityTextChangeElement];
  
@@ -273,7 +273,7 @@ index 8e8b6b785ed6e2831f107e925c387f723f55a8fc..33324bbca5953f6f2f9d829e4c7b5d7d
        id selected_text = [native_focus_object selectedTextMarkerRange];
        if (selected_text) {
          NSString* const NSAccessibilitySelectedTextMarkerRangeAttribute =
-@@ -541,6 +542,7 @@ void PostAnnouncementNotification(NSString* announcement) {
+@@ -541,6 +542,7 @@ NSDictionary* BrowserAccessibilityManagerMac::
          [user_info setObject:selected_text
                        forKey:NSAccessibilitySelectedTextMarkerRangeAttribute];
        }
@@ -297,7 +297,7 @@ index e59ac93d0e1554a2df5d8c74db2beba25d090228..6657c48664bdec4964b382f80309d1bf
  
  namespace content {
  
-@@ -22,6 +24,7 @@
+@@ -22,6 +24,7 @@ namespace {
  // verifies there are no existing open connections), and then indicates that
  // Chrome should continue execution without access to launchservicesd.
  void DisableSystemServices() {
@@ -325,7 +325,7 @@ index 7c018cce2c2d9981c94e91e5d97cff0d37548b13..cfb0fb20c81f908caac9933b820e40e0
  extern "C" {
  // Undocumented IOBluetooth Preference API [1]. Used by `blueutil` [2] and
  // `Karabiner` [3] to programmatically control the Bluetooth state. Calling the
-@@ -48,6 +49,7 @@
+@@ -48,6 +49,7 @@ extern "C" {
  // [4] https://support.apple.com/kb/PH25091
  void IOBluetoothPreferenceSetControllerPowerState(int state);
  }
@@ -333,7 +333,7 @@ index 7c018cce2c2d9981c94e91e5d97cff0d37548b13..cfb0fb20c81f908caac9933b820e40e0
  
  namespace {
  
-@@ -120,8 +122,10 @@ CBCentralManagerState GetCBManagerState(CBCentralManager* manager) {
+@@ -120,8 +122,10 @@ BluetoothAdapterMac::BluetoothAdapterMac()
        controller_state_function_(
            base::BindRepeating(&BluetoothAdapterMac::GetHostControllerState,
                                base::Unretained(this))),
@@ -344,7 +344,7 @@ index 7c018cce2c2d9981c94e91e5d97cff0d37548b13..cfb0fb20c81f908caac9933b820e40e0
        should_update_name_(true),
        classic_discovery_manager_(
            BluetoothDiscoveryManagerMac::CreateClassic(this)),
-@@ -306,8 +310,12 @@ CBCentralManagerState GetCBManagerState(CBCentralManager* manager) {
+@@ -306,8 +310,12 @@ base::WeakPtr<BluetoothAdapter> BluetoothAdapterMac::GetWeakPtr() {
  }
  
  bool BluetoothAdapterMac::SetPoweredImpl(bool powered) {

+ 4 - 4
patches/chromium/render_widget_host_view_mac.patch

@@ -25,7 +25,7 @@ index c242af13bdf58b1c830781badaf27aadc3c0179b..2ba56a1951c7a1a76c5a6ecef1d04235
  // These are not documented, so use only after checking -respondsToSelector:.
  @interface NSApplication (UndocumentedSpeechMethods)
  - (void)speakString:(NSString*)string;
-@@ -573,6 +578,9 @@ - (BOOL)acceptsMouseEventsWhenInactive {
+@@ -573,6 +578,9 @@ void ExtractUnderlines(NSAttributedString* string,
  }
  
  - (BOOL)acceptsFirstMouse:(NSEvent*)theEvent {
@@ -35,7 +35,7 @@ index c242af13bdf58b1c830781badaf27aadc3c0179b..2ba56a1951c7a1a76c5a6ecef1d04235
    return [self acceptsMouseEventsWhenInactive];
  }
  
-@@ -983,6 +991,10 @@ - (void)keyEvent:(NSEvent*)theEvent wasKeyEquivalent:(BOOL)equiv {
+@@ -983,6 +991,10 @@ void ExtractUnderlines(NSAttributedString* string,
                                eventType == NSKeyDown &&
                                !(modifierFlags & NSCommandKeyMask);
  
@@ -46,7 +46,7 @@ index c242af13bdf58b1c830781badaf27aadc3c0179b..2ba56a1951c7a1a76c5a6ecef1d04235
    // We only handle key down events and just simply forward other events.
    if (eventType != NSKeyDown) {
      _hostHelper->ForwardKeyboardEvent(event, latency_info);
-@@ -1759,9 +1771,11 @@ - (NSAccessibilityRole)accessibilityRole {
+@@ -1759,9 +1771,11 @@ void ExtractUnderlines(NSAttributedString* string,
  // Since this implementation doesn't have to wait any IPC calls, this doesn't
  // make any key-typing jank. --hbono 7/23/09
  //
@@ -58,7 +58,7 @@ index c242af13bdf58b1c830781badaf27aadc3c0179b..2ba56a1951c7a1a76c5a6ecef1d04235
  
  - (NSArray*)validAttributesForMarkedText {
    // This code is just copied from WebKit except renaming variables.
-@@ -1770,7 +1784,10 @@ - (NSArray*)validAttributesForMarkedText {
+@@ -1770,7 +1784,10 @@ extern NSString* NSTextInputReplacementRangeAttributeName;
          initWithObjects:NSUnderlineStyleAttributeName,
                          NSUnderlineColorAttributeName,
                          NSMarkedClauseSegmentAttributeName,

+ 1 - 1
patches/chromium/webview_cross_drag.patch

@@ -26,7 +26,7 @@ diff --git a/content/browser/web_contents/web_drag_dest_mac.mm b/content/browser
 index b874b3c4b16ca87c9730c6caaf5788cff0ab3493..2c82d63d646c9201abd6a669b726dae0f8bec12b 100644
 --- a/content/browser/web_contents/web_drag_dest_mac.mm
 +++ b/content/browser/web_contents/web_drag_dest_mac.mm
-@@ -419,9 +419,7 @@ - (void)setDragStartTrackersForProcess:(int)processID {
+@@ -419,9 +419,7 @@ void DropCompletionCallback(
  }
  
  - (bool)isValidDragTarget:(content::RenderWidgetHostImpl*)targetRWH {

+ 3 - 3
patches/v8/add_realloc.patch

@@ -12,10 +12,10 @@ when we override ReallocateBufferMemory, so we therefore need to implement
 Realloc on the v8 side.
 
 diff --git a/include/v8.h b/include/v8.h
-index 96d6cb815c5a733a1f04117781fe88909c4e67bc..b97acc4cd3d3125512b927b201ed83334f556baf 100644
+index 77ac5098624a9536d1036d93232a6f3565c8c6ca..21b3d0b890bb234570e1ec241be83ac50e9066c8 100644
 --- a/include/v8.h
 +++ b/include/v8.h
-@@ -5003,6 +5003,13 @@ class V8_EXPORT ArrayBuffer : public Object {
+@@ -5041,6 +5041,13 @@ class V8_EXPORT ArrayBuffer : public Object {
       */
      virtual void* AllocateUninitialized(size_t length) = 0;
  
@@ -30,7 +30,7 @@ index 96d6cb815c5a733a1f04117781fe88909c4e67bc..b97acc4cd3d3125512b927b201ed8333
       * Free the memory block of size |length|, pointed to by |data|.
       * That memory is guaranteed to be previously allocated by |Allocate|.
 diff --git a/src/api/api.cc b/src/api/api.cc
-index 0294e383fe47f4b16e70d84f8afa2f351fb650ab..1a2cd2c1566fab5ec67a23956bcf998e4252f84f 100644
+index b2d6db3661a564d20f6d07a67bff627ba2ee75da..feda31f69bf53b392506bd87ac5d966b1e6b9329 100644
 --- a/src/api/api.cc
 +++ b/src/api/api.cc
 @@ -528,6 +528,10 @@ void V8::SetSnapshotDataBlob(StartupData* snapshot_blob) {

+ 3 - 3
patches/v8/build_gn.patch

@@ -9,7 +9,7 @@ necessary for native modules to load.
 Also, some fixes relating to mksnapshot on ARM.
 
 diff --git a/BUILD.gn b/BUILD.gn
-index 6c1088d932f3bc6eedec49a329120275a4fd8a2d..a04cd604ab7b7c300f7d7b4a7034d03397f3728f 100644
+index 1ed2de137f7cec05fe583372d6bc096a4cec8ab0..f005e7f0d819f9aa5c434829e6d16e6bd7c4797e 100644
 --- a/BUILD.gn
 +++ b/BUILD.gn
 @@ -311,7 +311,7 @@ config("internal_config") {
@@ -21,7 +21,7 @@ index 6c1088d932f3bc6eedec49a329120275a4fd8a2d..a04cd604ab7b7c300f7d7b4a7034d033
      defines += [ "BUILDING_V8_SHARED" ]
    }
  }
-@@ -3971,7 +3971,7 @@ if (current_toolchain == v8_generator_toolchain) {
+@@ -4004,7 +4004,7 @@ if (current_toolchain == v8_generator_toolchain) {
        "src/interpreter/bytecodes.h",
      ]
  
@@ -30,7 +30,7 @@ index 6c1088d932f3bc6eedec49a329120275a4fd8a2d..a04cd604ab7b7c300f7d7b4a7034d033
  
      deps = [
        ":v8_libbase",
-@@ -4004,6 +4004,8 @@ if (current_toolchain == v8_snapshot_toolchain) {
+@@ -4037,6 +4037,8 @@ if (current_toolchain == v8_snapshot_toolchain) {
  
      configs = [ ":internal_config" ]
  

+ 3 - 3
patches/v8/dcheck.patch

@@ -6,10 +6,10 @@ Subject: dcheck.patch
 https://github.com/auchenberg/volkswagen
 
 diff --git a/src/api/api.cc b/src/api/api.cc
-index 1a2cd2c1566fab5ec67a23956bcf998e4252f84f..2de35499e25a930169af6b82e82e3c38b65da0b7 100644
+index feda31f69bf53b392506bd87ac5d966b1e6b9329..edfb00f65d21190a65d8245f6d20dabb0b46a2cd 100644
 --- a/src/api/api.cc
 +++ b/src/api/api.cc
-@@ -8689,7 +8689,7 @@ void Isolate::SetPromiseRejectCallback(PromiseRejectCallback callback) {
+@@ -8727,7 +8727,7 @@ void Isolate::SetPromiseRejectCallback(PromiseRejectCallback callback) {
  }
  
  void Isolate::PerformMicrotaskCheckpoint() {
@@ -19,7 +19,7 @@ index 1a2cd2c1566fab5ec67a23956bcf998e4252f84f..2de35499e25a930169af6b82e82e3c38
    isolate->default_microtask_queue()->PerformCheckpoint(this);
  }
 diff --git a/src/heap/heap.cc b/src/heap/heap.cc
-index 687122d04f0569f6b8e1bc2f177b2d9f7dc775f5..5034492ec5f88fcc5c1b6c4b3d2dea3c52258a3e 100644
+index cf7abaa7a0defa244bd6b147b77ab9d01ff277f7..dc7b206cce6a7fb7df659710094c8beff3b83044 100644
 --- a/src/heap/heap.cc
 +++ b/src/heap/heap.cc
 @@ -5474,9 +5474,9 @@ void Heap::TearDown() {

+ 1 - 1
patches/v8/do_not_export_private_v8_symbols_on_windows.patch

@@ -12,7 +12,7 @@ This patch can be safely removed if, when it is removed, `node.lib` does not
 contain any standard C++ library exports (e.g. `std::ostringstream`).
 
 diff --git a/BUILD.gn b/BUILD.gn
-index 45c7580386a2a5cb3eadf79da493f7077e52adc4..e2365d005b2c1b1a606a9621873fecca301ecb19 100644
+index cede99e30985e29beaa6dd51c3a8230dc02c3ef8..436810b87f77764384d045ee5a8433881ce57ff6 100644
 --- a/BUILD.gn
 +++ b/BUILD.gn
 @@ -311,6 +311,10 @@ config("internal_config") {

+ 2 - 2
patches/v8/expose_mksnapshot.patch

@@ -6,10 +6,10 @@ Subject: expose_mksnapshot.patch
 Needed in order to target mksnapshot for mksnapshot zip.
 
 diff --git a/BUILD.gn b/BUILD.gn
-index a04cd604ab7b7c300f7d7b4a7034d03397f3728f..45c7580386a2a5cb3eadf79da493f7077e52adc4 100644
+index f005e7f0d819f9aa5c434829e6d16e6bd7c4797e..cede99e30985e29beaa6dd51c3a8230dc02c3ef8 100644
 --- a/BUILD.gn
 +++ b/BUILD.gn
-@@ -3982,7 +3982,6 @@ if (current_toolchain == v8_generator_toolchain) {
+@@ -4015,7 +4015,6 @@ if (current_toolchain == v8_generator_toolchain) {
  
  if (current_toolchain == v8_snapshot_toolchain) {
    v8_executable("mksnapshot") {

+ 2 - 2
patches/v8/revert_cleanup_switch_offset_of_to_offsetof_where_possible.patch

@@ -6,7 +6,7 @@ Subject: Revert "[cleanup] Switch {OFFSET_OF} to {offsetof} where possible."
 This reverts commit d287e4bc46243841c77cf9798516ee4dcc54bf43.
 
 diff --git a/src/deoptimizer/deoptimizer.h b/src/deoptimizer/deoptimizer.h
-index 58c65562d98628718066683194f829156534e1df..41034325724470b38797e32f27c5908a79dee128 100644
+index 41ef7d2336e0b49fd4cc02d56556ebca2c605a49..2766ed7c6381a279d6161c058ea33fffe9860426 100644
 --- a/src/deoptimizer/deoptimizer.h
 +++ b/src/deoptimizer/deoptimizer.h
 @@ -488,14 +488,14 @@ class Deoptimizer : public Malloced {
@@ -28,7 +28,7 @@ index 58c65562d98628718066683194f829156534e1df..41034325724470b38797e32f27c5908a
    }
  
    V8_EXPORT_PRIVATE static int GetDeoptimizedCodeCount(Isolate* isolate);
-@@ -731,11 +731,11 @@ class FrameDescription {
+@@ -732,11 +732,11 @@ class FrameDescription {
    int parameter_count() { return parameter_count_; }
  
    static int registers_offset() {

+ 31 - 0
script/export_all_patches.py

@@ -0,0 +1,31 @@
+#!/usr/bin/env python
+
+import argparse
+import json
+import os
+import sys
+
+from lib import git
+
+
+def export_patches(dirs):
+  for patch_dir, repo in dirs.iteritems():
+    git.export_patches(repo=repo, out_dir=patch_dir)
+
+
+def parse_args():
+  parser = argparse.ArgumentParser(description='Export Electron patches')
+  parser.add_argument('config', nargs='+',
+                      type=argparse.FileType('r'),
+                      help='patches\' config(s) in the JSON format')
+  return parser.parse_args()
+
+
+def main():
+  configs = parse_args().config
+  for config_json in configs:
+    export_patches(json.load(config_json))
+
+
+if __name__ == '__main__':
+  main()

+ 2 - 135
script/git-export-patches

@@ -6,115 +6,7 @@ import re
 import subprocess
 import sys
 
-
-def guess_base_commit(repo):
-  """Guess which commit the patches might be based on"""
-  try:
-    args = [
-      'git',
-      '-C',
-      repo,
-      'rev-parse',
-      '--verify',
-      'refs/patches/upstream-head',
-    ]
-    upstream_head = subprocess.check_output(args).strip()
-    args = [
-      'git',
-      '-C',
-      repo,
-      'rev-list',
-      '--count',
-      upstream_head + '..',
-    ]
-    num_commits = subprocess.check_output(args).strip()
-    return [upstream_head, num_commits]
-  except subprocess.CalledProcessError:
-    args = [
-      'git',
-      '-C',
-      repo,
-      'describe',
-      '--tags',
-    ]
-    return subprocess.check_output(args).rsplit('-', 2)[0:2]
-
-
-def format_patch(repo, since):
-  args = [
-    'git',
-    '-C',
-    repo,
-    '-c',
-    'core.attributesfile=' + os.path.join(os.path.dirname(os.path.realpath(__file__)), '.electron.attributes'),
-    # Ensure it is not possible to match anything
-    # Disabled for now as we have consistent chunk headers
-    # '-c',
-    # 'diff.electron.xfuncname=$^',
-    'format-patch',
-    '--keep-subject',
-    '--no-stat',
-    '--stdout',
-
-    # Per RFC 3676 the signature is separated from the body by a line with
-    # '-- ' on it. If the signature option is omitted the signature defaults
-    # to the Git version number.
-    '--no-signature',
-
-    # The name of the parent commit object isn't useful information in this
-    # context, so zero it out to avoid needless patch-file churn.
-    '--zero-commit',
-
-    # Some versions of git print out different numbers of characters in the
-    # 'index' line of patches, so pass --full-index to get consistent
-    # behaviour.
-    '--full-index',
-    since
-  ]
-  return subprocess.check_output(args)
-
-
-def split_patches(patch_data):
-  """Split a concatenated series of patches into N separate patches"""
-  patches = []
-  patch_start = re.compile('^From [0-9a-f]+ ')
-  for line in patch_data.splitlines():
-    if patch_start.match(line):
-      patches.append([])
-    patches[-1].append(line)
-  return patches
-
-
-def munge_subject_to_filename(subject):
-  """Derive a suitable filename from a commit's subject"""
-  if subject.endswith('.patch'):
-    subject = subject[:-6]
-  return re.sub(r'[^A-Za-z0-9-]+', '_', subject).strip('_').lower() + '.patch'
-
-
-def get_file_name(patch):
-  """Return the name of the file to which the patch should be written"""
-  for line in patch:
-    if line.startswith('Patch-Filename: '):
-      return line[len('Patch-Filename: '):]
-  # If no patch-filename header, munge the subject.
-  for line in patch:
-    if line.startswith('Subject: '):
-      return munge_subject_to_filename(line[len('Subject: '):])
-
-
-def remove_patch_filename(patch):
-  """Strip out the Patch-Filename trailer from a patch's message body"""
-  force_keep_next_line = False
-  for i, l in enumerate(patch):
-    is_patchfilename = l.startswith('Patch-Filename: ')
-    next_is_patchfilename = i < len(patch) - 1 and patch[i+1].startswith('Patch-Filename: ')
-    if not force_keep_next_line and (is_patchfilename or (next_is_patchfilename and len(l.rstrip()) == 0)):
-      pass # drop this line
-    else:
-      yield l
-    force_keep_next_line = l.startswith('Subject: ')
-
+from lib import git
 
 def main(argv):
   parser = argparse.ArgumentParser()
@@ -127,32 +19,7 @@ def main(argv):
            "most recent tag or remote branch.")
   args = parser.parse_args(argv)
 
-  repo = '.'
-  patch_range = args.patch_range
-  if patch_range is None:
-    patch_range, num_patches = guess_base_commit(repo)
-    sys.stderr.write("Exporting {} patches since {}\n".format(num_patches, patch_range))
-  patch_data = format_patch(repo, patch_range)
-  patches = split_patches(patch_data)
-
-  out_dir = args.output
-  try:
-    os.mkdir(out_dir)
-  except OSError:
-    pass
-
-  # remove old patches, so that deleted commits are correctly reflected in the
-  # patch files (as a removed file)
-  for p in os.listdir(out_dir):
-    if p.endswith('.patch'):
-      os.remove(os.path.join(out_dir, p))
-
-  with open(os.path.join(out_dir, '.patches'), 'w') as pl:
-    for patch in patches:
-      filename = get_file_name(patch)
-      with open(os.path.join(out_dir, filename), 'w') as f:
-        f.write('\n'.join(remove_patch_filename(patch)).rstrip('\n') + '\n')
-      pl.write(filename + '\n')
+  git.export_patches('.', args.output, patch_range=args.patch_range)
 
 
 if __name__ == '__main__':

+ 143 - 1
script/lib/git.py

@@ -7,7 +7,9 @@ structure, or make assumptions about the passed arguments or calls' outcomes.
 """
 
 import os
+import re
 import subprocess
+import sys
 
 
 def is_repo_root(path):
@@ -126,7 +128,7 @@ def reset(repo):
 
 
 def commit(repo, author, message):
-  """ Commit whatever in the index is now."""
+  """Commit whatever in the index is now."""
 
   # Let's setup committer info so git won't complain about it being missing.
   # TODO: Is there a better way to set committer's name and email?
@@ -142,3 +144,143 @@ def commit(repo, author, message):
   return_code = subprocess.call(args, env=env)
   committed_successfully = (return_code == 0)
   return committed_successfully
+
+def get_upstream_head(repo):
+  args = [
+    'git',
+    '-C',
+    repo,
+    'rev-parse',
+    '--verify',
+    'refs/patches/upstream-head',
+  ]
+  return subprocess.check_output(args).strip()
+
+def get_commit_count(repo, commit_range):
+  args = [
+    'git',
+    '-C',
+    repo,
+    'rev-list',
+    '--count',
+    commit_range
+  ]
+  return int(subprocess.check_output(args).strip())
+
+def guess_base_commit(repo):
+  """Guess which commit the patches might be based on"""
+  try:
+    upstream_head = get_upstream_head(repo)
+    num_commits = get_commit_count(repo, upstream_head + '..')
+    return [upstream_head, num_commits]
+  except subprocess.CalledProcessError:
+    args = [
+      'git',
+      '-C',
+      repo,
+      'describe',
+      '--tags',
+    ]
+    return subprocess.check_output(args).rsplit('-', 2)[0:2]
+
+
+def format_patch(repo, since):
+  args = [
+    'git',
+    '-C',
+    repo,
+    '-c',
+    'core.attributesfile=' + os.path.join(os.path.dirname(os.path.realpath(__file__)), '.electron.attributes'),
+    # Ensure it is not possible to match anything
+    # Disabled for now as we have consistent chunk headers
+    # '-c',
+    # 'diff.electron.xfuncname=$^',
+    'format-patch',
+    '--keep-subject',
+    '--no-stat',
+    '--stdout',
+
+    # Per RFC 3676 the signature is separated from the body by a line with
+    # '-- ' on it. If the signature option is omitted the signature defaults
+    # to the Git version number.
+    '--no-signature',
+
+    # The name of the parent commit object isn't useful information in this
+    # context, so zero it out to avoid needless patch-file churn.
+    '--zero-commit',
+
+    # Some versions of git print out different numbers of characters in the
+    # 'index' line of patches, so pass --full-index to get consistent
+    # behaviour.
+    '--full-index',
+    since
+  ]
+  return subprocess.check_output(args)
+
+
+def split_patches(patch_data):
+  """Split a concatenated series of patches into N separate patches"""
+  patches = []
+  patch_start = re.compile('^From [0-9a-f]+ ')
+  for line in patch_data.splitlines():
+    if patch_start.match(line):
+      patches.append([])
+    patches[-1].append(line)
+  return patches
+
+
+def munge_subject_to_filename(subject):
+  """Derive a suitable filename from a commit's subject"""
+  if subject.endswith('.patch'):
+    subject = subject[:-6]
+  return re.sub(r'[^A-Za-z0-9-]+', '_', subject).strip('_').lower() + '.patch'
+
+
+def get_file_name(patch):
+  """Return the name of the file to which the patch should be written"""
+  for line in patch:
+    if line.startswith('Patch-Filename: '):
+      return line[len('Patch-Filename: '):]
+  # If no patch-filename header, munge the subject.
+  for line in patch:
+    if line.startswith('Subject: '):
+      return munge_subject_to_filename(line[len('Subject: '):])
+
+
+def remove_patch_filename(patch):
+  """Strip out the Patch-Filename trailer from a patch's message body"""
+  force_keep_next_line = False
+  for i, l in enumerate(patch):
+    is_patchfilename = l.startswith('Patch-Filename: ')
+    next_is_patchfilename = i < len(patch) - 1 and patch[i+1].startswith('Patch-Filename: ')
+    if not force_keep_next_line and (is_patchfilename or (next_is_patchfilename and len(l.rstrip()) == 0)):
+      pass # drop this line
+    else:
+      yield l
+    force_keep_next_line = l.startswith('Subject: ')
+
+
+def export_patches(repo, out_dir, patch_range=None):
+  if patch_range is None:
+    patch_range, num_patches = guess_base_commit(repo)
+    sys.stderr.write("Exporting {} patches since {}\n".format(num_patches, patch_range))
+  patch_data = format_patch(repo, patch_range)
+  patches = split_patches(patch_data)
+
+  try:
+    os.mkdir(out_dir)
+  except OSError:
+    pass
+
+  # remove old patches, so that deleted commits are correctly reflected in the
+  # patch files (as a removed file)
+  for p in os.listdir(out_dir):
+    if p.endswith('.patch'):
+      os.remove(os.path.join(out_dir, p))
+
+  with open(os.path.join(out_dir, '.patches'), 'w') as pl:
+    for patch in patches:
+      filename = get_file_name(patch)
+      with open(os.path.join(out_dir, filename), 'w') as f:
+        f.write('\n'.join(remove_patch_filename(patch)).rstrip('\n') + '\n')
+      pl.write(filename + '\n')