mirror of
				https://github.com/tc39/test262.git
				synced 2025-10-31 19:53:50 +01:00 
			
		
		
		
	sourceRevisionAtLastExport: 33f2fb0e53d135f0ee17cfccd9d993eb2a6f47de targetRevisionAtLastExport: 31340cbd9add103f586d501b0c3354b7b182abc0
		
			
				
	
	
		
			500 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			500 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| // Copyright 2016 the V8 project authors. All rights reserved.
 | |
| // Use of this source code is governed by a BSD-style license that can be
 | |
| // found in the LICENSE file.
 | |
| 
 | |
| // Flags: --validate-asm --allow-natives-syntax
 | |
| 
 | |
| // Note that this test file contains tests that explicitly check modules are
 | |
| // valid asm.js and then break them with invalid instantiation arguments. If
 | |
| // this script is run more than once (e.g. --stress-opt) then modules remain
 | |
| // broken in the second run and assertions would fail. We prevent re-runs.
 | |
| // Flags: --nostress-opt
 | |
| 
 | |
| function assertValidAsm(func) {
 | |
|   assertTrue(%IsAsmWasmCode(func));
 | |
| }
 | |
| 
 | |
| (function TestConst() {
 | |
|   function Module(s) {
 | |
|     "use asm";
 | |
|     var fround = s.Math.fround;
 | |
|     // Global constants. These are treated just like numeric literals.
 | |
|     const fConst = fround(-3.0);
 | |
|     const dConst = -3.0;
 | |
|     const iConst = -3;
 | |
| 
 | |
|     // consts can be used to initialize other consts.
 | |
|     const fPrime = fConst;
 | |
| 
 | |
|     // The following methods verify that return statements with global constants
 | |
|     // do not need type annotations.
 | |
|     function f() {
 | |
|       return fPrime;
 | |
|     }
 | |
|     function d() {
 | |
|       return dConst;
 | |
|     }
 | |
|     function i() {
 | |
|       return iConst;
 | |
|     }
 | |
| 
 | |
|     // The following methods verify that locals initialized with global
 | |
|     // constants do not need type annotations.
 | |
|     function fVar() {
 | |
|       var v = fPrime;
 | |
|       return fround(v);
 | |
|     }
 | |
|     function iVar() {
 | |
|       var v = iConst;
 | |
|       return v|0;
 | |
|     }
 | |
|     function dVar() {
 | |
|       var v = dConst;
 | |
|       return +v;
 | |
|     }
 | |
| 
 | |
|     return {
 | |
|       f: f, d: d, i: i,
 | |
|       fVar: fVar, dVar: dVar, iVar: iVar,
 | |
|     };
 | |
|   }
 | |
| 
 | |
|   function DisallowAssignToConstGlobal() {
 | |
|     const constant = 0;
 | |
|     function invalid(i) {
 | |
|       i = i|0;
 | |
|       constant = i;
 | |
|       return constant;
 | |
|     }
 | |
|     return invalid;
 | |
|   }
 | |
| 
 | |
|   var m = Module(this);
 | |
|   assertValidAsm(Module);
 | |
| 
 | |
|   assertEquals(-3, m.i());
 | |
|   assertEquals(-3.0, m.d());
 | |
|   assertEquals(Math.fround(-3.0), m.f());
 | |
| 
 | |
|   assertEquals(-3, m.iVar());
 | |
|   assertEquals(-3.0, m.dVar());
 | |
|   assertEquals(Math.fround(-3.0), m.fVar());
 | |
| 
 | |
|   var m = DisallowAssignToConstGlobal();
 | |
|   assertFalse(%IsAsmWasmCode(DisallowAssignToConstGlobal));
 | |
| })();
 | |
| 
 | |
