After spending way too much time trying to debug my Fan to Javascript compiler, I broke down and hacked up a little FWT-based AST viewer. I’m pretty sure we’ll fold this into the core distro, just need to clean up the code first, and figure out where to put it.
Archive for the ‘Fantom’ Category
Fan AST Viewer
Friday, June 12th, 2009Extending built-in types
Tuesday, June 2nd, 2009I ran into an issue where I really needed to tag the built-in Javascript types with additional information to make Fan work better. The big one is annotating a Number to be either a Int or Float, which you need to do to make all the equality checks work consistently (since 5 != 5f).
This is was my first attempt, which I assumed would work:
>>> var x = 15;
>>> x.$fanType = sys_Type.find("sys::Int");
>>> x.$fanType
undefined
But no dice. After a bit of googling, I found this page, which says in order to add properties to the built-in types, you must create objects using the constructor syntax:
>>> var x = new Number(15);
>>> x.$fanType = sys_Type.find("sys::Int");
>>> x.$fanType
"sys::Int"
I assume this a performance optimization, where you can use a primitive int value in the first case, and have to allocate an object in the latter. Though since Javascript is a pure-OO language, I would be interested in seeing how VMs actually implement this behavoir.
Edit 8 Jun 09: Just realized using the object syntax breaks equality checks for numbers:
>>> var x = new Number(4); >>> var y = new Number(4); >>> x == y false
Which sort of sucks, but you can work around it using valueOf, but still annoying.
>>> x.valueOf() == y.valueOf() true
Javascript Bitwise Operators
Friday, May 15th, 2009I stumbled across an interesting “edge” case in Javascript when porting gfx to Javascript.
Turns out Javascript converts numbers to 32-bit signed numbers before evaluating bitwise operators. This is problematic because it prevents you from using the msb for 32-bit bitmaks:
Java: 0xaabbcc | 0xff000000 = 0xffaabbcc (4289379276) Javascript: 0xaabbcc | 0xff000000 = 0xffabbcc (-554434)
The workaround is pretty straightforward, you simply have to add 2^32+1 to convert back to an “unsigned” value:
var x = 0xaabbcc | 0xff000000; if (x < 0) x += 0xffffffff+1;
But unfortunately, that means I have to wrap all bitwise operations in a method call, and perform that check, which I expect will not be anywhere near as fast as the straight operator call.
