Title: [232037] trunk
Revision
232037
Author
[email protected]
Date
2018-05-21 16:42:21 -0700 (Mon, 21 May 2018)

Log Message

Unreviewed, rolling out r232030.
https://bugs.webkit.org/show_bug.cgi?id=185850

"Caused
TestWebKitAPI.IndexedDB.StructuredCloneBackwardCompatibility
API test to fail" (Requested by cdumez on #webkit).

Reverted changeset:

"File's structured serialization should serialize lastModified
attribute"
https://bugs.webkit.org/show_bug.cgi?id=185773
https://trac.webkit.org/changeset/232030

Modified Paths

Added Paths

Removed Paths

  • trunk/LayoutTests/imported/w3c/web-platform-tests/html/webappapis/structured-clone/

Diff

Modified: trunk/LayoutTests/ChangeLog (232036 => 232037)


--- trunk/LayoutTests/ChangeLog	2018-05-21 23:34:15 UTC (rev 232036)
+++ trunk/LayoutTests/ChangeLog	2018-05-21 23:42:21 UTC (rev 232037)
@@ -1,3 +1,19 @@
+2018-05-21  Commit Queue  <[email protected]>
+
+        Unreviewed, rolling out r232030.
+        https://bugs.webkit.org/show_bug.cgi?id=185850
+
+        "Caused
+        TestWebKitAPI.IndexedDB.StructuredCloneBackwardCompatibility
+        API test to fail" (Requested by cdumez on #webkit).
+
+        Reverted changeset:
+
+        "File's structured serialization should serialize lastModified
+        attribute"
+        https://bugs.webkit.org/show_bug.cgi?id=185773
+        https://trac.webkit.org/changeset/232030
+
 2018-05-11  Ryosuke Niwa  <[email protected]>
 
         REGRESSION: performance-api/performance-observer-entry-sort.html is flaky

Modified: trunk/LayoutTests/TestExpectations (232036 => 232037)


--- trunk/LayoutTests/TestExpectations	2018-05-21 23:34:15 UTC (rev 232036)
+++ trunk/LayoutTests/TestExpectations	2018-05-21 23:42:21 UTC (rev 232037)
@@ -241,6 +241,8 @@
 imported/w3c/web-platform-tests/workers/nested_worker.worker.html [ Skip ]
 imported/w3c/web-platform-tests/workers/opaque-origin.html [ Skip ]
 imported/w3c/web-platform-tests/workers/semantics/interface-objects/003.html [ Skip ]
+imported/w3c/web-platform-tests/workers/semantics/structured-clone/shared.html [ Skip ]
+imported/w3c/web-platform-tests/workers/semantics/structured-clone/dedicated.html [ Skip ]
 imported/w3c/web-platform-tests/workers/semantics/multiple-workers/003.html [ Skip ]
 imported/w3c/web-platform-tests/workers/semantics/multiple-workers/005.html [ Skip ]
 imported/w3c/web-platform-tests/workers/Worker_cross_origin_security_err.htm [ Skip ]

Modified: trunk/LayoutTests/fast/storage/serialized-script-value.html (232036 => 232037)


--- trunk/LayoutTests/fast/storage/serialized-script-value.html	2018-05-21 23:34:15 UTC (rev 232036)
+++ trunk/LayoutTests/fast/storage/serialized-script-value.html	2018-05-21 23:42:21 UTC (rev 232037)
@@ -6,8 +6,6 @@
     <body>
         <script>
 
