HaxeFoundation/haxe — pull request #2255 by deltaluca (2013-10-13 19:10:29+00:00)
Title: Optimisations of Std.is and Std.string for js.

These are optimisations, absolutely specific to JS code generation (Other trivial optimisations like Std.is(_, Dynamic) -> true are not included, as those apply to all targets).

These are written as a JS-specific filter, as these optimisations must occur before DCE.

```js
class Test {
static function main() {
var x = 10;
trace(Std.is(x, Int));
trace(Std.is(x, Float));
trace(Std.is(x, String));
trace(Std.is(x, Bool));
trace(Std.is(x, Array));
trace(!Std.is(x, Int));
trace(!Std.is(x, Float));
trace(!Std.is(x, String));
trace(!Std.is(x, Bool));
trace(!Std.is(x, Array));

var x = 10;
trace(Std.string(x));
var x = 10.0;
trace(Std.string(x));
var x = "10";
trace(Std.string(x));
var x = true;
trace(Std.string(x));
}
}
```

before:
```js
(function () { "use strict";
var Std = function() { }
Std.__name__ = true;
Std.string = function(s) {
return js.Boot.__string_rec(s,"");
}
var Test = function() { }
Test.__name__ = true;
Test.main = function() {
var x = 10;
console.log(js.Boot.__instanceof(x,Int));
console.log(js.Boot.__instanceof(x,Float));
console.log(js.Boot.__instanceof(x,String));
console.log(js.Boot.__instanceof(x,Bool));
console.log(js.Boot.__instanceof(x,Array));
console.log(!js.Boot.__instanceof(x,Int));
console.log(!js.Boot.__instanceof(x,Float));
console.log(!js.Boot.__instanceof(x,String));
console.log(!js.Boot.__instanceof(x,Bool));
console.log(!js.Boot.__instanceof(x,Array));
var x1 = 10;
console.log(Std.string(x1));
var x2 = 10.0;
console.log(Std.string(x2));
var x3 = "10";
console.log(Std.string(x3));
var x4 = true;
console.log(Std.string(x4));
}
var js = {}
js.Boot = function() { }
js.Boot.__name__ = true;
js.Boot.__string_rec = function(o,s) {
if(o == null) return "null";
if(s.length >= 5) return "<...>";
var t = typeof(o);
if(t == "function" && (o.__name__ || o.__ename__)) t = "object";
switch(t) {
case "object":
if(o instanceof Array) {
if(o.__enum__) {
if(o.length == 2) return o[0];
var str = o[0] + "(";
s += "\t";
var _g1 = 2;
var _g = o.length;
while(_g1 < _g) {
var i = _g1++;
if(i != 2) str += "," + js.Boot.__string_rec(o[i],s); else str += js.Boot.__string_rec(o[i],s);
}
return str + ")";
}
var l = o.length;
var i;
var str = "[";
s += "\t";
var _g = 0;
while(_g < l) {
var i1 = _g++;
str += (i1 > 0?",":"") + js.Boot.__string_rec(o[i1],s);
}
str += "]";
return str;
}
var tostr;
try {
tostr = o.toString;
} catch( e ) {
return "???";
}
if(tostr != null && tostr != Object.toString) {
var s2 = o.toString();
if(s2 != "[object Object]") return s2;
}
var k = null;
var str = "{\n";
s += "\t";
var hasp = o.hasOwnProperty != null;
for( var k in o ) { ;
if(hasp && !o.hasOwnProperty(k)) {
continue;
}
if(k == "prototype" || k == "__class__" || k == "__super__" || k == "__interfaces__" || k == "__properties__") {
continue;
}
if(str.length != 2) str += ", \n";
str += s + k + " : " + js.Boot.__string_rec(o[k],s);
}
s = s.substring(1);
str += "\n" + s + "}";
return str;
case "function":
return "";
case "string":
return o;
default:
return String(o);
}
}
js.Boot.__interfLoop = function(cc,cl) {
if(cc == null) return false;
if(cc == cl) return true;
var intf = cc.__interfaces__;
if(intf != null) {
var _g1 = 0;
var _g = intf.length;
while(_g1 < _g) {
var i = _g1++;
var i1 = intf[i];
if(i1 == cl || js.Boot.__interfLoop(i1,cl)) return true;
}
}
return js.Boot.__interfLoop(cc.__super__,cl);
}
js.Boot.__instanceof = function(o,cl) {
if(cl == null) return false;
switch(cl) {
case Int:
return (o|0) === o;
case Float:
return typeof(o) == "number";
case Bool:
return typeof(o) == "boolean";
case String:
return typeof(o) == "string";
case Dynamic:
return true;
default:
if(o != null) {
if(typeof(cl) == "function") {
if(o instanceof cl) {
if(cl == Array) return o.__enum__ == null;
return true;
}
if(js.Boot.__interfLoop(o.__class__,cl)) return true;
}
} else return false;
if(cl == Class && o.__name__ != null) return true;
if(cl == Enum && o.__ename__ != null) return true;
return o.__enum__ == cl;
}
}
String.prototype.__class__ = String;
String.__name__ = true;
Array.prototype.__class__ = Array;
Array.__name__ = true;
var Int = { __name__ : ["Int"]};
var Dynamic = { __name__ : ["Dynamic"]};
var Float = Number;
Float.__name__ = ["Float"];
var Bool = Boolean;
Bool.__ename__ = ["Bool"];
var Class = { __name__ : ["Class"]};
var Enum = { };
Test.main();
})();
```

now:
```js
(function () { "use strict";
var Test = function() { }
Test.main = function() {
var x = 10;
console.log((x | 0) === x);
console.log(typeof(x) == "number");
console.log(typeof(x) == "string");
console.log(typeof(x) == "boolean");
console.log((x instanceof Array));
console.log((x | 0) !== x);
console.log(typeof(x) != "number");
console.log(typeof(x) != "string");
console.log(typeof(x) != "boolean");
console.log(!(x instanceof Array));
var x1 = 10;
console.log("" + x1);
var x2 = 10.0;
console.log("" + x2);
var x3 = "10";
console.log(x3);
var x4 = true;
console.log("" + x4);
}
Test.main();
})();
```