OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 // Flags: --expose-wasm --allow-natives-syntax |
| 6 |
| 7 if ((typeof drainJobQueue) != "function") { |
| 8 drainJobQueue = () => { %RunMicrotasks() }; |
| 9 } |
| 10 |
| 11 load("test/mjsunit/wasm/wasm-constants.js"); |
| 12 load("test/mjsunit/wasm/wasm-module-builder.js"); |
| 13 |
| 14 function assertEq(val, expected) { |
| 15 assertEquals(expected, val); |
| 16 } |
| 17 function wasmIsSupported() { |
| 18 return (typeof WebAssembly.Module) == "function"; |
| 19 } |
| 20 function assertErrorMessage(func, type, msg) { |
| 21 //TODO assertThrows(func, type, msg); |
| 22 assertThrows(func, type); |
| 23 } |
| 24 |
| 25 let PROP_FLAGS = false; // property flags are implemented correctly |
| 26 |
| 27 let emptyModuleBinary = (() => { |
| 28 var builder = new WasmModuleBuilder(); |
| 29 return new Int8Array(builder.toBuffer()); |
| 30 })(); |
| 31 |
| 32 let exportingModuleBinary = (() => { |
| 33 var builder = new WasmModuleBuilder(); |
| 34 builder.addFunction("f", kSig_i_v) |
| 35 .addBody([kExprI32Const, 42]) |
| 36 .exportAs("f"); |
| 37 return new Int8Array(builder.toBuffer()); |
| 38 })(); |
| 39 |
| 40 let importingModuleBinary = (() => { |
| 41 var builder = new WasmModuleBuilder(); |
| 42 builder.addImport("f", kSig_i_v); |
| 43 return new Int8Array(builder.toBuffer()); |
| 44 })(); |
| 45 |
| 46 // 'WebAssembly' data property on global object |
| 47 let wasmDesc = Object.getOwnPropertyDescriptor(this, 'WebAssembly'); |
| 48 assertEq(typeof wasmDesc.value, "object"); |
| 49 assertEq(wasmDesc.writable, true); |
| 50 assertEq(wasmDesc.enumerable, false); |
| 51 assertEq(wasmDesc.configurable, true); |
| 52 |
| 53 // 'WebAssembly' object |
| 54 assertEq(WebAssembly, wasmDesc.value); |
| 55 //TODO assertEq(String(WebAssembly), "[object WebAssembly]"); |
| 56 |
| 57 // 'WebAssembly.(Compile|Runtime)Error' data property |
| 58 let compileErrorDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'CompileErro
r'); |
| 59 let runtimeErrorDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'RuntimeErro
r'); |
| 60 assertEq(typeof compileErrorDesc.value, "function"); |
| 61 assertEq(typeof runtimeErrorDesc.value, "function"); |
| 62 if (PROP_FLAGS) assertEq(compileErrorDesc.writable, true); |
| 63 if (PROP_FLAGS) assertEq(runtimeErrorDesc.writable, true); |
| 64 if (PROP_FLAGS) assertEq(compileErrorDesc.enumerable, false); |
| 65 if (PROP_FLAGS) assertEq(runtimeErrorDesc.enumerable, false); |
| 66 if (PROP_FLAGS) assertEq(compileErrorDesc.configurable, true); |
| 67 if (PROP_FLAGS) assertEq(runtimeErrorDesc.configurable, true); |
| 68 |
| 69 // 'WebAssembly.(Compile|Runtime)Error' constructor function |
| 70 let CompileError = WebAssembly.CompileError; |
| 71 let RuntimeError = WebAssembly.RuntimeError; |
| 72 assertEq(CompileError, compileErrorDesc.value); |
| 73 assertEq(RuntimeError, runtimeErrorDesc.value); |
| 74 assertEq(CompileError.length, 1); |
| 75 assertEq(RuntimeError.length, 1); |
| 76 assertEq(CompileError.name, "CompileError"); |
| 77 assertEq(RuntimeError.name, "RuntimeError"); |
| 78 |
| 79 // 'WebAssembly.(Compile|Runtime)Error' instance objects |
| 80 let compileError = new CompileError; |
| 81 let runtimeError = new RuntimeError; |
| 82 assertEq(compileError instanceof CompileError, true); |
| 83 assertEq(runtimeError instanceof RuntimeError, true); |
| 84 assertEq(compileError instanceof Error, true); |
| 85 assertEq(runtimeError instanceof Error, true); |
| 86 assertEq(compileError instanceof TypeError, false); |
| 87 assertEq(runtimeError instanceof TypeError, false); |
| 88 assertEq(compileError.message, ""); |
| 89 assertEq(runtimeError.message, ""); |
| 90 assertEq(new CompileError("hi").message, "hi"); |
| 91 assertEq(new RuntimeError("hi").message, "hi"); |
| 92 |
| 93 // 'WebAssembly.Module' data property |
| 94 let moduleDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'Module'); |
| 95 assertEq(typeof moduleDesc.value, "function"); |
| 96 assertEq(moduleDesc.writable, true); |
| 97 assertEq(moduleDesc.enumerable, false); |
| 98 assertEq(moduleDesc.configurable, true); |
| 99 |
| 100 // 'WebAssembly.Module' constructor function |
| 101 let Module = WebAssembly.Module; |
| 102 assertEq(Module, moduleDesc.value); |
| 103 //TODO assertEq(Module.length, 1); |
| 104 //TODO assertEq(Module.name, "Module"); |
| 105 assertErrorMessage(() => Module(), TypeError, /constructor without new is forbid
den/); |
| 106 assertErrorMessage(() => new Module(), TypeError, /requires more than 0 argument
s/); |
| 107 assertErrorMessage(() => new Module(undefined), TypeError, "first argument must
be an ArrayBuffer or typed array object"); |
| 108 assertErrorMessage(() => new Module(1), TypeError, "first argument must be an Ar
rayBuffer or typed array object"); |
| 109 assertErrorMessage(() => new Module({}), TypeError, "first argument must be an A
rrayBuffer or typed array object"); |
| 110 //TODO assertErrorMessage(() => new Module(new Uint8Array()), CompileError, /fai
led to match magic number/); |
| 111 //TODO assertErrorMessage(() => new Module(new ArrayBuffer()), CompileError, /fa
iled to match magic number/); |
| 112 assertEq(new Module(emptyModuleBinary) instanceof Module, true); |
| 113 assertEq(new Module(emptyModuleBinary.buffer) instanceof Module, true); |
| 114 |
| 115 // 'WebAssembly.Module.prototype' data property |
| 116 let moduleProtoDesc = Object.getOwnPropertyDescriptor(Module, 'prototype'); |
| 117 assertEq(typeof moduleProtoDesc.value, "object"); |
| 118 if (PROP_FLAGS) assertEq(moduleProtoDesc.writable, false); |
| 119 if (PROP_FLAGS) assertEq(moduleProtoDesc.enumerable, false); |
| 120 if (PROP_FLAGS) assertEq(moduleProtoDesc.configurable, false); |
| 121 |
| 122 // 'WebAssembly.Module.prototype' object |
| 123 let moduleProto = Module.prototype; |
| 124 assertEq(moduleProto, moduleProtoDesc.value); |
| 125 assertEq(String(moduleProto), "[object Object]"); |
| 126 assertEq(Object.getPrototypeOf(moduleProto), Object.prototype); |
| 127 |
| 128 // 'WebAssembly.Module' instance objects |
| 129 let emptyModule = new Module(emptyModuleBinary); |
| 130 let importingModule = new Module(importingModuleBinary); |
| 131 let exportingModule = new Module(exportingModuleBinary); |
| 132 assertEq(typeof emptyModule, "object"); |
| 133 //TODO assertEq(String(emptyModule), "[object WebAssembly.Module]"); |
| 134 assertEq(Object.getPrototypeOf(emptyModule), moduleProto); |
| 135 |
| 136 if (false) { // TODO: Module.imports support |
| 137 // 'WebAssembly.Module.imports' data property |
| 138 let moduleImportsDesc = Object.getOwnPropertyDescriptor(Module, 'imports'); |
| 139 assertEq(typeof moduleImportsDesc.value, "function"); |
| 140 assertEq(moduleImportsDesc.writable, true); |
| 141 assertEq(moduleImportsDesc.enumerable, false); |
| 142 assertEq(moduleImportsDesc.configurable, true); |
| 143 |
| 144 // 'WebAssembly.Module.imports' method |
| 145 let moduleImports = moduleImportsDesc.value; |
| 146 assertEq(moduleImports.length, 1); |
| 147 assertErrorMessage(() => moduleImports(), TypeError, /requires more than 0 argum
ents/); |
| 148 assertErrorMessage(() => moduleImports(undefined), TypeError, /first argument mu
st be a WebAssembly.Module/); |
| 149 assertErrorMessage(() => moduleImports({}), TypeError, /first argument must be a
WebAssembly.Module/); |
| 150 var arr = moduleImports(new Module(wasmTextToBinary('(module)'))); |
| 151 assertEq(arr instanceof Array, true); |
| 152 assertEq(arr.length, 0); |
| 153 var arr = moduleImports(new Module(wasmTextToBinary('(module (func (import "a" "
b")) (memory (import "c" "d") 1) (table (import "e" "f") 1 anyfunc) (global (imp
ort "g" "⚡") i32))'))); |
| 154 assertEq(arr instanceof Array, true); |
| 155 assertEq(arr.length, 4); |
| 156 assertEq(arr[0].kind, "function"); |
| 157 assertEq(arr[0].module, "a"); |
| 158 assertEq(arr[0].name, "b"); |
| 159 assertEq(arr[1].kind, "memory"); |
| 160 assertEq(arr[1].module, "c"); |
| 161 assertEq(arr[1].name, "d"); |
| 162 assertEq(arr[2].kind, "table"); |
| 163 assertEq(arr[2].module, "e"); |
| 164 assertEq(arr[2].name, "f"); |
| 165 assertEq(arr[3].kind, "global"); |
| 166 assertEq(arr[3].module, "g"); |
| 167 assertEq(arr[3].name, "⚡"); |
| 168 } |
| 169 |
| 170 if (false) { // TODO: Module.exports property |
| 171 // 'WebAssembly.Module.exports' data property |
| 172 let moduleExportsDesc = Object.getOwnPropertyDescriptor(Module, 'exports'); |
| 173 assertEq(typeof moduleExportsDesc.value, "function"); |
| 174 assertEq(moduleExportsDesc.writable, true); |
| 175 assertEq(moduleExportsDesc.enumerable, false); |
| 176 assertEq(moduleExportsDesc.configurable, true); |
| 177 |
| 178 // 'WebAssembly.Module.exports' method |
| 179 let moduleExports = moduleExportsDesc.value; |
| 180 assertEq(moduleExports.length, 1); |
| 181 assertErrorMessage(() => moduleExports(), TypeError, /requires more than 0 argum
ents/); |
| 182 assertErrorMessage(() => moduleExports(undefined), TypeError, /first argument mu
st be a WebAssembly.Module/); |
| 183 assertErrorMessage(() => moduleExports({}), TypeError, /first argument must be a
WebAssembly.Module/); |
| 184 var arr = moduleExports(emptyModule); |
| 185 assertEq(arr instanceof Array, true); |
| 186 assertEq(arr.length, 0); |
| 187 var arr = moduleExports(new Module(wasmTextToBinary('(module (func (export "a"))
(memory (export "b") 1) (table (export "c") 1 anyfunc) (global (export "⚡") i32
(i32.const 0)))'))); |
| 188 assertEq(arr instanceof Array, true); |
| 189 assertEq(arr.length, 4); |
| 190 assertEq(arr[0].kind, "function"); |
| 191 assertEq(arr[0].name, "a"); |
| 192 assertEq(arr[1].kind, "memory"); |
| 193 assertEq(arr[1].name, "b"); |
| 194 assertEq(arr[2].kind, "table"); |
| 195 assertEq(arr[2].name, "c"); |
| 196 assertEq(arr[3].kind, "global"); |
| 197 assertEq(arr[3].name, "⚡"); |
| 198 } |
| 199 |
| 200 // 'WebAssembly.Instance' data property |
| 201 let instanceDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'Instance'); |
| 202 assertEq(typeof instanceDesc.value, "function"); |
| 203 assertEq(instanceDesc.writable, true); |
| 204 assertEq(instanceDesc.enumerable, false); |
| 205 assertEq(instanceDesc.configurable, true); |
| 206 |
| 207 // 'WebAssembly.Instance' constructor function |
| 208 let Instance = WebAssembly.Instance; |
| 209 assertEq(Instance, instanceDesc.value); |
| 210 //TODO assertEq(Instance.length, 1); |
| 211 //TODO assertEq(Instance.name, "Instance"); |
| 212 assertErrorMessage(() => Instance(), TypeError, /constructor without new is forb
idden/); |
| 213 assertErrorMessage(() => new Instance(1), TypeError, "first argument must be a W
ebAssembly.Module"); |
| 214 assertErrorMessage(() => new Instance({}), TypeError, "first argument must be a
WebAssembly.Module"); |
| 215 //TODO assertErrorMessage(() => new Instance(emptyModule, null), TypeError, "sec
ond argument must be an object"); |
| 216 //TODO assertEq(new Instance(emptyModule) instanceof Instance, true); |
| 217 //TODO assertEq(new Instance(emptyModule, {}) instanceof Instance, true); |
| 218 |
| 219 // 'WebAssembly.Instance.prototype' data property |
| 220 let instanceProtoDesc = Object.getOwnPropertyDescriptor(Instance, 'prototype'); |
| 221 assertEq(typeof instanceProtoDesc.value, "object"); |
| 222 if (PROP_FLAGS) assertEq(instanceProtoDesc.writable, false); |
| 223 if (PROP_FLAGS) assertEq(instanceProtoDesc.enumerable, false); |
| 224 if (PROP_FLAGS) assertEq(instanceProtoDesc.configurable, false); |
| 225 |
| 226 // 'WebAssembly.Instance.prototype' object |
| 227 let instanceProto = Instance.prototype; |
| 228 assertEq(instanceProto, instanceProtoDesc.value); |
| 229 assertEq(String(instanceProto), "[object Object]"); |
| 230 assertEq(Object.getPrototypeOf(instanceProto), Object.prototype); |
| 231 |
| 232 // 'WebAssembly.Instance' instance objects |
| 233 let exportingInstance = new Instance(exportingModule); |
| 234 assertEq(typeof exportingInstance, "object"); |
| 235 //TODO:name assertEq(String(exportingInstance), "[object WebAssembly.Instance]")
; |
| 236 //TODO assertEq(Object.getPrototypeOf(exportingInstance), instanceProto); |
| 237 |
| 238 // 'WebAssembly.Instance' 'exports' data property |
| 239 let instanceExportsDesc = Object.getOwnPropertyDescriptor(exportingInstance, 'ex
ports'); |
| 240 assertEq(typeof instanceExportsDesc.value, "object"); |
| 241 assertEq(instanceExportsDesc.writable, true); |
| 242 assertEq(instanceExportsDesc.enumerable, true); |
| 243 assertEq(instanceExportsDesc.configurable, true); |
| 244 |
| 245 // Exported WebAssembly functions |
| 246 let f = exportingInstance.exports.f; |
| 247 assertEq(f instanceof Function, true); |
| 248 assertEq(f.length, 0); |
| 249 assertEq('name' in f, true); |
| 250 assertEq(Function.prototype.call.call(f), 42); |
| 251 assertErrorMessage(() => new f(), TypeError, /is not a constructor/); |
| 252 |
| 253 // 'WebAssembly.Memory' data property |
| 254 let memoryDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'Memory'); |
| 255 assertEq(typeof memoryDesc.value, "function"); |
| 256 assertEq(memoryDesc.writable, true); |
| 257 assertEq(memoryDesc.enumerable, false); |
| 258 assertEq(memoryDesc.configurable, true); |
| 259 |
| 260 // 'WebAssembly.Memory' constructor function |
| 261 let Memory = WebAssembly.Memory; |
| 262 assertEq(Memory, memoryDesc.value); |
| 263 //TODO assertEq(Memory.length, 1); |
| 264 //TODO assertEq(Memory.name, "Memory"); |
| 265 assertErrorMessage(() => Memory(), TypeError, /constructor without new is forbid
den/); |
| 266 assertErrorMessage(() => new Memory(1), TypeError, "first argument must be a mem
ory descriptor"); |
| 267 assertErrorMessage(() => new Memory({initial:{valueOf() { throw new Error("here"
)}}}), Error, "here"); |
| 268 assertErrorMessage(() => new Memory({initial:-1}), RangeError, /bad Memory initi
al size/); |
| 269 assertErrorMessage(() => new Memory({initial:Math.pow(2,32)}), RangeError, /bad
Memory initial size/); |
| 270 assertErrorMessage(() => new Memory({initial:1, maximum: Math.pow(2,32)/Math.pow
(2,14) }), RangeError, /bad Memory maximum size/); |
| 271 assertErrorMessage(() => new Memory({initial:2, maximum:1 }), RangeError, /bad M
emory maximum size/); |
| 272 assertErrorMessage(() => new Memory({maximum: -1 }), RangeError, /bad Memory max
imum size/); |
| 273 assertEq(new Memory({initial:1}) instanceof Memory, true); |
| 274 assertEq(new Memory({initial:1.5}).buffer.byteLength, kPageSize); |
| 275 |
| 276 // 'WebAssembly.Memory.prototype' data property |
| 277 let memoryProtoDesc = Object.getOwnPropertyDescriptor(Memory, 'prototype'); |
| 278 assertEq(typeof memoryProtoDesc.value, "object"); |
| 279 if (PROP_FLAGS) assertEq(memoryProtoDesc.writable, false); |
| 280 if (PROP_FLAGS) assertEq(memoryProtoDesc.enumerable, false); |
| 281 if (PROP_FLAGS) assertEq(memoryProtoDesc.configurable, false); |
| 282 |
| 283 // 'WebAssembly.Memory.prototype' object |
| 284 let memoryProto = Memory.prototype; |
| 285 assertEq(memoryProto, memoryProtoDesc.value); |
| 286 assertEq(String(memoryProto), "[object Object]"); |
| 287 assertEq(Object.getPrototypeOf(memoryProto), Object.prototype); |
| 288 |
| 289 // 'WebAssembly.Memory' instance objects |
| 290 let mem1 = new Memory({initial:1}); |
| 291 assertEq(typeof mem1, "object"); |
| 292 //TODO assertEq(String(mem1), "[object WebAssembly.Memory]"); |
| 293 assertEq(Object.getPrototypeOf(mem1), memoryProto); |
| 294 |
| 295 // 'WebAssembly.Memory.prototype.buffer' accessor property |
| 296 let bufferDesc = Object.getOwnPropertyDescriptor(memoryProto, 'buffer'); |
| 297 assertEq(typeof bufferDesc.get, "function"); |
| 298 assertEq(bufferDesc.set, undefined); |
| 299 assertEq(bufferDesc.enumerable, false); |
| 300 assertEq(bufferDesc.configurable, true); |
| 301 |
| 302 // 'WebAssembly.Memory.prototype.buffer' getter |
| 303 let bufferGetter = bufferDesc.get; |
| 304 assertErrorMessage(() => bufferGetter.call(), TypeError, /called on incompatible
undefined/); |
| 305 assertErrorMessage(() => bufferGetter.call({}), TypeError, /called on incompatib
le Object/); |
| 306 assertEq(bufferGetter.call(mem1) instanceof ArrayBuffer, true); |
| 307 assertEq(bufferGetter.call(mem1).byteLength, kPageSize); |
| 308 |
| 309 // 'WebAssembly.Memory.prototype.grow' data property |
| 310 let memGrowDesc = Object.getOwnPropertyDescriptor(memoryProto, 'grow'); |
| 311 assertEq(typeof memGrowDesc.value, "function"); |
| 312 assertEq(memGrowDesc.enumerable, false); |
| 313 assertEq(memGrowDesc.configurable, true); |
| 314 |
| 315 // 'WebAssembly.Memory.prototype.grow' method |
| 316 |
| 317 if (false) { // TODO: bugs with Memory.grow |
| 318 let memGrow = memGrowDesc.value; |
| 319 assertEq(memGrow.length, 1); |
| 320 assertErrorMessage(() => memGrow.call(), TypeError, /called on incompatible unde
fined/); |
| 321 assertErrorMessage(() => memGrow.call({}), TypeError, /called on incompatible Ob
ject/); |
| 322 assertErrorMessage(() => memGrow.call(mem1, -1), RangeError, /bad Memory grow de
lta/); |
| 323 assertErrorMessage(() => memGrow.call(mem1, Math.pow(2,32)), RangeError, /bad Me
mory grow delta/); |
| 324 var mem = new Memory({initial:1, maximum:2}); |
| 325 var buf = mem.buffer; |
| 326 assertEq(buf.byteLength, kPageSize); |
| 327 assertEq(mem.grow(0), 1); |
| 328 assertEq(buf !== mem.buffer, true); |
| 329 assertEq(buf.byteLength, 0); |
| 330 buf = mem.buffer; |
| 331 assertEq(buf.byteLength, kPageSize); |
| 332 assertEq(mem.grow(1), 1); |
| 333 assertEq(buf !== mem.buffer, true); |
| 334 assertEq(buf.byteLength, 0); |
| 335 buf = mem.buffer; |
| 336 assertEq(buf.byteLength, 2 * kPageSize); |
| 337 assertErrorMessage(() => mem.grow(1), Error, /failed to grow memory/); |
| 338 assertEq(buf, mem.buffer); |
| 339 } |
| 340 |
| 341 // 'WebAssembly.Table' data property |
| 342 let tableDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'Table'); |
| 343 assertEq(typeof tableDesc.value, "function"); |
| 344 assertEq(tableDesc.writable, true); |
| 345 assertEq(tableDesc.enumerable, false); |
| 346 assertEq(tableDesc.configurable, true); |
| 347 |
| 348 // 'WebAssembly.Table' constructor function |
| 349 let Table = WebAssembly.Table; |
| 350 assertEq(Table, tableDesc.value); |
| 351 //TODO assertEq(Table.length, 1); |
| 352 //TODO assertEq(Table.name, "Table"); |
| 353 assertErrorMessage(() => Table(), TypeError, /constructor without new is forbidd
en/); |
| 354 assertErrorMessage(() => new Table(1), TypeError, "first argument must be a tabl
e descriptor"); |
| 355 assertErrorMessage(() => new Table({initial:1, element:1}), TypeError, /must be
"anyfunc"/); |
| 356 assertErrorMessage(() => new Table({initial:1, element:"any"}), TypeError, /must
be "anyfunc"/); |
| 357 assertErrorMessage(() => new Table({initial:1, element:{valueOf() { return "anyf
unc" }}}), TypeError, /must be "anyfunc"/); |
| 358 assertErrorMessage(() => new Table({initial:{valueOf() { throw new Error("here")
}}, element:"anyfunc"}), Error, "here"); |
| 359 assertErrorMessage(() => new Table({initial:-1, element:"anyfunc"}), RangeError,
/bad Table initial size/); |
| 360 assertErrorMessage(() => new Table({initial:Math.pow(2,32), element:"anyfunc"}),
RangeError, /bad Table initial size/); |
| 361 assertErrorMessage(() => new Table({initial:2, maximum:1, element:"anyfunc"}), R
angeError, /bad Table maximum size/); |
| 362 assertErrorMessage(() => new Table({initial:2, maximum:Math.pow(2,32), element:"
anyfunc"}), RangeError, /bad Table maximum size/); |
| 363 assertEq(new Table({initial:1, element:"anyfunc"}) instanceof Table, true); |
| 364 assertEq(new Table({initial:1.5, element:"anyfunc"}) instanceof Table, true); |
| 365 assertEq(new Table({initial:1, maximum:1.5, element:"anyfunc"}) instanceof Table
, true); |
| 366 //TODO:maximum assertEq(new Table({initial:1, maximum:Math.pow(2,32)-1, element:
"anyfunc"}) instanceof Table, true); |
| 367 |
| 368 // 'WebAssembly.Table.prototype' data property |
| 369 let tableProtoDesc = Object.getOwnPropertyDescriptor(Table, 'prototype'); |
| 370 assertEq(typeof tableProtoDesc.value, "object"); |
| 371 if (PROP_FLAGS) assertEq(tableProtoDesc.writable, false); |
| 372 if (PROP_FLAGS) assertEq(tableProtoDesc.enumerable, false); |
| 373 if (PROP_FLAGS) assertEq(tableProtoDesc.configurable, false); |
| 374 |
| 375 // 'WebAssembly.Table.prototype' object |
| 376 let tableProto = Table.prototype; |
| 377 assertEq(tableProto, tableProtoDesc.value); |
| 378 assertEq(String(tableProto), "[object Object]"); |
| 379 assertEq(Object.getPrototypeOf(tableProto), Object.prototype); |
| 380 |
| 381 // 'WebAssembly.Table' instance objects |
| 382 let tbl1 = new Table({initial:2, element:"anyfunc"}); |
| 383 assertEq(typeof tbl1, "object"); |
| 384 //TODO:name assertEq(String(tbl1), "[object WebAssembly.Table]"); |
| 385 assertEq(Object.getPrototypeOf(tbl1), tableProto); |
| 386 |
| 387 // 'WebAssembly.Table.prototype.length' accessor data property |
| 388 let lengthDesc = Object.getOwnPropertyDescriptor(tableProto, 'length'); |
| 389 assertEq(typeof lengthDesc.get, "function"); |
| 390 assertEq(lengthDesc.set, undefined); |
| 391 assertEq(lengthDesc.enumerable, false); |
| 392 assertEq(lengthDesc.configurable, true); |
| 393 |
| 394 // 'WebAssembly.Table.prototype.length' getter |
| 395 let lengthGetter = lengthDesc.get; |
| 396 assertEq(lengthGetter.length, 0); |
| 397 assertErrorMessage(() => lengthGetter.call(), TypeError, /called on incompatible
undefined/); |
| 398 assertErrorMessage(() => lengthGetter.call({}), TypeError, /called on incompatib
le Object/); |
| 399 assertEq(typeof lengthGetter.call(tbl1), "number"); |
| 400 assertEq(lengthGetter.call(tbl1), 2); |
| 401 |
| 402 // 'WebAssembly.Table.prototype.get' data property |
| 403 let getDesc = Object.getOwnPropertyDescriptor(tableProto, 'get'); |
| 404 assertEq(typeof getDesc.value, "function"); |
| 405 assertEq(getDesc.enumerable, false); |
| 406 assertEq(getDesc.configurable, true); |
| 407 |
| 408 // 'WebAssembly.Table.prototype.get' method |
| 409 let get = getDesc.value; |
| 410 //TODO:length assertEq(get.length, 1); |
| 411 assertErrorMessage(() => get.call(), TypeError, /called on incompatible undefine
d/); |
| 412 assertErrorMessage(() => get.call({}), TypeError, /called on incompatible Object
/); |
| 413 assertEq(get.call(tbl1, 0), null); |
| 414 assertEq(get.call(tbl1, 1), null); |
| 415 assertEq(get.call(tbl1, 1.5), null); |
| 416 assertErrorMessage(() => get.call(tbl1, 2), RangeError, /bad Table get index/); |
| 417 assertErrorMessage(() => get.call(tbl1, 2.5), RangeError, /bad Table get index/)
; |
| 418 assertErrorMessage(() => get.call(tbl1, -1), RangeError, /bad Table get index/); |
| 419 //TODO assertErrorMessage(() => get.call(tbl1, Math.pow(2,33)), RangeError, /bad
Table get index/); |
| 420 assertErrorMessage(() => get.call(tbl1, {valueOf() { throw new Error("hi") }}),
Error, "hi"); |
| 421 |
| 422 // 'WebAssembly.Table.prototype.set' data property |
| 423 let setDesc = Object.getOwnPropertyDescriptor(tableProto, 'set'); |
| 424 assertEq(typeof setDesc.value, "function"); |
| 425 assertEq(setDesc.enumerable, false); |
| 426 assertEq(setDesc.configurable, true); |
| 427 |
| 428 // 'WebAssembly.Table.prototype.set' method |
| 429 let set = setDesc.value; |
| 430 //TODO assertEq(set.length, 2); |
| 431 assertErrorMessage(() => set.call(), TypeError, /called on incompatible undefine
d/); |
| 432 assertErrorMessage(() => set.call({}), TypeError, /called on incompatible Object
/); |
| 433 assertErrorMessage(() => set.call(tbl1, 0), TypeError, /requires more than 1 arg
ument/); |
| 434 assertErrorMessage(() => set.call(tbl1, 2, null), RangeError, /bad Table set ind
ex/); |
| 435 assertErrorMessage(() => set.call(tbl1, -1, null), RangeError, /bad Table set in
dex/); |
| 436 //TODO assertErrorMessage(() => set.call(tbl1, Math.pow(2,33), null), RangeError
, /bad Table set index/); |
| 437 assertErrorMessage(() => set.call(tbl1, 0, undefined), TypeError, /can only assi
gn WebAssembly exported functions to Table/); |
| 438 assertErrorMessage(() => set.call(tbl1, 0, {}), TypeError, /can only assign WebA
ssembly exported functions to Table/); |
| 439 assertErrorMessage(() => set.call(tbl1, 0, function() {}), TypeError, /can only
assign WebAssembly exported functions to Table/); |
| 440 assertErrorMessage(() => set.call(tbl1, 0, Math.sin), TypeError, /can only assig
n WebAssembly exported functions to Table/); |
| 441 assertErrorMessage(() => set.call(tbl1, {valueOf() { throw Error("hai") }}, null
), Error, "hai"); |
| 442 assertEq(set.call(tbl1, 0, null), undefined); |
| 443 assertEq(set.call(tbl1, 1, null), undefined); |
| 444 |
| 445 // 'WebAssembly.Table.prototype.grow' data property |
| 446 let tblGrowDesc = Object.getOwnPropertyDescriptor(tableProto, 'grow'); |
| 447 assertEq(typeof tblGrowDesc.value, "function"); |
| 448 assertEq(tblGrowDesc.enumerable, false); |
| 449 assertEq(tblGrowDesc.configurable, true); |
| 450 |
| 451 // 'WebAssembly.Table.prototype.grow' method |
| 452 if (false) { // TODO: Table.grow |
| 453 let tblGrow = tblGrowDesc.value; |
| 454 //TODO assertEq(tblGrow.length, 1); |
| 455 assertErrorMessage(() => tblGrow.call(), TypeError, /called on incompatible unde
fined/); |
| 456 assertErrorMessage(() => tblGrow.call({}), TypeError, /called on incompatible Ob
ject/); |
| 457 assertErrorMessage(() => tblGrow.call(tbl1, -1), RangeError, /bad Table grow del
ta/); |
| 458 assertErrorMessage(() => tblGrow.call(tbl1, Math.pow(2,32)), RangeError, /bad Ta
ble grow delta/); |
| 459 var tbl = new Table({element:"anyfunc", initial:1, maximum:2}); |
| 460 assertEq(tbl.length, 1); |
| 461 assertEq(tbl.grow(0), 1); |
| 462 assertEq(tbl.length, 1); |
| 463 assertEq(tbl.grow(1), 1); |
| 464 assertEq(tbl.length, 2); |
| 465 assertErrorMessage(() => tbl.grow(1), Error, /failed to grow table/); |
| 466 } |
| 467 |
| 468 // 'WebAssembly.compile' data property |
| 469 let compileDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'compile'); |
| 470 assertEq(typeof compileDesc.value, "function"); |
| 471 assertEq(compileDesc.writable, true); |
| 472 assertEq(compileDesc.enumerable, false); |
| 473 assertEq(compileDesc.configurable, true); |
| 474 |
| 475 // 'WebAssembly.compile' function |
| 476 let compile = WebAssembly.compile; |
| 477 assertEq(compile, compileDesc.value); |
| 478 //TODO assertEq(compile.length, 1); |
| 479 //TODO assertEq(compile.name, "compile"); |
| 480 function assertCompileError(args, err, msg) { |
| 481 var error = null; |
| 482 try { |
| 483 compile(...args).catch(e => error = e); |
| 484 } catch (e) { |
| 485 // TODO: error shouldn't be thrown, but should be globbed onto the promise. |
| 486 error = e; |
| 487 } |
| 488 drainJobQueue(); |
| 489 assertEq(error instanceof err, true); |
| 490 assertEq(Boolean(error.stack.match("js-api.js")), true); |
| 491 //TODO assertEq(Boolean(error.message.match(msg)), true); |
| 492 } |
| 493 assertCompileError([], TypeError, /requires more than 0 arguments/); |
| 494 //TODO assertCompileError([undefined], TypeError, /first argument must be an Arr
ayBuffer or typed array object/); |
| 495 //TODO assertCompileError([1], TypeError, /first argument must be an ArrayBuffer
or typed array object/); |
| 496 //TODO assertCompileError([{}], TypeError, /first argument must be an ArrayBuffe
r or typed array object/); |
| 497 //TODO assertCompileError([new Uint8Array()], CompileError, /failed to match mag
ic number/); |
| 498 //TODO assertCompileError([new ArrayBuffer()], CompileError, /failed to match ma
gic number/); |
| 499 function assertCompileSuccess(bytes) { |
| 500 var module = null; |
| 501 compile(bytes).then(m => module = m); |
| 502 drainJobQueue(); |
| 503 assertEq(module instanceof Module, true); |
| 504 } |
| 505 assertCompileSuccess(emptyModuleBinary); |
| 506 assertCompileSuccess(emptyModuleBinary.buffer); |
| 507 |
| 508 if (false) { // TODO: implement WebAssembly.instantiate |
| 509 // 'WebAssembly.instantiate' data property |
| 510 let instantiateDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'instantiat
e'); |
| 511 assertEq(typeof instantiateDesc.value, "function"); |
| 512 assertEq(instantiateDesc.writable, true); |
| 513 assertEq(instantiateDesc.enumerable, false); |
| 514 assertEq(instantiateDesc.configurable, true); |
| 515 |
| 516 // 'WebAssembly.instantiate' function |
| 517 let instantiate = WebAssembly.instantiate; |
| 518 assertEq(instantiate, instantiateDesc.value); |
| 519 assertEq(instantiate.length, 2); |
| 520 assertEq(instantiate.name, "instantiate"); |
| 521 function assertInstantiateError(args, err, msg) { |
| 522 var error = null; |
| 523 try { |
| 524 instantiate(...args).catch(e => error = e); |
| 525 } catch(e) { |
| 526 error = e; |
| 527 } |
| 528 drainJobQueue(); |
| 529 assertEq(error instanceof err, true); |
| 530 assertEq(Boolean(error.stack.match("jsapi.js")), true); |
| 531 assertEq(Boolean(error.message.match(msg)), true); |
| 532 } |
| 533 assertInstantiateError([], TypeError, /requires more than 0 arguments/); |
| 534 assertInstantiateError([undefined], TypeError, /first argument must be a WebAs
sembly.Module, ArrayBuffer or typed array object/); |
| 535 assertInstantiateError([1], TypeError, /first argument must be a WebAssembly.M
odule, ArrayBuffer or typed array object/); |
| 536 assertInstantiateError([{}], TypeError, /first argument must be a WebAssembly.
Module, ArrayBuffer or typed array object/); |
| 537 assertInstantiateError([new Uint8Array()], CompileError, /failed to match magi
c number/); |
| 538 assertInstantiateError([new ArrayBuffer()], CompileError, /failed to match mag
ic number/); |
| 539 assertInstantiateError([importingModule], TypeError, /second argument must be
an object/); |
| 540 assertInstantiateError([importingModule, null], TypeError, /second argument mu
st be an object/); |
| 541 assertInstantiateError([importingModuleBinary, null], TypeError, /second argum
ent must be an object/); |
| 542 function assertInstantiateSuccess(module, imports) { |
| 543 var result = null; |
| 544 instantiate(module, imports).then(r => result = r); |
| 545 drainJobQueue(); |
| 546 if (module instanceof Module) { |
| 547 assertEq(result instanceof Instance, true); |
| 548 } else { |
| 549 assertEq(result.module instanceof Module, true); |
| 550 assertEq(result.instance instanceof Instance, true); |
| 551 } |
| 552 } |
| 553 assertInstantiateSuccess(emptyModule); |
| 554 assertInstantiateSuccess(emptyModuleBinary); |
| 555 assertInstantiateSuccess(emptyModuleBinary.buffer); |
| 556 assertInstantiateSuccess(importingModule, {"":{f:()=>{}}}); |
| 557 assertInstantiateSuccess(importingModuleBinary, {"":{f:()=>{}}}); |
| 558 assertInstantiateSuccess(importingModuleBinary.buffer, {"":{f:()=>{}}}); |
| 559 } |
OLD | NEW |