3 let validInputTestCases = [
4 // input as string, expected result as string.
16 ["{ valueOf: () => { return 4; } }", "29"],
19 let validInputTypedTestCases = validInputTestCases.map((element) => { return [eval("(" + element[0] + ")"), eval(element[1])] });
21 function isIdentical(result, expected)
23 if (expected === expected) {
24 if (result !== expected)
26 if (!expected && 1 / expected === -Infinity && 1 / result !== -Infinity)
31 return result !== result;
35 // Test Math.clz32() without arguments.
36 function opaqueClz32NoArgument() {
39 noInline(opaqueClz32NoArgument);
40 noOSRExitFuzzing(opaqueClz32NoArgument);
42 function testNoArgument() {
43 for (let i = 0; i < 1e4; ++i) {
44 let output = opaqueClz32NoArgument();
46 throw "Failed opaqueClz32NoArgument";
49 if (numberOfDFGCompiles(opaqueClz32NoArgument) > 1)
50 throw "The call without arguments should never exit.";
55 // Test Math.clz32() with a very polymorphic input. All test cases are seen at each iteration.
56 function opaqueAllTypesClz32(argument) {
57 return Math.clz32(argument);
59 noInline(opaqueAllTypesClz32);
60 noOSRExitFuzzing(opaqueAllTypesClz32);
62 function testAllTypesCall() {
63 for (let i = 0; i < 1e3; ++i) {
64 for (let testCaseInput of validInputTypedTestCases) {
65 let output = opaqueAllTypesClz32(testCaseInput[0]);
66 if (!isIdentical(output, testCaseInput[1]))
67 throw "Failed testAllTypesCall for input " + testCaseInput[0] + " expected " + testCaseInput[1] + " got " + output;
70 if (numberOfDFGCompiles(opaqueAllTypesClz32) > 2)
71 throw "We should have detected clz32() was polymorphic and generated a generic version.";
76 // Test Math.clz32() on a completely typed input. Every call see only one type.
77 function testSingleTypeCall() {
78 for (let testCaseInput of validInputTestCases) {
80 function opaqueClz32(argument) {
81 return Math.clz32(argument);
83 noInline(opaqueClz32);
84 noOSRExitFuzzing(opaqueClz32);
86 for (let i = 0; i < 1e4; ++i) {
87 if (!isIdentical(opaqueClz32(${testCaseInput[0]}), ${testCaseInput[1]})) {
88 throw "Failed testSingleTypeCall()";
91 if (numberOfDFGCompiles(opaqueClz32) > 1)
92 throw "We should have compiled a single clz32 for the expected type.";
99 // Test Math.clz32() on constants
100 function testConstant() {
101 for (let testCaseInput of validInputTestCases) {
103 function opaqueClz32OnConstant() {
104 return Math.clz32(${testCaseInput[0]});
106 noInline(opaqueClz32OnConstant);
107 noOSRExitFuzzing(opaqueClz32OnConstant);
109 for (let i = 0; i < 1e4; ++i) {
110 if (!isIdentical(opaqueClz32OnConstant(), ${testCaseInput[1]})) {
111 throw "Failed testConstant()";
114 if (numberOfDFGCompiles(opaqueClz32OnConstant) > 1)
115 throw "We should have compiled a single clz32 for the expected type.";
122 // Verify we call valueOf() exactly once per call.
123 function opaqueClz32ForSideEffects(argument) {
124 return Math.clz32(argument);
126 noInline(opaqueClz32ForSideEffects);
127 noOSRExitFuzzing(opaqueClz32ForSideEffects);
129 function testSideEffect() {
132 valueOf: function() { ++this.counter; return 16; }
134 let clz3216 = Math.clz32(16);
135 for (let i = 0; i < 1e4; ++i) {
136 if (opaqueClz32ForSideEffects(testObject) !== clz3216)
137 throw "Incorrect result in testSideEffect()";
139 if (testObject.counter !== 1e4)
140 throw "Failed testSideEffect()";
141 if (numberOfDFGCompiles(opaqueClz32ForSideEffects) > 1)
142 throw "opaqueClz32ForSideEffects() is predictable, it should only be compiled once.";
147 // Verify clz32() is not subject to CSE if the argument has side effects.
148 function opaqueClz32ForCSE(argument) {
149 return Math.clz32(argument) + Math.clz32(argument) + Math.clz32(argument);
151 noInline(opaqueClz32ForCSE);
152 noOSRExitFuzzing(opaqueClz32ForCSE);
157 valueOf: function() { ++this.counter; return 16; }
159 let clz3216 = Math.clz32(16);
160 let threeClz3216 = clz3216 + clz3216 + clz3216;
161 for (let i = 0; i < 1e4; ++i) {
162 if (opaqueClz32ForCSE(testObject) !== threeClz3216)
163 throw "Incorrect result in testCSE()";
165 if (testObject.counter !== 3e4)
166 throw "Failed testCSE()";
167 if (numberOfDFGCompiles(opaqueClz32ForCSE) > 1)
168 throw "opaqueClz32ForCSE() is predictable, it should only be compiled once.";
173 // Verify clz32() is not subject to DCE if the argument has side effects.
174 function opaqueClz32ForDCE(argument) {
175 Math.clz32(argument);
177 noInline(opaqueClz32ForDCE);
178 noOSRExitFuzzing(opaqueClz32ForDCE);
183 valueOf: function() { ++this.counter; return 16; }
185 for (let i = 0; i < 1e4; ++i) {
186 opaqueClz32ForDCE(testObject);
188 if (testObject.counter !== 1e4)
189 throw "Failed testDCE()";
190 if (numberOfDFGCompiles(opaqueClz32ForDCE) > 1)
191 throw "opaqueClz32ForDCE() is predictable, it should only be compiled once.";
196 // Test exceptions in the argument.
197 function testException() {
199 function opaqueClz32WithException(argument) {
200 let result = Math.clz32(argument);
204 noInline(opaqueClz32WithException);
206 let testObject = { valueOf: () => { return 64; } };
207 let clz3264 = Math.clz32(64);
209 // Warm up without exception.
210 for (let i = 0; i < 1e3; ++i) {
211 if (opaqueClz32WithException(testObject) !== clz3264)
212 throw "Incorrect result in opaqueClz32WithException()";
215 let testThrowObject = { valueOf: () => { throw testObject; return 64; } };
217 for (let i = 0; i < 1e2; ++i) {
219 if (opaqueClz32WithException(testThrowObject) !== 8)
220 throw "This code should not be reached!!";
222 if (e !== testObject) {
223 throw "Wrong object thrown from opaqueClz32WithException."
228 if (counter !== 1e3) {
229 throw "Invalid count in testException()";