Serialize DOMException

Make DOMException serializable.
We don't support the stack property due to some technical difficulties.

Spec: https://github.com/heycam/webidl/pull/732
Intent-to-Ship: https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/f8JngIi8qYs

Bug: 970079
Change-Id: I909bb5f32a79baac19108bc18eaf91eb597a8c85
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1697462
Commit-Queue: Yutaka Hirano <yhirano@chromium.org>
Reviewed-by: Jeremy Roman <jbroman@chromium.org>
Reviewed-by: Yuki Shiino <yukishiino@chromium.org>
Cr-Commit-Position: refs/heads/master@{#678689}
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/serialization_tag.h b/third_party/blink/renderer/bindings/core/v8/serialization/serialization_tag.h
index 34015ea8..05430a2 100644
--- a/third_party/blink/renderer/bindings/core/v8/serialization/serialization_tag.h
+++ b/third_party/blink/renderer/bindings/core/v8/serialization/serialization_tag.h
@@ -105,6 +105,7 @@
             // corner_points:Point2D[length] -> DetectedText (ref)
   kDetectedTextTag = 't',  // bounding_box:DOMRectReadOnly,
                            // landmarks:Landmark[length] -> DetectedFace (ref)
+  kDOMExceptionTag = 'x',  // name:String,message:String,stack:String
   kVersionTag = 0xFF       // version:uint32_t -> Uses this as the file version.
 };
 
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.cc b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.cc
index c866cf0..0b0da0ca 100644
--- a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.cc
+++ b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.cc
@@ -8,6 +8,7 @@
 #include "third_party/blink/public/platform/web_blob_info.h"
 #include "third_party/blink/renderer/bindings/core/v8/serialization/unpacked_serialized_script_value.h"
 #include "third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h"
+#include "third_party/blink/renderer/core/dom/dom_exception.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
 #include "third_party/blink/renderer/core/fileapi/blob.h"
 #include "third_party/blink/renderer/core/fileapi/file.h"
@@ -559,6 +560,15 @@
 
       return MakeGarbageCollected<TransformStream>(readable, writable);
     }
+    case kDOMExceptionTag: {
+      // See the serialization side for |stack_unused|.
+      String name, message, stack_unused;
+      if (!ReadUTF8String(&name) || !ReadUTF8String(&message) ||
+          !ReadUTF8String(&stack_unused)) {
+        return nullptr;
+      }
+      return DOMException::Create(name, message);
+    }
     default:
       break;
   }
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer.cc b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer.cc
index 04fc3a09..e93bcaa 100644
--- a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer.cc
+++ b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer.cc
@@ -8,6 +8,7 @@
 #include "third_party/blink/public/platform/web_blob_info.h"
 #include "third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_blob.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_dom_exception.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_dom_matrix.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_dom_matrix_read_only.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_dom_point.h"
@@ -565,6 +566,17 @@
                                       transferables_->writable_streams.size()));
     return true;
   }
+  if (wrapper_type_info == V8DOMException::GetWrapperTypeInfo()) {
+    DOMException* exception = wrappable->ToImpl<DOMException>();
+    WriteTag(kDOMExceptionTag);
+    WriteUTF8String(exception->name());
+    WriteUTF8String(exception->message());
+    // We may serialize the stack property in the future, so we store a null
+    // string in order to avoid future scheme changes.
+    String stack_unused;
+    WriteUTF8String(stack_unused);
+    return true;
+  }
   return false;
 }
 
diff --git a/third_party/blink/renderer/core/dom/dom_exception.idl b/third_party/blink/renderer/core/dom/dom_exception.idl
index bbf3701..2e3e9ad 100644
--- a/third_party/blink/renderer/core/dom/dom_exception.idl
+++ b/third_party/blink/renderer/core/dom/dom_exception.idl
@@ -31,8 +31,9 @@
 // https://heycam.github.io/webidl/#es-DOMException
 
 [
-    Constructor(optional DOMString message = "", optional DOMString name = "Error"),
     Exposed=(Window,Worker),
+    Constructor(optional DOMString message = "", optional DOMString name = "Error"),
+    Serializable,
     DoNotCheckConstants
 ] interface DOMException {
 
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window-expected.txt b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window-expected.txt
index b61da1ae..d86c1db 100644
--- a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window-expected.txt
@@ -7,7 +7,7 @@
 PASS JS-engine-created TypeError (cross-site iframe)
 PASS web API-created TypeError (worker)
 PASS web API-created TypeError (cross-site iframe)
-FAIL web API-created DOMException (worker) Failed to execute 'postMessage' on 'Worker': DOMException object could not be cloned.
-FAIL web API-created DOMException (cross-site iframe) Failed to execute 'postMessage' on 'Window': DOMException object could not be cloned.
+FAIL web API-created DOMException (worker) assert_equals: expected (string) "Error: Failed to execute 'createElement' on 'Document': The tag name provided ('') is not a valid name.\n    at http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:33:14\n    at Test.<anonymous> (http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:41:19)\n    at Test.step (http://web-platform.test:8001/resources/testharness.js:1611:25)\n    at async_test (http://web-platform.test:8001/resources/testharness.js:576:22)\n    at stackTests (http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:40:3)\n    at http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:31:1" but got (undefined) undefined
+FAIL web API-created DOMException (cross-site iframe) assert_equals: expected (string) "Error: Failed to execute 'createElement' on 'Document': The tag name provided ('') is not a valid name.\n    at http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:33:14\n    at Test.<anonymous> (http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:60:19)\n    at Test.step (http://web-platform.test:8001/resources/testharness.js:1611:25)\n    at async_test (http://web-platform.test:8001/resources/testharness.js:576:22)\n    at stackTests (http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:57:3)\n    at http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:31:1" but got (undefined) undefined
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/structuredclone_0-expected.txt b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/structuredclone_0-expected.txt
index 562698b..bf553eb 100644
--- a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/structuredclone_0-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/structuredclone_0-expected.txt
@@ -38,7 +38,7 @@
 PASS Cloning a modified Error
 PASS Error.message: getter is ignored when cloning
 PASS Error.message: undefined property is stringified
-FAIL DOMException objects can be cloned Failed to execute 'postMessage' on 'Worker': DOMException object could not be cloned.
-FAIL DOMException objects created by the UA can be cloned Failed to execute 'postMessage' on 'Worker': DOMException object could not be cloned.
+PASS DOMException objects can be cloned
+PASS DOMException objects created by the UA can be cloned
 Harness: the test ran to completion.