Bug 1486000 - Extend wasm js-api tests; r=bbouvier
authorMs2ger <Ms2ger@igalia.com>
Thu, 30 Aug 2018 12:10:51 +0200
changeset 491843 18c0aff587fa935a8149f83d58664e77c35e598a
parent 491842 c8ef72fa7be8e4619eaaff709fb4c38525df6f05
child 491844 ce10788000f5738e176f486548e81c87d7a1c08f
push id1815
push userffxbld-merge
push dateMon, 15 Oct 2018 10:40:45 +0000
treeherdermozilla-release@18d4c09e9378 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbbouvier
bugs1486000
milestone63.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1486000 - Extend wasm js-api tests; r=bbouvier
testing/web-platform/meta/MANIFEST.json
testing/web-platform/meta/wasm/jsapi/global/constructor.any.js.ini
testing/web-platform/meta/wasm/jsapi/global/value-set.any.js.ini
testing/web-platform/meta/wasm/jsapi/memory/constructor.any.js.ini
testing/web-platform/meta/wasm/jsapi/memory/grow.any.js.ini
testing/web-platform/meta/wasm/jsapi/table/constructor.any.js.ini
testing/web-platform/meta/wasm/jsapi/table/get-set.any.js.ini
testing/web-platform/meta/wasm/jsapi/table/grow.any.js.ini
testing/web-platform/tests/wasm/jsapi/global/constructor.any.js
testing/web-platform/tests/wasm/jsapi/global/toString.any.js
testing/web-platform/tests/wasm/jsapi/global/value-set.any.js
testing/web-platform/tests/wasm/jsapi/global/valueOf.any.js
testing/web-platform/tests/wasm/jsapi/instance/constructor.any.js
testing/web-platform/tests/wasm/jsapi/instance/exports.any.js
testing/web-platform/tests/wasm/jsapi/instance/toString.any.js
testing/web-platform/tests/wasm/jsapi/interface.any.js
testing/web-platform/tests/wasm/jsapi/memory/buffer.any.js
testing/web-platform/tests/wasm/jsapi/memory/constructor.any.js
testing/web-platform/tests/wasm/jsapi/memory/grow.any.js
testing/web-platform/tests/wasm/jsapi/memory/toString.any.js
testing/web-platform/tests/wasm/jsapi/module/constructor.any.js
testing/web-platform/tests/wasm/jsapi/module/customSections.any.js
testing/web-platform/tests/wasm/jsapi/module/exports.any.js
testing/web-platform/tests/wasm/jsapi/module/imports.any.js
testing/web-platform/tests/wasm/jsapi/module/toString.any.js
testing/web-platform/tests/wasm/jsapi/table/assertions.js
testing/web-platform/tests/wasm/jsapi/table/constructor.any.js
testing/web-platform/tests/wasm/jsapi/table/get-set.any.js
testing/web-platform/tests/wasm/jsapi/table/grow.any.js
testing/web-platform/tests/wasm/jsapi/table/length.any.js
testing/web-platform/tests/wasm/jsapi/table/toString.any.js
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -310194,16 +310194,21 @@
      {}
     ]
    ],
    "wasm/jsapi/bad-imports.js": [
     [
      {}
     ]
    ],
+   "wasm/jsapi/table/assertions.js": [
+    [
+     {}
+    ]
+   ],
    "wasm/jsapi/wasm-constants.js": [
     [
      {}
     ]
    ],
    "wasm/jsapi/wasm-module-builder.js": [
     [
      {}
@@ -394817,16 +394822,80 @@
       "jsshell": true
      }
     ],
     [
      "/wasm/jsapi/constructor/instantiate-bad-imports.any.worker.html",
      {}
     ]
    ],
+   "wasm/jsapi/global/constructor.any.js": [
+    [
+     "/wasm/jsapi/global/constructor.any.html",
+     {}
+    ],
+    [
+     "/wasm/jsapi/global/constructor.any.js",
+     {
+      "jsshell": true
+     }
+    ],
+    [
+     "/wasm/jsapi/global/constructor.any.worker.html",
+     {}
+    ]
+   ],
+   "wasm/jsapi/global/toString.any.js": [
+    [
+     "/wasm/jsapi/global/toString.any.html",
+     {}
+    ],
+    [
+     "/wasm/jsapi/global/toString.any.js",
+     {
+      "jsshell": true
+     }
+    ],
+    [
+     "/wasm/jsapi/global/toString.any.worker.html",
+     {}
+    ]
+   ],
+   "wasm/jsapi/global/value-set.any.js": [
+    [
+     "/wasm/jsapi/global/value-set.any.html",
+     {}
+    ],
+    [
+     "/wasm/jsapi/global/value-set.any.js",
+     {
+      "jsshell": true
+     }
+    ],
+    [
+     "/wasm/jsapi/global/value-set.any.worker.html",
+     {}
+    ]
+   ],
+   "wasm/jsapi/global/valueOf.any.js": [
+    [
+     "/wasm/jsapi/global/valueOf.any.html",
+     {}
+    ],
+    [
+     "/wasm/jsapi/global/valueOf.any.js",
+     {
+      "jsshell": true
+     }
+    ],
+    [
+     "/wasm/jsapi/global/valueOf.any.worker.html",
+     {}
+    ]
+   ],
    "wasm/jsapi/instance/constructor-bad-imports.any.js": [
     [
      "/wasm/jsapi/instance/constructor-bad-imports.any.html",
      {}
     ],
     [
      "/wasm/jsapi/instance/constructor-bad-imports.any.js",
      {
@@ -394849,48 +394918,128 @@
       "jsshell": true
      }
     ],
     [
      "/wasm/jsapi/instance/constructor.any.worker.html",
      {}
     ]
    ],
+   "wasm/jsapi/instance/exports.any.js": [
+    [
+     "/wasm/jsapi/instance/exports.any.html",
+     {}
+    ],
+    [
+     "/wasm/jsapi/instance/exports.any.js",
+     {
+      "jsshell": true
+     }
+    ],
+    [
+     "/wasm/jsapi/instance/exports.any.worker.html",
+     {}
+    ]
+   ],
+   "wasm/jsapi/instance/toString.any.js": [
+    [
+     "/wasm/jsapi/instance/toString.any.html",
+     {}
+    ],
+    [
+     "/wasm/jsapi/instance/toString.any.js",
+     {
+      "jsshell": true
+     }
+    ],
+    [
+     "/wasm/jsapi/instance/toString.any.worker.html",
+     {}
+    ]
+   ],
    "wasm/jsapi/interface.any.js": [
     [
      "/wasm/jsapi/interface.any.html",
      {}
     ],
     [
      "/wasm/jsapi/interface.any.js",
      {
       "jsshell": true
      }
     ],
     [
      "/wasm/jsapi/interface.any.worker.html",
      {}
     ]
    ],
+   "wasm/jsapi/memory/buffer.any.js": [
+    [
+     "/wasm/jsapi/memory/buffer.any.html",
+     {}
+    ],
+    [
+     "/wasm/jsapi/memory/buffer.any.js",
+     {
+      "jsshell": true
+     }
+    ],
+    [
+     "/wasm/jsapi/memory/buffer.any.worker.html",
+     {}
+    ]
+   ],
    "wasm/jsapi/memory/constructor.any.js": [
     [
      "/wasm/jsapi/memory/constructor.any.html",
      {}
     ],
     [
      "/wasm/jsapi/memory/constructor.any.js",
      {
       "jsshell": true
      }
     ],
     [
      "/wasm/jsapi/memory/constructor.any.worker.html",
      {}
     ]
    ],
+   "wasm/jsapi/memory/grow.any.js": [
+    [
+     "/wasm/jsapi/memory/grow.any.html",
+     {}
+    ],
+    [
+     "/wasm/jsapi/memory/grow.any.js",
+     {
+      "jsshell": true
+     }
+    ],
+    [
+     "/wasm/jsapi/memory/grow.any.worker.html",
+     {}
+    ]
+   ],
+   "wasm/jsapi/memory/toString.any.js": [
+    [
+     "/wasm/jsapi/memory/toString.any.html",
+     {}
+    ],
+    [
+     "/wasm/jsapi/memory/toString.any.js",
+     {
+      "jsshell": true
+     }
+    ],
+    [
+     "/wasm/jsapi/memory/toString.any.worker.html",
+     {}
+    ]
+   ],
    "wasm/jsapi/module/constructor.any.js": [
     [
      "/wasm/jsapi/module/constructor.any.html",
      {}
     ],
     [
      "/wasm/jsapi/module/constructor.any.js",
      {
@@ -394945,32 +395094,112 @@
       "jsshell": true
      }
     ],
     [
      "/wasm/jsapi/module/imports.any.worker.html",
      {}
     ]
    ],
+   "wasm/jsapi/module/toString.any.js": [
+    [
+     "/wasm/jsapi/module/toString.any.html",
+     {}
+    ],
+    [
+     "/wasm/jsapi/module/toString.any.js",
+     {
+      "jsshell": true
+     }
+    ],
+    [
+     "/wasm/jsapi/module/toString.any.worker.html",
+     {}
+    ]
+   ],
    "wasm/jsapi/table/constructor.any.js": [
     [
      "/wasm/jsapi/table/constructor.any.html",
      {}
     ],
     [
      "/wasm/jsapi/table/constructor.any.js",
      {
       "jsshell": true
      }
     ],
     [
      "/wasm/jsapi/table/constructor.any.worker.html",
      {}
     ]
    ],