| (function TestModuleArgs() {
 | |
|   function Module1(stdlib) {
 | |
|     "use asm";
 | |
|     function foo() { }
 | |
|     return { foo: foo };
 | |
|   }
 | |
|   function Module2(stdlib, ffi) {
 | |
|     "use asm";
 | |
|     function foo() { }
 | |
|     return { foo: foo };
 | |
|   }
 | |
|   function Module3(stdlib, ffi, heap) {
 | |
|     "use asm";
 | |
|     function foo() { }
 | |
|     return { foo: foo };
 | |
|   }
 | |
|   var modules = [Module1, Module2, Module3];
 | |
|   var heap = new ArrayBuffer(1024 * 1024);
 | |
|   for (var i = 0; i < modules.length; ++i) {
 | |
|     print('Module' + (i + 1));
 | |
|     var module = modules[i];
 | |
|     var m = module();
 | |
|     assertValidAsm(module);
 | |
|     var m = module({});
 | |
|     assertValidAsm(module);
 | |
|     var m = module({}, {});
 | |
|     assertValidAsm(module);
 | |
|     var m = module({}, {}, heap);
 | |
|     assertValidAsm(module);
 | |
|     var m = module({}, {}, heap, {});
 | |
|     assertValidAsm(module);
 | |
|   }
 | |
| })();
 | |
| 
 | |
| (function TestBadModule() {
 | |
|   function Module(stdlib, ffi, heap) {
 | |
|     "use asm";
 | |
|     function foo() { var y = 3; var x = 1 + y; return 123; }
 | |
|     return { foo: foo };
 | |
|   }
 | |
|   var m = Module({});
 | |
|   assertFalse(%IsAsmWasmCode(Module));
 | |
|   assertEquals(123, m.foo());
 | |
| })();
 | |
| 
 | |
| (function TestBadArgTypes() {
 | |
|   function Module(a, b, c) {
 | |
|     "use asm";
 | |
|     var NaN = a.NaN;
 | |
|     return {};
 | |
|   }
 | |
|   var m = Module(1, 2, 3);
 | |
|   assertFalse(%IsAsmWasmCode(Module));
 | |
|   assertEquals({}, m);
 | |
| })();
 | |
| 
 | |
| (function TestBadArgTypesMismatch() {
 | |
|   function Module(a, b, c) {
 | |
|     "use asm";
 | |
|     var NaN = a.NaN;
 | |
|     return {};
 | |
|   }
 | |
|   var m = Module(1, 2);
 | |
|   assertFalse(%IsAsmWasmCode(Module));
 | |
|   assertEquals({}, m);
 | |
| })();
 | |
| 
 | |
| (function TestModuleNoStdlib() {
 | |
|   function Module() {
 | |
|     "use asm";
 | |
|     function foo() { return 123; }
 | |
|     return { foo: foo };
 | |
|   }
 | |
|   var m = Module({});
 | |
|   assertValidAsm(Module);
 | |
|   assertEquals(123, m.foo());
 | |
| })();
 | |
| 
 | |
| (function TestModuleWith5() {
 | |
|   function Module(a, b, c, d, e) {
 | |
|     "use asm";
 | |
|     function foo() { return 123; }
 | |
|     return { foo: foo };
 | |
|   }
 | |
|   var heap = new ArrayBuffer(1024 * 1024);
 | |
|   var m = Module({}, {}, heap);
 | |
|   assertFalse(%IsAsmWasmCode(Module));
 | |
|   assertEquals(123, m.foo());
 | |
| })();
 | |
| 
 | |
| (function TestModuleNoStdlibCall() {
 | |
|   function Module(stdlib, ffi, heap) {
 | |
|     "use asm";
 | |
|     function foo() { return 123; }
 | |
|     return { foo: foo };
 | |
|   }
 | |
|   var m = Module();
 | |
|   assertValidAsm(Module);
 | |
|   assertEquals(123, m.foo());
 | |
| })();
 | |
| 
 | |
| (function TestModuleNew() {
 | |
|   function Module(stdlib, ffi, heap) {
 | |
|     "use asm";
 | |
|     function foo() { return 123; }
 | |
|     return { foo: foo };
 | |
|   }
 | |
|   var m = new Module({}, {});
 | |
|   assertValidAsm(Module);
 | |
|   assertEquals(123, m.foo());
 | |
| })();
 | |
