Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[js] optimize Std.is for common types #2543

Merged
merged 1 commit into from
Jan 25, 2014

Conversation

nadako
Copy link
Member

@nadako nadako commented Jan 18, 2014

This is the second part of @deltaluca's JS optimization moved to api_inline as @ncannasse requested in #2255.

I added some unit tests to Std.unit.hx to ensure that nothing breaks.

I also added the generation of __typeof__ next to __instanceof__ that was already there, as well as __strict_eq__ and __strict_neq__ for JS strict equality operators. I believe some code in Std/Boot/Type could be ported to use those instead of __js__ magic.

Main.hx

class Main
{
    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));
    }
}

Generated before:

(function () { "use strict";
var Main = function() { };
Main.__name__ = true;
Main.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 js = {};
js.Boot = function() { };
js.Boot.__name__ = true;
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 = { };
Main.main();
})();

Generated after:

(function () { "use strict";
var Main = function() { };
Main.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) && x.__enum__ == null);
    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) && x.__enum__ == null));
};
Main.main();
})();

@ncannasse
Copy link
Member

We could add EField(EThis,f) to is_trivial, but it's good enough as it to be merged now.

ncannasse added a commit that referenced this pull request Jan 25, 2014
[js] optimize Std.is for common types
@ncannasse ncannasse merged commit 6b26f5d into HaxeFoundation:development Jan 25, 2014
@nadako nadako deleted the stdis_opt branch January 25, 2014 19:59
@aduros
Copy link
Contributor

aduros commented Jan 26, 2014

👍 Thanks Nadako/Luca!

I added the new magic to http://haxe.org/doc/advanced/magic?lang=en

@Simn
Copy link
Member

Simn commented Jan 26, 2014

I was wondering why all target authors went for untyped __magic__(stuff) instead of something like js.Lib.magic(stuff).

@nadako
Copy link
Member Author

nadako commented Jan 26, 2014

That is actually a good point. I personally just followed the __instanceof__ style when making these patches and will be happy to rework it if we make clear decision on that.

@aduros
Copy link
Contributor

aduros commented Jan 26, 2014

@Simn: Yup, now that we have macros, I'd love to have everything converted to methods if possible.

@Simn
Copy link
Member

Simn commented Jan 26, 2014

Well we cannot change it at the moment anyway, I was just wondering.

@ncannasse
Copy link
Member

@Simn originaly we didn't have inlining and even in that case you maybe don't want it to be exposed. For instance I don't think it's a good idea to add platform-specific type checking since Haxe already provides one already that is cross platform.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants