| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- //-------------------------------------------------------------------------------------------------------
- // Copyright (C) Microsoft. All rights reserved.
- // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
- //-------------------------------------------------------------------------------------------------------
- var NonwideningOperation = {
- None: 0,
- Neg: 1,
- Ld: 2,
- ConvNum: 3,
- Count: 4
- };
- var bools = [false, true];
- // Test helper constants and variables
- var indent = 0;
- var nonwideningOperation = -1;
- var minTreeDepth = (53 - 32) >> 1;
- var maxTreeDepth = (53 - 32 + 1) << 1;
- var midTreeDepth = (minTreeDepth + maxTreeDepth) >> 1;
- for(var treeDepth = minTreeDepth;
- treeDepth <= maxTreeDepth;
- treeDepth += treeDepth <= midTreeDepth ? treeDepth - (minTreeDepth - 1) : ((maxTreeDepth - treeDepth) >> 1) + 1) {
- for(var treeBranches = 1; treeBranches <= 8; treeBranches <<= 1) {
- for(var useNegativeNumbersIndex = 0; useNegativeNumbersIndex < bools.length; ++useNegativeNumbersIndex) {
- var useNegativeNumbers = bools[useNegativeNumbersIndex];
- echo("generateAndRun(" + treeDepth + ", " + treeBranches + ", " + useNegativeNumbers + ");");
- generateAndRun(treeDepth, treeBranches, useNegativeNumbers);
- }
- }
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Test helpers
- function generateAndRun(treeDepth, treeBranches, useNegativeNumbers) {
- var low_i32 = -0x80000001;
- var high_i32 = 0x7fffffff;
- var ui32 = 0xffffffff;
- var f = "";
- f += echos("(function test() {", 1);
- {
- f += echos("echo(inner(" + toHex(useNegativeNumbers ? low_i32 : high_i32) + "));");
- f += echos("function inner(a) {", 1);
- {
- f += echos("a |= 0;");
- f += echos("var r = 0;");
- buildTree(treeDepth, treeBranches).traverse(function visit(node) {
- nonwideningOperation = (nonwideningOperation + 1) % NonwideningOperation.Count;
- var nodeName = varName(node.number);
- var dst =
- nonwideningOperation === NonwideningOperation.None || nonwideningOperation === NonwideningOperation.ConvNum
- ? nodeName
- : tempName(node.number);
- var parentNodeName = node.parent ? varName(node.parent.number) : "a";
- if(nonwideningOperation === NonwideningOperation.Neg)
- parentNodeName = "-" + parentNodeName;
- else if(nonwideningOperation === NonwideningOperation.ConvNum)
- parentNodeName = "+" + parentNodeName;
- var right =
- node.parent && nonwideningOperation !== NonwideningOperation.Neg && (node.number & 3) === 0
- ? useNegativeNumbers ? low_i32 : ui32
- : parentNodeName;
- f += echos("var " + dst + " = " + parentNodeName + " + " + right + " + 1;");
- if(nonwideningOperation === NonwideningOperation.Neg)
- f += echos("var " + nodeName + " = -" + dst + ";");
- else if(nonwideningOperation === NonwideningOperation.Ld)
- f += echos("var " + nodeName + " = " + dst + ";");
- if(node.left || node.right)
- return;
- f += echos("r ^= " + nodeName + ";");
- });
- f += echos("return r;");
- }
- f += echos("}", -1);
- }
- f += echos("});", -1);
- f = f.substring(0, f.length - 1);
- echo(f);
- f = eval(f);
- f();
- echo();
- function buildTree(depth, branches, numberContainer, parent) {
- function TreeNode(number, parent) {
- this.number = number;
- this.parent = parent ? parent : null;
- this.left = null;
- this.right = null;
- }
- TreeNode.prototype.traverse = function (visit) {
- visit(this);
- if(this.left)
- this.left.traverse(visit);
- if(this.right)
- this.right.traverse(visit);
- };
- if(depth <= 0)
- throw new Error("Invalid tree depth");
- if(branches <= 0)
- throw new Error("Invalid number of branches");
- if((branches & branches - 1) !== 0)
- throw new Error("Number of branches must be a power of 2");
- if(!numberContainer)
- numberContainer = [0];
- else if(numberContainer[0] < 0)
- throw new Error("Invalid node number");
- var node = new TreeNode(numberContainer[0]++, parent);
- if(--depth !== 0) {
- var branch = branches !== 1;
- if(branch)
- branches >>= 1;
- node.left = buildTree(depth, branches, numberContainer, node);
- if(branch)
- node.right = buildTree(depth, branches, numberContainer, node);
- }
- return node;
- }
- function varName(number) {
- return "v" + number;
- }
- function tempName(number) {
- return "t" + number;
- }
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function toHex(n) {
- if(typeof n !== "number")
- return n;
- return n >= 0 ? "0x" + n.toString(16) : "-0x" + (-n).toString(16);
- }
- function echos(s, changeIndent) {
- if(changeIndent && changeIndent < 0)
- indent += changeIndent * 4;
- if(s && s !== "") {
- var spaces = "";
- for(var i = 0; i < indent; ++i)
- spaces += " ";
- s = spaces + s + "\n";
- }
- else if(s === "")
- s = "\n";
- else
- s = "";
- if(changeIndent && changeIndent > 0)
- indent += changeIndent * 4;
- return s;
- }
- function echo() {
- var doEcho;
- if(this.WScript)
- doEcho = function (s) { this.WScript.Echo(s); };
- else if(this.document)
- doEcho = function (s) {
- var div = this.document.createElement("div");
- div.innerText = s;
- this.document.body.appendChild(div);
- };
- else
- doEcho = function (s) { this.print(s); };
- echo = function () {
- var s = "";
- for(var i = 0; i < arguments.length; ++i)
- s += arguments[i];
- doEcho(s);
- };
- echo.apply(this, arguments);
- }
|