| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Flags: --expose-wasm --allow-natives-syntax | 5 // Flags: --expose-wasm --allow-natives-syntax |
| 6 | 6 |
| 7 load("test/mjsunit/wasm/wasm-constants.js"); | 7 load("test/mjsunit/wasm/wasm-constants.js"); |
| 8 load("test/mjsunit/wasm/wasm-module-builder.js"); | 8 load("test/mjsunit/wasm/wasm-module-builder.js"); |
| 9 | 9 |
| 10 function testCallFFI(func, check) { | 10 function testCallFFI(func, check) { |
| 11 var builder = new WasmModuleBuilder(); | 11 var builder = new WasmModuleBuilder(); |
| 12 | 12 |
| 13 var sig_index = builder.addType(kSig_i_dd); | 13 var sig_index = builder.addType(kSig_i_dd); |
| 14 builder.addImport("func", sig_index); | 14 builder.addImport("", "func", sig_index); |
| 15 builder.addFunction("main", sig_index) | 15 builder.addFunction("main", sig_index) |
| 16 .addBody([ | 16 .addBody([ |
| 17 kExprGetLocal, 0, // -- | 17 kExprGetLocal, 0, // -- |
| 18 kExprGetLocal, 1, // -- | 18 kExprGetLocal, 1, // -- |
| 19 kExprCallFunction, 0 // -- | 19 kExprCallFunction, 0 // -- |
| 20 ]) // -- | 20 ]) // -- |
| 21 .exportFunc(); | 21 .exportFunc(); |
| 22 | 22 |
| 23 var main = builder.instantiate({func: func}).exports.main; | 23 var main = builder.instantiate({"": {func: func}}).exports.main; |
| 24 | 24 |
| 25 for (var i = 0; i < 100000; i += 10003) { | 25 for (var i = 0; i < 100000; i += 10003) { |
| 26 var a = 22.5 + i, b = 10.5 + i; | 26 var a = 22.5 + i, b = 10.5 + i; |
| 27 var r = main(a, b); | 27 var r = main(a, b); |
| 28 if (check) { | 28 if (check) { |
| 29 check(r, a, b); | 29 check(r, a, b); |
| 30 } | 30 } |
| 31 } | 31 } |
| 32 } | 32 } |
| 33 | 33 |
| 34 var global = (function() { return this; })(); | 34 var global = (function() { return this; })(); |
| 35 var params = [-99, -99, -99, -99, -99]; | 35 var params = [-99, -99, -99, -99, -99]; |
| 36 var was_called = false; | 36 var was_called = false; |
| 37 var length = -1; | 37 var length = -1; |
| 38 | 38 |
| 39 function FOREIGN_SUB(a, b) { | 39 function FOREIGN_SUB(a, b) { |
| 40 print("FOREIGN_SUB(" + a + ", " + b + ")"); | 40 // print("FOREIGN_SUB(" + a + ", " + b + ")"); |
| 41 was_called = true; | 41 was_called = true; |
| 42 params[0] = this; | 42 params[0] = this; |
| 43 params[1] = a; | 43 params[1] = a; |
| 44 params[2] = b; | 44 params[2] = b; |
| 45 return (a - b) | 0; | 45 return (a - b) | 0; |
| 46 } | 46 } |
| 47 | 47 |
| 48 function check_FOREIGN_SUB(r, a, b) { | 48 function check_FOREIGN_SUB(r, a, b) { |
| 49 assertEquals(a - b | 0, r); | 49 assertEquals(a - b | 0, r); |
| 50 assertTrue(was_called); | 50 assertTrue(was_called); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 68 var bind_sub = FOREIGN_SUB.bind(); | 68 var bind_sub = FOREIGN_SUB.bind(); |
| 69 testCallFFI(bind_sub, check_FOREIGN_SUB); | 69 testCallFFI(bind_sub, check_FOREIGN_SUB); |
| 70 | 70 |
| 71 var main_for_constructor_test; | 71 var main_for_constructor_test; |
| 72 print("Constructor"); | 72 print("Constructor"); |
| 73 (function testCallConstructor() { | 73 (function testCallConstructor() { |
| 74 class C {} | 74 class C {} |
| 75 var builder = new WasmModuleBuilder(); | 75 var builder = new WasmModuleBuilder(); |
| 76 | 76 |
| 77 var sig_index = builder.addType(kSig_i_dd); | 77 var sig_index = builder.addType(kSig_i_dd); |
| 78 builder.addImport("func", sig_index); | 78 builder.addImport("", "func", sig_index); |
| 79 builder.addFunction("main", sig_index) | 79 builder.addFunction("main", sig_index) |
| 80 .addBody([ | 80 .addBody([ |
| 81 kExprGetLocal, 0, // -- | 81 kExprGetLocal, 0, // -- |
| 82 kExprGetLocal, 1, // -- | 82 kExprGetLocal, 1, // -- |
| 83 kExprCallFunction, 0 // -- | 83 kExprCallFunction, 0 // -- |
| 84 ]) // -- | 84 ]) // -- |
| 85 .exportFunc(); | 85 .exportFunc(); |
| 86 | 86 |
| 87 main_for_constructor_test = builder.instantiate({func: C}).exports.main; | 87 main_for_constructor_test = builder.instantiate({"": {func: C}}).exports.main; |
| 88 | 88 |
| 89 assertThrows("main_for_constructor_test(12, 43)", TypeError); | 89 assertThrows("main_for_constructor_test(12, 43)", TypeError); |
| 90 }) (); | 90 }) (); |
| 91 | 91 |
| 92 print("Native function"); | 92 print("Native function"); |
| 93 (function test_ffi_call_to_native() { | 93 (function test_ffi_call_to_native() { |
| 94 | 94 |
| 95 var builder = new WasmModuleBuilder(); | 95 var builder = new WasmModuleBuilder(); |
| 96 | 96 |
| 97 var sig_index = builder.addType(kSig_d_v); | 97 var sig_index = builder.addType(kSig_d_v); |
| 98 builder.addImport("func", sig_index); | 98 builder.addImport("", "func", sig_index); |
| 99 builder.addFunction("main", sig_index) | 99 builder.addFunction("main", sig_index) |
| 100 .addBody([ | 100 .addBody([ |
| 101 kExprCallFunction, 0 // -- | 101 kExprCallFunction, 0 // -- |
| 102 ]) // -- | 102 ]) // -- |
| 103 .exportFunc(); | 103 .exportFunc(); |
| 104 | 104 |
| 105 var main = builder.instantiate({func: Object.prototype.toString}).exports.main
; | 105 var main = builder.instantiate({"": {func: Object.prototype.toString}}).export
s.main; |
| 106 // The result of the call to Object.prototype.toString should be | 106 // The result of the call to Object.prototype.toString should be |
| 107 // [object Undefined]. However, we cannot test for this result because wasm | 107 // [object Undefined]. However, we cannot test for this result because wasm |
| 108 // cannot return objects but converts them to float64 in this test. | 108 // cannot return objects but converts them to float64 in this test. |
| 109 assertEquals(NaN, main()); | 109 assertEquals(NaN, main()); |
| 110 })(); | 110 })(); |
| 111 | 111 |
| 112 print("Callable JSObject"); | 112 print("Callable JSObject"); |
| 113 testCallFFI(%GetCallable(), function check(r, a, b) {assertEquals(a - b, r);}); | 113 testCallFFI(%GetCallable(), function check(r, a, b) {assertEquals(a - b, r);}); |
| 114 | 114 |
| 115 function FOREIGN_ABCD(a, b, c, d) { | 115 function FOREIGN_ABCD(a, b, c, d) { |
| 116 print("FOREIGN_ABCD(" + a + ", " + b + ", " + c + ", " + d + ")"); | 116 // print("FOREIGN_ABCD(" + a + ", " + b + ", " + c + ", " + d + ")"); |
| 117 was_called = true; | 117 was_called = true; |
| 118 params[0] = this; | 118 params[0] = this; |
| 119 params[1] = a; | 119 params[1] = a; |
| 120 params[2] = b; | 120 params[2] = b; |
| 121 params[3] = c; | 121 params[3] = c; |
| 122 params[4] = d; | 122 params[4] = d; |
| 123 return (a * b * 6) | 0; | 123 return (a * b * 6) | 0; |
| 124 } | 124 } |
| 125 | 125 |
| 126 function check_FOREIGN_ABCD(r, a, b) { | 126 function check_FOREIGN_ABCD(r, a, b) { |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 // Check that returning weird values doesn't crash | 217 // Check that returning weird values doesn't crash |
| 218 testCallFFI(returnValue(undefined), checkReturn(0)); | 218 testCallFFI(returnValue(undefined), checkReturn(0)); |
| 219 testCallFFI(returnValue(null), checkReturn(0)); | 219 testCallFFI(returnValue(null), checkReturn(0)); |
| 220 testCallFFI(returnValue("0"), checkReturn(0)); | 220 testCallFFI(returnValue("0"), checkReturn(0)); |
| 221 testCallFFI(returnValue("-77"), checkReturn(-77)); | 221 testCallFFI(returnValue("-77"), checkReturn(-77)); |
| 222 | 222 |
| 223 var objWithValueOf = {valueOf: function() { return 198; }} | 223 var objWithValueOf = {valueOf: function() { return 198; }} |
| 224 | 224 |
| 225 testCallFFI(returnValue(objWithValueOf), checkReturn(198)); | 225 testCallFFI(returnValue(objWithValueOf), checkReturn(198)); |
| 226 | 226 |
| 227 | |
| 228 function testCallBinopVoid(type, func, check) { | 227 function testCallBinopVoid(type, func, check) { |
| 229 var passed_length = -1; | 228 var passed_length = -1; |
| 230 var passed_a = -1; | 229 var passed_a = -1; |
| 231 var passed_b = -1; | 230 var passed_b = -1; |
| 232 var args_a = -1; | 231 var args_a = -1; |
| 233 var args_b = -1; | 232 var args_b = -1; |
| 234 | 233 |
| 235 ffi = {func: function(a, b) { | 234 ffi = {"": {func: function(a, b) { |
| 236 passed_length = arguments.length; | 235 passed_length = arguments.length; |
| 237 passed_a = a; | 236 passed_a = a; |
| 238 passed_b = b; | 237 passed_b = b; |
| 239 args_a = arguments[0]; | 238 args_a = arguments[0]; |
| 240 args_b = arguments[1]; | 239 args_b = arguments[1]; |
| 241 }}; | 240 }}}; |
| 242 | 241 |
| 243 var builder = new WasmModuleBuilder(); | 242 var builder = new WasmModuleBuilder(); |
| 244 | 243 |
| 245 builder.addImport("func", makeSig_v_xx(type)); | 244 builder.addImport("", "func", makeSig_v_xx(type)); |
| 246 builder.addFunction("main", makeSig_r_xx(kAstI32, type)) | 245 builder.addFunction("main", makeSig_r_xx(kAstI32, type)) |
| 247 .addBody([ | 246 .addBody([ |
| 248 kExprGetLocal, 0, // -- | 247 kExprGetLocal, 0, // -- |
| 249 kExprGetLocal, 1, // -- | 248 kExprGetLocal, 1, // -- |
| 250 kExprCallFunction, 0, // -- | 249 kExprCallFunction, 0, // -- |
| 251 kExprI8Const, 99 // -- | 250 kExprI8Const, 99 // -- |
| 252 ]) // -- | 251 ]) // -- |
| 253 .exportFunc() | 252 .exportFunc() |
| 254 | 253 |
| 255 var main = builder.instantiate(ffi).exports.main; | 254 var main = builder.instantiate(ffi).exports.main; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 286 assertEquals(expected_b, passed_b); | 285 assertEquals(expected_b, passed_b); |
| 287 } | 286 } |
| 288 } | 287 } |
| 289 | 288 |
| 290 | 289 |
| 291 testCallBinopVoid(kAstI32); | 290 testCallBinopVoid(kAstI32); |
| 292 // TODO testCallBinopVoid(kAstI64); | 291 // TODO testCallBinopVoid(kAstI64); |
| 293 testCallBinopVoid(kAstF32); | 292 testCallBinopVoid(kAstF32); |
| 294 testCallBinopVoid(kAstF64); | 293 testCallBinopVoid(kAstF64); |
| 295 | 294 |
| 296 | |
| 297 | |
| 298 (function testCallPrint() { | 295 (function testCallPrint() { |
| 299 var builder = new WasmModuleBuilder(); | 296 var builder = new WasmModuleBuilder(); |
| 300 | 297 |
| 301 builder.addImport("print", makeSig_v_x(kAstI32)); | 298 builder.addImport("", "print", makeSig_v_x(kAstI32)); |
| 302 builder.addImport("print", makeSig_v_x(kAstF64)); | 299 builder.addImport("", "print", makeSig_v_x(kAstF64)); |
| 303 builder.addFunction("main", makeSig_v_x(kAstF64)) | 300 builder.addFunction("main", makeSig_v_x(kAstF64)) |
| 304 .addBody([ | 301 .addBody([ |
| 305 kExprI8Const, 97, // -- | 302 kExprI8Const, 97, // -- |
| 306 kExprCallFunction, 0, // -- | 303 kExprCallFunction, 0, // -- |
| 307 kExprGetLocal, 0, // -- | 304 kExprGetLocal, 0, // -- |
| 308 kExprCallFunction, 1 // -- | 305 kExprCallFunction, 1 // -- |
| 309 ]) // -- | 306 ]) // -- |
| 310 .exportFunc() | 307 .exportFunc() |
| 311 | 308 |
| 312 var main = builder.instantiate({print: print}).exports.main; | 309 var main = builder.instantiate({"": {print: print}}).exports.main; |
| 313 for (var i = -9; i < 900; i += 6.125) main(i); | 310 for (var i = -9; i < 900; i += 6.125) main(i); |
| 314 })(); | 311 })(); |
| 315 | 312 |
| 316 | 313 |
| 317 (function testImportNumbers() { | 314 (function testImportNumbers() { |
| 315 print("TestImportNumbers..."); |
| 318 var builder = new WasmModuleBuilder(); | 316 var builder = new WasmModuleBuilder(); |
| 319 | 317 |
| 320 builder.addImport('0', kSig_v_i); | 318 builder.addImport("", '0', kSig_v_i); |
| 321 | 319 |
| 322 builder.instantiate({0: print}); | 320 builder.instantiate({"": {0: print}}); |
| 323 })(); | 321 })(); |
| 324 | 322 |
| 325 (function testImportNumbers2() { | 323 (function testImportNumbers2() { |
| 324 print("TestImportNumbers2..."); |
| 326 var builder = new WasmModuleBuilder(); | 325 var builder = new WasmModuleBuilder(); |
| 327 | 326 |
| 328 builder.addImportWithModule('foo', '0', kSig_v_i); | 327 builder.addImport('foo', '0', kSig_v_i); |
| 329 builder.addImportWithModule('0', 'foo', kSig_v_i); | 328 builder.addImport('0', 'foo', kSig_v_i); |
| 330 builder.addImportWithModule('0', '0', kSig_v_i); | 329 builder.addImport('0', '0', kSig_v_i); |
| 331 builder.addImportWithModule('18', '-3', kSig_v_i); | 330 builder.addImport('18', '-3', kSig_v_i); |
| 332 builder.addImportWithModule('-3', '18', kSig_v_i); | 331 builder.addImport('-3', '18', kSig_v_i); |
| 333 | 332 |
| 334 builder.instantiate({ | 333 builder.instantiate({ |
| 335 foo: {0: print}, | 334 foo: {0: print}, |
| 336 0: {0: print, foo: print}, | 335 0: {0: print, foo: print}, |
| 337 18: {'-3': print}, | 336 18: {'-3': print}, |
| 338 '-3': {18: print} | 337 '-3': {18: print} |
| 339 }); | 338 }); |
| 340 })(); | 339 })(); |
| 341 | 340 |
| 342 (function ImportSymbolAsVoidDoesNotThrow() { | 341 (function ImportSymbolAsVoidDoesNotThrow() { |
| 342 print("ImportSymbolAsVoidDoesNotThrow..."); |
| 343 var builder = new WasmModuleBuilder(); | 343 var builder = new WasmModuleBuilder(); |
| 344 // Return type is void, so there should be no ToNumber conversion. | 344 // Return type is void, so there should be no ToNumber conversion. |
| 345 var index = builder.addImport("func", kSig_v_v); | 345 var index = builder.addImport("", "func", kSig_v_v); |
| 346 builder.addFunction("main", kSig_v_v) | 346 builder.addFunction("main", kSig_v_v) |
| 347 .addBody([kExprCallFunction, 0]) | 347 .addBody([kExprCallFunction, 0]) |
| 348 .exportFunc(); | 348 .exportFunc(); |
| 349 var func = () => Symbol(); | 349 var func = () => Symbol(); |
| 350 var main = builder.instantiate({func: func}).exports.main; | 350 var main = builder.instantiate({"": {func: func}}).exports.main; |
| 351 main(); | 351 main(); |
| 352 })(); | 352 })(); |
| 353 | 353 |
| 354 (function ToNumberCalledOnImport() { | 354 (function ToNumberCalledOnImport() { |
| 355 var builder = new WasmModuleBuilder(); | 355 var builder = new WasmModuleBuilder(); |
| 356 // Return type is int, so there should be a ToNumber conversion. | 356 // Return type is int, so there should be a ToNumber conversion. |
| 357 var index = builder.addImport("func", kSig_i_v); | 357 var index = builder.addImport("", "func", kSig_i_v); |
| 358 builder.addFunction("main", kSig_i_v) | 358 builder.addFunction("main", kSig_i_v) |
| 359 .addBody([kExprCallFunction, 0]) | 359 .addBody([kExprCallFunction, 0]) |
| 360 .exportFunc(); | 360 .exportFunc(); |
| 361 var num_valueOf = 0; | 361 var num_valueOf = 0; |
| 362 function Foo() {} | 362 function Foo() {} |
| 363 Foo.prototype.valueOf = () => ++num_valueOf; | 363 Foo.prototype.valueOf = () => ++num_valueOf; |
| 364 var func = () => new Foo(); | 364 var func = () => new Foo(); |
| 365 var main = builder.instantiate({func: func}).exports.main; | 365 var main = builder.instantiate({"": {func: func}}).exports.main; |
| 366 main(); | 366 main(); |
| 367 assertEquals(1, num_valueOf); | 367 assertEquals(1, num_valueOf); |
| 368 main(); | 368 main(); |
| 369 assertEquals(2, num_valueOf); | 369 assertEquals(2, num_valueOf); |
| 370 })(); | 370 })(); |
| 371 | 371 |
| 372 (function ToNumberNotCalledOnVoidImport() { | 372 (function ToNumberNotCalledOnVoidImport() { |
| 373 var builder = new WasmModuleBuilder(); | 373 var builder = new WasmModuleBuilder(); |
| 374 // Return type is void, so there should be no ToNumber conversion. | 374 // Return type is void, so there should be no ToNumber conversion. |
| 375 var index = builder.addImport("func", kSig_v_v); | 375 var index = builder.addImport("", "func", kSig_v_v); |
| 376 builder.addFunction("main", kSig_v_v) | 376 builder.addFunction("main", kSig_v_v) |
| 377 .addBody([kExprCallFunction, 0]) | 377 .addBody([kExprCallFunction, 0]) |
| 378 .exportFunc(); | 378 .exportFunc(); |
| 379 var num_valueOf = 0; | 379 var num_valueOf = 0; |
| 380 function Foo() {} | 380 function Foo() {} |
| 381 Foo.prototype.valueOf = () => ++num_valueOf; | 381 Foo.prototype.valueOf = () => ++num_valueOf; |
| 382 var func = () => new Foo(); | 382 var func = () => new Foo(); |
| 383 var main = builder.instantiate({func: func}).exports.main; | 383 var main = builder.instantiate({"": {func: func}}).exports.main; |
| 384 main(); | 384 main(); |
| 385 main(); | 385 main(); |
| 386 assertEquals(0, num_valueOf); | 386 assertEquals(0, num_valueOf); |
| 387 })(); | 387 })(); |
| OLD | NEW |