fholm / IronJS

IronJS - A JavaScript implementation for .NET
http://ironjs.wordpress.com
Apache License 2.0
680 stars 79 forks source link

Missing identifier in output of CoffeeScript compiler #45

Closed itowlson closed 13 years ago

itowlson commented 13 years ago

If you compile the following CoffeeScript source:

id = (x) -> x

under IronJS, it compiles to this:

(function() {
  var ;
  id = function(x) {
    return x;
  };
}).call(this);

The var ; on the second line should be var id;.

(A CoffeeScript script which defines multiple functions should return in multiple identifiers e.g. var square, cube;.)

otac0n commented 13 years ago

This appears to be an issue with the Array.prototype.sort function.

Given this preamble:

var a = [];
var b = [];
a.push("x");
b.push("y");
a.push("z");

The expression a.concat(b).join(",") produces "x,z,y", as it should, but the expression a.sort().concat(b.sort()).join(",") produces ",,".

The elements of the a and b arrays are all undefined after the sort operation.

otac0n commented 13 years ago

Interestingly enough, these two programs produce different results:

var a = ["a", "b", "c"];
a.sort();

and:

var a = [];
a.push("a");
a.push("b");
a.push("c");
a.sort();

This leads me to believe that the Push operation is not adding the items to the array in the same way that the array initializer is.

My current best bet is that we are handling the Get and Put methods on arrays inconsistently.

otac0n commented 13 years ago

OK, on line 309 of Native.Array.fs

ao.Dense.[i].Value <- ao.Prototype.Get(uint32 i)

We are overwriting the values with undefined.

I believe that the Get function should be returning the proper value, but it isn't, and I'm not sure why we are even doing this overwriting.

I'm gonna have to defer to Fredrik to fix this one, since he recently re-wrote the array stuff.

otac0n commented 13 years ago

AH HA! I figured it out.

We were pre-allocating 10 spots in the internal dense array, to minimize the number of array copies.

When it came time to sort, we were sorting the entire dense array (instead of just the first length items), but the old length value stayed the same. Couple that with the fact that undefined values sort to the top, and we get the behavior you are seeing.

My last comment must have been observed AFTER the initial sort, so that when the elements in the array were found to not exist, we were looking through the prototype chain to fill the gaps.

I'll get a fix out here in about 10 minutes.