+   "wasm/jsapi/table/get-set.any.js": [
+    [
+     "/wasm/jsapi/table/get-set.any.html",
+     {}
+    ],
+    [
+     "/wasm/jsapi/table/get-set.any.js",
+     {
+      "jsshell": true
+     }
+    ],
+    [
+     "/wasm/jsapi/table/get-set.any.worker.html",
+     {}
+    ]
+   ],
+   "wasm/jsapi/table/grow.any.js": [
+    [
+     "/wasm/jsapi/table/grow.any.html",
+     {}
+    ],
+    [
+     "/wasm/jsapi/table/grow.any.js",
+     {
+      "jsshell": true
+     }
+    ],
+    [
+     "/wasm/jsapi/table/grow.any.worker.html",
+     {}
+    ]
+   ],
+   "wasm/jsapi/table/length.any.js": [
+    [
+     "/wasm/jsapi/table/length.any.html",
+     {}
+    ],
+    [
+     "/wasm/jsapi/table/length.any.js",
+     {
+      "jsshell": true
+     }
+    ],
+    [
+     "/wasm/jsapi/table/length.any.worker.html",
+     {}
+    ]
+   ],
+   "wasm/jsapi/table/toString.any.js": [
+    [
+     "/wasm/jsapi/table/toString.any.html",
+     {}
+    ],
+    [
+     "/wasm/jsapi/table/toString.any.js",
+     {
+      "jsshell": true
+     }
+    ],
+    [
+     "/wasm/jsapi/table/toString.any.worker.html",
+     {}
+    ]
+   ],
    "wasm/wasm_local_iframe_test.html": [
     [
      "/wasm/wasm_local_iframe_test.html",
      {}
     ]
    ],
    "wasm/wasm_serialization_tests.html": [
     [
@@ -647668,50 +647897,110 @@
   "wasm/jsapi/bad-imports.js": [
    "f076baacca8b3e6addf49f6841874d11bfcfe5a2",
    "support"
   ],
   "wasm/jsapi/constructor/instantiate-bad-imports.any.js": [
    "86700298dfae66de6f4d026baa29e6e3584320f7",
    "testharness"
   ],
+  "wasm/jsapi/global/constructor.any.js": [
+   "7a45cc4191c55684cde187fc73fb9741d6f5c2c5",
+   "testharness"
+  ],
+  "wasm/jsapi/global/toString.any.js": [
+   "ca025576c2b49604f053c83002f3a9cc8ef41a7b",
+   "testharness"
+  ],
+  "wasm/jsapi/global/value-set.any.js": [
+   "b4e6770f10ed9e3ad55b9ae18ee96deda3ff171e",
+   "testharness"
+  ],
+  "wasm/jsapi/global/valueOf.any.js": [
+   "176c5a784698399351eedeaac0ec305aa8ab7b81",
+   "testharness"
+  ],
   "wasm/jsapi/instance/constructor-bad-imports.any.js": [
    "24c51c10dc5df9d52c06bfb0715e435b17f24f7a",
    "testharness"
   ],
   "wasm/jsapi/instance/constructor.any.js": [
-   "93a3ffda033729d64562a583e823fab05f35f6fe",
+   "61a8f53a014c192f28a0c25252cf3702561e7191",
+   "testharness"
+  ],
+  "wasm/jsapi/instance/exports.any.js": [
+   "31423918720543da2ba25e392267bf541b756242",
+   "testharness"
+  ],
+  "wasm/jsapi/instance/toString.any.js": [
+   "08dcb14a50d04f6db196626ddb93f2b50da8f055",
    "testharness"
   ],
   "wasm/jsapi/interface.any.js": [
-   "64c1f60da1c7888be994f222af69f401402ae5f4",
+   "5d76ac56ec5fafde8dde3924df863a2694bd6691",
+   "testharness"
+  ],
+  "wasm/jsapi/memory/buffer.any.js": [
+   "b04460b6c5e56cf1fe990e3107aa9efcb4964ed5",
    "testharness"
   ],
   "wasm/jsapi/memory/constructor.any.js": [
-   "33256f85e45749cc46842dccbd1ee7c40db41ae5",
+   "f9907ca6104d8ec76861e43b6b981042d86fb865",
+   "testharness"
+  ],
+  "wasm/jsapi/memory/grow.any.js": [
+   "95300399f192b7eab70dd8f07c43f4db37eebe01",
+   "testharness"
+  ],
+  "wasm/jsapi/memory/toString.any.js": [
+   "4e15d75ea20f1ebfeba5dc7c8a9a52c253dd01bf",
    "testharness"
   ],
   "wasm/jsapi/module/constructor.any.js": [
-   "0f5eecf957e8ca6af851ce12f5c18266a2eb0460",
+   "32f183fac8738d30cc8a432768da315949320257",
    "testharness"
   ],
   "wasm/jsapi/module/customSections.any.js": [
-   "146aa7fd332ca9b061fef51a7378d29f8c9c165e",
+   "58ac63b61c93a015bfa9d5daab39f8d5b48548da",
    "testharness"
   ],
   "wasm/jsapi/module/exports.any.js": [
-   "c7ecdcf6b619b4ab93cf4e878addeb9bed736d4e",
+   "e63a885a4c34add0f6787d3642de83d9766568d1",
    "testharness"
   ],
   "wasm/jsapi/module/imports.any.js": [
-   "522b262f549b9a07c0a426cd474151d3d3e02749",
-   "testharness"
+   "640da591d21d8924d261fdc58b8e7cc762187a11",
+   "testharness"
+  ],
+  "wasm/jsapi/module/toString.any.js": [
+   "d9231a132ca8bf965f69c3cc81070a2ffe179efa",
+   "testharness"
+  ],
+  "wasm/jsapi/table/assertions.js": [
+   "dde2fd770904207a1f9f287fa48d82954a418f2e",
+   "support"
   ],
   "wasm/jsapi/table/constructor.any.js": [
-   "4aeac10f7adc6e0ec0abc56fa66c0259102798e2",
+   "e924bdb2ba42c67bcc6d4a949c2eeb50eac63e31",
+   "testharness"
+  ],
+  "wasm/jsapi/table/get-set.any.js": [
+   "2bb43a9308d732b5b6fa689c181ac411880c3733",
+   "testharness"
+  ],
+  "wasm/jsapi/table/grow.any.js": [
+   "d3efb511e4b1db1efa089322c0a3079705dfbdbd",
+   "testharness"
+  ],
+  "wasm/jsapi/table/length.any.js": [
+   "a6a9661dbaddc800cb99b7b8e2b804cb0c8e3c62",
+   "testharness"
+  ],
+  "wasm/jsapi/table/toString.any.js": [
+   "e576477910ad3198b446b4addf89ba9a571d020b",
    "testharness"
   ],
   "wasm/jsapi/wasm-constants.js": [
    "f056f9cbfcfbac52d0506edddd01c8fad8636ebb",
    "support"
   ],
   "wasm/jsapi/wasm-module-builder.js": [
    "6e9284e773105db5751c5483ed9333a45272b180",
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/wasm/jsapi/global/constructor.any.js.ini
@@ -0,0 +1,30 @@
+[constructor.any.html]
+  [Order of evaluation]
+    expected: FAIL
+
+  [Explicit value undefined for type f32]
+    expected: FAIL
+
+  [Explicit value undefined for type f64]
+    expected: FAIL
+
+[constructor.any.worker.html]
+  [Order of evaluation]
+    expected: FAIL
+
+  [Explicit value undefined for type f32]
+    expected: FAIL
+
+  [Explicit value undefined for type f64]
+    expected: FAIL
+
+[constructor.any.js]
+  [Order of evaluation]
+    expected: FAIL
+
+  [Explicit value undefined for type f32]
+    expected: FAIL
+
+  [Explicit value undefined for type f64]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/wasm/jsapi/global/value-set.any.js.ini
@@ -0,0 +1,12 @@
+[value-set.any.html]
+  [Calling setter without argument]
+    expected: FAIL
+
+[value-set.any.worker.html]
+  [Calling setter without argument]
+    expected: FAIL
+
+[value-set.any.js]
+  [Calling setter without argument]
+    expected: FAIL
+
--- a/testing/web-platform/meta/wasm/jsapi/memory/constructor.any.js.ini
+++ b/testing/web-platform/meta/wasm/jsapi/memory/constructor.any.js.ini
@@ -1,10 +1,10 @@
 [constructor.any.html]
-  [Empty descriptor]
+  [Invalid descriptor argument]
     expected: FAIL
 
   [Undefined initial value in descriptor]
     expected: FAIL
 
   [Out-of-range initial value in descriptor: NaN]
     expected: FAIL
 
@@ -40,17 +40,17 @@
 
   [Out-of-range maximum value in descriptor: 68719476736]
     expected: FAIL
 
   [Proxy descriptor]
     expected: FAIL
 
 [constructor.any.worker.html]
-  [Empty descriptor]
+  [Invalid descriptor argument]
     expected: FAIL
 
   [Undefined initial value in descriptor]
     expected: FAIL
 
   [Out-of-range initial value in descriptor: NaN]
     expected: FAIL
 
@@ -86,17 +86,17 @@
 
   [Out-of-range maximum value in descriptor: 68719476736]
     expected: FAIL
 
   [Proxy descriptor]
     expected: FAIL
 
 [constructor.any.js]
-  [Empty descriptor]
+  [Invalid descriptor argument]
     expected: FAIL
 
   [Undefined initial value in descriptor]
     expected: FAIL
 
   [Out-of-range initial value in descriptor: NaN]
     expected: FAIL
 
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/wasm/jsapi/memory/grow.any.js.ini
@@ -0,0 +1,93 @@
+[grow.any.html]
+  [Missing arguments]
+    expected: FAIL
+
+  [Out-of-range argument: undefined]
+    expected: FAIL
+
+  [Out-of-range argument: NaN]
+    expected: FAIL
+
+  [Out-of-range argument: Infinity]
+    expected: FAIL
+
+  [Out-of-range argument: -Infinity]
+    expected: FAIL
+
+  [Out-of-range argument: -1]
+    expected: FAIL
+
+  [Out-of-range argument: 4294967296]
+    expected: FAIL
+
+  [Out-of-range argument: 68719476736]
+    expected: FAIL
+
+  [Out-of-range argument: "0x100000000"]
+    expected: FAIL
+
+  [Out-of-range argument: object "[object Object\]"]
+    expected: FAIL
+
+[grow.any.worker.html]
+  [Missing arguments]
+    expected: FAIL
+
+  [Out-of-range argument: undefined]
+    expected: FAIL
+
+  [Out-of-range argument: NaN]
+    expected: FAIL
+
+  [Out-of-range argument: Infinity]
+    expected: FAIL
+
+  [Out-of-range argument: -Infinity]
+    expected: FAIL
+
+  [Out-of-range argument: -1]
+    expected: FAIL
+
+  [Out-of-range argument: 4294967296]
+    expected: FAIL
+
+  [Out-of-range argument: 68719476736]
+    expected: FAIL
+
+  [Out-of-range argument: "0x100000000"]
+    expected: FAIL
+
+  [Out-of-range argument: object "[object Object\]"]
+    expected: FAIL
+
+[grow.any.js]
+  [Missing arguments]
+    expected: FAIL
+
+  [Out-of-range argument: undefined]
+    expected: FAIL
+
+  [Out-of-range argument: NaN]
+    expected: FAIL
+
+  [Out-of-range argument: Infinity]
+    expected: FAIL
+
+  [Out-of-range argument: -Infinity]
+    expected: FAIL
+
+  [Out-of-range argument: -1]
+    expected: FAIL
+
+  [Out-of-range argument: 4294967296]
+    expected: FAIL
+
+  [Out-of-range argument: 68719476736]
+    expected: FAIL
+
+  [Out-of-range argument: "0x100000000"]
+    expected: FAIL
+
+  [Out-of-range argument: object "[object Object\]"]
+    expected: FAIL
+
--- a/testing/web-platform/meta/wasm/jsapi/table/constructor.any.js.ini
+++ b/testing/web-platform/meta/wasm/jsapi/table/constructor.any.js.ini
@@ -36,16 +36,22 @@
     expected: FAIL
 
   [Out-of-range maximum value in descriptor: 68719476736]
     expected: FAIL
 
   [Proxy descriptor]
     expected: FAIL
 
+  [Type conversion for descriptor.element]
+    expected: FAIL
+
+  [Order of evaluation for descriptor]
+    expected: FAIL
+
 [constructor.any.worker.html]
   [Undefined initial value in descriptor]
     expected: FAIL
 
   [Out-of-range initial value in descriptor: NaN]
     expected: FAIL
 
   [Out-of-range maximum value in descriptor: NaN]
@@ -79,16 +85,22 @@
     expected: FAIL
 
   [Out-of-range maximum value in descriptor: 68719476736]
     expected: FAIL
 
   [Proxy descriptor]
     expected: FAIL
 
+  [Type conversion for descriptor.element]
+    expected: FAIL
+
+  [Order of evaluation for descriptor]
+    expected: FAIL
+
 [constructor.any.js]
   [Undefined initial value in descriptor]
     expected: FAIL
 
   [Out-of-range initial value in descriptor: NaN]
     expected: FAIL
 
   [Out-of-range maximum value in descriptor: NaN]
@@ -121,8 +133,15 @@
   [Out-of-range initial value in descriptor: 68719476736]
     expected: FAIL
 
   [Out-of-range maximum value in descriptor: 68719476736]
     expected: FAIL
 
   [Proxy descriptor]
     expected: FAIL
+
+  [Type conversion for descriptor.element]
+    expected: FAIL
+
+  [Order of evaluation for descriptor]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/wasm/jsapi/table/get-set.any.js.ini
@@ -0,0 +1,174 @@
+[get-set.any.html]
+  [Missing arguments: get]
+    expected: FAIL
+
+  [Getting out-of-range argument: undefined]
+    expected: FAIL
+
+  [Setting out-of-range argument: undefined]
+    expected: FAIL
+
+  [Getting out-of-range argument: NaN]
+    expected: FAIL
+
+  [Setting out-of-range argument: NaN]
+    expected: FAIL
+
+  [Getting out-of-range argument: Infinity]
+    expected: FAIL
+
+  [Setting out-of-range argument: Infinity]
+    expected: FAIL
+
+  [Getting out-of-range argument: -Infinity]
+    expected: FAIL
+
+  [Setting out-of-range argument: -Infinity]
+    expected: FAIL
+
+  [Getting out-of-range argument: -1]
+    expected: FAIL
+
+  [Setting out-of-range argument: -1]
+    expected: FAIL
+
+  [Getting out-of-range argument: 4294967296]
+    expected: FAIL
+
+  [Setting out-of-range argument: 4294967296]
+    expected: FAIL
+
+  [Getting out-of-range argument: 68719476736]
+    expected: FAIL
+
+  [Setting out-of-range argument: 68719476736]
+    expected: FAIL
+
+  [Getting out-of-range argument: "0x100000000"]
+    expected: FAIL
+
+  [Setting out-of-range argument: "0x100000000"]
+    expected: FAIL
+
+  [Getting out-of-range argument: object "[object Object\]"]
+    expected: FAIL
+
+  [Setting out-of-range argument: object "[object Object\]"]
+    expected: FAIL
+
+[get-set.any.worker.html]
+  [Missing arguments: get]
+    expected: FAIL
+
+  [Getting out-of-range argument: undefined]
+    expected: FAIL
+
+  [Setting out-of-range argument: undefined]
+    expected: FAIL
+
+  [Getting out-of-range argument: NaN]
+    expected: FAIL
+
+  [Setting out-of-range argument: NaN]
+    expected: FAIL
+
+  [Getting out-of-range argument: Infinity]
+    expected: FAIL
+
+  [Setting out-of-range argument: Infinity]
+    expected: FAIL
+
+  [Getting out-of-range argument: -Infinity]
+    expected: FAIL
+
+  [Setting out-of-range argument: -Infinity]
+    expected: FAIL
+
+  [Getting out-of-range argument: -1]
+    expected: FAIL
+
+  [Setting out-of-range argument: -1]
+    expected: FAIL
+
+  [Getting out-of-range argument: 4294967296]
+    expected: FAIL
+
+  [Setting out-of-range argument: 4294967296]
+    expected: FAIL
+
+  [Getting out-of-range argument: 68719476736]
+    expected: FAIL
+
+  [Setting out-of-range argument: 68719476736]
+    expected: FAIL
+
+  [Getting out-of-range argument: "0x100000000"]
+    expected: FAIL
+
+  [Setting out-of-range argument: "0x100000000"]
+    expected: FAIL
+
+  [Getting out-of-range argument: object "[object Object\]"]
+    expected: FAIL
+
+  [Setting out-of-range argument: object "[object Object\]"]
+    expected: FAIL
+
+[get-set.any.js]
+  [Missing arguments: get]
+    expected: FAIL
+
+  [Getting out-of-range argument: undefined]
+    expected: FAIL
+
+  [Setting out-of-range argument: undefined]
+    expected: FAIL
+
+  [Getting out-of-range argument: NaN]
+    expected: FAIL
+
+  [Setting out-of-range argument: NaN]
+    expected: FAIL
+
+  [Getting out-of-range argument: Infinity]
+    expected: FAIL
+
+  [Setting out-of-range argument: Infinity]
+    expected: FAIL
+
+  [Getting out-of-range argument: -Infinity]
+    expected: FAIL
+
+  [Setting out-of-range argument: -Infinity]
+    expected: FAIL
+
+  [Getting out-of-range argument: -1]
+    expected: FAIL
+
+  [Setting out-of-range argument: -1]
+    expected: FAIL
+
+  [Getting out-of-range argument: 4294967296]
+    expected: FAIL
+
+  [Setting out-of-range argument: 4294967296]
+    expected: FAIL
+
+  [Getting out-of-range argument: 68719476736]
+    expected: FAIL
+
+  [Setting out-of-range argument: 68719476736]
+    expected: FAIL
+
+  [Getting out-of-range argument: "0x100000000"]
+    expected: FAIL
+
+  [Setting out-of-range argument: "0x100000000"]
+    expected: FAIL
+
+  [Getting out-of-range argument: object "[object Object\]"]
+    expected: FAIL
+
+  [Setting out-of-range argument: object "[object Object\]"]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/wasm/jsapi/table/grow.any.js.ini
@@ -0,0 +1,93 @@
+[grow.any.html]
+  [Missing arguments]
+    expected: FAIL
+
+  [Out-of-range argument: undefined]
+    expected: FAIL
+
+  [Out-of-range argument: NaN]
+    expected: FAIL
+
+  [Out-of-range argument: Infinity]
+    expected: FAIL
+
+  [Out-of-range argument: -Infinity]
+    expected: FAIL
+
+  [Out-of-range argument: -1]
+    expected: FAIL
+
+  [Out-of-range argument: 4294967296]
+    expected: FAIL
+
+  [Out-of-range argument: 68719476736]
+    expected: FAIL
+
+  [Out-of-range argument: "0x100000000"]
+    expected: FAIL
+
+  [Out-of-range argument: object "[object Object\]"]
+    expected: FAIL
+
+[grow.any.worker.html]
+  [Missing arguments]
+    expected: FAIL
+
+  [Out-of-range argument: undefined]
+    expected: FAIL
+
+  [Out-of-range argument: NaN]
+    expected: FAIL
+
+  [Out-of-range argument: Infinity]
+    expected: FAIL
+
+  [Out-of-range argument: -Infinity]
+    expected: FAIL
+
+  [Out-of-range argument: -1]
+    expected: FAIL
+
+  [Out-of-range argument: 4294967296]
+    expected: FAIL
+
+  [Out-of-range argument: 68719476736]
+    expected: FAIL
+
+  [Out-of-range argument: "0x100000000"]
+    expected: FAIL
+
+  [Out-of-range argument: object "[object Object\]"]
+    expected: FAIL
+
+[grow.any.js]
+  [Missing arguments]
+    expected: FAIL
+
+  [Out-of-range argument: undefined]
+    expected: FAIL
+
+  [Out-of-range argument: NaN]
+    expected: FAIL
+
+  [Out-of-range argument: Infinity]
+    expected: FAIL
+
+  [Out-of-range argument: -Infinity]
+    expected: FAIL
+
+  [Out-of-range argument: -1]
+    expected: FAIL
+
+  [Out-of-range argument: 4294967296]
+    expected: FAIL
+
+  [Out-of-range argument: 68719476736]
+    expected: FAIL
+
+  [Out-of-range argument: "0x100000000"]
+    expected: FAIL
+
+  [Out-of-range argument: object "[object Object\]"]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/wasm/jsapi/global/constructor.any.js
@@ -0,0 +1,121 @@
+// META: global=jsshell
+// META: script=/wasm/jsapi/assertions.js
+
+function assert_Global(actual, expected) {
+  assert_equals(Object.getPrototypeOf(actual), WebAssembly.Global.prototype,
+                "prototype");
+  assert_true(Object.isExtensible(actual), "extensible");
+
+  assert_equals(actual.value, expected, "value");
+  assert_equals(actual.valueOf(), expected, "valueOf");
+}
+
+test(() => {
+  assert_function_name(WebAssembly.Global, "Global", "WebAssembly.Global");
+}, "name");
+
+test(() => {
+  assert_function_length(WebAssembly.Global, 1, "WebAssembly.Global");
+}, "length");
+
+test(() => {
+  assert_throws(new TypeError(), () => new WebAssembly.Global());
+}, "No arguments");
+
+test(() => {
+  const argument = { "value": "i32" };
+  assert_throws(new TypeError(), () => WebAssembly.Global(argument));
+}, "Calling");
+
+test(() => {
+  const order = [];
+
+  new WebAssembly.Global({
+    get value() {
+      order.push("descriptor value");
+      return {
+        toString() {
+          order.push("descriptor value toString");
+          return "f64";
+        },
+      };
+    },
+
+    get mutable() {
+      order.push("descriptor mutable");
+      return false;
+    },
+  }, {
+    valueOf() {
+      order.push("value valueOf()");
+    }
+  });
+
+  assert_array_equals(order, [
+    "descriptor mutable",
+    "descriptor value",
+    "descriptor value toString",
+    "value valueOf()",
+  ]);
+}, "Order of evaluation");
+
+test(() => {
+  const invalidArguments = [
+    undefined,
+    null,
+    false,
+    true,
+    "",
+    "test",
+    Symbol(),
+    1,
+    NaN,
+    {},
+  ];
+  for (const invalidArgument of invalidArguments) {
+    assert_throws(new TypeError(),
+                  () => new WebAssembly.Global(invalidArgument),
+                  `new Global(${format_value(invalidArgument)})`);
+  }
+}, "Invalid descriptor argument");
+
+test(() => {
+  const invalidTypes = ["i16", "i128", "f16", "f128", "u32", "u64", "i32\0"];
+  for (const value of invalidTypes) {
+    const argument = { value };
+    assert_throws(new TypeError(), () => new WebAssembly.Global(argument));
+  }
+}, "Invalid type argument");
+
+test(() => {
+  const argument = { "value": "i64" };
+  const global = new WebAssembly.Global(argument);
+  assert_throws(new TypeError(), () => global.value);
+  assert_throws(new TypeError(), () => global.valueOf());
+}, "i64 with default");
+
+for (const type of ["i32", "f32", "f64"]) {
+  test(() => {
+    const argument = { "value": type };
+    const global = new WebAssembly.Global(argument);
+    assert_Global(global, 0);
+  }, `Default value for type ${type}`);
+
+  const valueArguments = [
+    [undefined, 0],
+    [null, 0],
+    [true, 1],
+    [false, 0],
+    [2, 2],
+    ["3", 3],
+    [{ toString() { return "5" } }, 5, "object with toString"],
+    [{ valueOf() { return "8" } }, 8, "object with valueOf"],
+  ];
+  for (const [value, expected, name = format_value(value)] of valueArguments) {
+    test(() => {
+      const argument = { "value": type };
+      const global = new WebAssembly.Global(argument, value);
+      assert_Global(global, expected);
+    }, `Explicit value ${name} for type ${type}`);
+  }
+}
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/wasm/jsapi/global/toString.any.js
@@ -0,0 +1,7 @@
+// META: global=jsshell
+
+test(() => {
+  const argument = { "value": "i32" };
+  const global = new WebAssembly.Global(argument);
+  assert_class_string(global, "WebAssembly.Global");
+}, "Object.prototype.toString on an Global");
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/wasm/jsapi/global/value-set.any.js
@@ -0,0 +1,94 @@
+// META: global=jsshell
+
+test(() => {
+  const thisValues = [
+    undefined,
+    null,
+    true,
+    "",
+    Symbol(),
+    1,
+    {},
+    WebAssembly.Global,
+    WebAssembly.Global.prototype,
+  ];
+
+  const desc = Object.getOwnPropertyDescriptor(WebAssembly.Global.prototype, "value");
+  assert_equals(typeof desc, "object");
+
+  const getter = desc.get;
+  assert_equals(typeof getter, "function");
+
+  const setter = desc.set;
+  assert_equals(typeof setter, "function");
+
+  for (const thisValue of thisValues) {
+    assert_throws(new TypeError(), () => getter.call(thisValue), `getter with this=${format_value(thisValue)}`);
+    assert_throws(new TypeError(), () => setter.call(thisValue, 1), `setter with this=${format_value(thisValue)}`);
+  }
+}, "Branding");
+
+for (const type of ["i32", "f32", "f64"]) {
+  const immutableOptions = [
+    [{}, "missing"],
+    [{ "mutable": undefined }, "undefined"],
+    [{ "mutable": null }, "null"],
+    [{ "mutable": false }, "false"],
+    [{ "mutable": "" }, "empty string"],
+    [{ "mutable": 0 }, "zero"],
+  ];
+  for (const [opts, name] of immutableOptions) {
+    test(() => {
+      opts.value = type;
+      const global = new WebAssembly.Global(opts);
+      assert_equals(global.value, 0, "initial value");
+      assert_equals(global.valueOf(), 0, "initial valueOf");
+
+      assert_throws(new TypeError(), () => global.value = 1);
+
+      assert_equals(global.value, 0, "post-set value");
+      assert_equals(global.valueOf(), 0, "post-set valueOf");
+    }, `Immutable ${type} (${name})`);
+  }
+
+  const mutableOptions = [
+    [{ "mutable": true }, "true"],
+    [{ "mutable": 1 }, "one"],
+    [{ "mutable": "x" }, "string"],
+    [Object.create({ "mutable": true }), "true on prototype"],
+  ];
+  for (const [opts, name] of mutableOptions) {
+    test(() => {
+      opts.value = type;
+      const global = new WebAssembly.Global(opts);
+      assert_equals(global.value, 0, "initial value");
+      assert_equals(global.valueOf(), 0, "initial valueOf");
+
+      global.value = 1;
+
+      assert_equals(global.value, 1, "post-set value");
+      assert_equals(global.valueOf(), 1, "post-set valueOf");
+    }, `Mutable ${type} (${name})`);
+  }
+}
+
+test(() => {
+  const argument = { "value": "i64", "mutable": true };
+  const global = new WebAssembly.Global(argument);
+  assert_throws(new TypeError(), () => global.value);
+  assert_throws(new TypeError(), () => global.value = 0);
+  assert_throws(new TypeError(), () => global.valueOf());
+}, "i64 with default");
+
+
+test(() => {
+  const argument = { "value": "i32", "mutable": true };
+  const global = new WebAssembly.Global(argument);
+  const desc = Object.getOwnPropertyDescriptor(WebAssembly.Global.prototype, "value");
+  assert_equals(typeof desc, "object");
+
+  const setter = desc.set;
+  assert_equals(typeof setter, "function");
+
+  assert_throws(new TypeError(), () => setter.call(global));
+}, "Calling setter without argument");
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/wasm/jsapi/global/valueOf.any.js
@@ -0,0 +1,22 @@
+// META: global=jsshell
+
+test(() => {
+  const argument = { "value": "i32" };
+  const thisValues = [
+    undefined,
+    null,
+    true,
+    "",
+    Symbol(),
+    1,
+    {},
+    WebAssembly.Global,
+    WebAssembly.Global.prototype,
+  ];
+
+  const fn = WebAssembly.Global.prototype.valueOf;
+
+  for (const thisValue of thisValues) {
+    assert_throws(new TypeError(), () => fn.call(thisValue), `this=${format_value(thisValue)}`);
+  }
+}, "Branding");
--- a/testing/web-platform/tests/wasm/jsapi/instance/constructor.any.js
+++ b/testing/web-platform/tests/wasm/jsapi/instance/constructor.any.js
@@ -23,16 +23,17 @@ function assert_Instance(instance, expec
   assert_false(Object.isExtensible(exports), "extensible exports");
   for (const [key, expected] of Object.entries(expected_exports)) {
     const property = Object.getOwnPropertyDescriptor(exports, key);
     assert_equals(typeof property, "object", `${key} should be present`);
     assert_false(property.writable, `${key}: writable`);
     assert_true(property.enumerable, `${key}: enumerable`);
     assert_false(property.configurable, `${key}: configurable`);
     const actual = property.value;
+    assert_true(Object.isExtensible(actual), `${key}: extensible`);
 
     switch (expected.kind) {
     case "function":
       assert_exported_function(actual, expected, `value of ${key}`);
       break;
     case "global":
       assert_equals(Object.getPrototypeOf(actual), WebAssembly.Global.prototype,
                     `value of ${key}: prototype`);
@@ -71,16 +72,49 @@ test(() => {
   assert_function_length(WebAssembly.Instance, 1, "WebAssembly.Instance");
 }, "length");
 
 test(() => {
   assert_throws(new TypeError(), () => new WebAssembly.Instance());
 }, "No arguments");
 
 test(() => {
+  const invalidArguments = [
+    undefined,
+    null,
+    true,
+    "",
+    Symbol(),
+    1,
+    {},
+    WebAssembly.Module,
+    WebAssembly.Module.prototype,
+  ];
+  for (const argument of invalidArguments) {
+    assert_throws(new TypeError(), () => new WebAssembly.Instance(argument),
+                  `new Instance(${format_value(argument)})`);
+  }
+}, "Non-Module arguments");
+
+test(() => {
+  const module = new WebAssembly.Module(emptyModuleBinary);
+  const invalidArguments = [
+    null,
+    true,
+    "",
+    Symbol(),
+    1,
+  ];
+  for (const argument of invalidArguments) {
+    assert_throws(new TypeError(), () => new WebAssembly.Instance(module, argument),
+                  `new Instance(module, ${format_value(argument)})`);
+  }
+}, "Non-object imports");
+
+test(() => {
   const module = new WebAssembly.Module(emptyModuleBinary);
   assert_throws(new TypeError(), () => WebAssembly.Instance(module));
 }, "Calling");
 
 test(() => {
   const module = new WebAssembly.Module(emptyModuleBinary);
   const arguments = [
     [],
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/wasm/jsapi/instance/exports.any.js
@@ -0,0 +1,53 @@
+// META: global=jsshell
+// META: script=/wasm/jsapi/wasm-constants.js
+// META: script=/wasm/jsapi/wasm-module-builder.js
+
+let emptyModuleBinary;
+setup(() => {
+  emptyModuleBinary = new WasmModuleBuilder().toBuffer();
+});
+
+test(() => {
+  const thisValues = [
+    undefined,
+    null,
+    true,
+    "",
+    Symbol(),
+    1,
+    {},
+    WebAssembly.Instance,
+    WebAssembly.Instance.prototype,
+  ];
+
+  const desc = Object.getOwnPropertyDescriptor(WebAssembly.Instance.prototype, "exports");
+  assert_equals(typeof desc, "object");
+
+  const getter = desc.get;
+  assert_equals(typeof getter, "function");
+
+  assert_equals(typeof desc.set, "undefined");
+
+  for (const thisValue of thisValues) {
+    assert_throws(new TypeError(), () => getter.call(thisValue), `this=${format_value(thisValue)}`);
+  }
+}, "Branding");
+
+test(() => {
+  const module = new WebAssembly.Module(emptyModuleBinary);
+  const instance = new WebAssembly.Instance(module);
+  const exports = instance.exports;
+  instance.exports = {};
+  assert_equals(instance.exports, exports, "Should not change the exports");
+}, "Setting (sloppy mode)");
+
+test(() => {
+  const module = new WebAssembly.Module(emptyModuleBinary);
+  const instance = new WebAssembly.Instance(module);
+  const exports = instance.exports;
+  assert_throws(new TypeError(), () => {
+    "use strict";
+    instance.exports = {};
+  });
+  assert_equals(instance.exports, exports, "Should not change the exports");
+}, "Setting (strict mode)");
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/wasm/jsapi/instance/toString.any.js
@@ -0,0 +1,10 @@
+// META: global=jsshell
+// META: script=/wasm/jsapi/wasm-constants.js
+// META: script=/wasm/jsapi/wasm-module-builder.js
+
+test(() => {
+  const emptyModuleBinary = new WasmModuleBuilder().toBuffer();
+  const module = new WebAssembly.Module(emptyModuleBinary);
+  const instance = new WebAssembly.Instance(module);
+  assert_class_string(instance, "WebAssembly.Instance");
+}, "Object.prototype.toString on an Instance");
--- a/testing/web-platform/tests/wasm/jsapi/interface.any.js
+++ b/testing/web-platform/tests/wasm/jsapi/interface.any.js
@@ -58,16 +58,20 @@ test(() => {
   assert_equals(typeof propdesc, "object");
   assert_true(propdesc.writable, "writable");
   assert_false(propdesc.enumerable, "enumerable");
   assert_true(propdesc.configurable, "configurable");
   assert_equals(propdesc.value, this.WebAssembly);
 }, "WebAssembly: property descriptor");
 
 test(() => {
+  assert_throws(new TypeError(), () => WebAssembly());
+}, "WebAssembly: calling");
+
+test(() => {
   assert_throws(new TypeError(), () => new WebAssembly());
 }, "WebAssembly: constructing");
 
 const interfaces = [
   "Module",
   "Instance",
   "Memory",
   "Table",
@@ -84,24 +88,33 @@ for (const name of interfaces) {
     assert_true(propdesc.writable, "writable");
     assert_false(propdesc.enumerable, "enumerable");
     assert_true(propdesc.configurable, "configurable");
     assert_equals(propdesc.value, WebAssembly[name]);
   }, `WebAssembly.${name}: property descriptor`);
 
   test(() => {
     const interface_object = WebAssembly[name];
+    const propdesc = Object.getOwnPropertyDescriptor(interface_object, "prototype");
+    assert_equals(typeof propdesc, "object");
+    assert_false(propdesc.writable, "writable");
+    assert_false(propdesc.enumerable, "enumerable");
+    assert_false(propdesc.configurable, "configurable");
+  }, `WebAssembly.${name}: prototype`);
+
+  test(() => {
+    const interface_object = WebAssembly[name];
     const interface_prototype_object = interface_object.prototype;
     const propdesc = Object.getOwnPropertyDescriptor(interface_prototype_object, "constructor");
     assert_equals(typeof propdesc, "object");
     assert_true(propdesc.writable, "writable");
     assert_false(propdesc.enumerable, "enumerable");
     assert_true(propdesc.configurable, "configurable");
     assert_equals(propdesc.value, interface_object);
-  }, `WebAssembly.${name}: prototype`);
+  }, `WebAssembly.${name}: prototype.constructor`);
 }
 
 test_operations(WebAssembly, "WebAssembly", [
   ["validate", 1],
   ["compile", 1],
   ["instantiate", 1],
 ]);
 
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/wasm/jsapi/memory/buffer.any.js
@@ -0,0 +1,50 @@
+// META: global=jsshell
+
+test(() => {
+  const thisValues = [
+    undefined,
+    null,
+    true,
+    "",
+    Symbol(),
+    1,
+    {},
+    WebAssembly.Memory,
+    WebAssembly.Memory.prototype,
+  ];
+
+  const desc = Object.getOwnPropertyDescriptor(WebAssembly.Memory.prototype, "buffer");
+  assert_equals(typeof desc, "object");
+
+  const getter = desc.get;
+  assert_equals(typeof getter, "function");
+
+  assert_equals(typeof desc.set, "undefined");
+
+  for (const thisValue of thisValues) {
+    assert_throws(new TypeError(), () => getter.call(thisValue), `this=${format_value(thisValue)}`);
+  }
+}, "Branding");
+
+test(() => {
+  const argument = { "initial": 0 };
+  const memory = new WebAssembly.Memory(argument);
+  const memory2 = new WebAssembly.Memory(argument);
+  const buffer = memory.buffer;
+  assert_not_equals(buffer, memory2.buffer, "Need two distinct buffers");
+  memory.buffer = memory2.buffer;
+  assert_equals(memory.buffer, buffer, "Should not change the buffer");
+}, "Setting (sloppy mode)");
+
+test(() => {
+  const argument = { "initial": 0 };
+  const memory = new WebAssembly.Memory(argument);
+  const memory2 = new WebAssembly.Memory(argument);
+  const buffer = memory.buffer;
+  assert_not_equals(buffer, memory2.buffer, "Need two distinct buffers");
+  assert_throws(new TypeError(), () => {
+    "use strict";
+    memory.buffer = memory2.buffer;
+  });
+  assert_equals(memory.buffer, buffer, "Should not change the buffer");
+}, "Setting (strict mode)");
--- a/testing/web-platform/tests/wasm/jsapi/memory/constructor.any.js
+++ b/testing/web-platform/tests/wasm/jsapi/memory/constructor.any.js
@@ -1,17 +1,28 @@
 // META: global=jsshell
-// META: script=/wasm/jsapi/wasm-constants.js
-// META: script=/wasm/jsapi/wasm-module-builder.js
 // META: script=/wasm/jsapi/assertions.js
 
-let emptyModuleBinary;
-setup(() => {
-  emptyModuleBinary = new WasmModuleBuilder().toBuffer();
-});
+function assert_Memory(memory, expected) {
+  assert_equals(Object.getPrototypeOf(memory), WebAssembly.Memory.prototype,
+                "prototype");
+  assert_true(Object.isExtensible(memory), "extensible");
+
+  // https://github.com/WebAssembly/spec/issues/840
+  assert_equals(memory.buffer, memory.buffer, "buffer should be idempotent");
+  assert_equals(Object.getPrototypeOf(memory.buffer), ArrayBuffer.prototype,
+                "prototype of buffer");
+  assert_true(Object.isExtensible(memory.buffer), "buffer extensibility");
+  assert_equals(memory.buffer.byteLength, 0x10000 * expected.size, "size of buffer");
+  if (expected.size > 0) {
+    const array = new Uint8Array(memory.buffer);
+    assert_equals(array[0], 0, "first element of buffer");
+    assert_equals(array[array.byteLength - 1], 0, "last element of buffer");
+  }
+}
 
 test(() => {
   assert_function_name(WebAssembly.Memory, "Memory", "WebAssembly.Memory");
 }, "name");
 
 test(() => {
   assert_function_length(WebAssembly.Memory, 1, "WebAssembly.Memory");
 }, "length");
@@ -21,18 +32,34 @@ test(() => {
 }, "No arguments");
 
 test(() => {
   const argument = { "initial": 0 };
   assert_throws(new TypeError(), () => WebAssembly.Memory(argument));
 }, "Calling");
 
 test(() => {
-  assert_throws(new TypeError(), () => new WebAssembly.Memory({}));
-}, "Empty descriptor");
+  const invalidArguments = [
+    undefined,
+    null,
+    false,
+    true,
+    "",
+    "test",
+    Symbol(),
+    1,
+    NaN,
+    {},
+  ];
+  for (const invalidArgument of invalidArguments) {
+    assert_throws(new TypeError(),
+                  () => new WebAssembly.Memory(invalidArgument),
+                  `new Memory(${format_value(invalidArgument)})`);
+  }
+}, "Invalid descriptor argument");
 
 test(() => {
   assert_throws(new TypeError(), () => new WebAssembly.Memory({ "initial": undefined }));
 }, "Undefined initial value in descriptor");
 
 const outOfRangeValues = [
   NaN,
   Infinity,
@@ -60,12 +87,51 @@ test(() => {
     get(o, x) {
       return 0;
     },
   });
   new WebAssembly.Memory(proxy);
 }, "Proxy descriptor");
 
 test(() => {
+  const order = [];
+
+  new WebAssembly.Memory({
+    get maximum() {
+      order.push("maximum");
+      return {
+        valueOf() {
+          order.push("maximum valueOf");
+          return 1;
+        },
+      };
+    },
+
+    get initial() {
+      order.push("initial");
+      return {
+        valueOf() {
+          order.push("initial valueOf");
+          return 1;
+        },
+      };
+    },
+  });
+
+  assert_array_equals(order, [
+    "initial",
+    "initial valueOf",
+    "maximum",
+    "maximum valueOf",
+  ]);
+}, "Order of evaluation for descriptor");
+
+test(() => {
   const argument = { "initial": 0 };
   const memory = new WebAssembly.Memory(argument);
-  assert_equals(Object.getPrototypeOf(memory), WebAssembly.Memory.prototype);
-}, "Prototype");
+  assert_Memory(memory, { "size": 0 });
+}, "Zero initial");
+
+test(() => {
+  const argument = { "initial": 4 };
+  const memory = new WebAssembly.Memory(argument);
+  assert_Memory(memory, { "size": 4 });
+}, "Non-zero initial");
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/wasm/jsapi/memory/grow.any.js
@@ -0,0 +1,170 @@
+// META: global=jsshell
+
+function assert_ArrayBuffer(actual, expected, message) {
+  // https://github.com/WebAssembly/spec/issues/840
+  assert_equals(Object.getPrototypeOf(actual), ArrayBuffer.prototype,
+                `${message}: prototype`);
+  if (expected.detached) {
+    // https://github.com/tc39/ecma262/issues/678
+    let byteLength;
+    try {
+      byteLength = actual.byteLength;
+    } catch (e) {
+      byteLength = 0;
+    }
+    assert_equals(byteLength, 0, `${message}: detached size`);
+  } else {
+    assert_equals(actual.byteLength, 0x10000 * expected.size, `${message}: size`);
+    if (expected.size > 0) {
+      const array = new Uint8Array(actual);
+      assert_equals(array[0], 0, `${message}: first element`);
+      assert_equals(array[array.byteLength - 1], 0, `${message}: last element`);
+    }
+  }
+}
+
+test(() => {
+  const argument = { "initial": 0 };
+  const memory = new WebAssembly.Memory(argument);
+  assert_throws(new TypeError(), () => memory.grow());
+}, "Missing arguments");
+
+test(t => {
+  const thisValues = [
+    undefined,
+    null,
+    true,
+    "",
+    Symbol(),
+    1,
+    {},
+    WebAssembly.Memory,
+    WebAssembly.Memory.prototype,
+  ];
+
+  const argument = {
+    valueOf: t.unreached_func("Should not touch the argument (valueOf)"),
+    toString: t.unreached_func("Should not touch the argument (toString)"),
+  };
+
+  const fn = WebAssembly.Memory.prototype.grow;
+
+  for (const thisValue of thisValues) {
+    assert_throws(new TypeError(), () => fn.call(thisValue, argument), `this=${format_value(thisValue)}`);
+  }
+}, "Branding");
+
+test(() => {
+  const argument = { "initial": 0 };
+  const memory = new WebAssembly.Memory(argument);
+  const oldMemory = memory.buffer;
+  assert_ArrayBuffer(oldMemory, { "size": 0 }, "Buffer before growing");
+
+  const result = memory.grow(2);
+  assert_equals(result, 0);
+
+  const newMemory = memory.buffer;
+  assert_not_equals(oldMemory, newMemory);
+  assert_ArrayBuffer(oldMemory, { "detached": true }, "Old buffer after growing");
+  assert_ArrayBuffer(newMemory, { "size": 2 }, "New buffer after growing");
+}, "Zero initial");
+
+test(() => {
+  const argument = { "initial": { valueOf() { return 0 } } };
+  const memory = new WebAssembly.Memory(argument);
+  const oldMemory = memory.buffer;
+  assert_ArrayBuffer(oldMemory, { "size": 0 }, "Buffer before growing");
+
+  const result = memory.grow({ valueOf() { return 2 } });
+  assert_equals(result, 0);
+
+  const newMemory = memory.buffer;
+  assert_not_equals(oldMemory, newMemory);
+  assert_ArrayBuffer(oldMemory, { "detached": true }, "Old buffer after growing");
+  assert_ArrayBuffer(newMemory, { "size": 2 }, "New buffer after growing");
+}, "Zero initial with valueOf");
+
+test(() => {
+  const argument = { "initial": 3 };
+  const memory = new WebAssembly.Memory(argument);
+  const oldMemory = memory.buffer;
+  assert_ArrayBuffer(oldMemory, { "size": 3 }, "Buffer before growing");
+
+  const result = memory.grow(2);
+  assert_equals(result, 3);
+
+  const newMemory = memory.buffer;
+  assert_not_equals(oldMemory, newMemory);
+  assert_ArrayBuffer(oldMemory, { "detached": true }, "Old buffer after growing");
+  assert_ArrayBuffer(newMemory, { "size": 5 }, "New buffer after growing");
+}, "Non-zero initial");
+
+test(() => {
+  const argument = { "initial": 0, "maximum": 2 };
+  const memory = new WebAssembly.Memory(argument);
+  const oldMemory = memory.buffer;
+  assert_ArrayBuffer(oldMemory, { "size": 0 }, "Buffer before growing");
+
+  const result = memory.grow(2);
+  assert_equals(result, 0);
+
+  const newMemory = memory.buffer;
+  assert_not_equals(oldMemory, newMemory);
+  assert_ArrayBuffer(oldMemory, { "detached": true }, "Old buffer after growing");
+  assert_ArrayBuffer(newMemory, { "size": 2 }, "New buffer after growing");
+}, "Zero initial with respected maximum");
+
+test(() => {
+  const argument = { "initial": 0, "maximum": 2 };
+  const memory = new WebAssembly.Memory(argument);
+  const oldMemory = memory.buffer;
+  assert_ArrayBuffer(oldMemory, { "size": 0 }, "Buffer before growing");
+
+  const result = memory.grow(1);
+  assert_equals(result, 0);
+
+  const newMemory = memory.buffer;
+  assert_not_equals(oldMemory, newMemory);
+  assert_ArrayBuffer(oldMemory, { "detached": true }, "Old buffer after growing once");
+  assert_ArrayBuffer(newMemory, { "size": 1 }, "New buffer after growing once");
+
+  const result2 = memory.grow(1);
+  assert_equals(result2, 1);
+
+  const newestMemory = memory.buffer;
+  assert_not_equals(newMemory, newestMemory);
+  assert_ArrayBuffer(oldMemory, { "detached": true }, "New buffer after growing twice");
+  assert_ArrayBuffer(newMemory, { "detached": true }, "New buffer after growing twice");
+  assert_ArrayBuffer(newestMemory, { "size": 2 }, "Newest buffer after growing twice");
+}, "Zero initial with respected maximum grown twice");
+
+test(() => {
+  const argument = { "initial": 1, "maximum": 2 };
+  const memory = new WebAssembly.Memory(argument);
+  const oldMemory = memory.buffer;
+  assert_ArrayBuffer(oldMemory, { "size": 1 }, "Buffer before growing");
+
+  assert_throws(new RangeError(), () => memory.grow(2));
+  assert_equals(memory.buffer, oldMemory);
+  assert_ArrayBuffer(memory.buffer, { "size": 1 }, "Buffer before trying to grow");
+}, "Zero initial growing too much");
+
+const outOfRangeValues = [
+  undefined,
+  NaN,
+  Infinity,
+  -Infinity,
+  -1,
+  0x100000000,
+  0x1000000000,
+  "0x100000000",
+  { valueOf() { return 0x100000000; } },
+];
+
+for (const value of outOfRangeValues) {
+  test(() => {
+    const argument = { "initial": 0 };
+    const memory = new WebAssembly.Memory(argument);
+    assert_throws(new TypeError(), () => memory.grow(value));
+  }, `Out-of-range argument: ${format_value(value)}`);
+}
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/wasm/jsapi/memory/toString.any.js
@@ -0,0 +1,7 @@
+// META: global=jsshell
+
+test(() => {
+  const argument = { "initial": 0 };
+  const memory = new WebAssembly.Memory(argument);
+  assert_class_string(memory, "WebAssembly.Memory");
+}, "Object.prototype.toString on an Memory");
--- a/testing/web-platform/tests/wasm/jsapi/module/constructor.any.js
+++ b/testing/web-platform/tests/wasm/jsapi/module/constructor.any.js
@@ -20,16 +20,41 @@ test(() => {
   assert_throws(new TypeError(), () => new WebAssembly.Module());
 }, "No arguments");
 
 test(() => {
   assert_throws(new TypeError(), () => WebAssembly.Module(emptyModuleBinary));
 }, "Calling");
 
 test(() => {
+  const invalidArguments = [
+    undefined,
+    null,
+    true,
+    "test",
+    Symbol(),
+    7,
+    NaN,
+    {},
+    ArrayBuffer,
+    ArrayBuffer.prototype,
+    Array.from(emptyModuleBinary),
+  ];
+  for (const argument of invalidArguments) {
+    assert_throws(new TypeError(), () => new WebAssembly.Module(argument),
+                  `new Module(${format_value(argument)})`);
+  }
+}, "Invalid arguments");
+
+test(() => {
   const buffer = new Uint8Array();
   assert_throws(new WebAssembly.CompileError(), () => new WebAssembly.Module(buffer));
 }, "Empty buffer");
 
 test(() => {
   const module = new WebAssembly.Module(emptyModuleBinary);
   assert_equals(Object.getPrototypeOf(module), WebAssembly.Module.prototype);
 }, "Prototype");
+
+test(() => {
+  const module = new WebAssembly.Module(emptyModuleBinary);
+  assert_true(Object.isExtensible(module));
+}, "Extensibility");
--- a/testing/web-platform/tests/wasm/jsapi/module/customSections.any.js
+++ b/testing/web-platform/tests/wasm/jsapi/module/customSections.any.js
@@ -1,20 +1,22 @@
 // META: global=jsshell
 // META: script=/wasm/jsapi/wasm-constants.js
 // META: script=/wasm/jsapi/wasm-module-builder.js
 
 function assert_ArrayBuffer(buffer, expected) {
   assert_equals(Object.getPrototypeOf(buffer), ArrayBuffer.prototype, "Prototype");
+  assert_true(Object.isExtensible(buffer), "isExtensible");
   assert_array_equals(new Uint8Array(buffer), expected);
 }
 
 function assert_sections(sections, expected) {
   assert_true(Array.isArray(sections), "Should be array");
   assert_equals(Object.getPrototypeOf(sections), Array.prototype, "Prototype");
+  assert_true(Object.isExtensible(sections), "isExtensible");
 
   assert_equals(sections.length, expected.length);
   for (let i = 0; i < expected.length; ++i) {
     assert_ArrayBuffer(sections[i], expected[i]);
   }
 }
 
 let emptyModuleBinary;
@@ -24,20 +26,31 @@ setup(() => {
 
 test(() => {
   assert_throws(new TypeError(), () => WebAssembly.Module.customSections());
   const module = new WebAssembly.Module(emptyModuleBinary);
   assert_throws(new TypeError(), () => WebAssembly.Module.customSections(module));
 }, "Missing arguments");
 
 test(() => {
-  assert_throws(new TypeError(), () => WebAssembly.Module.customSections({}, ""));
-  assert_throws(new TypeError(), () => WebAssembly.Module.customSections("", ""));
-  assert_throws(new TypeError(), () => WebAssembly.Module.customSections(undefined, ""));
-  assert_throws(new TypeError(), () => WebAssembly.Module.customSections(null, ""));
+  const invalidArguments = [
+    undefined,
+    null,
+    true,
+    "",
+    Symbol(),
+    1,
+    {},
+    WebAssembly.Module,
+    WebAssembly.Module.prototype,
+  ];
+  for (const argument of invalidArguments) {
+    assert_throws(new TypeError(), () => WebAssembly.Module.customSections(argument, ""),
+                  `customSections(${format_value(argument)})`);
+  }
 }, "Non-Module arguments");
 
 test(() => {
   const module = new WebAssembly.Module(emptyModuleBinary);
   const fn = WebAssembly.Module.customSections;
   const thisValues = [
     undefined,
     null,
@@ -97,8 +110,53 @@ test(() => {
     bytes1,
   ])
 
   assert_sections(WebAssembly.Module.customSections(module, ""), [])
   assert_sections(WebAssembly.Module.customSections(module, "\0"), [])
   assert_sections(WebAssembly.Module.customSections(module, "name\0"), [])
   assert_sections(WebAssembly.Module.customSections(module, "foo\0"), [])
 }, "Custom sections");
+
+test(() => {
+  const bytes = [87, 101, 98, 65, 115, 115, 101, 109, 98, 108, 121];
+  const name = "yee\uD801\uDC37eey"
+
+  const binary = new Binary;
+  binary.emit_section(kUnknownSectionCode, section => {
+    section.emit_string(name);
+    section.emit_bytes(bytes);
+  });
+
+  const builder = new WasmModuleBuilder();
+  builder.addExplicitSection(binary);
+  const buffer = builder.toBuffer();
+  const module = new WebAssembly.Module(buffer);
+
+  assert_sections(WebAssembly.Module.customSections(module, name), [
+    bytes,
+  ]);
+  assert_sections(WebAssembly.Module.customSections(module, "yee\uFFFDeey"), []);
+  assert_sections(WebAssembly.Module.customSections(module, "yee\uFFFD\uFFFDeey"), []);
+}, "Custom sections with surrogate pairs");
+
+test(() => {
+  const bytes = [87, 101, 98, 65, 115, 115, 101, 109, 98, 108, 121];
+
+  const binary = new Binary;
+  binary.emit_section(kUnknownSectionCode, section => {
+    section.emit_string("na\uFFFDme");
+    section.emit_bytes(bytes);
+  });
+
+  const builder = new WasmModuleBuilder();
+  builder.addExplicitSection(binary);
+  const buffer = builder.toBuffer();
+  const module = new WebAssembly.Module(buffer);
+
+  assert_sections(WebAssembly.Module.customSections(module, "name"), []);
+  assert_sections(WebAssembly.Module.customSections(module, "na\uFFFDme"), [
+    bytes,
+  ]);
+  assert_sections(WebAssembly.Module.customSections(module, "na\uDC01me"), [
+    bytes,
+  ]);
+}, "Custom sections with U+FFFD");
--- a/testing/web-platform/tests/wasm/jsapi/module/exports.any.js
+++ b/testing/web-platform/tests/wasm/jsapi/module/exports.any.js
@@ -2,25 +2,64 @@
 // META: script=/wasm/jsapi/wasm-constants.js
 // META: script=/wasm/jsapi/wasm-module-builder.js
 
 let emptyModuleBinary;
 setup(() => {
   emptyModuleBinary = new WasmModuleBuilder().toBuffer();
 });
 
+function assert_ModuleExportDescriptor(export_, expected) {
+  assert_equals(Object.getPrototypeOf(export_), Object.prototype, "Prototype");
+  assert_true(Object.isExtensible(export_), "isExtensible");
+
+  const name = Object.getOwnPropertyDescriptor(export_, "name");
+  assert_true(name.writable, "name: writable");
+  assert_true(name.enumerable, "name: enumerable");
+  assert_true(name.configurable, "name: configurable");
+  assert_equals(name.value, expected.name);
+
+  const kind = Object.getOwnPropertyDescriptor(export_, "kind");
+  assert_true(kind.writable, "kind: writable");
+  assert_true(kind.enumerable, "kind: enumerable");
+  assert_true(kind.configurable, "kind: configurable");
+  assert_equals(kind.value, expected.kind);
+}
+
+function assert_exports(exports, expected) {
+  assert_true(Array.isArray(exports), "Should be array");
+  assert_equals(Object.getPrototypeOf(exports), Array.prototype, "Prototype");
+  assert_true(Object.isExtensible(exports), "isExtensible");
+
+  assert_equals(exports.length, expected.length);
+  for (let i = 0; i < expected.length; ++i) {
+    assert_ModuleExportDescriptor(exports[i], expected[i]);
+  }
+}
+
 test(() => {
   assert_throws(new TypeError(), () => WebAssembly.Module.exports());
 }, "Missing arguments");
 
 test(() => {
-  assert_throws(new TypeError(), () => WebAssembly.Module.exports({}));
-  assert_throws(new TypeError(), () => WebAssembly.Module.exports(""));
-  assert_throws(new TypeError(), () => WebAssembly.Module.exports(undefined));
-  assert_throws(new TypeError(), () => WebAssembly.Module.exports(null));
+  const invalidArguments = [
+    undefined,
+    null,
+    true,
+    "",
+    Symbol(),
+    1,
+    {},
+    WebAssembly.Module,
+    WebAssembly.Module.prototype,
+  ];
+  for (const argument of invalidArguments) {
+    assert_throws(new TypeError(), () => WebAssembly.Module.exports(argument),
+                  `exports(${format_value(argument)})`);
+  }
 }, "Non-Module arguments");
 
 test(() => {
   const module = new WebAssembly.Module(emptyModuleBinary);
   const fn = WebAssembly.Module.exports;
   const thisValues = [
     undefined,
     null,
@@ -35,48 +74,24 @@ test(() => {
   for (const thisValue of thisValues) {
     assert_array_equals(fn.call(thisValue, module), []);
   }
 }, "Branding");
 
 test(() => {
   const module = new WebAssembly.Module(emptyModuleBinary);
   const exports = WebAssembly.Module.exports(module);
-  assert_true(Array.isArray(exports));
-}, "Return type");
-
-test(() => {
-  const module = new WebAssembly.Module(emptyModuleBinary);
-  const exports = WebAssembly.Module.exports(module);
-  assert_true(Array.isArray(exports), "Should be array");
-  assert_equals(Object.getPrototypeOf(exports), Array.prototype, "Prototype");
-  assert_array_equals(exports, []);
+  assert_exports(exports, []);
 }, "Empty module");
 
 test(() => {
   const module = new WebAssembly.Module(emptyModuleBinary);
   assert_not_equals(WebAssembly.Module.exports(module), WebAssembly.Module.exports(module));
 }, "Empty module: array caching");
 
-function assert_ModuleExportDescriptor(export_, expected) {
-  assert_equals(Object.getPrototypeOf(export_), Object.prototype, "Prototype");
-
-  const name = Object.getOwnPropertyDescriptor(export_, "name");
-  assert_true(name.writable, "name: writable");
-  assert_true(name.enumerable, "name: enumerable");
-  assert_true(name.configurable, "name: configurable");
-  assert_equals(name.value, expected.name);
-
-  const kind = Object.getOwnPropertyDescriptor(export_, "kind");
-  assert_true(kind.writable, "kind: writable");
-  assert_true(kind.enumerable, "kind: enumerable");
-  assert_true(kind.configurable, "kind: configurable");
-  assert_equals(kind.value, expected.kind);
-}
-
 test(() => {
   const builder = new WasmModuleBuilder();
 
   builder
     .addFunction("fn", kSig_v_v)
     .addBody([
         kExprEnd
     ])
@@ -98,24 +113,18 @@ test(() => {
     .exportAs("global2")
     .init = 1.2;
 
   builder.addMemory(0, 256, true);
 
   const buffer = builder.toBuffer()
   const module = new WebAssembly.Module(buffer);
   const exports = WebAssembly.Module.exports(module);
-  assert_true(Array.isArray(exports), "Should be array");
-  assert_equals(Object.getPrototypeOf(exports), Array.prototype, "Prototype");
-
   const expected = [
     { "kind": "function", "name": "fn" },
     { "kind": "function", "name": "fn2" },
     { "kind": "table", "name": "table" },
     { "kind": "global", "name": "global" },
     { "kind": "global", "name": "global2" },
     { "kind": "memory", "name": "memory" },
   ];
-  assert_equals(exports.length, expected.length);
-  for (let i = 0; i < expected.length; ++i) {
-    assert_ModuleExportDescriptor(exports[i], expected[i]);
-  }
+  assert_exports(exports, expected);
 }, "exports");
--- a/testing/web-platform/tests/wasm/jsapi/module/imports.any.js
+++ b/testing/web-platform/tests/wasm/jsapi/module/imports.any.js
@@ -1,26 +1,71 @@
 // META: global=jsshell
 // META: script=/wasm/jsapi/wasm-constants.js
 // META: script=/wasm/jsapi/wasm-module-builder.js
 
+function assert_ModuleImportDescriptor(import_, expected) {
+  assert_equals(Object.getPrototypeOf(import_), Object.prototype, "Prototype");
+  assert_true(Object.isExtensible(import_), "isExtensible");
+
+  const module = Object.getOwnPropertyDescriptor(import_, "module");
+  assert_true(module.writable, "module: writable");
+  assert_true(module.enumerable, "module: enumerable");
+  assert_true(module.configurable, "module: configurable");
+  assert_equals(module.value, expected.module);
+
+  const name = Object.getOwnPropertyDescriptor(import_, "name");
+  assert_true(name.writable, "name: writable");
+  assert_true(name.enumerable, "name: enumerable");
+  assert_true(name.configurable, "name: configurable");
+  assert_equals(name.value, expected.name);
+
+  const kind = Object.getOwnPropertyDescriptor(import_, "kind");
+  assert_true(kind.writable, "kind: writable");
+  assert_true(kind.enumerable, "kind: enumerable");
+  assert_true(kind.configurable, "kind: configurable");
+  assert_equals(kind.value, expected.kind);
+}
+
+function assert_imports(imports, expected) {
+  assert_true(Array.isArray(imports), "Should be array");
+  assert_equals(Object.getPrototypeOf(imports), Array.prototype, "Prototype");
+  assert_true(Object.isExtensible(imports), "isExtensible");
+
+  assert_equals(imports.length, expected.length);
+  for (let i = 0; i < expected.length; ++i) {
+    assert_ModuleImportDescriptor(imports[i], expected[i]);
+  }
+}
+
 let emptyModuleBinary;
 setup(() => {
   emptyModuleBinary = new WasmModuleBuilder().toBuffer();
 });
 
 test(() => {
   assert_throws(new TypeError(), () => WebAssembly.Module.imports());
 }, "Missing arguments");
 
 test(() => {
-  assert_throws(new TypeError(), () => WebAssembly.Module.imports({}));
-  assert_throws(new TypeError(), () => WebAssembly.Module.imports(""));
-  assert_throws(new TypeError(), () => WebAssembly.Module.imports(undefined));
-  assert_throws(new TypeError(), () => WebAssembly.Module.imports(null));
+  const invalidArguments = [
+    undefined,
+    null,
+    true,
+    "",
+    Symbol(),
+    1,
+    {},
+    WebAssembly.Module,
+    WebAssembly.Module.prototype,
+  ];
+  for (const argument of invalidArguments) {
+    assert_throws(new TypeError(), () => WebAssembly.Module.imports(argument),
+                  `imports(${format_value(argument)})`);
+  }
 }, "Non-Module arguments");
 
 test(() => {
   const module = new WebAssembly.Module(emptyModuleBinary);
   const fn = WebAssembly.Module.imports;
   const thisValues = [
     undefined,
     null,
@@ -41,65 +86,35 @@ test(() => {
   const module = new WebAssembly.Module(emptyModuleBinary);
   const imports = WebAssembly.Module.imports(module);
   assert_true(Array.isArray(imports));
 }, "Return type");
 
 test(() => {
   const module = new WebAssembly.Module(emptyModuleBinary);
   const imports = WebAssembly.Module.imports(module);
-  assert_true(Array.isArray(imports), "Should be array");
-  assert_equals(Object.getPrototypeOf(imports), Array.prototype, "Prototype");
-  assert_array_equals(imports, []);
+  assert_imports(imports, []);
 }, "Empty module");
 
 test(() => {
   const module = new WebAssembly.Module(emptyModuleBinary);
   assert_not_equals(WebAssembly.Module.imports(module), WebAssembly.Module.imports(module));
 }, "Empty module: array caching");
 
-function assert_ModuleImportDescriptor(import_, expected) {
-  assert_equals(Object.getPrototypeOf(import_), Object.prototype, "Prototype");
-
-  const module = Object.getOwnPropertyDescriptor(import_, "module");
-  assert_true(module.writable, "module: writable");
-  assert_true(module.enumerable, "module: enumerable");
-  assert_true(module.configurable, "module: configurable");
-  assert_equals(module.value, expected.module);
-
-  const name = Object.getOwnPropertyDescriptor(import_, "name");
-  assert_true(name.writable, "name: writable");
-  assert_true(name.enumerable, "name: enumerable");
-  assert_true(name.configurable, "name: configurable");
-  assert_equals(name.value, expected.name);
-
-  const kind = Object.getOwnPropertyDescriptor(import_, "kind");
-  assert_true(kind.writable, "kind: writable");
-  assert_true(kind.enumerable, "kind: enumerable");
-  assert_true(kind.configurable, "kind: configurable");
-  assert_equals(kind.value, expected.kind);
-}
-
 test(() => {
   const builder = new WasmModuleBuilder();
 
   builder.addImport("module", "fn", kSig_v_v);
   builder.addImportedGlobal("module", "global", kWasmI32);
   builder.addImportedMemory("module", "memory", 0, 128);
   builder.addImportedTable("module", "table", 0, 128);
 
   const buffer = builder.toBuffer()
   const module = new WebAssembly.Module(buffer);
   const imports = WebAssembly.Module.imports(module);
-  assert_true(Array.isArray(imports), "Should be array");
-  assert_equals(Object.getPrototypeOf(imports), Array.prototype, "Prototype");
-
   const expected = [
     { "module": "module", "kind": "function", "name": "fn" },
     { "module": "module", "kind": "global", "name": "global" },
     { "module": "module", "kind": "memory", "name": "memory" },
     { "module": "module", "kind": "table", "name": "table" },
   ];
-  assert_equals(imports.length, expected.length);
-  for (let i = 0; i < expected.length; ++i) {
-    assert_ModuleImportDescriptor(imports[i], expected[i]);
-  }
+  assert_imports(imports, expected);
 }, "imports");
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/wasm/jsapi/module/toString.any.js
@@ -0,0 +1,9 @@
+// META: global=jsshell
+// META: script=/wasm/jsapi/wasm-constants.js
+// META: script=/wasm/jsapi/wasm-module-builder.js
+
+test(() => {
+  const emptyModuleBinary = new WasmModuleBuilder().toBuffer();
+  const module = new WebAssembly.Module(emptyModuleBinary);
+  assert_class_string(module, "WebAssembly.Module");
+}, "Object.prototype.toString on an Module");
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/wasm/jsapi/table/assertions.js
@@ -0,0 +1,11 @@
+function assert_equal_to_array(table, expected, message) {
+  assert_equals(table.length, expected.length, `${message}: length`);
+  assert_throws(new RangeError(), () => table.get(-1), `${message}: table.get(-1)`);
+  for (let i = 0; i < expected.length; ++i) {
+    assert_equals(table.get(i), expected[i], `${message}: table.get(${i} of ${expected.length})`);
+  }
+  assert_throws(new RangeError(), () => table.get(expected.length),
+                `${message}: table.get(${expected.length} of ${expected.length})`);
+  assert_throws(new RangeError(), () => table.get(expected.length + 1),
+                `${message}: table.get(${expected.length + 1} of ${expected.length})`);
+}
--- a/testing/web-platform/tests/wasm/jsapi/table/constructor.any.js
+++ b/testing/web-platform/tests/wasm/jsapi/table/constructor.any.js
@@ -1,40 +1,64 @@
 // META: global=jsshell
-// META: script=/wasm/jsapi/wasm-constants.js
-// META: script=/wasm/jsapi/wasm-module-builder.js
 // META: script=/wasm/jsapi/assertions.js
 
-let emptyModuleBinary;
-setup(() => {
-  emptyModuleBinary = new WasmModuleBuilder().toBuffer();
-});
+function assert_Table(actual, expected) {
+  assert_equals(Object.getPrototypeOf(actual), WebAssembly.Table.prototype,
+                "prototype");
+  assert_true(Object.isExtensible(actual), "extensible");
+
+  assert_equals(actual.length, expected.length, "length");
+  for (let i = 0; i < expected.length; ++i) {
+    assert_equals(actual.get(i), null, `actual.get(${i})`);
+  }
+}
 
 test(() => {
   assert_function_name(WebAssembly.Table, "Table", "WebAssembly.Table");
 }, "name");
 
 test(() => {
   assert_function_length(WebAssembly.Table, 1, "WebAssembly.Table");
 }, "length");
 
 test(() => {
   assert_throws(new TypeError(), () => new WebAssembly.Table());
 }, "No arguments");
 
 test(() => {
-  const argument = { "initial": 0 };
+  const argument = { "element": "anyfunc", "initial": 0 };
   assert_throws(new TypeError(), () => WebAssembly.Table(argument));
 }, "Calling");
 
 test(() => {
   assert_throws(new TypeError(), () => new WebAssembly.Table({}));
 }, "Empty descriptor");
 
 test(() => {
+  const invalidArguments = [
+    undefined,
+    null,
+    false,
+    true,
+    "",
+    "test",
+    Symbol(),
+    1,
+    NaN,
+    {},
+  ];
+  for (const invalidArgument of invalidArguments) {
+    assert_throws(new TypeError(),
+                  () => new WebAssembly.Table(invalidArgument),
+                  `new Table(${format_value(invalidArgument)})`);
+  }
+}, "Invalid descriptor argument");
+
+test(() => {
   assert_throws(new TypeError(), () => new WebAssembly.Table({ "element": "anyfunc", "initial": undefined }));
 }, "Undefined initial value in descriptor");
 
 test(() => {
   assert_throws(new TypeError(), () => new WebAssembly.Table({ "element": undefined, "initial": 0 }));
 }, "Undefined element value in descriptor");
 
 const outOfRangeValues = [
@@ -52,32 +76,98 @@ for (const value of outOfRangeValues) {
   }, `Out-of-range initial value in descriptor: ${format_value(value)}`);
 
   test(() => {
     assert_throws(new TypeError(), () => new WebAssembly.Table({ "element": "anyfunc", "initial": 0, "maximum": value }));
   }, `Out-of-range maximum value in descriptor: ${format_value(value)}`);
 }
 
 test(() => {
+  assert_throws(new RangeError(), () => new WebAssembly.Table({ "element": "anyfunc", "initial": 10, "maximum": 9 }));
+}, "Initial value exceeds maximum");
+
+test(() => {
+  const argument = { "element": "anyfunc", "initial": 0 };
+  const table = new WebAssembly.Table(argument);
+  assert_Table(table, { "length": 0 });
+}, "Basic (zero)");
+
+test(() => {
+  const argument = { "element": "anyfunc", "initial": 5 };
+  const table = new WebAssembly.Table(argument);
+  assert_Table(table, { "length": 5 });
+}, "Basic (non-zero)");
+
+test(() => {
   const proxy = new Proxy({}, {
     has(o, x) {
       assert_unreached(`Should not call [[HasProperty]] with ${x}`);
     },
     get(o, x) {
       switch (x) {
       case "element":
         return "anyfunc";
       case "initial":
       case "maximum":
         return 0;
       default:
         return undefined;
       }
     },
   });
-  new WebAssembly.Table(proxy);
+  const table = new WebAssembly.Table(proxy);
+  assert_Table(table, { "length": 0 });
 }, "Proxy descriptor");
 
 test(() => {
-  const argument = { "element": "anyfunc", "initial": 0 };
-  const table = new WebAssembly.Table(argument);
-  assert_equals(Object.getPrototypeOf(table), WebAssembly.Table.prototype);
-}, "Prototype");
+  const table = new WebAssembly.Table({
+    "element": {
+      toString() { return "anyfunc"; },
+    },
+    "initial": 1,
+  });
+  assert_Table(table, { "length": 1 });
+}, "Type conversion for descriptor.element");
+
+test(() => {
+  const order = [];
+
+  new WebAssembly.Table({
+    get maximum() {
+      order.push("maximum");
+      return {
+        valueOf() {
+          order.push("maximum valueOf");
+          return 1;
+        },
+      };
+    },
+
+    get initial() {
+      order.push("initial");
+      return {
+        valueOf() {
+          order.push("initial valueOf");
+          return 1;
+        },
+      };
+    },
+
+    get element() {
+      order.push("element");
+      return {
+        toString() {
+          order.push("element toString");
+          return "anyfunc";
+        },
+      };
+    },
+  });
+
+  assert_array_equals(order, [
+    "element",
+    "element toString",
+    "initial",
+    "initial valueOf",
+    "maximum",
+    "maximum valueOf",
+  ]);
+}, "Order of evaluation for descriptor");
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/wasm/jsapi/table/get-set.any.js
@@ -0,0 +1,220 @@
+// META: global=jsshell
+// META: script=/wasm/jsapi/wasm-constants.js
+// META: script=/wasm/jsapi/wasm-module-builder.js
+// META: script=assertions.js
+
+let functions;
+setup(() => {
+  const builder = new WasmModuleBuilder();
+
+  builder
+    .addFunction("fn", kSig_v_d)
+    .addBody([
+        kExprEnd
+    ])
+    .exportFunc();
+  builder
+    .addFunction("fn2", kSig_v_v)
+    .addBody([
+        kExprEnd
+    ])
+    .exportFunc();
+
+  const buffer = builder.toBuffer()
+  const module = new WebAssembly.Module(buffer);
+  const instance = new WebAssembly.Instance(module, {});
+  functions = instance.exports;
+});
+
+test(() => {
+  const argument = { "element": "anyfunc", "initial": 5 };
+  const table = new WebAssembly.Table(argument);
+  assert_throws(new TypeError(), () => table.get());
+}, "Missing arguments: get");
+
+test(t => {
+  const thisValues = [
+    undefined,
+    null,
+    true,
+    "",
+    Symbol(),
+    1,
+    {},
+    WebAssembly.Table,
+    WebAssembly.Table.prototype,
+  ];
+
+  const argument = {
+    valueOf: t.unreached_func("Should not touch the argument (valueOf)"),
+    toString: t.unreached_func("Should not touch the argument (toString)"),
+  };
+
+  const fn = WebAssembly.Table.prototype.get;
+
+  for (const thisValue of thisValues) {
+    assert_throws(new TypeError(), () => fn.call(thisValue, argument), `this=${format_value(thisValue)}`);
+  }
+}, "Branding: get");
+
+test(() => {
+  const argument = { "element": "anyfunc", "initial": 5 };
+  const table = new WebAssembly.Table(argument);
+  assert_throws(new TypeError(), () => table.set());
+  assert_throws(new TypeError(), () => table.set(0));
+}, "Missing arguments: set");
+
+test(t => {
+  const thisValues = [
+    undefined,
+    null,
+    true,
+    "",
+    Symbol(),
+    1,
+    {},
+    WebAssembly.Table,
+    WebAssembly.Table.prototype,
+  ];
+
+  const argument = {
+    valueOf: t.unreached_func("Should not touch the argument (valueOf)"),
+    toString: t.unreached_func("Should not touch the argument (toString)"),
+  };
+
+  const fn = WebAssembly.Table.prototype.set;
+
+  for (const thisValue of thisValues) {
+    assert_throws(new TypeError(), () => fn.call(thisValue, argument, null), `this=${format_value(thisValue)}`);
+  }
+}, "Branding: set");
+
+test(() => {
+  const argument = { "element": "anyfunc", "initial": 5 };
+  const table = new WebAssembly.Table(argument);
+  assert_equal_to_array(table, [null, null, null, null, null]);
+
+  const {fn, fn2} = functions;
+
+  assert_equals(table.set(0, fn), undefined, "set() returns undefined.");
+  table.set(2, fn2);
+  table.set(4, fn);
+
+  assert_equal_to_array(table, [fn, null, fn2, null, fn]);
+
+  table.set(0, null);
+  assert_equal_to_array(table, [null, null, fn2, null, fn]);
+}, "Basic");
+
+test(() => {
+  const argument = { "element": "anyfunc", "initial": 5 };
+  const table = new WebAssembly.Table(argument);
+  assert_equal_to_array(table, [null, null, null, null, null]);
+
+  const {fn, fn2} = functions;
+
+  table.set(0, fn);
+  table.set(2, fn2);
+  table.set(4, fn);
+
+  assert_equal_to_array(table, [fn, null, fn2, null, fn]);
+
+  table.grow(4);
+
+  assert_equal_to_array(table, [fn, null, fn2, null, fn, null, null, null, null]);
+}, "Growing");
+
+test(() => {
+  const argument = { "element": "anyfunc", "initial": 5 };
+  const table = new WebAssembly.Table(argument);
+  assert_equal_to_array(table, [null, null, null, null, null]);
+
+  const {fn} = functions;
+
+  assert_throws(new RangeError(), () => table.set(-1, fn));
+  assert_throws(new RangeError(), () => table.set(5, fn));
+  assert_equal_to_array(table, [null, null, null, null, null]);
+}, "Setting out-of-bounds");
+
+test(() => {
+  const argument = { "element": "anyfunc", "initial": 1 };
+  const table = new WebAssembly.Table(argument);
+  assert_equal_to_array(table, [null]);
+
+  const invalidArguments = [
+    undefined,
+    true,
+    false,
+    "test",
+    Symbol(),
+    7,
+    NaN,
+    {},
+  ];
+  for (const argument of invalidArguments) {
+    assert_throws(new TypeError(), () => table.set(0, argument),
+                  `set(${format_value(argument)})`);
+  }
+  assert_equal_to_array(table, [null]);
+}, "Setting non-function");
+
+test(() => {
+  const argument = { "element": "anyfunc", "initial": 1 };
+  const table = new WebAssembly.Table(argument);
+  assert_equal_to_array(table, [null]);
+
+  const fn = function() {};
+  assert_throws(new TypeError(), () => table.set(0, fn));
+  assert_equal_to_array(table, [null]);
+}, "Setting non-wasm function");
+
+test(() => {
+  const argument = { "element": "anyfunc", "initial": 1 };
+  const table = new WebAssembly.Table(argument);
+  assert_equal_to_array(table, [null]);
+
+  const fn = () => {};
+  assert_throws(new TypeError(), () => table.set(0, fn));
+  assert_equal_to_array(table, [null]);
+}, "Setting non-wasm arrow function");
+
+const outOfRangeValues = [
+  undefined,
+  NaN,
+  Infinity,
+  -Infinity,
+  -1,
+  0x100000000,
+  0x1000000000,
+  "0x100000000",
+  { valueOf() { return 0x100000000; } },
+];
+
+for (const value of outOfRangeValues) {
+  test(() => {
+    const argument = { "element": "anyfunc", "initial": 1 };
+    const table = new WebAssembly.Table(argument);
+    assert_throws(new TypeError(), () => table.get(value));
+  }, `Getting out-of-range argument: ${format_value(value)}`);
+
+  test(() => {
+    const argument = { "element": "anyfunc", "initial": 1 };
+    const table = new WebAssembly.Table(argument);
+    assert_throws(new TypeError(), () => table.set(value, null));
+  }, `Setting out-of-range argument: ${format_value(value)}`);
+}
+
+test(() => {
+  const argument = { "element": "anyfunc", "initial": 1 };
+  const table = new WebAssembly.Table(argument);
+  let called = 0;
+  const value = {
+    valueOf() {
+      called++;
+      return 0;
+    },
+  };
+  assert_throws(new TypeError(), () => table.set(value, {}));
+  assert_equals(called, 1);
+}, "Order of argument conversion");
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/wasm/jsapi/table/grow.any.js
@@ -0,0 +1,86 @@
+// META: global=jsshell
+// META: script=assertions.js
+
+function nulls(n) {
+  return Array(n).fill(null);
+}
+
+test(() => {
+  const argument = { "element": "anyfunc", "initial": 5 };
+  const table = new WebAssembly.Table(argument);
+  assert_throws(new TypeError(), () => table.grow());
+}, "Missing arguments");
+
+test(t => {
+  const thisValues = [
+    undefined,
+    null,
+    true,
+    "",
+    Symbol(),
+    1,
+    {},
+    WebAssembly.Table,
+    WebAssembly.Table.prototype,
+  ];
+
+  const argument = {
+    valueOf: t.unreached_func("Should not touch the argument (valueOf)"),
+    toString: t.unreached_func("Should not touch the argument (toString)"),
+  };
+
+  const fn = WebAssembly.Table.prototype.grow;
+
+  for (const thisValue of thisValues) {
+    assert_throws(new TypeError(), () => fn.call(thisValue, argument), `this=${format_value(thisValue)}`);
+  }
+}, "Branding");
+
+test(() => {
+  const argument = { "element": "anyfunc", "initial": 5 };
+  const table = new WebAssembly.Table(argument);
+  assert_equal_to_array(table, nulls(5), "before");
+
+  const result = table.grow(3);
+  assert_equals(result, 5);
+  assert_equal_to_array(table, nulls(8), "after");
+}, "Basic");
+
+test(() => {
+  const argument = { "element": "anyfunc", "initial": 3, "maximum": 5 };
+  const table = new WebAssembly.Table(argument);
+  assert_equal_to_array(table, nulls(3), "before");
+
+  const result = table.grow(2);
+  assert_equals(result, 3);
+  assert_equal_to_array(table, nulls(5), "after");
+}, "Reached maximum");
+
+test(() => {
+  const argument = { "element": "anyfunc", "initial": 2, "maximum": 5 };
+  const table = new WebAssembly.Table(argument);
+  assert_equal_to_array(table, nulls(2), "before");
+
+  assert_throws(new RangeError(), () => table.grow(4));
+  assert_equal_to_array(table, nulls(2), "after");
+}, "Exceeded maximum");
+
+const outOfRangeValues = [
+  undefined,
+  NaN,
+  Infinity,
+  -Infinity,
+  -1,
+  0x100000000,
+  0x1000000000,
+  "0x100000000",
+  { valueOf() { return 0x100000000; } },
+];
+
+for (const value of outOfRangeValues) {
+  test(() => {
+    const argument = { "element": "anyfunc", "initial": 1 };
+    const table = new WebAssembly.Table(argument);
+    assert_throws(new TypeError(), () => table.grow(value));
+  }, `Out-of-range argument: ${format_value(value)}`);
+}
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/wasm/jsapi/table/length.any.js
@@ -0,0 +1,46 @@
+// META: global=jsshell
+
+test(() => {
+  const thisValues = [
+    undefined,
+    null,
+    true,
+    "",
+    Symbol(),
+    1,
+    {},
+    WebAssembly.Table,
+    WebAssembly.Table.prototype,
+  ];
+
+  const desc = Object.getOwnPropertyDescriptor(WebAssembly.Table.prototype, "length");
+  assert_equals(typeof desc, "object");
+
+  const getter = desc.get;
+  assert_equals(typeof getter, "function");
+
+  assert_equals(typeof desc.set, "undefined");
+
+  for (const thisValue of thisValues) {
+    assert_throws(new TypeError(), () => getter.call(thisValue), `this=${format_value(thisValue)}`);
+  }
+}, "Branding");
+
+test(() => {
+  const argument = { "element": "anyfunc", "initial": 2 };
+  const table = new WebAssembly.Table(argument);
+  assert_equals(table.length, 2, "Initial length");
+  table.length = 4;
+  assert_equals(table.length, 2, "Should not change the length");
+}, "Setting (sloppy mode)");
+
+test(() => {
+  const argument = { "element": "anyfunc", "initial": 2 };
+  const table = new WebAssembly.Table(argument);
+  assert_equals(table.length, 2, "Initial length");
+  assert_throws(new TypeError(), () => {
+    "use strict";
+    table.length = 4;
+  });
+  assert_equals(table.length, 2, "Should not change the length");
+}, "Setting (strict mode)");
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/wasm/jsapi/table/toString.any.js
@@ -0,0 +1,7 @@
+// META: global=jsshell
+
+test(() => {
+  const argument = { "element": "anyfunc", "initial": 0 };
+  const table = new WebAssembly.Table(argument);
+  assert_class_string(table, "WebAssembly.Table");
+}, "Object.prototype.toString on an Table");