| 
 | |
| (function TestMultipleFailures() {
 | |
|   function Module(stdlib) {
 | |
|     "use asm";
 | |
|     var NaN = stdlib.NaN;
 | |
|     function foo() { return 123; }
 | |
|     return { foo: foo };
 | |
|   }
 | |
|   var m1 = Module(1, 2, 3);
 | |
|   assertFalse(%IsAsmWasmCode(Module));
 | |
|   var m2 = Module(1, 2, 3);
 | |
|   assertFalse(%IsAsmWasmCode(Module));
 | |
|   assertEquals(123, m1.foo());
 | |
|   assertEquals(123, m2.foo());
 | |
| })();
 | |
| 
 | |
| (function TestFailureThenSuccess() {
 | |
|   function MkModule() {
 | |
|     function Module(stdlib, ffi, heap) {
 | |
|       "use asm";
 | |
|       var NaN = stdlib.NaN;
 | |
|       function foo() { return 123; }
 | |
|       return { foo: foo };
 | |
|     }
 | |
|     return Module;
 | |
|   }
 | |
|   var Module1 = MkModule();
 | |
|   var Module2 = MkModule();
 | |
|   var heap = new ArrayBuffer(1024 * 1024);
 | |
|   var m1 = Module1(1, 2, 3);
 | |
|   assertFalse(%IsAsmWasmCode(Module1));
 | |
|   var m2 = Module2({}, {}, heap);
 | |
|   assertFalse(%IsAsmWasmCode(Module2));
 | |
|   assertEquals(123, m1.foo());
 | |
|   assertEquals(123, m2.foo());
 | |
| })();
 | |
| 
 | |
| (function TestSuccessThenFailure() {
 | |
|   function MkModule() {
 | |
|     function Module(stdlib, ffi, heap) {
 | |
|       "use asm";
 | |
|       var NaN = stdlib.NaN;
 | |
|       function foo() { return 123; }
 | |
|       return { foo: foo };
 | |
|     }
 | |
|     return Module;
 | |
|   }
 | |
|   var Module1 = MkModule();
 | |
|   var Module2 = MkModule();
 | |
|   var heap = new ArrayBuffer(1024 * 1024);
 | |
|   var m1 = Module1({NaN: NaN}, {}, heap);
 | |
|   assertValidAsm(Module1);
 | |
|   var m2 = Module2(1, 2, 3);
 | |
|   assertFalse(%IsAsmWasmCode(Module2));
 | |
|   assertEquals(123, m1.foo());
 | |
|   assertEquals(123, m2.foo());
 | |
| })();
 | |
| 
 | |
| (function TestSuccessThenFailureThenRetry() {
 | |
|   function MkModule() {
 | |
|     function Module(stdlib, ffi, heap) {
 | |
|       "use asm";
 | |
|       var NaN = stdlib.NaN;
 | |
|       function foo() { return 123; }
 | |
|       return { foo: foo };
 | |
|     }
 | |
|     return Module;
 | |
|   }
 | |
|   var Module1 = MkModule();
 | |
|   var Module2 = MkModule();
 | |
|   var heap = new ArrayBuffer(1024 * 1024);
 | |
|   var m1a = Module1({NaN: NaN}, {}, heap);
 | |
|   assertValidAsm(Module1);
 | |
|   var m2 = Module2(1, 2, 3);
 | |
|   assertFalse(%IsAsmWasmCode(Module2));
 | |
|   var m1b = Module1({NaN: NaN}, {}, heap);
 | |
|   assertFalse(%IsAsmWasmCode(Module1));
 | |
|   assertEquals(123, m1a.foo());
 | |
|   assertEquals(123, m1b.foo());
 | |
|   assertEquals(123, m2.foo());
 | |
| })();
 | |
| 
 | |
| (function TestBoundFunction() {
 | |
|   function Module(stdlib, ffi, heap) {
 | |
|     "use asm";
 | |
|     function foo() { return 123; }
 | |
|     return { foo: foo };
 | |
|   }
 | |
|   var heap = new ArrayBuffer(1024 * 1024);
 | |
|   var ModuleBound = Module.bind(this, {}, {}, heap);
 | |
|   var m = ModuleBound();
 | |
|   assertValidAsm(Module);
 | |
|   assertEquals(123, m.foo());
 | |
| })();
 | |
| 
 | |
| (function TestBadConstUnsignedReturn() {
 | |
|   function Module() {
 | |
|     "use asm";
 | |
|     const i = 0xffffffff;
 | |
|     function foo() { return i; }
 | |
|     return { foo: foo };
 | |
|   }
 | |
|   var m = Module();
 | |
|   assertFalse(%IsAsmWasmCode(Module));
 | |
|   assertEquals(0xffffffff, m.foo());
 | |
| })();
 | |
| 
 | |
| (function TestBadBooleanParamAnnotation() {
 | |
|   function Module() {
 | |
|     "use asm";
 | |
|     function foo(x) {
 | |
|       x = x | true;
 | |
|       return x;
 | |
|     }
 | |
|     return { foo: foo };
 | |
|   }
 | |
|   var m = Module();
 | |
|   assertFalse(%IsAsmWasmCode(Module));
 | |
|   assertEquals(3, m.foo(3));
 | |
| })();
 | |
| 
 | |
| (function TestBadExportTwice() {
 | |
|   function Module() {
 | |
|     "use asm";
 | |
|     function bar() { return 1; }
 | |
|     function baz() { return 2; }
 | |
|     return {foo: bar, foo: baz};
 | |
|   }
 | |
|   var m = Module();
 | |
|   assertTrue(%IsAsmWasmCode(Module));
 | |
|   assertEquals(2, m.foo());
 | |
| })();
 | |
| 
 | |
| (function TestBadImport() {
 | |
|   function Module(stdlib) {
 | |
|     "use asm";
 | |
|     var set = 0;
 | |
|     var foo = stdlib[set];
 | |
|     return {};
 | |
|   }
 | |
|   var m = Module(this);
 | |
|   assertFalse(%IsAsmWasmCode(Module));
 | |
| })();
 | |
| 
 | |
| (function TestBadFroundTrue() {
 | |
|   function Module(stdlib) {
 | |
|     "use asm";
 | |
|     var fround = stdlib.Math.fround;
 | |
|     function foo() {
 | |
|       var x = fround(true);
 | |
|       return +x;
 | |
|     }
 | |
|     return { foo: foo };
 | |
|   }
 | |
|   var m = Module(this);
 | |
|   assertFalse(%IsAsmWasmCode(Module));
 | |
|   assertEquals(1, m.foo());
 | |
| })();
 | |
| 
 | |
| (function TestBadCase() {
 | |
|   function Module() {
 | |
|     "use asm";
 | |
|     function foo(x) {
 | |
|       x = x | 0;
 | |
|       switch (x|0) {
 | |
|         case true:
 | |
|           return 42;
 | |
|         default:
 | |
|           return 43;
 | |
|       }
 | |
|       return 0;
 | |
|     }
 | |
|     return { foo: foo };
 | |
|   }
 | |
|   var m = Module();
 | |
|   assertFalse(%IsAsmWasmCode(Module));
 | |
|   assertEquals(43, m.foo(3));
 | |
| })();
 | |
| 
 | |
| (function TestVarHidesExport() {
 | |
|   function Module() {
 | |
|     "use asm";
 | |
|     var foo;
 | |
|     function foo() {}
 | |
|     return foo;
 | |
|   }
 | |
|   Module();
 | |
|   assertFalse(%IsAsmWasmCode(Module));
 | |
| })();
 | |
| 
 | |
| (function TestUndefinedGlobalCall() {
 | |
|   function Module() {
 | |
|     "use asm";
 | |
|     function foo() {
 | |
|       return bar() | 0;
 | |
|     }
 | |
|     return foo;
 | |
|   }
 | |
|   Module();
 | |
|   assertFalse(%IsAsmWasmCode(Module));
 | |
| })();
 | |
