haxe icon indicating copy to clipboard operation
haxe copied to clipboard

[js] Passing String.charAt takes weird closure

Open Simn opened this issue 9 years ago • 1 comments

class Main {
    static function main() {
        var str = "fdsf";
        run(str.charAt);
    }

    static function run(cb:Int->String) trace(cb(2));
}

Generated:

// Generated by Haxe 3.3.0
(function () { "use strict";
var Main = function() { };
Main.main = function() {
    Main.run($bind("fdsf","fdsf".charAt));
};
Main.run = function(cb) {
    console.log(cb(2));
};
var $_, $fid = 0;
function $bind(o,m) { if( m == null ) return null; if( m.__id__ == null ) m.__id__ = $fid++; var f; if( o.hx__closures__ == null ) o.hx__closures__ = {}; else f = o.hx__closures__[m.__id__]; if( f == null ) { f = function(){ return f.method.apply(f.scope, arguments); }; f.scope = o; f.method = m; o.hx__closures__[m.__id__] = f; } return f; }
Main.main();
})();

Errors with TypeError: Cannot assign to read only property 'hx__closures__' of fdsf. Not a regression and might be broken on other targets too.

Simn avatar Aug 29 '16 19:08 Simn

This can be fixed like this:

function $bind(o, m) {
	if (m == null) return null;
	var t = typeof o;
+	if (t == 'string')
+		return function () {
+			return m.apply(o, arguments);
+		};
	if (m.__id__ == null) m.__id__ = $global.$haxeUID++;
	var f;
	if (o.hx__closures__ == null) o.hx__closures__ = {};
	else f = o.hx__closures__[m.__id__];
	if (f == null) {
		f = m.bind(o);
		o.hx__closures__[m.__id__] = f;
	}
	return f;
}

Idk if it's better to generate function wrapper at bind call for string closures instead. Changing $bind itself also supports Dynamic cases i think.

RblSb avatar Dec 10 '25 01:12 RblSb