params.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft Corporation and contributors. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. WScript.Flag("-wasmI64");
  6. function* paramTypes() {
  7. while(true) {
  8. yield "i32";
  9. yield "i64";
  10. yield "f32";
  11. yield "f64";
  12. }
  13. }
  14. function* callArguments() {
  15. // 3 values to rotate which type will receive which arg
  16. while(true) {
  17. yield {value: -12345, i32: "(i32.const -12345)", i64: "(i64.const -12345)", f32: `(f32.const ${Math.fround(-12345)})`, f64: `(f64.const -12345.0)`};
  18. yield {value: "0xabcdef12345678", i32: "(i32.const 0)", i64: "(i64.const 0xabcdef12345678)", f32: "(f32.const 0)", f64: "(f64.const 0)"};
  19. yield {value: Math.PI, i32: `(i32.const ${Math.PI|0})`, i64: `(i64.const ${Math.PI|0})`, f32: `(f32.const ${Math.fround(Math.PI)})`, f64: `(f64.const ${Math.PI})`};
  20. }
  21. }
  22. const tested = {};
  23. function test(n) {
  24. if (n in tested) {
  25. return tested[n];
  26. }
  27. print(`Test(${n})`)
  28. const typeGen = paramTypes();
  29. const argGen = callArguments();
  30. let params = [], wasmCallTxt = [], callArgs = [], verify = [];
  31. for (let i = 0; i < n; ++i) {
  32. const type = typeGen.next().value;
  33. const getLocal = `(get_local ${i|0})`;
  34. const arg = argGen.next().value;
  35. params.push(type);
  36. wasmCallTxt.push(getLocal);
  37. callArgs.push(arg.value);
  38. verify.push(`(${type}.ne ${getLocal} ${arg[type]}) (br_if 0 (i32.const 0)) (drop)`);
  39. }
  40. const paramsTxt = params.join(" ");
  41. const txt = `(module
  42. (func $verify (param ${paramsTxt}) (result i32)
  43. ${verify.join("\n ")}
  44. (i32.const 1)
  45. )
  46. (func (export "foo") (param ${paramsTxt}) (result i32)
  47. (call $verify
  48. ${wasmCallTxt.join("\n ")}
  49. )
  50. )
  51. )`;
  52. //print(txt);
  53. const buf = WebAssembly.wabt.convertWast2Wasm(txt);
  54. try {
  55. const module = new WebAssembly.Module(buf);
  56. const {exports: {foo}} = new WebAssembly.Instance(module);
  57. if (foo(...callArgs) !== 1) {
  58. print(`FAILED. Failed to validate with ${n} arguments`);
  59. }
  60. tested[n] = true;
  61. return true;
  62. } catch (e) {
  63. }
  64. tested[n] = false;
  65. }
  66. const [forceTest] = WScript.Arguments;
  67. if (forceTest !== undefined) {
  68. const res = test(forceTest);
  69. print(res ? "Module is valid" : "Module is invalid");
  70. } else {
  71. let nParams = 9000;
  72. let inc = 1000;
  73. let direction = true;
  74. while (inc !== 0) {
  75. if (test(nParams)) {
  76. if (direction) {
  77. nParams += inc;
  78. } else {
  79. direction = true;
  80. inc >>= 1;
  81. nParams += inc;
  82. }
  83. } else {
  84. if (!direction) {
  85. nParams -= inc;
  86. } else {
  87. direction = false;
  88. inc >>= 1;
  89. // make sure the last test is a passing one
  90. inc = inc || 1;
  91. nParams -= inc;
  92. }
  93. }
  94. if (nParams > 100000 || nParams < 0) {
  95. print(`FAILED. Params reached ${nParams} long. Expected an error by now`);
  96. break;
  97. }
  98. }
  99. print(`Support at most ${nParams} params`);
  100. }