-const currentVersion = 0x07;
-
 // Here's a little Q&D helper for future adventurers needing to rebaseline this.
 
 function dec2hex(n) {
@@ -45,7 +43,7 @@
 
 testSerialization({foo: 'zoo', bar: {baz: 'myNewKey'}},
 [
-    currentVersion, 0x00, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00,
+    0x06, 0x00, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00,
     0x80, 0x66, 0x6f, 0x6f, 0x10, 0x03, 0x00, 0x00,
     0x80, 0x7a, 0x6f, 0x6f, 0x03, 0x00, 0x00, 0x80,
     0x62, 0x61, 0x72, 0x02, 0x03, 0x00, 0x00, 0x80,
@@ -68,7 +66,7 @@
 
 testSerialization({foo: 'zoo', bar: 'myNewKey'},
 [
-    currentVersion, 0x00, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00,
+    0x06, 0x00, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00,
     0x80, 0x66, 0x6f, 0x6f, 0x10, 0x03, 0x00, 0x00,
     0x80, 0x7a, 0x6f, 0x6f, 0x03, 0x00, 0x00, 0x80,
     0x62, 0x61, 0x72, 0x10, 0x08, 0x00, 0x00, 0x80,
@@ -76,7 +74,7 @@
     0xff, 0xff, 0xff, 0xff
 ],
 [
-    currentVersion, 0x00, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00,
+    0x03, 0x00, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00,
     0x00, 0x66, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x10,
     0x03, 0x00, 0x00, 0x00, 0x7a, 0x00, 0x6f, 0x00,
     0x6f, 0x00, 0x03, 0x00, 0x00, 0x00, 0x62, 0x00,
@@ -88,7 +86,7 @@
 
 testSerialization([],
 [
-    currentVersion, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+    0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
     0x00, 0xff, 0xff, 0xff, 0xff
 ],
 [
@@ -97,7 +95,7 @@
 ]);
 testSerialization({foo: "zoo"},
 [
-    currentVersion, 0x00, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00,
+    0x06, 0x00, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00,
     0x80, 0x66, 0x6f, 0x6f, 0x10, 0x03, 0x00, 0x00,
     0x80, 0x7a, 0x6f, 0x6f, 0xff, 0xff, 0xff, 0xff
 ],
@@ -109,7 +107,7 @@
 ]);
 testSerialization({foo: null},
 [
-    currentVersion, 0x00, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00,
+    0x06, 0x00, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00,
     0x80, 0x66, 0x6f, 0x6f, 0x04, 0xff, 0xff, 0xff,
     0xff
 ],
@@ -121,7 +119,7 @@
 
 testSerialization({},
 [
-    currentVersion, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff, 0xff,
+    0x06, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff, 0xff,
     0xff
 ],
 [
@@ -131,7 +129,7 @@
 
 testSerialization(undefined,
 [
-    currentVersion, 0x00, 0x00, 0x00, 0x03
+    0x06, 0x00, 0x00, 0x00, 0x03
 ],
 [
     0x03, 0x00, 0x00, 0x00, 0x03
@@ -138,7 +136,7 @@
 ]);
 testSerialization(true,
 [
-    currentVersion, 0x00, 0x00, 0x00, 0x09
+    0x06, 0x00, 0x00, 0x00, 0x09
 ],
 [
     0x03, 0x00, 0x00, 0x00, 0x09
@@ -145,7 +143,7 @@
 ]);
 testSerialization(false,
 [
-    currentVersion, 0x00, 0x00, 0x00, 0x08
+    0x06, 0x00, 0x00, 0x00, 0x08
 ],
 [
     0x03, 0x00, 0x00, 0x00, 0x08
@@ -152,7 +150,7 @@
 ]);
 testSerialization(new Array(100),
 [
-    currentVersion, 0x00, 0x00, 0x00, 0x01, 0x64, 0x00, 0x00,
+    0x06, 0x00, 0x00, 0x00, 0x01, 0x64, 0x00, 0x00,
     0x00, 0xff, 0xff, 0xff, 0xff
 ],
 [
@@ -161,7 +159,7 @@
 ]);
 testSerialization(10,
 [
-    currentVersion, 0x00, 0x00, 0x00, 0x05, 0x0a, 0x00, 0x00,
+    0x06, 0x00, 0x00, 0x00, 0x05, 0x0a, 0x00, 0x00,
     0x00
 ],
 [
@@ -170,7 +168,7 @@
 ]);
 testSerialization(-10,
 [
-    currentVersion, 0x00, 0x00, 0x00, 0x05, 0xf6, 0xff, 0xff,
+    0x06, 0x00, 0x00, 0x00, 0x05, 0xf6, 0xff, 0xff,
     0xff
 ],
 [
@@ -179,7 +177,7 @@
 ]);
 testSerialization(Math.pow(2,30),
 [
-    currentVersion, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
+    0x06, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
     0x40
 ],
 [
@@ -188,7 +186,7 @@
 ]);
 testSerialization(Math.pow(2,55),
 [
-    currentVersion, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
+    0x06, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
     0x00, 0x00, 0x00, 0x60, 0x43,
 ],
 [
@@ -197,7 +195,7 @@
 ]);
 testSerialization(1.23,
 [
-    currentVersion, 0x00, 0x00, 0x00, 0x0a, 0xae, 0x47, 0xe1,
+    0x06, 0x00, 0x00, 0x00, 0x0a, 0xae, 0x47, 0xe1,
     0x7a, 0x14, 0xae, 0xf3, 0x3f
 ],
 [
@@ -206,7 +204,7 @@
 ]);
 testSerialization("",
 [
-    currentVersion, 0x00, 0x00, 0x00, 0x11
+    0x06, 0x00, 0x00, 0x00, 0x11
 ],
 [
     0x03, 0x00, 0x00, 0x00, 0x11
@@ -213,7 +211,7 @@
 ]);
 testSerialization("abc",
 [
-    currentVersion, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, 0x00,
+    0x06, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, 0x00,
     0x80, 0x61, 0x62, 0x63
 ],
 [
@@ -222,7 +220,7 @@
 ]);
 testSerialization({integer: 123},
 [
-    currentVersion, 0x00, 0x00, 0x00, 0x02, 0x07, 0x00, 0x00,
+    0x06, 0x00, 0x00, 0x00, 0x02, 0x07, 0x00, 0x00,
     0x80, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72,
     0x05, 0x7b, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
     0xff
@@ -235,7 +233,7 @@
 ]);
 testSerialization({string: "str"},
 [
-    currentVersion, 0x00, 0x00, 0x00, 0x02, 0x06, 0x00, 0x00,
+    0x06, 0x00, 0x00, 0x00, 0x02, 0x06, 0x00, 0x00,
     0x80, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x10,
     0x03, 0x00, 0x00, 0x80, 0x73, 0x74, 0x72, 0xff,
     0xff, 0xff, 0xff
@@ -249,7 +247,7 @@
 ]);
 testSerialization({list: [1,2,3]},
 [
-    currentVersion, 0x00, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00,
+    0x06, 0x00, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00,
     0x80, 0x6c, 0x69, 0x73, 0x74, 0x01, 0x03, 0x00,
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x01,
     0x00, 0x00, 0x00, 0x05, 0x02, 0x00, 0x00, 0x00,
@@ -268,7 +266,7 @@
 ]);
 testSerialization(null,
 [
-    currentVersion, 0x00, 0x00, 0x00, 0x04
+    0x06, 0x00, 0x00, 0x00, 0x04
 ],
 [
     0x03, 0x00, 0x00, 0x00, 0x04
@@ -275,7 +273,7 @@
 ]);
 testSerialization(/abc/,
 [
-    currentVersion, 0x00, 0x00, 0x00, 0x12, 0x03, 0x00, 0x00,
+    0x06, 0x00, 0x00, 0x00, 0x12, 0x03, 0x00, 0x00,
     0x80, 0x61, 0x62, 0x63, 0x00, 0x00, 0x00, 0x80
 ],
 [
@@ -289,7 +287,7 @@
 outerObject['outer'] = innerObject;
 testSerialization(outerObject,
 [
-    currentVersion, 0x00, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00,
+    0x06, 0x00, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00,
     0x80, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x02, 0x05,
     0x00, 0x00, 0x80, 0x68, 0x65, 0x6c, 0x6c, 0x6f,
     0x10, 0x05, 0x00, 0x00, 0x80, 0x74, 0x68, 0x65,
@@ -311,7 +309,7 @@
 ]);
 testSerialization(innerObject,
 [
-    currentVersion, 0x00, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00,
+    0x06, 0x00, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00,
     0x80, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x10, 0x05,
     0x00, 0x00, 0x80, 0x74, 0x68, 0x65, 0x72, 0x65,
     0xff, 0xff, 0xff, 0xff
@@ -327,7 +325,7 @@
 var unicodeObject = {a: 'a', u: String.fromCharCode(0x03B1,0x03B2), d: 42};
 testSerialization(unicodeObject,
 [
-    currentVersion, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00,
+    0x06, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00,
     0x80, 0x61, 0x10, 0xfe, 0xff, 0xff, 0xff, 0x00,
     0x01, 0x00, 0x00, 0x80, 0x75, 0x10, 0x02, 0x00,
     0x00, 0x00, 0xb1, 0x03, 0xb2, 0x03, 0x01, 0x00,
@@ -345,7 +343,7 @@
 unicodeObject.a = 'ab';
 testSerialization(unicodeObject,
 [
-    currentVersion, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00,
+    0x06, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00,
     0x80, 0x61, 0x10, 0x02, 0x00, 0x00, 0x80, 0x61,
     0x62, 0x01, 0x00, 0x00, 0x80, 0x75, 0x10, 0x02,
     0x00, 0x00, 0x00, 0xb1, 0x03, 0xb2, 0x03, 0x01,
@@ -370,7 +368,7 @@
 arrayObject[''] = null;
 testSerialization(arrayObject,
 [
-    currentVersion, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+    0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
     0x00, 0xfd, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00,
     0x80, 0x61, 0x09, 0x01, 0x00, 0x00, 0x80, 0x62,
     0x08, 0x03, 0x00, 0x00, 0x80, 0x66, 0x6f, 0x6f,
@@ -384,7 +382,7 @@
 arrayObject[1] = 'bar';
 testSerialization(arrayObject,
 [
-    currentVersion, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00,
+    0x06, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00,
     0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00,
     0x00, 0x80, 0x66, 0x6f, 0x6f, 0x01, 0x00, 0x00,
     0x00, 0x10, 0x03, 0x00, 0x00, 0x80, 0x62, 0x61,
@@ -405,7 +403,7 @@
 
 testSerialization(mapObject,
 [
-    currentVersion, 0x00, 0x00, 0x00, 0x1e, 0x07, 0x05, 0x02,
+    0x06, 0x00, 0x00, 0x00, 0x1e, 0x07, 0x05, 0x02,
     0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00,
     0x00, 0x00, 0xf8, 0x3f, 0x02, 0xff, 0xff, 0xff,
     0xff, 0x13, 0x00, 0x10, 0x03, 0x00, 0x00, 0x80,
@@ -426,7 +424,7 @@
 
 testSerialization(setObject,
 [
-    currentVersion, 0x00, 0x00, 0x00, 0x1d, 0x07, 0x0a, 0x00,
+    0x06, 0x00, 0x00, 0x00, 0x1d, 0x07, 0x0a, 0x00,
     0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x3f, 0x13,
     0x00, 0x10, 0x03, 0x00, 0x00, 0x80, 0x62, 0x61,
     0x72, 0x1a, 0xfe, 0xff, 0xff, 0xff, 0x00, 0x20,

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (232036 => 232037)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2018-05-21 23:34:15 UTC (rev 232036)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2018-05-21 23:42:21 UTC (rev 232037)
@@ -1,3 +1,19 @@
+2018-05-21  Commit Queue  <[email protected]>
+
+        Unreviewed, rolling out r232030.
+        https://bugs.webkit.org/show_bug.cgi?id=185850
+
+        "Caused
+        TestWebKitAPI.IndexedDB.StructuredCloneBackwardCompatibility
+        API test to fail" (Requested by cdumez on #webkit).
+
+        Reverted changeset:
+
+        "File's structured serialization should serialize lastModified
+        attribute"
+        https://bugs.webkit.org/show_bug.cgi?id=185773
+        https://trac.webkit.org/changeset/232030
+
 2018-05-21  Chris Dumez  <[email protected]>
 
         File's structured serialization should serialize lastModified attribute

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/keypath-special-identifiers-expected.txt (232036 => 232037)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/keypath-special-identifiers-expected.txt	2018-05-21 23:34:15 UTC (rev 232036)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/keypath-special-identifiers-expected.txt	2018-05-21 23:42:21 UTC (rev 232037)
@@ -4,6 +4,6 @@
 PASS Type: Blob, identifier: size 
 PASS Type: Blob, identifier: type 
 PASS Type: File, identifier: name 
-PASS Type: File, identifier: lastModified 
+FAIL Type: File, identifier: lastModified assert_equals: Property should be used as key expected 0 but got 1
 FAIL Type: File, identifier: lastModifiedDate Provided data is inadequate.
 

Copied: trunk/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/structured-clone/common.js (from rev 232033, trunk/LayoutTests/imported/w3c/web-platform-tests/html/webappapis/structured-clone/structured-clone-battery-of-tests.js) (0 => 232037)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/structured-clone/common.js	                        (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/structured-clone/common.js	2018-05-21 23:42:21 UTC (rev 232037)
@@ -0,0 +1,596 @@
+function createWorker(msg) {
+  // `type` is defined in the test case itself
+  if (type == 'dedicated')
+    return new Worker('dedicated.js#'+encodeURIComponent(msg));
+  else if (type == 'shared')
+    return (new SharedWorker('shared.js#'+encodeURIComponent(msg))).port;
+  else
+    assert_unreached('invalid or missing `type`');
+}
+
+function check(msg, input, callback, test_obj) {
+  if (!test_obj)
+    test_obj = async_test(msg);
+  test_obj.step(function() {
+    var w = createWorker(msg);
+    if (typeof input === 'function')
+      input = this.step(input);
+    w.postMessage(input);
+    w._onmessage_ = this.step_func(function(ev) { callback(ev.data, input, this); });
+  });
+}
+
+function compare_primitive(actual, input, test_obj) {
+  assert_equals(actual, input);
+  if (test_obj)
+    test_obj.done();
+}
+function compare_Array(callback, callback_is_async) {
+  return function(actual, input, test_obj) {
+    if (typeof actual === 'string')
+      assert_unreached(actual);
+    assert_true(actual instanceof Array, 'instanceof Array');
+    assert_not_equals(actual, input);
+    assert_equals(actual.length, input.length, 'length');
+    callback(actual, input);
+    if (test_obj && !callback_is_async)
+      test_obj.done();
+  }
+}
+
+function compare_Object(callback, callback_is_async) {
+  return function(actual, input, test_obj) {
+    if (typeof actual === 'string')
+      assert_unreached(actual);
+    assert_true(actual instanceof Object, 'instanceof Object');
+    assert_false(actual instanceof Array, 'instanceof Array');
+    assert_not_equals(actual, input);
+    callback(actual, input);
+    if (test_obj && !callback_is_async)
+      test_obj.done();
+  }
+}
+
+function enumerate_props(compare_func, test_obj) {
+  return function(actual, input) {
+    for (var x in input) {
+      compare_func(actual[x], input[x], test_obj);
+    }
+  };
+}
+
+check('primitive undefined', undefined, compare_primitive);
+check('primitive null', null, compare_primitive);
+check('primitive true', true, compare_primitive);
+check('primitive false', false, compare_primitive);
+check('primitive string, empty string', '', compare_primitive);
+check('primitive string, lone high surrogate', '\uD800', compare_primitive);
+check('primitive string, lone low surrogate', '\uDC00', compare_primitive);
+check('primitive string, NUL', '\u0000', compare_primitive);
+check('primitive string, astral character', '\uDBFF\uDFFD', compare_primitive);
+check('primitive number, 0.2', 0.2, compare_primitive);
+check('primitive number, 0', 0, compare_primitive);
+check('primitive number, -0', -0, compare_primitive);
+check('primitive number, NaN', NaN, compare_primitive);
+check('primitive number, Infinity', Infinity, compare_primitive);
+check('primitive number, -Infinity', -Infinity, compare_primitive);
+check('primitive number, 9007199254740992', 9007199254740992, compare_primitive);
+check('primitive number, -9007199254740992', -9007199254740992, compare_primitive);
+check('primitive number, 9007199254740994', 9007199254740994, compare_primitive);
+check('primitive number, -9007199254740994', -9007199254740994, compare_primitive);
+
+check('Array primitives', [undefined,
+                           null,
+                           true,
+                           false,
+                           '',
+                           '\uD800',
+                           '\uDC00',
+                           '\u0000',
+                           '\uDBFF\uDFFD',
+                           0.2,
+                           0,
+                           -0,
+                           NaN,
+                           Infinity,
+                           -Infinity,
+                           9007199254740992,
+                           -9007199254740992,
+                           9007199254740994,
+                           -9007199254740994], compare_Array(enumerate_props(compare_primitive)));
+check('Object primitives', {'undefined':undefined,
+                           'null':null,
+                           'true':true,
+                           'false':false,
+                           'empty':'',
+                           'high surrogate':'\uD800',
+                           'low surrogate':'\uDC00',
+                           'nul':'\u0000',
+                           'astral':'\uDBFF\uDFFD',
+                           '0.2':0.2,
+                           '0':0,
+                           '-0':-0,
+                           'NaN':NaN,
+                           'Infinity':Infinity,
+                           '-Infinity':-Infinity,
+                           '9007199254740992':9007199254740992,
+                           '-9007199254740992':-9007199254740992,
+                           '9007199254740994':9007199254740994,
+                           '-9007199254740994':-9007199254740994}, compare_Object(enumerate_props(compare_primitive)));
+
+function compare_Boolean(actual, input, test_obj) {
+  if (typeof actual === 'string')
+    assert_unreached(actual);
+  assert_true(actual instanceof Boolean, 'instanceof Boolean');
+  assert_equals(String(actual), String(input), 'converted to primitive');
+  assert_not_equals(actual, input);
+  if (test_obj)
+    test_obj.done();
+}
+check('Boolean true', new Boolean(true), compare_Boolean);
+check('Boolean false', new Boolean(false), compare_Boolean);
+check('Array Boolean objects', [new Boolean(true), new Boolean(false)], compare_Array(enumerate_props(compare_Boolean)));
+check('Object Boolean objects', {'true':new Boolean(true), 'false':new Boolean(false)}, compare_Object(enumerate_props(compare_Boolean)));
+
+function compare_obj(what) {
+  var Type = window[what];
+  return function(actual, input, test_obj) {
+    if (typeof actual === 'string')
+      assert_unreached(actual);
+    assert_true(actual instanceof Type, 'instanceof '+what);
+    assert_equals(Type(actual), Type(input), 'converted to primitive');
+    assert_not_equals(actual, input);
+    if (test_obj)
+      test_obj.done();
+  };
+}
+check('String empty string', new String(''), compare_obj('String'));
+check('String lone high surrogate', new String('\uD800'), compare_obj('String'));
+check('String lone low surrogate', new String('\uDC00'), compare_obj('String'));
+check('String NUL', new String('\u0000'), compare_obj('String'));
+check('String astral character', new String('\uDBFF\uDFFD'), compare_obj('String'));
+check('Array String objects', [new String(''),
+                               new String('\uD800'),
+                               new String('\uDC00'),
+                               new String('\u0000'),
+                               new String('\uDBFF\uDFFD')], compare_Array(enumerate_props(compare_obj('String'))));
+check('Object String objects', {'empty':new String(''),
+                               'high surrogate':new String('\uD800'),
+                               'low surrogate':new String('\uDC00'),
+                               'nul':new String('\u0000'),
+                               'astral':new String('\uDBFF\uDFFD')}, compare_Object(enumerate_props(compare_obj('String'))));
+
+check('Number 0.2', new Number(0.2), compare_obj('Number'));
+check('Number 0', new Number(0), compare_obj('Number'));
+check('Number -0', new Number(-0), compare_obj('Number'));
+check('Number NaN', new Number(NaN), compare_obj('Number'));
+check('Number Infinity', new Number(Infinity), compare_obj('Number'));
+check('Number -Infinity', new Number(-Infinity), compare_obj('Number'));
+check('Number 9007199254740992', new Number(9007199254740992), compare_obj('Number'));
+check('Number -9007199254740992', new Number(-9007199254740992), compare_obj('Number'));
+check('Number 9007199254740994', new Number(9007199254740994), compare_obj('Number'));
+check('Number -9007199254740994', new Number(-9007199254740994), compare_obj('Number'));
+check('Array Number objects', [new Number(0.2),
+                               new Number(0),
+                               new Number(-0),
+                               new Number(NaN),
+                               new Number(Infinity),
+                               new Number(-Infinity),
+                               new Number(9007199254740992),
+                               new Number(-9007199254740992),
+                               new Number(9007199254740994),
+                               new Number(-9007199254740994)], compare_Array(enumerate_props(compare_obj('Number'))));
+check('Object Number objects', {'0.2':new Number(0.2),
+                               '0':new Number(0),
+                               '-0':new Number(-0),
+                               'NaN':new Number(NaN),
+                               'Infinity':new Number(Infinity),
+                               '-Infinity':new Number(-Infinity),
+                               '9007199254740992':new Number(9007199254740992),
+                               '-9007199254740992':new Number(-9007199254740992),
+                               '9007199254740994':new Number(9007199254740994),
+                               '-9007199254740994':new Number(-9007199254740994)}, compare_Object(enumerate_props(compare_obj('Number'))));
+
+function compare_Date(actual, input, test_obj) {
+  if (typeof actual === 'string')
+    assert_unreached(actual);
+  assert_true(actual instanceof Date, 'instanceof Date');
+  assert_equals(Number(actual), Number(input), 'converted to primitive');
+  assert_not_equals(actual, input);
+  if (test_obj)
+    test_obj.done();
+}
+check('Date 0', new Date(0), compare_Date);
+check('Date -0', new Date(-0), compare_Date);
+check('Date -8.64e15', new Date(-8.64e15), compare_Date);
+check('Date 8.64e15', new Date(8.64e15), compare_Date);
+check('Array Date objects', [new Date(0),
+                             new Date(-0),
+                             new Date(-8.64e15),
+                             new Date(8.64e15)], compare_Array(enumerate_props(compare_Date)));
+check('Object Date objects', {'0':new Date(0),
+                              '-0':new Date(-0),
+                              '-8.64e15':new Date(-8.64e15),
+                              '8.64e15':new Date(8.64e15)}, compare_Object(enumerate_props(compare_Date)));
+
+function compare_RegExp(expected_source) {
+  // XXX ES6 spec doesn't define exact serialization for `source` (it allows several ways to escape)
+  return function(actual, input, test_obj) {
+    if (typeof actual === 'string')
+      assert_unreached(actual);
+    assert_true(actual instanceof RegExp, 'instanceof RegExp');
+    assert_equals(actual.global, input.global, 'global');
+    assert_equals(actual.ignoreCase, input.ignoreCase, 'ignoreCase');
+    assert_equals(actual.multiline, input.multiline, 'multiline');
+    assert_equals(actual.source, expected_source, 'source');
+    assert_equals(actual.sticky, input.sticky, 'sticky');
+    assert_equals(actual.unicode, input.unicode, 'unicode');
+    assert_equals(actual.lastIndex, 0, 'lastIndex');
+    assert_not_equals(actual, input);
+    if (test_obj)
+      test_obj.done();
+  }
+}
+function func_RegExp_flags_lastIndex() {
+  var r = /foo/gim;
+  r.lastIndex = 2;
+  return r;
+}
+function func_RegExp_sticky() {
+  return new RegExp('foo', 'y');
+}
+function func_RegExp_unicode() {
+  return new RegExp('foo', 'u');
+}
+check('RegExp flags and lastIndex', func_RegExp_flags_lastIndex, compare_RegExp('foo'));
+check('RegExp sticky flag', func_RegExp_sticky, compare_RegExp('foo'));
+check('RegExp unicode flag', func_RegExp_unicode, compare_RegExp('foo'));
+check('RegExp empty', new RegExp(''), compare_RegExp('(?:)'));
+check('RegExp slash', new RegExp('/'), compare_RegExp('\\/'));
+check('RegExp new line', new RegExp('\n'), compare_RegExp('\\n'));
+check('Array RegExp object, RegExp flags and lastIndex', [func_RegExp_flags_lastIndex()], compare_Array(enumerate_props(compare_RegExp('foo'))));
+check('Array RegExp object, RegExp sticky flag', function() { return [func_RegExp_sticky()]; }, compare_Array(enumerate_props(compare_RegExp('foo'))));
+check('Array RegExp object, RegExp unicode flag', function() { return [func_RegExp_unicode()]; }, compare_Array(enumerate_props(compare_RegExp('foo'))));
+check('Array RegExp object, RegExp empty', [new RegExp('')], compare_Array(enumerate_props(compare_RegExp('(?:)'))));
+check('Array RegExp object, RegExp slash', [new RegExp('/')], compare_Array(enumerate_props(compare_RegExp('\\/'))));
+check('Array RegExp object, RegExp new line', [new RegExp('\n')], compare_Array(enumerate_props(compare_RegExp('\\n'))));
+check('Object RegExp object, RegExp flags and lastIndex', {'x':func_RegExp_flags_lastIndex()}, compare_Object(enumerate_props(compare_RegExp('foo'))));
+check('Object RegExp object, RegExp sticky flag', function() { return {'x':func_RegExp_sticky()}; }, compare_Object(enumerate_props(compare_RegExp('foo'))));
+check('Object RegExp object, RegExp unicode flag', function() { return {'x':func_RegExp_unicode()}; }, compare_Object(enumerate_props(compare_RegExp('foo'))));
+check('Object RegExp object, RegExp empty', {'x':new RegExp('')}, compare_Object(enumerate_props(compare_RegExp('(?:)'))));
+check('Object RegExp object, RegExp slash', {'x':new RegExp('/')}, compare_Object(enumerate_props(compare_RegExp('\\/'))));
+check('Object RegExp object, RegExp new line', {'x':new RegExp('\n')}, compare_Object(enumerate_props(compare_RegExp('\\n'))));
+
+function compare_Blob(actual, input, test_obj, expect_File) {
+  if (typeof actual === 'string')
+    assert_unreached(actual);
+  assert_true(actual instanceof Blob, 'instanceof Blob');
+  if (!expect_File)
+    assert_false(actual instanceof File, 'instanceof File');
+  assert_equals(actual.size, input.size, 'size');
+  assert_equals(actual.type, input.type, 'type');
+  assert_not_equals(actual, input);
+  var ev_reader = new FileReader();
+  var input_reader = new FileReader();
+  var read_count = 0;
+  var read_done = test_obj.step_func(function() {
+    read_count++;
+    if (read_count == 2) {
+      var ev_result = ev_reader.result;
+      var input_result = input_reader.result;
+      assert_equals(ev_result.byteLength, input_result.byteLength, 'byteLength');
+      var ev_view = new DataView(ev_result);
+      var input_view = new DataView(input_result);
+      for (var i = 0; i < ev_result.byteLength; ++i) {
+        assert_equals(ev_view.getUint8(i), input_view.getUint8(i), 'getUint8('+i+')');
+      }
+      if (test_obj)
+        test_obj.done();
+    }
+  });
+  var read_error = test_obj.step_func(function() { assert_unreached('FileReader error'); });
+  ev_reader.readAsArrayBuffer(actual);
+  ev_reader._onload_ = read_done;
+  ev_reader._onabort_ = ev_reader._onerror_ = read_error;
+  input_reader.readAsArrayBuffer(input);
+  input_reader._onload_ = read_done;
+  input_reader._onabort_ = input_reader._onerror_ = read_error;
+}
+function func_Blob_basic() {
+  return new Blob(['foo'], {type:'text/x-bar'});
+}
+check('Blob basic', func_Blob_basic, compare_Blob);
+
+function b(str) {
+  return parseInt(str, 2);
+}
+function encode_cesu8(codeunits) {
+  // http://www.unicode.org/reports/tr26/ section 2.2
+  // only the 3-byte form is supported
+  var rv = [];
+  codeunits.forEach(function(codeunit) {
+    rv.push(b('11100000') + ((codeunit & b('1111000000000000')) >> 12));
+    rv.push(b('10000000') + ((codeunit & b('0000111111000000')) >> 6));
+    rv.push(b('10000000') +  (codeunit & b('0000000000111111')));
+  });
+  return rv;
+}
+function func_Blob_bytes(arr) {
+  return function() {
+    var buffer = new ArrayBuffer(arr.length);
+    var view = new DataView(buffer);
+    for (var i = 0; i < arr.length; ++i) {
+      view.setUint8(i, arr[i]);
+    }
+    return new Blob([view]);
+  };
+}
+check('Blob unpaired high surrogate (invalid utf-8)', func_Blob_bytes(encode_cesu8([0xD800])), compare_Blob);
+check('Blob unpaired low surrogate (invalid utf-8)', func_Blob_bytes(encode_cesu8([0xDC00])), compare_Blob);
+check('Blob paired surrogates (invalid utf-8)', func_Blob_bytes(encode_cesu8([0xD800, 0xDC00])), compare_Blob);
+
+function func_Blob_empty() {
+  return new Blob(['']);
+}
+check('Blob empty', func_Blob_empty , compare_Blob);
+function func_Blob_NUL() {
+  return new Blob(['\u0000']);
+}
+check('Blob NUL', func_Blob_NUL, compare_Blob);
+
+async_test(function(test_obj) {
+  check(test_obj.name, [test_obj.step(func_Blob_basic)], compare_Array(enumerate_props(compare_Blob, test_obj), true), test_obj);
+}, 'Array Blob object, Blob basic');
+async_test(function(test_obj) {
+  check(test_obj.name, [test_obj.step(func_Blob_bytes([0xD800]))], compare_Array(enumerate_props(compare_Blob, test_obj), true), test_obj);
+}, 'Array Blob object, Blob unpaired high surrogate (invalid utf-8)');
+async_test(function(test_obj) {
+  check(test_obj.name, [test_obj.step(func_Blob_bytes([0xDC00]))], compare_Array(enumerate_props(compare_Blob, test_obj), true), test_obj);
+}, 'Array Blob object, Blob unpaired low surrogate (invalid utf-8)');
+async_test(function(test_obj) {
+  check(test_obj.name, [test_obj.step(func_Blob_bytes([0xD800, 0xDC00]))], compare_Array(enumerate_props(compare_Blob, test_obj), true), test_obj);
+}, 'Array Blob object, Blob paired surrogates (invalid utf-8)');
+async_test(function(test_obj) {
+  check(test_obj.name, [test_obj.step(func_Blob_empty)], compare_Array(enumerate_props(compare_Blob, test_obj), true), test_obj);
+}, 'Array Blob object, Blob empty');
+async_test(function(test_obj) {
+  check(test_obj.name, [test_obj.step(func_Blob_NUL)], compare_Array(enumerate_props(compare_Blob, test_obj), true), test_obj);
+}, 'Array Blob object, Blob NUL');
+
+async_test(function(test_obj) {
+  check(test_obj.name, {'x':test_obj.step(func_Blob_basic)}, compare_Object(enumerate_props(compare_Blob, test_obj), true), test_obj);
+}, 'Object Blob object, Blob basic');
+async_test(function(test_obj) {
+  check(test_obj.name, {'x':test_obj.step(func_Blob_bytes([0xD800]))}, compare_Object(enumerate_props(compare_Blob, test_obj), true), test_obj);
+}, 'Object Blob object, Blob unpaired high surrogate (invalid utf-8)');
+async_test(function(test_obj) {
+  check(test_obj.name, {'x':test_obj.step(func_Blob_bytes([0xDC00]))}, compare_Object(enumerate_props(compare_Blob, test_obj), true), test_obj);
+}, 'Object Blob object, Blob unpaired low surrogate (invalid utf-8)');
+async_test(function(test_obj) {
+  check(test_obj.name, {'x':test_obj.step(func_Blob_bytes([0xD800, 0xDC00]))}, compare_Object(enumerate_props(compare_Blob, test_obj), true), test_obj);
+}, 'Object Blob object, Blob paired surrogates (invalid utf-8)');
+async_test(function(test_obj) {
+  check(test_obj.name, {'x':test_obj.step(func_Blob_empty)}, compare_Object(enumerate_props(compare_Blob, test_obj), true), test_obj);
+}, 'Object Blob object, Blob empty');
+async_test(function(test_obj) {
+  check(test_obj.name, {'x':test_obj.step(func_Blob_NUL)}, compare_Object(enumerate_props(compare_Blob, test_obj), true), test_obj);
+}, 'Object Blob object, Blob NUL');
+
+function compare_File(actual, input, test_obj) {
+  assert_true(actual instanceof File, 'instanceof File');
+  assert_equals(actual.name, input.name, 'name');
+  assert_equals(actual.lastModified, input.lastModified, 'lastModified');
+  compare_Blob(actual, input, test_obj, true);
+}
+function func_File_basic() {
+  return new File(['foo'], 'bar', {type:'text/x-bar', lastModified:42});
+}
+check('File basic', func_File_basic, compare_File);
+
+function compare_FileList(actual, input, test_obj) {
+  if (typeof actual === 'string')
+    assert_unreached(actual);
+  assert_true(actual instanceof FileList, 'instanceof FileList');
+  assert_equals(actual.length, input.length, 'length');
+  assert_not_equals(actual, input);
+  // XXX when there's a way to populate or construct a FileList,
+  // check the items in the FileList
+  if (test_obj)
+    test_obj.done();
+}
+function func_FileList_empty() {
+  var input = document.createElement('input');
+  input.type = 'file';
+  return input.files;
+}
+check('FileList empty', func_FileList_empty, compare_FileList);
+check('Array FileList object, FileList empty', [func_FileList_empty], compare_Array(enumerate_props(compare_FileList)));
+check('Object FileList object, FileList empty', {'x':func_FileList_empty}, compare_Object(enumerate_props(compare_FileList)));
+
+function compare_ArrayBufferView(view) {
+  var Type = window[view];
+  return function(actual, input, test_obj) {
+    if (typeof actual === 'string')
+      assert_unreached(actual);
+    assert_true(actual instanceof Type, 'instanceof '+view);
+    assert_equals(actual.length, input.length, 'length');
+    assert_not_equals(actual.buffer, input.buffer, 'buffer');
+    for (var i = 0; i < actual.length; ++i) {
+      assert_equals(actual[i], input[i], 'actual['+i+']');
+    }
+    if (test_obj)
+      test_obj.done();
+  };
+}
+function compare_ImageData(actual, input, test_obj) {
+  if (typeof actual === 'string')
+    assert_unreached(actual);
+  assert_equals(actual.width, input.width, 'width');
+  assert_equals(actual.height, input.height, 'height');
+  assert_not_equals(actual.data, input.data, 'data');
+  compare_ArrayBufferView('Uint8ClampedArray')(actual.data, input.data, null);
+  if (test_obj)
+    test_obj.done();
+}
+function func_ImageData_1x1_transparent_black() {
+  var canvas = document.createElement('canvas');
+  var ctx = canvas.getContext('2d');
+  return ctx.createImageData(1, 1);
+}
+check('ImageData 1x1 transparent black', func_ImageData_1x1_transparent_black, compare_ImageData);
+function func_ImageData_1x1_non_transparent_non_black() {
+  var canvas = document.createElement('canvas');
+  var ctx = canvas.getContext('2d');
+  var imagedata = ctx.createImageData(1, 1);
+  imagedata.data[0] = 100;
+  imagedata.data[1] = 101;
+  imagedata.data[2] = 102;
+  imagedata.data[3] = 103;
+  return imagedata;
+}
+check('ImageData 1x1 non-transparent non-black', func_ImageData_1x1_non_transparent_non_black, compare_ImageData);
+async_test(function(test_obj) {
+  check(test_obj.name, [test_obj.step(func_ImageData_1x1_transparent_black)], compare_Array(enumerate_props(compare_ImageData)), test_obj);
+}, 'Array ImageData object, ImageData 1x1 transparent black');
+async_test(function(test_obj) {
+  check(test_obj.name, [test_obj.step(func_ImageData_1x1_non_transparent_non_black)], compare_Array(enumerate_props(compare_ImageData)), test_obj);
+}, 'Array ImageData object, ImageData 1x1 non-transparent non-black');
+async_test(function(test_obj) {
+  check(test_obj.name, {'x':test_obj.step(func_ImageData_1x1_transparent_black)}, compare_Object(enumerate_props(compare_ImageData)), test_obj);
+}, 'Object ImageData object, ImageData 1x1 transparent black');
+async_test(function(test_obj) {
+  check(test_obj.name, {'x':test_obj.step(func_ImageData_1x1_non_transparent_non_black)}, compare_Object(enumerate_props(compare_ImageData)), test_obj);
+}, 'Object ImageData object, ImageData 1x1 non-transparent non-black');
+
+function compare_ImageBitmap(actual, input, test_obj) {
+  if (typeof actual === 'string')
+    assert_unreached(actual);
+  assert_equals(actual instanceof ImageBitmap, 'instanceof ImageBitmap');
+  assert_not_equals(actual, input);
+  // XXX paint the ImageBitmap on a canvas and check the data
+  if (test_obj)
+    test_obj.done();
+}
+function get_canvas_1x1_transparent_black() {
+  var canvas = document.createElement('canvas');
+  canvas.width = 1;
+  canvas.height = 1;
+  return canvas;
+}
+async_test(function(test_obj) {
+  var canvas = get_canvas_1x1_transparent_black();
+  createImageBitmap(canvas, function(image) { check(test_obj.name, image, compare_ImageBitmap, test_obj); });
+}, 'ImageBitmap 1x1 transparent black');
+function get_canvas_1x1_non_transparent_non_black() {
+  var canvas = document.createElement('canvas');
+  canvas.width = 1;
+  canvas.height = 1;
+  var ctx = canvas.getContext('2d');
+  var imagedata = ctx.getImageData(0, 0, 1, 1);
+  imagedata.data[0] = 100;
+  imagedata.data[1] = 101;
+  imagedata.data[2] = 102;
+  imagedata.data[3] = 103;
+  return canvas;
+}
+async_test(function(test_obj) {
+  var canvas = get_canvas_1x1_non_transparent_non_black();
+  createImageBitmap(canvas, function(image) { check(test_obj.name, image, compare_ImageBitmap, test_obj); });
+}, 'ImageBitmap 1x1 non-transparent non-black');
+
+async_test(function(test_obj) {
+  var canvas = get_canvas_1x1_transparent_black();
+  createImageBitmap(canvas, function(image) { check(test_obj.name, [image], compare_Array(enumerate_props(compare_ImageBitmap)), test_obj); });
+}, 'Array ImageBitmap object, ImageBitmap 1x1 transparent black');
+async_test(function(test_obj) {
+  var canvas = get_canvas_1x1_non_transparent_non_black();
+  createImageBitmap(canvas, function(image) { check(test_obj.name, [image], compare_Array(enumerate_props(compare_ImageBitmap)), test_obj); });
+}, 'Array ImageBitmap object, ImageBitmap 1x1 non-transparent non-black');
+
+async_test(function(test_obj) {
+  var canvas = get_canvas_1x1_transparent_black();
+  createImageBitmap(canvas, function(image) { check(test_obj.name, {'x':image}, compare_Object(enumerate_props(compare_ImageBitmap)), test_obj); });
+}, 'Object ImageBitmap object, ImageBitmap 1x1 transparent black');
+async_test(function(test_obj) {
+  var canvas = get_canvas_1x1_non_transparent_non_black();
+  createImageBitmap(canvas, function(image) { check(test_obj.name, {'x':image}, compare_Object(enumerate_props(compare_ImageBitmap)), test_obj); });
+}, 'Object ImageBitmap object, ImageBitmap 1x1 non-transparent non-black');
+
+check('Array sparse', new Array(10), compare_Array(enumerate_props(compare_primitive)));
+check('Array with non-index property', function() {
+  var rv = [];
+  rv.foo = 'bar';
+  return rv;
+}, compare_Array(enumerate_props(compare_primitive)));
+check('Object with index property and length', {'0':'foo', 'length':1}, compare_Object(enumerate_props(compare_primitive)));
+function check_circular_property(prop) {
+  return function(actual) {
+    assert_equals(actual[prop], actual);
+  };
+}
+check('Array with circular reference', function() {
+  var rv = [];
+  rv[0] = rv;
+  return rv;
+}, compare_Array(check_circular_property('0')));
+check('Object with circular reference', function() {
+  var rv = {};
+  rv['x'] = rv;
+  return rv;
+}, compare_Object(check_circular_property('x')));
+function check_identical_property_values(prop1, prop2) {
+  return function(actual) {
+    assert_equals(actual[prop1], actual[prop2]);
+  };
+}
+check('Array with identical property values', function() {
+  var obj = {}
+  return [obj, obj];
+}, compare_Array(check_identical_property_values('0', '1')));
+check('Object with identical property values', function() {
+  var obj = {}
+  return {'x':obj, 'y':obj};
+}, compare_Object(check_identical_property_values('x', 'y')));
+
+function check_absent_property(prop) {
+  return function(actual) {
+    assert_false(prop in actual);
+  };
+}
+check('Object with property on prototype', function() {
+  var Foo = function() {};
+  Foo.prototype = {'foo':'bar'};
+  return new Foo();
+}, compare_Object(check_absent_property('foo')));
+
+check('Object with non-enumerable property', function() {
+  var rv = {};
+  Object.defineProperty(rv, 'foo', {value:'bar', enumerable:false, writable:true, configurable:true});
+  return rv;
+}, compare_Object(check_absent_property('foo')));
+
+function check_writable_property(prop) {
+  return function(actual, input) {
+    assert_equals(actual[prop], input[prop]);
+    actual[prop] += ' baz';
+    assert_equals(actual[prop], input[prop] + ' baz');
+  };
+}
+check('Object with non-writable property', function() {
+  var rv = {};
+  Object.defineProperty(rv, 'foo', {value:'bar', enumerable:true, writable:false, configurable:true});
+  return rv;
+}, compare_Object(check_writable_property('foo')));
+
+function check_configurable_property(prop) {
+  return function(actual, input) {
+    assert_equals(actual[prop], input[prop]);
+    delete actual[prop];
+    assert_false('prop' in actual);
+  };
+}
+check('Object with non-configurable property', function() {
+  var rv = {};
+  Object.defineProperty(rv, 'foo', {value:'bar', enumerable:true, writable:true, configurable:false});
+  return rv;
+}, compare_Object(check_configurable_property('foo')));

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/structured-clone/dedicated-expected.txt (232036 => 232037)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/structured-clone/dedicated-expected.txt	2018-05-21 23:34:15 UTC (rev 232036)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/structured-clone/dedicated-expected.txt	2018-05-21 23:42:21 UTC (rev 232037)
@@ -1,4 +1,6 @@
 
+Harness Error (TIMEOUT), message = null
+
 PASS primitive undefined 
 PASS primitive null 
 PASS primitive true 
@@ -50,45 +52,45 @@
 PASS Array Date objects 
 PASS Object Date objects 
 PASS RegExp flags and lastIndex 
-FAIL RegExp sticky flag assert_equals: sticky expected true but got false
-FAIL RegExp unicode flag assert_equals: unicode expected true but got false
+FAIL RegExp sticky flag assert_unreached: FAIL: unknown test Reached unreachable code
+FAIL RegExp unicode flag assert_unreached: FAIL: unknown test Reached unreachable code
 PASS RegExp empty 
 PASS RegExp slash 
 PASS RegExp new line 
 PASS Array RegExp object, RegExp flags and lastIndex 
-FAIL Array RegExp object, RegExp sticky flag assert_equals: sticky expected true but got false
-FAIL Array RegExp object, RegExp unicode flag assert_equals: unicode expected true but got false
+FAIL Array RegExp object, RegExp sticky flag assert_unreached: FAIL: unknown test Reached unreachable code
+FAIL Array RegExp object, RegExp unicode flag assert_unreached: FAIL: unknown test Reached unreachable code
 PASS Array RegExp object, RegExp empty 
 PASS Array RegExp object, RegExp slash 
 PASS Array RegExp object, RegExp new line 
 PASS Object RegExp object, RegExp flags and lastIndex 
-FAIL Object RegExp object, RegExp sticky flag assert_equals: sticky expected true but got false
-FAIL Object RegExp object, RegExp unicode flag assert_equals: unicode expected true but got false
+FAIL Object RegExp object, RegExp sticky flag assert_unreached: FAIL: unknown test Reached unreachable code
+FAIL Object RegExp object, RegExp unicode flag assert_unreached: FAIL: unknown test Reached unreachable code
 PASS Object RegExp object, RegExp empty 
 PASS Object RegExp object, RegExp slash 
 PASS Object RegExp object, RegExp new line 
-PASS Blob basic 
-PASS Blob unpaired high surrogate (invalid utf-8) 
-PASS Blob unpaired low surrogate (invalid utf-8) 
-PASS Blob paired surrogates (invalid utf-8) 
-PASS Blob empty 
-PASS Blob NUL 
-PASS Array Blob object, Blob basic 
-PASS Array Blob object, Blob unpaired high surrogate (invalid utf-8) 
-PASS Array Blob object, Blob unpaired low surrogate (invalid utf-8) 
-PASS Array Blob object, Blob paired surrogates (invalid utf-8) 
-PASS Array Blob object, Blob empty 
-PASS Array Blob object, Blob NUL 
-PASS Object Blob object, Blob basic 
-PASS Object Blob object, Blob unpaired high surrogate (invalid utf-8) 
-PASS Object Blob object, Blob unpaired low surrogate (invalid utf-8) 
-PASS Object Blob object, Blob paired surrogates (invalid utf-8) 
-PASS Object Blob object, Blob empty 
-PASS Object Blob object, Blob NUL 
-PASS File basic 
-PASS FileList empty 
-PASS Array FileList object, FileList empty 
-PASS Object FileList object, FileList empty 
+FAIL Blob basic assert_unreached: FAIL ReferenceError: Can't find variable: File Reached unreachable code
+FAIL Blob unpaired high surrogate (invalid utf-8) assert_unreached: FAIL ReferenceError: Can't find variable: File Reached unreachable code
+FAIL Blob unpaired low surrogate (invalid utf-8) assert_unreached: FAIL ReferenceError: Can't find variable: File Reached unreachable code
+FAIL Blob paired surrogates (invalid utf-8) assert_unreached: FAIL ReferenceError: Can't find variable: File Reached unreachable code
+FAIL Blob empty assert_unreached: FAIL ReferenceError: Can't find variable: File Reached unreachable code
+FAIL Blob NUL assert_unreached: FAIL ReferenceError: Can't find variable: File Reached unreachable code
+FAIL Array Blob object, Blob basic assert_unreached: FAIL ReferenceError: Can't find variable: File Reached unreachable code
+FAIL Array Blob object, Blob unpaired high surrogate (invalid utf-8) assert_unreached: FAIL ReferenceError: Can't find variable: File Reached unreachable code
+FAIL Array Blob object, Blob unpaired low surrogate (invalid utf-8) assert_unreached: FAIL ReferenceError: Can't find variable: File Reached unreachable code
+FAIL Array Blob object, Blob paired surrogates (invalid utf-8) assert_unreached: FAIL ReferenceError: Can't find variable: File Reached unreachable code
+FAIL Array Blob object, Blob empty assert_unreached: FAIL ReferenceError: Can't find variable: File Reached unreachable code
+FAIL Array Blob object, Blob NUL assert_unreached: FAIL ReferenceError: Can't find variable: File Reached unreachable code
+FAIL Object Blob object, Blob basic assert_unreached: FAIL ReferenceError: Can't find variable: File Reached unreachable code
+FAIL Object Blob object, Blob unpaired high surrogate (invalid utf-8) assert_unreached: FAIL ReferenceError: Can't find variable: File Reached unreachable code
+FAIL Object Blob object, Blob unpaired low surrogate (invalid utf-8) assert_unreached: FAIL ReferenceError: Can't find variable: File Reached unreachable code
+FAIL Object Blob object, Blob paired surrogates (invalid utf-8) assert_unreached: FAIL ReferenceError: Can't find variable: File Reached unreachable code
+FAIL Object Blob object, Blob empty assert_unreached: FAIL ReferenceError: Can't find variable: File Reached unreachable code
+FAIL Object Blob object, Blob NUL assert_unreached: FAIL ReferenceError: Can't find variable: File Reached unreachable code
+FAIL File basic assert_true: instanceof File expected true got false
+FAIL FileList empty assert_unreached: FAIL ReferenceError: Can't find variable: FileList Reached unreachable code
+FAIL Array FileList object, FileList empty The object can not be cloned.
+FAIL Object FileList object, FileList empty The object can not be cloned.
 PASS ImageData 1x1 transparent black 
 PASS ImageData 1x1 non-transparent non-black 
 PASS Array ImageData object, ImageData 1x1 transparent black 
@@ -95,6 +97,12 @@
 PASS Array ImageData object, ImageData 1x1 non-transparent non-black 
 PASS Object ImageData object, ImageData 1x1 transparent black 
 PASS Object ImageData object, ImageData 1x1 non-transparent non-black 
+TIMEOUT ImageBitmap 1x1 transparent black Test timed out
+TIMEOUT ImageBitmap 1x1 non-transparent non-black Test timed out
+TIMEOUT Array ImageBitmap object, ImageBitmap 1x1 transparent black Test timed out
+TIMEOUT Array ImageBitmap object, ImageBitmap 1x1 non-transparent non-black Test timed out
+TIMEOUT Object ImageBitmap object, ImageBitmap 1x1 transparent black Test timed out
+TIMEOUT Object ImageBitmap object, ImageBitmap 1x1 non-transparent non-black Test timed out
 PASS Array sparse 
 PASS Array with non-index property 
 PASS Object with index property and length 
@@ -106,12 +114,4 @@
 PASS Object with non-enumerable property 
 PASS Object with non-writable property 
 PASS Object with non-configurable property 
-FAIL ImageBitmap 1x1 transparent black promise_test: Unhandled rejection with value: object "TypeError: Type error"
-FAIL ImageBitmap 1x1 non-transparent non-black promise_test: Unhandled rejection with value: object "TypeError: Type error"
-FAIL Array ImageBitmap object, ImageBitmap 1x1 transparent black promise_test: Unhandled rejection with value: object "TypeError: Type error"
-FAIL Array ImageBitmap object, ImageBitmap 1x1 transparent non-black promise_test: Unhandled rejection with value: object "TypeError: Type error"
-FAIL Object ImageBitmap object, ImageBitmap 1x1 transparent black promise_test: Unhandled rejection with value: object "TypeError: Type error"
-FAIL Object ImageBitmap object, ImageBitmap 1x1 transparent non-black promise_test: Unhandled rejection with value: object "TypeError: Type error"
-PASS ArrayBuffer 
-PASS MessagePort 
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/structured-clone/dedicated.html (232036 => 232037)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/structured-clone/dedicated.html	2018-05-21 23:34:15 UTC (rev 232036)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/structured-clone/dedicated.html	2018-05-21 23:42:21 UTC (rev 232037)
@@ -2,31 +2,8 @@
 <title>structured clone to dedicated worker</title>
 <script src=""
 <script src=""
-<script src=""
-<script src=""
-<script src=""
 <div id=log></div>
 <script>
-  runStructuredCloneBatteryOfTests({
-    setup() {
-      const blob = new Blob([`
-        _onmessage_ = ev => postMessage(ev.data, ev.data.transfer);
-      `], {type: 'text/_javascript_'});
-      this.blobURL = URL.createObjectURL(blob);
-      this.worker = new Worker(this.blobURL);
-    },
-    structuredClone(data, transfer) {
-      return new Promise(resolve => {
-        this.worker.addEventListener('message', function f(ev) {
-          this.worker.removeEventListener('message', f);
-          resolve(ev.data.data);
-        }.bind(this));
-        this.worker.postMessage({data, transfer}, transfer);
-      });
-    },
-    teardown() {
-      this.worker.terminate();
-      URL.revokeObjectURL(this.blobURL);
-    }
-  });
+var type = 'dedicated';
 </script>
+<script src=""

Added: trunk/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/structured-clone/dedicated.js (0 => 232037)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/structured-clone/dedicated.js	                        (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/structured-clone/dedicated.js	2018-05-21 23:42:21 UTC (rev 232037)
@@ -0,0 +1,4 @@
+importScripts('worker-common.js');
+_onmessage_ = function(ev) {
+  check(ev.data, self);
+};

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/structured-clone/shared-expected.txt (232036 => 232037)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/structured-clone/shared-expected.txt	2018-05-21 23:34:15 UTC (rev 232036)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/structured-clone/shared-expected.txt	2018-05-21 23:42:21 UTC (rev 232037)
@@ -1,4 +1,117 @@
-CONSOLE MESSAGE: line 19: ReferenceError: Can't find variable: SharedWorker
 
-FAIL structured clone to shared worker ReferenceError: Can't find variable: SharedWorker
+Harness Error (TIMEOUT), message = null
 
+FAIL primitive undefined Can't find variable: SharedWorker
+FAIL primitive null Can't find variable: SharedWorker
+FAIL primitive true Can't find variable: SharedWorker
+FAIL primitive false Can't find variable: SharedWorker
+FAIL primitive string, empty string Can't find variable: SharedWorker
+FAIL primitive string, lone high surrogate Can't find variable: SharedWorker
+FAIL primitive string, lone low surrogate Can't find variable: SharedWorker
+FAIL primitive string, NUL Can't find variable: SharedWorker
+FAIL primitive string, astral character Can't find variable: SharedWorker
+FAIL primitive number, 0.2 Can't find variable: SharedWorker
+FAIL primitive number, 0 Can't find variable: SharedWorker
+FAIL primitive number, -0 Can't find variable: SharedWorker
+FAIL primitive number, NaN Can't find variable: SharedWorker
+FAIL primitive number, Infinity Can't find variable: SharedWorker
+FAIL primitive number, -Infinity Can't find variable: SharedWorker
+FAIL primitive number, 9007199254740992 Can't find variable: SharedWorker
+FAIL primitive number, -9007199254740992 Can't find variable: SharedWorker
+FAIL primitive number, 9007199254740994 Can't find variable: SharedWorker
+FAIL primitive number, -9007199254740994 Can't find variable: SharedWorker
+FAIL Array primitives Can't find variable: SharedWorker
+FAIL Object primitives Can't find variable: SharedWorker
+FAIL Boolean true Can't find variable: SharedWorker
+FAIL Boolean false Can't find variable: SharedWorker
+FAIL Array Boolean objects Can't find variable: SharedWorker
+FAIL Object Boolean objects Can't find variable: SharedWorker
+FAIL String empty string Can't find variable: SharedWorker
+FAIL String lone high surrogate Can't find variable: SharedWorker
+FAIL String lone low surrogate Can't find variable: SharedWorker
+FAIL String NUL Can't find variable: SharedWorker
+FAIL String astral character Can't find variable: SharedWorker
+FAIL Array String objects Can't find variable: SharedWorker
+FAIL Object String objects Can't find variable: SharedWorker
+FAIL Number 0.2 Can't find variable: SharedWorker
+FAIL Number 0 Can't find variable: SharedWorker
+FAIL Number -0 Can't find variable: SharedWorker
+FAIL Number NaN Can't find variable: SharedWorker
+FAIL Number Infinity Can't find variable: SharedWorker
+FAIL Number -Infinity Can't find variable: SharedWorker
+FAIL Number 9007199254740992 Can't find variable: SharedWorker
+FAIL Number -9007199254740992 Can't find variable: SharedWorker
+FAIL Number 9007199254740994 Can't find variable: SharedWorker
+FAIL Number -9007199254740994 Can't find variable: SharedWorker
+FAIL Array Number objects Can't find variable: SharedWorker
+FAIL Object Number objects Can't find variable: SharedWorker
+FAIL Date 0 Can't find variable: SharedWorker
+FAIL Date -0 Can't find variable: SharedWorker
+FAIL Date -8.64e15 Can't find variable: SharedWorker
+FAIL Date 8.64e15 Can't find variable: SharedWorker
+FAIL Array Date objects Can't find variable: SharedWorker
+FAIL Object Date objects Can't find variable: SharedWorker
+FAIL RegExp flags and lastIndex Can't find variable: SharedWorker
+FAIL RegExp sticky flag Can't find variable: SharedWorker
+FAIL RegExp unicode flag Can't find variable: SharedWorker
+FAIL RegExp empty Can't find variable: SharedWorker
+FAIL RegExp slash Can't find variable: SharedWorker
+FAIL RegExp new line Can't find variable: SharedWorker
+FAIL Array RegExp object, RegExp flags and lastIndex Can't find variable: SharedWorker
+FAIL Array RegExp object, RegExp sticky flag Can't find variable: SharedWorker
+FAIL Array RegExp object, RegExp unicode flag Can't find variable: SharedWorker
+FAIL Array RegExp object, RegExp empty Can't find variable: SharedWorker
+FAIL Array RegExp object, RegExp slash Can't find variable: SharedWorker
+FAIL Array RegExp object, RegExp new line Can't find variable: SharedWorker
+FAIL Object RegExp object, RegExp flags and lastIndex Can't find variable: SharedWorker
+FAIL Object RegExp object, RegExp sticky flag Can't find variable: SharedWorker
+FAIL Object RegExp object, RegExp unicode flag Can't find variable: SharedWorker
+FAIL Object RegExp object, RegExp empty Can't find variable: SharedWorker
+FAIL Object RegExp object, RegExp slash Can't find variable: SharedWorker
+FAIL Object RegExp object, RegExp new line Can't find variable: SharedWorker
+FAIL Blob basic Can't find variable: SharedWorker
+FAIL Blob unpaired high surrogate (invalid utf-8) Can't find variable: SharedWorker
+FAIL Blob unpaired low surrogate (invalid utf-8) Can't find variable: SharedWorker
+FAIL Blob paired surrogates (invalid utf-8) Can't find variable: SharedWorker
+FAIL Blob empty Can't find variable: SharedWorker
+FAIL Blob NUL Can't find variable: SharedWorker
+FAIL Array Blob object, Blob basic Can't find variable: SharedWorker
+FAIL Array Blob object, Blob unpaired high surrogate (invalid utf-8) Can't find variable: SharedWorker
+FAIL Array Blob object, Blob unpaired low surrogate (invalid utf-8) Can't find variable: SharedWorker
+FAIL Array Blob object, Blob paired surrogates (invalid utf-8) Can't find variable: SharedWorker
+FAIL Array Blob object, Blob empty Can't find variable: SharedWorker
+FAIL Array Blob object, Blob NUL Can't find variable: SharedWorker
+FAIL Object Blob object, Blob basic Can't find variable: SharedWorker
+FAIL Object Blob object, Blob unpaired high surrogate (invalid utf-8) Can't find variable: SharedWorker
+FAIL Object Blob object, Blob unpaired low surrogate (invalid utf-8) Can't find variable: SharedWorker
+FAIL Object Blob object, Blob paired surrogates (invalid utf-8) Can't find variable: SharedWorker
+FAIL Object Blob object, Blob empty Can't find variable: SharedWorker
+FAIL Object Blob object, Blob NUL Can't find variable: SharedWorker
+FAIL File basic Can't find variable: SharedWorker
+FAIL FileList empty Can't find variable: SharedWorker
+FAIL Array FileList object, FileList empty Can't find variable: SharedWorker
+FAIL Object FileList object, FileList empty Can't find variable: SharedWorker
+FAIL ImageData 1x1 transparent black Can't find variable: SharedWorker
+FAIL ImageData 1x1 non-transparent non-black Can't find variable: SharedWorker
+FAIL Array ImageData object, ImageData 1x1 transparent black Can't find variable: SharedWorker
+FAIL Array ImageData object, ImageData 1x1 non-transparent non-black Can't find variable: SharedWorker
+FAIL Object ImageData object, ImageData 1x1 transparent black Can't find variable: SharedWorker
+FAIL Object ImageData object, ImageData 1x1 non-transparent non-black Can't find variable: SharedWorker
+TIMEOUT ImageBitmap 1x1 transparent black Test timed out
+TIMEOUT ImageBitmap 1x1 non-transparent non-black Test timed out
+TIMEOUT Array ImageBitmap object, ImageBitmap 1x1 transparent black Test timed out
+TIMEOUT Array ImageBitmap object, ImageBitmap 1x1 non-transparent non-black Test timed out
+TIMEOUT Object ImageBitmap object, ImageBitmap 1x1 transparent black Test timed out
+TIMEOUT Object ImageBitmap object, ImageBitmap 1x1 non-transparent non-black Test timed out
+FAIL Array sparse Can't find variable: SharedWorker
+FAIL Array with non-index property Can't find variable: SharedWorker
+FAIL Object with index property and length Can't find variable: SharedWorker
+FAIL Array with circular reference Can't find variable: SharedWorker
+FAIL Object with circular reference Can't find variable: SharedWorker
+FAIL Array with identical property values Can't find variable: SharedWorker
+FAIL Object with identical property values Can't find variable: SharedWorker
+FAIL Object with property on prototype Can't find variable: SharedWorker
+FAIL Object with non-enumerable property Can't find variable: SharedWorker
+FAIL Object with non-writable property Can't find variable: SharedWorker
+FAIL Object with non-configurable property Can't find variable: SharedWorker
+

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/structured-clone/shared.html (232036 => 232037)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/structured-clone/shared.html	2018-05-21 23:34:15 UTC (rev 232036)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/structured-clone/shared.html	2018-05-21 23:42:21 UTC (rev 232037)
@@ -2,35 +2,8 @@
 <title>structured clone to shared worker</title>
 <script src=""
 <script src=""
-<script src=""
-<script src=""
-<script src=""
 <div id=log></div>
 <script>
-  runStructuredCloneBatteryOfTests({
-    setup() {
-      const blob = new Blob([`
-        _onconnect_ = ev => {
-          const port = ev.ports[0];
-          port._onmessage_ = ev => port.postMessage(ev.data, ev.data.transfer);
-        };
-      `], {type: 'text/_javascript_'});
-      this.blobURL = URL.createObjectURL(blob);
-      this.worker = new SharedWorker(this.blobURL);
-      this.port = this.worker.port;
-    },
-    structuredClone(data, transfer) {
-      return new Promise(resolve => {
-        this.port.addEventListener('message', function f(ev) {
-          this.port.removeEventListener('message', f);
-          resolve(ev.data.data);
-        }.bind(this));
-        this.port.start();
-        this.port.postMessage({data, transfer}, transfer);
-      });
-    },
-    teardown() {
-      URL.revokeObjectURL(this.blobURL);
-    }
-  });
+var type = 'shared';
 </script>
+<script src=""

Added: trunk/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/structured-clone/shared.js (0 => 232037)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/structured-clone/shared.js	                        (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/structured-clone/shared.js	2018-05-21 23:42:21 UTC (rev 232037)
@@ -0,0 +1,6 @@
+importScripts('worker-common.js');
+_onconnect_ = function(connect_ev) {
+  connect_ev.ports[0]._onmessage_ = function(message_ev) {
+    check(message_ev.data, this);
+  };
+};

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/structured-clone/w3c-import.log (232036 => 232037)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/structured-clone/w3c-import.log	2018-05-21 23:34:15 UTC (rev 232036)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/structured-clone/w3c-import.log	2018-05-21 23:42:21 UTC (rev 232037)
@@ -14,5 +14,9 @@
 None
 ------------------------------------------------------------------------
 List of files:
+/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/structured-clone/common.js
 /LayoutTests/imported/w3c/web-platform-tests/workers/semantics/structured-clone/dedicated.html
+/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/structured-clone/dedicated.js
 /LayoutTests/imported/w3c/web-platform-tests/workers/semantics/structured-clone/shared.html
+/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/structured-clone/shared.js
+/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/structured-clone/worker-common.js

Added: trunk/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/structured-clone/worker-common.js (0 => 232037)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/structured-clone/worker-common.js	                        (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/workers/semantics/structured-clone/worker-common.js	2018-05-21 23:42:21 UTC (rev 232037)
@@ -0,0 +1,1018 @@
+var msg = decodeURIComponent(location.hash.substr(1));
+
+var log = [];
+function check_true(actual, msg) {
+  if (actual !== true) {
+    log.push(msg);
+    return false;
+  }
+  return true;
+}
+
+function check_Blob(msg, input, port, expect_File, orig_input) {
+  expect_File = !!expect_File;
+  orig_input = orig_input || input;
+  try {
+    var expected;
+    switch (msg) {
+      case 'Blob basic':
+      case 'File basic':
+        expected = [0x66, 0x6F, 0x6F];
+        expected.type = 'text/x-bar';
+        if (expect_File) {
+          expected.name = 'bar';
+          expected.lastModified = 42;
+        }
+        break;
+      case 'Blob unpaired high surrogate (invalid utf-8)':
+        expected = [0xED, 0xA0, 0x80];
+        expected.type = '';
+        break;
+      case 'Blob unpaired low surrogate (invalid utf-8)':
+        expected = [0xED, 0xB0, 0x80];
+        expected.type = '';
+        break;
+      case 'Blob paired surrogates (invalid utf-8)':
+        expected = [0xED, 0xA0, 0x80, 0xED, 0xB0, 0x80];
+        expected.type = '';
+        break;
+      case 'Blob empty':
+        expected = [];
+        expected.type = '';
+        break;
+      case 'Blob NUL':
+        var expected = [0x00];
+        expected.type = '';
+        break;
+      default:
+        check_true(false, 'check_Blob: unknown test');
+        return;
+        break;
+    }
+    if (check_true(input instanceof Blob, 'input instanceof Blob') &&
+        check_true((input instanceof File) == expect_File, '(input instanceof File) == expect_File') &&
+        check_true(input.size === expected.length, 'input.size === expected.length') &&
+        check_true(input.type === expected.type, 'input.type === expected.type')) {
+      if (!expect_File || (check_true(input.name === expected.name, 'input.name === expected.name') &&
+                           check_true(input.lastModified === expected.lastModified))) {
+        var reader = new FileReader();
+        var read_done = function() {
+          try {
+            var result = reader.result;
+            check_true(result.byteLength === expected.length, 'result.byteLength === expected.length')
+            var view = new DataView(result);
+            for (var i = 0; i < result.byteLength; ++i) {
+              check_true(view.getUint8(i) === expected[i], 'view.getUint8('+i+') === expected['+i+']')
+            }
+            if (log.length === 0) {
+              port.postMessage(orig_input);
+            } else {
+              port.postMessage('FAIL '+log);
+            }
+            close();
+          } catch(ex) {
+            postMessage('FAIL '+ex);
+            close();
+          }
+        }
+        var read_error = function() { port.postMessage('FAIL (got FileReader error)'); close(); };
+        reader.readAsArrayBuffer(input);
+        reader._onload_ = read_done;
+        reader._onabort_ = reader._onerror_ = read_error;
+      }
+    } else {
+      port.postMessage('FAIL '+log);
+      close();
+    }
+  } catch(ex) {
+    postMessage('FAIL '+ex);
+    close();
+  }
+}
+
+function check_ImageData(input, expected) {
+  if (check_true(input instanceof ImageData, 'input instanceof ImageData') &&
+      check_true(input.width === expected.width, 'input.width === '+expected.width) &&
+      check_true(input.height === expected.height, 'input.height === '+expected.height) &&
+      check_true(input.data instanceof Uint8ClampedArray, 'input.data instanceof Uint8ClampedArray') &&
+      check_true(input.data.length === expected.data.length, 'input.data.length === '+expected.data.length) &&
+      check_true(!('CanvasPixelArray' in self), "!('CanvasPixelArray' in self)")) {
+    for (var i = 0; i < input.length; ++i) {
+      if (!(check_true(input.data[i] === expected.data[i], 'input.data['+i+'] === '+expected.data[i]))) {
+        return false;
+      }
+    }
+    return true;
+  }
+  return false;
+}
+
+function check_ImageBitmap(input, expected) {
+  return check_true(input instanceof ImageBitmap, 'input instanceof ImageBitmap');
+  // XXX paint it on a proxy canvas and check the data
+}
+
+function check_RegExp(msg, input) {
+  // XXX ES6 spec doesn't define exact serialization for `source` (it allows several ways to escape)
+  switch (msg) {
+    case 'RegExp flags and lastIndex':
+      return check_true(input instanceof RegExp, "input instanceof RegExp") &&
+             check_true(input.source === 'foo', "input.source === 'foo'") &&
+             check_true(input.global === true, "input.global === true") &&
+             check_true(input.ignoreCase === true, "input.ignoreCase === true") &&
+             check_true(input.multiline === true, "input.multiline === true") &&
+             check_true(input.lastIndex === 0, "input.lastIndex === 0");
+      break;
+    case 'RegExp sticky flag':
+      return check_true(input instanceof RegExp, "input instanceof RegExp") &&
+             check_true(input.source === 'foo', "input.source === 'foo'") &&
+             check_true(input.global === false, "input.global === false") &&
+             check_true(input.ignoreCase === false, "input.ignoreCase === false") &&
+             check_true(input.multiline === false, "input.multiline === false") &&
+             check_true(input.sticky === true, "input.sticky === true") &&
+             check_true(input.unicode === false, "input.unicode === false") &&
+             check_true(input.lastIndex === 0, "input.lastIndex === 0");
+      break;
+    case 'RegExp unicode flag':
+      return check_true(input instanceof RegExp, "input instanceof RegExp") &&
+             check_true(input.source === 'foo', "input.source === 'foo'") &&
+             check_true(input.global === false, "input.global === false") &&
+             check_true(input.ignoreCase === false, "input.ignoreCase === false") &&
+             check_true(input.multiline === false, "input.multiline === false") &&
+             check_true(input.sticky === false, "input.sticky === false") &&
+             check_true(input.unicode === true, "input.unicode === true") &&
+             check_true(input.lastIndex === 0, "input.lastIndex === 0");
+      break;
+    case 'RegExp empty':
+      return check_true(input instanceof RegExp, "input instanceof RegExp") &&
+             check_true(input.source === '(?:)', "input.source === '(?:)'") &&
+             check_true(input.global === false, "input.global === false") &&
+             check_true(input.ignoreCase === false, "input.ignoreCase === false") &&
+             check_true(input.multiline === false, "input.multiline === false") &&
+             check_true(input.lastIndex === 0, "input.lastIndex === 0");
+      break;
+    case 'RegExp slash':
+      return check_true(input instanceof RegExp, "input instanceof RegExp") &&
+             check_true(input.source === '\\/', "input.source === '\\\\/'") &&
+             check_true(input.global === false, "input.global === false") &&
+             check_true(input.ignoreCase === false, "input.ignoreCase === false") &&
+             check_true(input.multiline === false, "input.multiline === false") &&
+             check_true(input.lastIndex === 0, "input.lastIndex === 0");
+      break;
+    case 'RegExp new line':
+      return check_true(input instanceof RegExp, "input instanceof RegExp") &&
+             check_true(input.source === '\\n', "input.source === '\\\\n'") &&
+             check_true(input.global === false, "input.global === false") &&
+             check_true(input.ignoreCase === false, "input.ignoreCase === false") &&
+             check_true(input.multiline === false, "input.multiline === false") &&
+             check_true(input.lastIndex === 0, "input.lastIndex === 0");
+      break;
+    default:
+      check_true(false, 'check_RegExp: unknown test');
+      return false;
+      break;
+  }
+}
+
+function check_FileList(msg, input) {
+  try {
+    return check_true(input instanceof FileList, 'input instanceof FileList') &&
+           check_true(input.length === 0, 'input.length === 0');
+  } catch(ex) {
+    return check_true(false, ex);
+  }
+}
+
+function check(input, port) {
+  try {
+    switch (msg) {
+      case 'primitive undefined':
+        if (check_true(input === undefined, 'input === undefined')) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'primitive null':
+        if (check_true(input === null, 'input === null')) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'primitive true':
+        if (check_true(input === true, 'input === true')) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'primitive false':
+        if (check_true(input === false, 'input === false')) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'primitive string, empty string':
+        if (check_true(input === '', "input === ''")) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'primitive string, lone high surrogate':
+        if (check_true(input === '\uD800', "input === '\uD800'")) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'primitive string, lone low surrogate':
+        if (check_true(input === '\uDC00', "input === '\uDC00'")) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'primitive string, NUL':
+        if (check_true(input === '\u0000', "input === '\u0000'")) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'primitive string, astral character':
+        if (check_true(input === '\uDBFF\uDFFD', "input === '\uDBFF\uDFFD'")) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'primitive number, 0.2':
+        if (check_true(input === 0.2, "input === 0.2")) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'primitive number, 0':
+        if (check_true(input === 0, "input === 0") &&
+            check_true(1/input === Infinity, "1/input === Infinity")) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'primitive number, -0':
+        if (check_true(input === 0, "input === 0") &&
+            check_true(1/input === -Infinity, "1/input === -Infinity")) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'primitive number, NaN':
+        if (check_true(input !== input, "input !== input")) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'primitive number, Infinity':
+        if (check_true(input === Infinity, "input === Infinity")) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'primitive number, -Infinity':
+        if (check_true(input === -Infinity, "input === -Infinity")) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'primitive number, 9007199254740992':
+        if (check_true(input === 9007199254740992, "input === 9007199254740992")) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'primitive number, -9007199254740992':
+        if (check_true(input === -9007199254740992, "input === -9007199254740992")) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'primitive number, 9007199254740994':
+        if (check_true(input === 9007199254740994, "input === 9007199254740994")) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'primitive number, -9007199254740994':
+        if (check_true(input === -9007199254740994, "input === -9007199254740994")) {
+          port.postMessage(input);
+          close();
+          break;
+        }
+      case 'Array primitives':
+        if (check_true(input instanceof Array, 'input instanceof Array') &&
+            check_true(input.length === 19, 'input.length === 19') &&
+            check_true(input[0] === undefined, 'input[0] === undefined') &&
+            check_true(input[1] === null, 'input[1] === null') &&
+            check_true(input[2] === true, 'input[2] === true') &&
+            check_true(input[3] === false, 'input[3] === false') &&
+            check_true(input[4] === '', "input[4] === ''") &&
+            check_true(input[5] === '\uD800', "input[5] === '\\uD800'") &&
+            check_true(input[6] === '\uDC00', "input[6] === '\\uDC00'") &&
+            check_true(input[7] === '\u0000', "input[7] === '\\u0000'") &&
+            check_true(input[8] === '\uDBFF\uDFFD', "input[8] === '\\uDBFF\\uDFFD'") &&
+            check_true(input[9] === 0.2, "input[9] === 0.2") &&
+            check_true(1/input[10] === Infinity, "1/input[10] === Infinity") &&
+            check_true(1/input[11] === -Infinity, "1/input[11] === -Infinity") &&
+            check_true(input[12] !== input[11], "input[12] !== input[11]") &&
+            check_true(input[13] === Infinity, "input[13] === Infinity") &&
+            check_true(input[14] === -Infinity, "input[14] === -Infinity") &&
+            check_true(input[15] === 9007199254740992, "input[15] === 9007199254740992") &&
+            check_true(input[16] === -9007199254740992, "input[16] === -9007199254740992") &&
+            check_true(input[17] === 9007199254740994, "input[17] === 9007199254740994") &&
+            check_true(input[18] === -9007199254740994, "input[18] === -9007199254740994")) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'Object primitives':
+        (function() {
+          if (check_true(input instanceof Object, 'input instanceof Object') &&
+              check_true(!(input instanceof Array), '!(input instanceof Array)') &&
+              check_true(input['undefined'] === undefined, "input['undefined'] === undefined") &&
+              check_true(input['null'] === null, "input['null'] === null") &&
+              check_true(input['true'] === true, "input['true'] === true") &&
+              check_true(input['false'] === false, "input['false'] === false") &&
+              check_true(input['empty'] === '', "input['empty'] === ''") &&
+              check_true(input['high surrogate'] === '\uD800', "input['high surrogate'] === '\uD800'") &&
+              check_true(input['low surrogate'] === '\uDC00', "input['low surrogate'] === '\uDC00'") &&
+              check_true(input['nul'] === '\u0000', "input['nul'] === '\u0000'") &&
+              check_true(input['astral'] === '\uDBFF\uDFFD', "input['astral'] === '\uDBFF\uDFFD'") &&
+              check_true(input['0.2'] === 0.2, "input['0.2'] === 0.2") &&
+              check_true(1/input['0'] === Infinity, "1/input['0'] === Infinity") &&
+              check_true(1/input['-0'] === -Infinity, "1/input['-0'] === -Infinity") &&
+              check_true(input['NaN'] !== input['NaN'], "input['NaN'] !== input['NaN']") &&
+              check_true(input['Infinity'] === Infinity, "input['Infinity'] === Infinity") &&
+              check_true(input['-Infinity'] === -Infinity, "input['-Infinity'] === -Infinity") &&
+              check_true(input['9007199254740992'] === 9007199254740992, "input['9007199254740992'] === 9007199254740992") &&
+              check_true(input['-9007199254740992'] === -9007199254740992, "input['-9007199254740992'] === -9007199254740992") &&
+              check_true(input['9007199254740994'] === 9007199254740994, "input['9007199254740994'] === 9007199254740994") &&
+              check_true(input['-9007199254740994'] === -9007199254740994, "input['9007199254740994'] === -9007199254740994")) {
+            var i = 0;
+            for (var x in input) {
+              i++;
+            }
+            if (check_true(i === 19, 'i === 19')) {
+              port.postMessage(input);
+              close();
+            }
+          }
+        })();
+        break;
+      case 'Boolean true':
+        if (check_true(input instanceof Boolean, "input instanceof Boolean") &&
+            check_true(String(input) === 'true', "String(input) === 'true'")) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'Boolean false':
+        if (check_true(input instanceof Boolean, "input instanceof Boolean") &&
+            check_true(String(input) === 'false', "String(input) === 'false'")) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'Array Boolean objects':
+        (function() {
+          if (check_true(input instanceof Array, 'input instanceof Array') &&
+              check_true(input.length === 2, 'input.length === 2') &&
+              check_true(String(input[0]) === 'true', "String(input[0]) === 'true'") &&
+              check_true(String(input[1]) === 'false', "String(input[1]) === 'false'")) {
+            for (var i = 0; i < input.length; ++i) {
+              if (!check_true(input[i] instanceof Boolean, 'input['+i+'] instanceof Boolean'))
+                return;
+            }
+            port.postMessage(input);
+            close();
+          }
+        })();
+        break;
+      case 'Object Boolean objects':
+        (function() {
+          if (check_true(input instanceof Object, 'input instanceof Object') &&
+              check_true(!(input instanceof Array), '!(input instanceof Array)') &&
+              check_true(String(input['true']) === 'true', "String(input['true']) === 'true'") &&
+              check_true(String(input['false']) === 'false', "String(input['false']) === 'false'")) {
+            var i = 0;
+            for (var x in input) {
+              i++;
+              if (!check_true(input[x] instanceof Boolean, 'input['+x+'] instanceof Boolean'))
+                return;
+            }
+            if (check_true(i === 2, 'i === 2')) {
+              port.postMessage(input);
+              close();
+            }
+          }
+        })();
+        break;
+      case 'String empty string':
+        if (check_true(input instanceof String, "input instanceof String") &&
+            check_true(String(input) === '', "String(input) === ''")) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'String lone high surrogate':
+        if (check_true(input instanceof String, "input instanceof String") &&
+            check_true(String(input) === '\uD800', "String(input) === '\\uD800'")) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'String lone low surrogate':
+        if (check_true(input instanceof String, "input instanceof String") &&
+            check_true(String(input) === '\uDC00', "String(input) === '\\uDC00'")) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'String NUL':
+        if (check_true(input instanceof String, "input instanceof String") &&
+            check_true(String(input) === '\u0000', "String(input) === '\\u0000'")) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'String astral character':
+        if (check_true(input instanceof String, "input instanceof String") &&
+            check_true(String(input) === '\uDBFF\uDFFD', "String(input) === '\\uDBFF\\uDFFD'")) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'Array String objects':
+        (function() {
+          if (check_true(input instanceof Array, 'input instanceof Array') &&
+              check_true(input.length === 5, 'input.length === 5') &&
+              check_true(String(input[0]) === '', "String(input[0]) === ''") &&
+              check_true(String(input[1]) === '\uD800', "String(input[1]) === '\\uD800'") &&
+              check_true(String(input[2]) === '\uDC00', "String(input[1]) === '\\uDC00'") &&
+              check_true(String(input[3]) === '\u0000', "String(input[2]) === '\\u0000'") &&
+              check_true(String(input[4]) === '\uDBFF\uDFFD', "String(input[3]) === '\\uDBFF\\uDFFD'")) {
+            for (var i = 0; i < input.length; ++i) {
+              if (!check_true(input[i] instanceof String, 'input['+i+'] instanceof String'))
+                return;
+            }
+            port.postMessage(input);
+            close();
+          }
+        })();
+        break;
+      case 'Object String objects':
+        (function() {
+          if (check_true(input instanceof Object, 'input instanceof Object') &&
+              check_true(!(input instanceof Array), '!(input instanceof Array)') &&
+              check_true(String(input['empty']) === '', "String(input['empty']) === ''") &&
+              check_true(String(input['high surrogate']) === '\uD800', "String(input['high surrogate']) === '\\uD800'") &&
+              check_true(String(input['low surrogate']) === '\uDC00', "String(input['low surrogate']) === '\\uDC00'") &&
+              check_true(String(input['nul']) === '\u0000', "String(input['nul']) === '\\u0000'") &&
+              check_true(String(input['astral']) === '\uDBFF\uDFFD', "String(input['astral']) === '\\uDBFF\\uDFFD'")) {
+            var i = 0;
+            for (var x in input) {
+              i++;
+              if (!check_true(input[x] instanceof String, 'input['+x+'] instanceof Boolean'))
+                return;
+            }
+            if (check_true(i === 5, 'i === 5')) {
+              port.postMessage(input);
+              close();
+            }
+          }
+        })();
+        break;
+      case 'Number 0.2':
+        if (check_true(input instanceof Number, "input instanceof Number") &&
+            check_true(Number(input) === 0.2, "Number(input) === 0.2")) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'Number 0':
+        if (check_true(input instanceof Number, "input instanceof Number") &&
+            check_true(1/Number(input) === Infinity, "1/Number(input) === Infinity")) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'Number -0':
+        if (check_true(input instanceof Number, "input instanceof Number") &&
+            check_true(1/Number(input) === -Infinity, "1/Number(input) === -Infinity")) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'Number NaN':
+        if (check_true(input instanceof Number, "input instanceof Number") &&
+            check_true(Number(input) !== Number(input), "Number(input) !== Number(input)")) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'Number Infinity':
+        if (check_true(input instanceof Number, "input instanceof Number") &&
+            check_true(Number(input) === Infinity, "Number(input) === Infinity")) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'Number -Infinity':
+        if (check_true(input instanceof Number, "input instanceof Number") &&
+            check_true(Number(input) === -Infinity, "Number(input) === -Infinity")) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'Number 9007199254740992':
+        if (check_true(input instanceof Number) &&
+            check_true(Number(input) === 9007199254740992, "Number(input) === 9007199254740992")) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'Number -9007199254740992':
+        if (check_true(input instanceof Number, "input instanceof Number") &&
+            check_true(Number(input) === -9007199254740992, "Number(input) === -9007199254740992")) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'Number 9007199254740994':
+        if (check_true(input instanceof Number, "input instanceof Number") &&
+            check_true(Number(input) === 9007199254740994, "Number(input) === 9007199254740994")) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'Number -9007199254740994':
+        if (check_true(input instanceof Number, "input instanceof Number") &&
+            check_true(Number(input) === -9007199254740994, "Number(input) === -9007199254740994")) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'Array Number objects':
+        (function() {
+          if (check_true(input instanceof Array, 'input instanceof Array') &&
+              check_true(input.length === 10, 'input.length === 10') &&
+              check_true(Number(input[0]) === 0.2, "Number(input[0]) === 0.2") &&
+              check_true(1/Number(input[1]) === Infinity, "1/Number(input[1]) === Infinity") &&
+              check_true(1/Number(input[2]) === -Infinity, "1/Number(input[2]) === -Infinity") &&
+              check_true(Number(input[3]) !== Number(input[3]), "Number(input[3]) !== Number(input[3])") &&
+              check_true(Number(input[4]) === Infinity, "Number(input[4]) === Infinity") &&
+              check_true(Number(input[5]) === -Infinity, "Number(input[5]) === -Infinity") &&
+              check_true(Number(input[6]) === 9007199254740992, "Number(input[6]) === 9007199254740992") &&
+              check_true(Number(input[7]) === -9007199254740992, "Number(input[7]) === -9007199254740992") &&
+              check_true(Number(input[8]) === 9007199254740994, "Number(input[8]) === 9007199254740994") &&
+              check_true(Number(input[9]) === -9007199254740994, "Number(input[9]) === -9007199254740994")) {
+            for (var i = 0; i < input.length; ++i) {
+              if (!check_true(input[i] instanceof Number, 'input['+i+'] instanceof Number'))
+                return;
+            }
+            port.postMessage(input);
+            close();
+          }
+        })();
+        break;
+      case 'Object Number objects':
+        (function() {
+          if (check_true(input instanceof Object, 'input instanceof Object') &&
+              check_true(!(input instanceof Array), '!(input instanceof Array)') &&
+              check_true(Number(input['0.2']) === 0.2, "Number(input['0.2']) === 0.2") &&
+              check_true(1/Number(input['0']) === Infinity, "1/Number(input['0']) === Infinity") &&
+              check_true(1/Number(input['-0']) === -Infinity, "1/Number(input['-0']) === -Infinity") &&
+              check_true(Number(input['NaN']) !== Number(input['NaN']), "Number(input['NaN']) !== Number(input['NaN'])") &&
+              check_true(Number(input['Infinity']) === Infinity, "Number(input['Infinity']) === Infinity") &&
+              check_true(Number(input['-Infinity']) === -Infinity, "Number(input['-Infinity']) === -Infinity") &&
+              check_true(Number(input['9007199254740992']) === 9007199254740992, "Number(input['9007199254740992']) === 9007199254740992") &&
+              check_true(Number(input['-9007199254740992']) === -9007199254740992, "Number(input['-9007199254740992']) === -9007199254740992") &&
+              check_true(Number(input['9007199254740994']) === 9007199254740994, "Number(input['9007199254740994']) === 9007199254740994") &&
+              check_true(Number(input['-9007199254740994']) === -9007199254740994, "Number(input['-9007199254740994']) === -9007199254740994")) {
+            var i = 0;
+            for (var x in input) {
+              i++;
+              if (!check_true(input[x] instanceof Number, 'input['+x+'] instanceof Number'))
+                return;
+            }
+            if (check_true(i === 10, 'i === 10')) {
+              port.postMessage(input);
+              close();
+            }
+          }
+        })();
+        break;
+      case 'Date 0':
+        if (check_true(input instanceof Date, "input instanceof Date") &&
+            check_true(1/Number(input) === 1/Number(new Date(0)), "1/Number(input) === 1/Number(new Date(0))")) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'Date -0':
+        if (check_true(input instanceof Date, "input instanceof Date") &&
+            check_true(1/Number(input) === 1/Number(new Date(-0)), "1/Number(input) === 1/Number(new Date(-0))")) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'Date -8.64e15':
+        if (check_true(input instanceof Date, "input instanceof Date") &&
+            check_true(Number(input) === -8.64e15, "Number(input) === -8.64e15")) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'Date 8.64e15':
+        if (check_true(input instanceof Date, "input instanceof Date") &&
+            check_true(Number(input) === 8.64e15, "Number(input) === 8.64e15")) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'Array Date objects':
+        (function() {
+          if (check_true(input instanceof Array, 'input instanceof Array') &&
+              check_true(input.length === 4, 'input.length === 4') &&
+              check_true(1/Number(input[0]) === 1/new Date(0), '1/Number(input[0]) === 1/new Date(0)') &&
+              check_true(1/Number(input[1]) === 1/new Date(-0), '1/Number(input[1]) === 1/new Date(-0)') &&
+              check_true(Number(input[2]) === -8.64e15, 'Number(input[2]) === -8.64e15') &&
+              check_true(Number(input[3]) === 8.64e15, 'Number(input[3]) === 8.64e15')) {
+            for (var i = 0; i < input.length; ++i) {
+              if (!check_true(input[i] instanceof Date, 'input['+i+'] instanceof Date'))
+                return;
+            }
+            port.postMessage(input);
+            close();
+          }
+        })();
+        break;
+      case 'Object Date objects':
+        (function() {
+          if (check_true(input instanceof Object, 'input instanceof Object') &&
+              check_true(!(input instanceof Array), '!(input instanceof Array)') &&
+              check_true(1/Number(input['0']) === 1/new Date(0), "1/Number(input['0']) === 1/new Date(0)") &&
+              check_true(1/Number(input['-0']) === 1/new Date(-0), "1/Number(input[1]) === 1/new Date(-0)") &&
+              check_true(Number(input['-8.64e15']) === -8.64e15, "Number(input['-8.64e15']) === -8.64e15") &&
+              check_true(Number(input['8.64e15']) === 8.64e15, "Number(input['8.64e15']) === 8.64e15")) {
+            var i = 0;
+            for (var x in input) {
+              i++;
+              if (!check_true(input[x] instanceof Date, 'input['+x+'] instanceof Date'))
+                return;
+            }
+            port.postMessage(input);
+            close();
+          }
+        })();
+        break;
+      case 'RegExp flags and lastIndex':
+      case 'RegExp empty':
+      case 'RegExp slash':
+      case 'RegExp new line':
+        if (check_RegExp(msg, input)) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'Array RegExp object, RegExp flags and lastIndex':
+      case 'Array RegExp object, RegExp empty':
+      case 'Array RegExp object, RegExp slash':
+      case 'Array RegExp object, RegExp new line':
+        if (check_true(input instanceof Array, 'input instanceof Array') &&
+            check_true(input.length === 1, 'input.length === 1') &&
+            check_RegExp(msg.substr('Array RegExp object, '.length), input[0])) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'Object RegExp object, RegExp flags and lastIndex':
+      case 'Object RegExp object, RegExp empty':
+      case 'Object RegExp object, RegExp slash':
+      case 'Object RegExp object, RegExp new line':
+        (function() {
+          if (check_true(input instanceof Object, 'input instanceof Object') &&
+              check_true(!(input instanceof Array), '!(input instanceof Array)') &&
+              check_RegExp(msg.substr('Object RegExp object, '.length), input['x'])) {
+            var i = 0;
+            for (var x in input) {
+              i++;
+            }
+            if (check_true(i === 1, 'i === 1')) {
+              port.postMessage(input);
+              close();
+            }
+          }
+        })();
+        break;
+      case 'Blob basic':
+      case 'Blob unpaired high surrogate (invalid utf-8)':
+      case 'Blob unpaired low surrogate (invalid utf-8)':
+      case 'Blob paired surrogates (invalid utf-8)':
+      case 'Blob empty':
+      case 'Blob NUL':
+        check_Blob(msg, input, port);
+        // no postMessage or close here, check_Blob takes care of that
+        break;
+      case 'Array Blob object, Blob basic':
+      case 'Array Blob object, Blob unpaired high surrogate (invalid utf-8)':
+      case 'Array Blob object, Blob unpaired low surrogate (invalid utf-8)':
+      case 'Array Blob object, Blob paired surrogates (invalid utf-8)':
+      case 'Array Blob object, Blob empty':
+      case 'Array Blob object, Blob NUL':
+        if (check_true(input instanceof Array, 'input instanceof Array') &&
+            check_true(input.length === 1, 'input.length === 1')) {
+          check_Blob(msg.substr('Array Blob object, '.length), input[0], port, false, input);
+          // no postMessage or close here, check_Blob takes care of that
+        }
+        break;
+      case 'Object Blob object, Blob basic':
+      case 'Object Blob object, Blob unpaired high surrogate (invalid utf-8)':
+      case 'Object Blob object, Blob unpaired low surrogate (invalid utf-8)':
+      case 'Object Blob object, Blob paired surrogates (invalid utf-8)':
+      case 'Object Blob object, Blob empty':
+      case 'Object Blob object, Blob NUL':
+        (function() {
+          if (check_true(input instanceof Object, 'input instanceof Object') &&
+              check_true(!(input instanceof Array), '!(input instanceof Array)')) {
+            var i = 0;
+            for (var x in input) {
+              i++;
+            }
+            if (check_true(i === 1, 'i === 1')) {
+              check_Blob(msg.substr('Object Blob object, '.length), input['x'], port, false, input);
+              // no postMessage or close here, check_Blob takes care of that
+            }
+          }
+        })();
+        break;
+      case 'File basic':
+        check_Blob(msg, input, port, true);
+        // no postMessage or close here, check_Blob takes care of that
+        break;
+      case 'FileList empty':
+        if (check_FileList(msg, input)) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'Array FileList object, FileList empty':
+        if (check_true(input instanceof Array, 'input instanceof Array') &&
+            check_true(input.length === 1, 'input.length === 1') &&
+            check_FileList(msg.substr('Array FileList object, '.length), input[0])) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'Object FileList object, FileList empty':
+        (function() {
+          if (check_true(input instanceof Object, 'input instanceof Object') &&
+              check_true(!(input instanceof Array), '!(input instanceof Array)') &&
+              check_FileList(msg.substr('Array FileList object, '.length), input['x'])) {
+            var i = 0;
+            for (var x in input) {
+              i++;
+            }
+            if (check_true(i === 1, 'i === 1')) {
+              port.postMessage(input);
+              close();
+            }
+          }
+        })();
+        break;
+      case 'ImageData 1x1 transparent black':
+        if (check_ImageData(input, {width:1, height:1, data:[0,0,0,0]})) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'ImageData 1x1 non-transparent non-black':
+        if (check_ImageData(input, {width:1, height:1, data:[100, 101, 102, 103]})) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'Array ImageData object, ImageData 1x1 transparent black':
+        if (check_true(input instanceof Array, 'input instanceof Array') &&
+            check_true(input.length === 1, 'input.length === 1') &&
+            check_ImageData(input[0], {width:1, height:1, data:[0,0,0,0]})) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'Array ImageData object, ImageData 1x1 non-transparent non-black':
+        if (check_true(input instanceof Array, 'input instanceof Array') &&
+            check_true(input.length === 1, 'input.length === 1') &&
+            check_ImageData(input[0], {width:1, height:1, data:[100, 101, 102, 103]})) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'Object ImageData object, ImageData 1x1 transparent black':
+        (function(){
+          if (check_true(input instanceof Object, 'input instanceof Object') &&
+              check_true(!(input instanceof Array), '!(input instanceof Array)') &&
+              check_ImageData(input['x'], {width:1, height:1, data:[0,0,0,0]})) {
+            var i = 0;
+            for (var x in input) {
+              i++;
+            }
+            if (check_true(i === 1, 'i === 1')) {
+              port.postMessage(input);
+              close();
+            }
+          }
+        })();
+        break;
+      case 'Object ImageData object, ImageData 1x1 non-transparent non-black':
+        (function() {
+          if (check_true(input instanceof Object, 'input instanceof Object') &&
+              check_true(!(input instanceof Array), '!(input instanceof Array)') &&
+              check_ImageData(input['x'], {width:1, height:1, data:[100, 101, 102, 103]})) {
+            var i = 0;
+            for (var x in input) {
+              i++;
+            }
+            if (check_true(i === 1, 'i === 1')) {
+              port.postMessage(input);
+              close();
+            }
+          }
+        })();
+        break;
+      case 'ImageBitmap 1x1 transparent black':
+        if (check_ImageBitmap(input, {width:1, height:1, data:[0, 0, 0, 0]})) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'ImageBitmap 1x1 non-transparent non-black':
+        if (check_ImageBitmap(input, {width:1, height:1, data:[100, 101, 102, 103]})) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'Array ImageBitmap object, ImageBitmap 1x1 transparent black':
+        if (check_true(input instanceof Array, 'input instanceof Array') &&
+            check_true(input.length === 1, 'input.length === 1') &&
+            check_ImageBitmap(input[0], {width:1, height:1, data:[0, 0, 0, 0]})) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'Array ImageBitmap object, ImageBitmap 1x1 non-transparent non-black':
+        if (check_true(input instanceof Array, 'input instanceof Array') &&
+            check_true(input.length === 1, 'input.length === 1') &&
+            check_ImageBitmap(input[0], {width:1, height:1, data:[100, 101, 102, 103]})) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'Object ImageBitmap object, ImageBitmap 1x1 transparent black':
+        (function() {
+          if (check_true(input instanceof Object, 'input instanceof Object') &&
+              check_true(!(input instanceof Array), '!(input instanceof Array)') &&
+              check_ImageBitmap(input['x'], {width:1, height:1, data:[0, 0, 0, 0]})) {
+            var i = 0;
+            for (var x in input) {
+              i++;
+            }
+            if (check_true(i === 1, 'i === 1')) {
+              port.postMessage(input);
+              close();
+            }
+          }
+        })();
+        break;
+      case 'Object ImageBitmap object, ImageBitmap 1x1 non-transparent non-black':
+        (function() {
+          if (check_true(input instanceof Object, 'input instanceof Object') &&
+              check_true(!(input instanceof Array), '!(input instanceof Array)') &&
+              check_ImageBitmap(input['x'], {width:1, height:1, data:[100, 101, 102, 103]})) {
+            var i = 0;
+            for (var x in input) {
+              i++;
+            }
+            if (check_true(i === 1, 'i === 1')) {
+              port.postMessage(input);
+              close();
+            }
+          }
+        })();
+        break;
+      case 'Array sparse':
+        (function() {
+          if (check_true(input instanceof Array, 'input instanceof Array') &&
+              check_true(input.length === 10, 'input.length === 10')) {
+            for (var x in input) {
+              check_true(false, 'unexpected enumerable property '+x);
+              return;
+            }
+            port.postMessage(input);
+            close();
+          }
+        })();
+        break;
+      case 'Array with non-index property':
+        if (check_true(input instanceof Array, 'input instanceof Array') &&
+            check_true(input.length === 0, 'input.length === 0') &&
+            check_true(input.foo === 'bar', "input.foo === 'bar'")) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'Object with index property and length':
+        if (check_true(input instanceof Object, 'input instanceof Object') &&
+            check_true(!(input instanceof Array), '!(input instanceof Array)') &&
+            check_true(input[0] === 'foo', "input[0] === 'foo'") &&
+            check_true(input.length === 1, 'input.length === 1')) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'Array with circular reference':
+        if (check_true(input instanceof Array, 'input instanceof Array') &&
+            check_true(input.length === 1, 'input.length === 1') &&
+            check_true(input[0] === input, "input[0] === input")) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'Object with circular reference':
+        if (check_true(input instanceof Object, 'input instanceof Object') &&
+            check_true(!(input instanceof Array), '!(input instanceof Array)') &&
+            check_true(input['x'] === input, "input['x'] === input")) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'Array with identical property values':
+        if (check_true(input instanceof Array, 'input instanceof Array') &&
+            check_true(input.length === 2, 'input.length === 2') &&
+            check_true(input[0] === input[1], "input[0] === input[1]")) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'Object with identical property values':
+        if (check_true(input instanceof Object, 'input instanceof Object') &&
+            check_true(!(input instanceof Array), '!(input instanceof Array)') &&
+            check_true(input['x'] === input['y'], "input['x'] === input['y']")) {
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'Object with property on prototype':
+      case 'Object with non-enumerable property':
+        if (check_true(input instanceof Object, 'input instanceof Object') &&
+            check_true(!(input instanceof Array), '!(input instanceof Array)') &&
+            check_true(!('foo' in input), "!('foo' in input)")) {
+          input = {};
+          Object.defineProperty(input, 'foo', {value:'bar', enumerable:false, writable:true, configurable:true});
+          port.postMessage(input);
+          close();
+        }
+        break;
+      case 'Object with non-writable property':
+        if (check_true(input instanceof Object, 'input instanceof Object') &&
+            check_true(!(input instanceof Array), '!(input instanceof Array)') &&
+            check_true(input.foo === 'bar', "input.foo === bar")) {
+          input.foo += ' baz';
+          if (check_true(input.foo === 'bar baz', "input.foo === 'bar baz'")) {
+            input = {};
+            Object.defineProperty(input, 'foo', {value:'bar', enumerable:true, writable:false, configurable:true});
+            port.postMessage(input);
+            close();
+          }
+        }
+        break;
+      case 'Object with non-configurable property':
+        if (check_true(input instanceof Object, 'input instanceof Object') &&
+            check_true(!(input instanceof Array), '!(input instanceof Array)') &&
+            check_true(input.foo === 'bar', "input.foo === bar")) {
+          delete input.foo;
+          if (check_true(!('foo' in input), "!('foo' in input)")) {
+            input = {};
+            Object.defineProperty(input, 'foo', {value:'bar', enumerable:true, writable:true, configurable:false});
+            port.postMessage(input);
+            close();
+          }
+        }
+        break;
+
+      default:
+        port.postMessage('FAIL: unknown test');
+        close();
+    }
+    if (log.length > 0) {
+      port.postMessage('FAIL '+log);
+      close();
+    }
+  } catch (ex) {
+    port.postMessage('FAIL '+ex);
+    close();
+  }
+}

Modified: trunk/Source/WebCore/ChangeLog (232036 => 232037)


--- trunk/Source/WebCore/ChangeLog	2018-05-21 23:34:15 UTC (rev 232036)
+++ trunk/Source/WebCore/ChangeLog	2018-05-21 23:42:21 UTC (rev 232037)
@@ -1,3 +1,19 @@
+2018-05-21  Commit Queue  <[email protected]>
+
+        Unreviewed, rolling out r232030.
+        https://bugs.webkit.org/show_bug.cgi?id=185850
+
+        "Caused
+        TestWebKitAPI.IndexedDB.StructuredCloneBackwardCompatibility
+        API test to fail" (Requested by cdumez on #webkit).
+
+        Reverted changeset:
+
+        "File's structured serialization should serialize lastModified
+        attribute"
+        https://bugs.webkit.org/show_bug.cgi?id=185773
+        https://trac.webkit.org/changeset/232030
+
 2018-05-21  Daniel Bates  <[email protected]>
 
         REGRESSION (r231107): CSP report-only policies are ignored for beacon, importScripts, fetch(), EventSource, and XHR

Modified: trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp (232036 => 232037)


--- trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp	2018-05-21 23:34:15 UTC (rev 232036)
+++ trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp	2018-05-21 23:42:21 UTC (rev 232037)
@@ -278,9 +278,8 @@
  * Version 4. added support for serializing non-index properties of arrays.
  * Version 5. added support for Map and Set types.
  * Version 6. added support for 8-bit strings.
- * Version 7. added support for File's lastModified attribute.
  */
-static const unsigned CurrentVersion = 7;
+static const unsigned CurrentVersion = 6;
 static const unsigned TerminatorTag = 0xFFFFFFFF;
 static const unsigned StringPoolTag = 0xFFFFFFFE;
 static const unsigned NonIndexPropertiesTag = 0xFFFFFFFD;
@@ -364,7 +363,7 @@
  *    FileTag FileData
  *
  * FileData :-
- *    <path:StringData> <url:StringData> <type:StringData> <name:StringData> <lastModified:double>
+ *    <path:StringData> <url:StringData> <type:StringData> <name:StringData>
  *
  * FileList :-
  *    FileListTag <length:uint32_t>(<file:FileData>){length}
@@ -1237,7 +1236,6 @@
         write(file.url());
         write(file.type());
         write(file.name());
-        write(static_cast<double>(file.lastModifiedOverride().value_or(-1)));
     }
 
 #if ENABLE(SUBTLE_CRYPTO)
@@ -2038,9 +2036,6 @@
         CachedStringRef name;
         if (!readStringData(name))
             return false;
-        double lastModified;
-        if (!read(lastModified))
-            return false;
 
         // If the blob URL for this file has an associated blob file path, prefer that one over the "built-in" path.
         String filePath = blobFilePathForBlobURL(url->string());
@@ -2048,7 +2043,7 @@
             filePath = path->string();
 
         if (m_isDOMGlobalObject)
-            file = File::deserialize(filePath, URL(URL(), url->string()), type->string(), name->string(), lastModified >= 0 ? std::make_optional<int64_t>(lastModified) : std::nullopt);
+            file = File::deserialize(filePath, URL(URL(), url->string()), type->string(), name->string());
         return true;
     }
 

Modified: trunk/Source/WebCore/fileapi/File.cpp (232036 => 232037)


--- trunk/Source/WebCore/fileapi/File.cpp	2018-05-21 23:34:15 UTC (rev 232036)
+++ trunk/Source/WebCore/fileapi/File.cpp	2018-05-21 23:42:21 UTC (rev 232037)
@@ -63,11 +63,10 @@
     ThreadableBlobRegistry::registerFileBlobURL(m_internalURL, path, m_type);
 }
 
-File::File(DeserializationContructor, const String& path, const URL& url, const String& type, const String& name, const std::optional<int64_t>& lastModified)
+File::File(DeserializationContructor, const String& path, const URL& url, const String& type, const String& name)
     : Blob(deserializationContructor, url, type, -1, path)
     , m_path(path)
     , m_name(name)
-    , m_lastModifiedDateOverride(lastModified)
 {
 }
 
@@ -81,7 +80,7 @@
 File::File(Vector<BlobPartVariant>&& blobPartVariants, const String& filename, const PropertyBag& propertyBag)
     : Blob(WTFMove(blobPartVariants), convertPropertyBag(propertyBag))
     , m_name(filename)
-    , m_lastModifiedDateOverride(propertyBag.lastModified.value_or(WallTime::now().secondsSinceEpoch().milliseconds()))
+    , m_overrideLastModifiedDate(propertyBag.lastModified.value_or(WallTime::now().secondsSinceEpoch().milliseconds()))
 {
 }
 
@@ -97,17 +96,17 @@
     , m_path(file.path())
     , m_relativePath(file.relativePath())
     , m_name(!name.isNull() ? name : file.name())
-    , m_lastModifiedDateOverride(file.m_lastModifiedDateOverride)
+    , m_overrideLastModifiedDate(file.m_overrideLastModifiedDate)
     , m_isDirectory(file.isDirectory())
 {
 }
 
-int64_t File::lastModified() const
+double File::lastModified() const
 {
-    if (m_lastModifiedDateOverride)
-        return m_lastModifiedDateOverride.value();
+    if (m_overrideLastModifiedDate)
+        return m_overrideLastModifiedDate.value();
 
-    int64_t result;
+    double result;
 
     // FIXME: This does sync-i/o on the main thread and also recalculates every time the method is called.
     // The i/o should be performed on a background thread,

Modified: trunk/Source/WebCore/fileapi/File.h (232036 => 232037)


--- trunk/Source/WebCore/fileapi/File.h	2018-05-21 23:34:15 UTC (rev 232036)
+++ trunk/Source/WebCore/fileapi/File.h	2018-05-21 23:42:21 UTC (rev 232037)
@@ -38,7 +38,7 @@
 class File final : public Blob {
 public:
     struct PropertyBag : BlobPropertyBag {
-        std::optional<int64_t> lastModified;
+        std::optional<long long> lastModified;
     };
 
     static Ref<File> create(const String& path)
@@ -52,9 +52,9 @@
         return adoptRef(*new File(WTFMove(blobPartVariants), filename, propertyBag));
     }
 
-    static Ref<File> deserialize(const String& path, const URL& srcURL, const String& type, const String& name, const std::optional<int64_t>& lastModified = std::nullopt)
+    static Ref<File> deserialize(const String& path, const URL& srcURL, const String& type, const String& name)
     {
-        return adoptRef(*new File(deserializationContructor, path, srcURL, type, name, lastModified));
+        return adoptRef(*new File(deserializationContructor, path, srcURL, type, name));
     }
 
     // Create a file with a name exposed to the author (via File.name and associated DOM properties) that differs from the one provided in the path.
@@ -83,8 +83,7 @@
     const String& relativePath() const { return m_relativePath; }
     void setRelativePath(const String& relativePath) { m_relativePath = relativePath; }
     const String& name() const { return m_name; }
-    WEBCORE_EXPORT int64_t lastModified() const; // Number of milliseconds since Epoch.
-    const std::optional<int64_t>& lastModifiedOverride() const { return m_lastModifiedDateOverride; } // Number of milliseconds since Epoch.
+    WEBCORE_EXPORT double lastModified() const;
 
     static String contentTypeForFile(const String& path);
 
@@ -101,7 +100,7 @@
     File(const Blob&, const String& name);
     File(const File&, const String& name);
 
-    File(DeserializationContructor, const String& path, const URL& srcURL, const String& type, const String& name, const std::optional<int64_t>& lastModified);
+    File(DeserializationContructor, const String& path, const URL& srcURL, const String& type, const String& name);
 
     static void computeNameAndContentType(const String& path, const String& nameOverride, String& effectiveName, String& effectiveContentType);
 #if ENABLE(FILE_REPLACEMENT)
@@ -112,7 +111,7 @@
     String m_relativePath;
     String m_name;
 
-    std::optional<int64_t> m_lastModifiedDateOverride;
+    std::optional<int64_t> m_overrideLastModifiedDate;
     mutable std::optional<bool> m_isDirectory;
 };
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to