| 
 | |
| (function TestConditionalReturn() {
 | |
|   function Module() {
 | |
|     'use asm';
 | |
|     function foo(a, b) {
 | |
|       a = +a;
 | |
|       b = +b;
 | |
|       // Allowed, despite not matching the spec, as emscripten emits this in
 | |
|       // practice.
 | |
|       return a == b ? +a : +b;
 | |
|     }
 | |
|     return foo;
 | |
|   }
 | |
|   var m = Module();
 | |
|   assertEquals(4, m(4, 4));
 | |
|   assertEquals(5, m(4, 5));
 | |
|   assertEquals(4, m(5, 4));
 | |
|   assertValidAsm(Module);
 | |
| })();
 | |
| 
 | |
| (function TestMismatchedConditionalReturn() {
 | |
|   function Module() {
 | |
|     'use asm';
 | |
|     function foo(a, b) {
 | |
|       a = +a;
 | |
|       return a == 0.0 ? 0 : +a;
 | |
|     }
 | |
|     return foo;
 | |
|   }
 | |
|   Module();
 | |
|   assertFalse(%IsAsmWasmCode(Module));
 | |
| })();
 | |
| 
 | |
| (function TestBadIntConditionalReturn() {
 | |
|   function Module() {
 | |
|     'use asm';
 | |
|     function foo(a, b) {
 | |
|       a = a | 0;
 | |
|       b = b | 0;
 | |
|       // Disallowed because signature must be signed, but these will be int.
 | |
|       return 1 ? a : b;
 | |
|     }
 | |
|     return foo;
 | |
|   }
 | |
|   Module();
 | |
|   assertFalse(%IsAsmWasmCode(Module));
 | |
| })();
 | |
| 
 | |
| (function TestBadSignedConditionalReturn() {
 | |
|   function Module() {
 | |
|     'use asm';
 | |
|     function foo(a, b) {
 | |
|       a = a | 0;
 | |
|       b = b | 0;
 | |
|       // Disallowed because conditional yields int, even when both sides
 | |
|       // are signed.
 | |
|       return 1 ? a | 0 : b | 0;
 | |
|     }
 | |
|     return foo;
 | |
|   }
 | |
|   Module();
 | |
|   assertFalse(%IsAsmWasmCode(Module));
 | |
| })();
 | |
| 
 | |
| (function TestAsmIsRegular() {
 | |
|   function Module() {
 | |
|     'use asm';
 | |
|     var g = 123;
 | |
|     function foo() {
 | |
|       return g | 0;
 | |
|     }
 | |
|     return {x: foo};
 | |
|   }
 | |
|   var o = Module();
 | |
|   assertValidAsm(Module);
 | |
|   assertFalse(o instanceof WebAssembly.Instance);
 | |
|   assertTrue(o instanceof Object);
 | |
|   assertTrue(o.__proto__ === Object.prototype);
 | |
|   var p = Object.getOwnPropertyDescriptor(o, "x")
 | |
|   assertTrue(p.writable);
 | |
|   assertTrue(p.enumerable);
 | |
|   assertTrue(p.configurable);
 | |
|   assertTrue(typeof o.x === 'function');
 | |
|   o.x = 5;
 | |
|   assertTrue(typeof o.x === 'number');
 | |
|   assertTrue(o.__single_function__ === undefined);
 | |
|   assertTrue(o.__foreign_init__ === undefined);
 | |
| })();
 | |
| 
 | |
| (function TestAsmExportOrderPreserved() {
 | |
|   function Module() {
 | |
|     "use asm";
 | |
|     function f() {}
 | |
|     function g() {}
 | |
|     return { a:f, b:g, x:f, c:g, d:f };
 | |
|   }
 | |
|   var m = Module();
 | |
|   assertValidAsm(Module);
 | |
|   var props = Object.getOwnPropertyNames(m);
 | |
|   assertEquals(["a","b","x","c","d"], props);
 | |
| })();
 |