diff --git a/haste-compiler.cabal b/haste-compiler.cabal
--- a/haste-compiler.cabal
+++ b/haste-compiler.cabal
@@ -1,5 +1,5 @@
 Name:           haste-compiler
-Version:        0.2.9
+Version:        0.2.10
 License:        BSD3
 License-File:   LICENSE
 Synopsis:       Haskell To ECMAScript compiler
@@ -26,6 +26,7 @@
     MVar.js
     StableName.js
     Integer.js
+    Int64.js
     md5.js
     array.js
     pointers.js
diff --git a/lib/Int64.js b/lib/Int64.js
new file mode 100644
--- /dev/null
+++ b/lib/Int64.js
@@ -0,0 +1,850 @@
+// Copyright 2009 The Closure Library Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS-IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * Constructs a 64-bit two's-complement integer, given its low and high 32-bit
+ * values as *signed* integers.  See the from* functions below for more
+ * convenient ways of constructing Longs.
+ *
+ * The internal representation of a long is the two given signed, 32-bit values.
+ * We use 32-bit pieces because these are the size of integers on which
+ * Javascript performs bit-operations.  For operations like addition and
+ * multiplication, we split each number into 16-bit pieces, which can easily be
+ * multiplied within Javascript's floating-point representation without overflow
+ * or change in sign.
+ *
+ * In the algorithms below, we frequently reduce the negative case to the
+ * positive case by negating the input(s) and then post-processing the result.
+ * Note that we must ALWAYS check specially whether those values are MIN_VALUE
+ * (-2^63) because -MIN_VALUE == MIN_VALUE (since 2^63 cannot be represented as
+ * a positive number, it overflows back into a negative).  Not handling this
+ * case would often result in infinite recursion.
+ *
+ * @param {number} low  The low (signed) 32 bits of the long.
+ * @param {number} high  The high (signed) 32 bits of the long.
+ * @constructor
+ */
+Long = function(low, high) {
+  /**
+   * @type {number}
+   * @private
+   */
+  this.low_ = low | 0;  // force into 32 signed bits.
+
+  /**
+   * @type {number}
+   * @private
+   */
+  this.high_ = high | 0;  // force into 32 signed bits.
+};
+
+
+// NOTE: Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the
+// from* methods on which they depend.
+
+
+/**
+ * A cache of the Long representations of small integer values.
+ * @type {!Object}
+ * @private
+ */
+Long.IntCache_ = {};
+
+
+/**
+ * Returns a Long representing the given (32-bit) integer value.
+ * @param {number} value The 32-bit integer in question.
+ * @return {!Long} The corresponding Long value.
+ */
+Long.fromInt = function(value) {
+  if (-128 <= value && value < 128) {
+    var cachedObj = Long.IntCache_[value];
+    if (cachedObj) {
+      return cachedObj;
+    }
+  }
+
+  var obj = new Long(value | 0, value < 0 ? -1 : 0);
+  if (-128 <= value && value < 128) {
+    Long.IntCache_[value] = obj;
+  }
+  return obj;
+};
+
+
+/**
+ * Returns a Long representing the given value, provided that it is a finite
+ * number.  Otherwise, zero is returned.
+ * @param {number} value The number in question.
+ * @return {!Long} The corresponding Long value.
+ */
+Long.fromNumber = function(value) {
+  if (isNaN(value) || !isFinite(value)) {
+    return Long.ZERO;
+  } else if (value <= -Long.TWO_PWR_63_DBL_) {
+    return Long.MIN_VALUE;
+  } else if (value + 1 >= Long.TWO_PWR_63_DBL_) {
+    return Long.MAX_VALUE;
+  } else if (value < 0) {
+    return Long.fromNumber(-value).negate();
+  } else {
+    return new Long(
+        (value % Long.TWO_PWR_32_DBL_) | 0,
+        (value / Long.TWO_PWR_32_DBL_) | 0);
+  }
+};
+
+
+/**
+ * Returns a Long representing the 64-bit integer that comes by concatenating
+ * the given high and low bits.  Each is assumed to use 32 bits.
+ * @param {number} lowBits The low 32-bits.
+ * @param {number} highBits The high 32-bits.
+ * @return {!Long} The corresponding Long value.
+ */
+Long.fromBits = function(lowBits, highBits) {
+  return new Long(lowBits, highBits);
+};
+
+
+/**
+ * Returns a Long representation of the given string, written using the given
+ * radix.
+ * @param {string} str The textual representation of the Long.
+ * @param {number=} opt_radix The radix in which the text is written.
+ * @return {!Long} The corresponding Long value.
+ */
+Long.fromString = function(str, opt_radix) {
+  if (str.length == 0) {
+    throw Error('number format error: empty string');
+  }
+
+  var radix = opt_radix || 10;
+  if (radix < 2 || 36 < radix) {
+    throw Error('radix out of range: ' + radix);
+  }
+
+  if (str.charAt(0) == '-') {
+    return Long.fromString(str.substring(1), radix).negate();
+  } else if (str.indexOf('-') >= 0) {
+    throw Error('number format error: interior "-" character: ' + str);
+  }
+
+  // Do several (8) digits each time through the loop, so as to
+  // minimize the calls to the very expensive emulated div.
+  var radixToPower = Long.fromNumber(Math.pow(radix, 8));
+
+  var result = Long.ZERO;
+  for (var i = 0; i < str.length; i += 8) {
+    var size = Math.min(8, str.length - i);
+    var value = parseInt(str.substring(i, i + size), radix);
+    if (size < 8) {
+      var power = Long.fromNumber(Math.pow(radix, size));
+      result = result.multiply(power).add(Long.fromNumber(value));
+    } else {
+      result = result.multiply(radixToPower);
+      result = result.add(Long.fromNumber(value));
+    }
+  }
+  return result;
+};
+
+
+// NOTE: the compiler should inline these constant values below and then remove
+// these variables, so there should be no runtime penalty for these.
+
+
+/**
+ * Number used repeated below in calculations.  This must appear before the
+ * first call to any from* function below.
+ * @type {number}
+ * @private
+ */
+Long.TWO_PWR_16_DBL_ = 1 << 16;
+
+
+/**
+ * @type {number}
+ * @private
+ */
+Long.TWO_PWR_24_DBL_ = 1 << 24;
+
+
+/**
+ * @type {number}
+ * @private
+ */
+Long.TWO_PWR_32_DBL_ =
+    Long.TWO_PWR_16_DBL_ * Long.TWO_PWR_16_DBL_;
+
+
+/**
+ * @type {number}
+ * @private
+ */
+Long.TWO_PWR_31_DBL_ =
+    Long.TWO_PWR_32_DBL_ / 2;
+
+
+/**
+ * @type {number}
+ * @private
+ */
+Long.TWO_PWR_48_DBL_ =
+    Long.TWO_PWR_32_DBL_ * Long.TWO_PWR_16_DBL_;
+
+
+/**
+ * @type {number}
+ * @private
+ */
+Long.TWO_PWR_64_DBL_ =
+    Long.TWO_PWR_32_DBL_ * Long.TWO_PWR_32_DBL_;
+
+
+/**
+ * @type {number}
+ * @private
+ */
+Long.TWO_PWR_63_DBL_ =
+    Long.TWO_PWR_64_DBL_ / 2;
+
+
+/** @type {!Long} */
+Long.ZERO = Long.fromInt(0);
+
+
+/** @type {!Long} */
+Long.ONE = Long.fromInt(1);
+
+
+/** @type {!Long} */
+Long.NEG_ONE = Long.fromInt(-1);
+
+
+/** @type {!Long} */
+Long.MAX_VALUE =
+    Long.fromBits(0xFFFFFFFF | 0, 0x7FFFFFFF | 0);
+
+
+/** @type {!Long} */
+Long.MIN_VALUE = Long.fromBits(0, 0x80000000 | 0);
+
+
+/**
+ * @type {!Long}
+ * @private
+ */
+Long.TWO_PWR_24_ = Long.fromInt(1 << 24);
+
+
+/** @return {number} The value, assuming it is a 32-bit integer. */
+Long.prototype.toInt = function() {
+  return this.low_;
+};
+
+
+/** @return {number} The closest floating-point representation to this value. */
+Long.prototype.toNumber = function() {
+  return this.high_ * Long.TWO_PWR_32_DBL_ +
+         this.getLowBitsUnsigned();
+};
+
+
+/**
+ * @param {number=} opt_radix The radix in which the text should be written.
+ * @return {string} The textual representation of this value.
+ * @override
+ */
+Long.prototype.toString = function(opt_radix) {
+  var radix = opt_radix || 10;
+  if (radix < 2 || 36 < radix) {
+    throw Error('radix out of range: ' + radix);
+  }
+
+  if (this.isZero()) {
+    return '0';
+  }
+
+  if (this.isNegative()) {
+    if (this.equals(Long.MIN_VALUE)) {
+      // We need to change the Long value before it can be negated, so we remove
+      // the bottom-most digit in this base and then recurse to do the rest.
+      var radixLong = Long.fromNumber(radix);
+      var div = this.div(radixLong);
+      var rem = div.multiply(radixLong).subtract(this);
+      return div.toString(radix) + rem.toInt().toString(radix);
+    } else {
+      return '-' + this.negate().toString(radix);
+    }
+  }
+
+  // Do several (6) digits each time through the loop, so as to
+  // minimize the calls to the very expensive emulated div.
+  var radixToPower = Long.fromNumber(Math.pow(radix, 6));
+
+  var rem = this;
+  var result = '';
+  while (true) {
+    var remDiv = rem.div(radixToPower);
+    var intval = rem.subtract(remDiv.multiply(radixToPower)).toInt();
+    var digits = intval.toString(radix);
+
+    rem = remDiv;
+    if (rem.isZero()) {
+      return digits + result;
+    } else {
+      while (digits.length < 6) {
+        digits = '0' + digits;
+      }
+      result = '' + digits + result;
+    }
+  }
+};
+
+
+/** @return {number} The high 32-bits as a signed value. */
+Long.prototype.getHighBits = function() {
+  return this.high_;
+};
+
+
+/** @return {number} The low 32-bits as a signed value. */
+Long.prototype.getLowBits = function() {
+  return this.low_;
+};
+
+
+/** @return {number} The low 32-bits as an unsigned value. */
+Long.prototype.getLowBitsUnsigned = function() {
+  return (this.low_ >= 0) ?
+      this.low_ : Long.TWO_PWR_32_DBL_ + this.low_;
+};
+
+
+/**
+ * @return {number} Returns the number of bits needed to represent the absolute
+ *     value of this Long.
+ */
+Long.prototype.getNumBitsAbs = function() {
+  if (this.isNegative()) {
+    if (this.equals(Long.MIN_VALUE)) {
+      return 64;
+    } else {
+      return this.negate().getNumBitsAbs();
+    }
+  } else {
+    var val = this.high_ != 0 ? this.high_ : this.low_;
+    for (var bit = 31; bit > 0; bit--) {
+      if ((val & (1 << bit)) != 0) {
+        break;
+      }
+    }
+    return this.high_ != 0 ? bit + 33 : bit + 1;
+  }
+};
+
+
+/** @return {boolean} Whether this value is zero. */
+Long.prototype.isZero = function() {
+  return this.high_ == 0 && this.low_ == 0;
+};
+
+
+/** @return {boolean} Whether this value is negative. */
+Long.prototype.isNegative = function() {
+  return this.high_ < 0;
+};
+
+
+/** @return {boolean} Whether this value is odd. */
+Long.prototype.isOdd = function() {
+  return (this.low_ & 1) == 1;
+};
+
+
+/**
+ * @param {Long} other Long to compare against.
+ * @return {boolean} Whether this Long equals the other.
+ */
+Long.prototype.equals = function(other) {
+  return (this.high_ == other.high_) && (this.low_ == other.low_);
+};
+
+
+/**
+ * @param {Long} other Long to compare against.
+ * @return {boolean} Whether this Long does not equal the other.
+ */
+Long.prototype.notEquals = function(other) {
+  return (this.high_ != other.high_) || (this.low_ != other.low_);
+};
+
+
+/**
+ * @param {Long} other Long to compare against.
+ * @return {boolean} Whether this Long is less than the other.
+ */
+Long.prototype.lessThan = function(other) {
+  return this.compare(other) < 0;
+};
+
+
+/**
+ * @param {Long} other Long to compare against.
+ * @return {boolean} Whether this Long is less than or equal to the other.
+ */
+Long.prototype.lessThanOrEqual = function(other) {
+  return this.compare(other) <= 0;
+};
+
+
+/**
+ * @param {Long} other Long to compare against.
+ * @return {boolean} Whether this Long is greater than the other.
+ */
+Long.prototype.greaterThan = function(other) {
+  return this.compare(other) > 0;
+};
+
+
+/**
+ * @param {Long} other Long to compare against.
+ * @return {boolean} Whether this Long is greater than or equal to the other.
+ */
+Long.prototype.greaterThanOrEqual = function(other) {
+  return this.compare(other) >= 0;
+};
+
+
+/**
+ * Compares this Long with the given one.
+ * @param {Long} other Long to compare against.
+ * @return {number} 0 if they are the same, 1 if the this is greater, and -1
+ *     if the given one is greater.
+ */
+Long.prototype.compare = function(other) {
+  if (this.equals(other)) {
+    return 0;
+  }
+
+  var thisNeg = this.isNegative();
+  var otherNeg = other.isNegative();
+  if (thisNeg && !otherNeg) {
+    return -1;
+  }
+  if (!thisNeg && otherNeg) {
+    return 1;
+  }
+
+  // at this point, the signs are the same, so subtraction will not overflow
+  if (this.subtract(other).isNegative()) {
+    return -1;
+  } else {
+    return 1;
+  }
+};
+
+
+/** @return {!Long} The negation of this value. */
+Long.prototype.negate = function() {
+  if (this.equals(Long.MIN_VALUE)) {
+    return Long.MIN_VALUE;
+  } else {
+    return this.not().add(Long.ONE);
+  }
+};
+
+
+/**
+ * Returns the sum of this and the given Long.
+ * @param {Long} other Long to add to this one.
+ * @return {!Long} The sum of this and the given Long.
+ */
+Long.prototype.add = function(other) {
+  // Divide each number into 4 chunks of 16 bits, and then sum the chunks.
+
+  var a48 = this.high_ >>> 16;
+  var a32 = this.high_ & 0xFFFF;
+  var a16 = this.low_ >>> 16;
+  var a00 = this.low_ & 0xFFFF;
+
+  var b48 = other.high_ >>> 16;
+  var b32 = other.high_ & 0xFFFF;
+  var b16 = other.low_ >>> 16;
+  var b00 = other.low_ & 0xFFFF;
+
+  var c48 = 0, c32 = 0, c16 = 0, c00 = 0;
+  c00 += a00 + b00;
+  c16 += c00 >>> 16;
+  c00 &= 0xFFFF;
+  c16 += a16 + b16;
+  c32 += c16 >>> 16;
+  c16 &= 0xFFFF;
+  c32 += a32 + b32;
+  c48 += c32 >>> 16;
+  c32 &= 0xFFFF;
+  c48 += a48 + b48;
+  c48 &= 0xFFFF;
+  return Long.fromBits((c16 << 16) | c00, (c48 << 16) | c32);
+};
+
+
+/**
+ * Returns the difference of this and the given Long.
+ * @param {Long} other Long to subtract from this.
+ * @return {!Long} The difference of this and the given Long.
+ */
+Long.prototype.subtract = function(other) {
+  return this.add(other.negate());
+};
+
+
+/**
+ * Returns the product of this and the given long.
+ * @param {Long} other Long to multiply with this.
+ * @return {!Long} The product of this and the other.
+ */
+Long.prototype.multiply = function(other) {
+  if (this.isZero()) {
+    return Long.ZERO;
+  } else if (other.isZero()) {
+    return Long.ZERO;
+  }
+
+  if (this.equals(Long.MIN_VALUE)) {
+    return other.isOdd() ? Long.MIN_VALUE : Long.ZERO;
+  } else if (other.equals(Long.MIN_VALUE)) {
+    return this.isOdd() ? Long.MIN_VALUE : Long.ZERO;
+  }
+
+  if (this.isNegative()) {
+    if (other.isNegative()) {
+      return this.negate().multiply(other.negate());
+    } else {
+      return this.negate().multiply(other).negate();
+    }
+  } else if (other.isNegative()) {
+    return this.multiply(other.negate()).negate();
+  }
+
+  // If both longs are small, use float multiplication
+  if (this.lessThan(Long.TWO_PWR_24_) &&
+      other.lessThan(Long.TWO_PWR_24_)) {
+    return Long.fromNumber(this.toNumber() * other.toNumber());
+  }
+
+  // Divide each long into 4 chunks of 16 bits, and then add up 4x4 products.
+  // We can skip products that would overflow.
+
+  var a48 = this.high_ >>> 16;
+  var a32 = this.high_ & 0xFFFF;
+  var a16 = this.low_ >>> 16;
+  var a00 = this.low_ & 0xFFFF;
+
+  var b48 = other.high_ >>> 16;
+  var b32 = other.high_ & 0xFFFF;
+  var b16 = other.low_ >>> 16;
+  var b00 = other.low_ & 0xFFFF;
+
+  var c48 = 0, c32 = 0, c16 = 0, c00 = 0;
+  c00 += a00 * b00;
+  c16 += c00 >>> 16;
+  c00 &= 0xFFFF;
+  c16 += a16 * b00;
+  c32 += c16 >>> 16;
+  c16 &= 0xFFFF;
+  c16 += a00 * b16;
+  c32 += c16 >>> 16;
+  c16 &= 0xFFFF;
+  c32 += a32 * b00;
+  c48 += c32 >>> 16;
+  c32 &= 0xFFFF;
+  c32 += a16 * b16;
+  c48 += c32 >>> 16;
+  c32 &= 0xFFFF;
+  c32 += a00 * b32;
+  c48 += c32 >>> 16;
+  c32 &= 0xFFFF;
+  c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48;
+  c48 &= 0xFFFF;
+  return Long.fromBits((c16 << 16) | c00, (c48 << 16) | c32);
+};
+
+
+/**
+ * Returns this Long divided by the given one.
+ * @param {Long} other Long by which to divide.
+ * @return {!Long} This Long divided by the given one.
+ */
+Long.prototype.div = function(other) {
+  if (other.isZero()) {
+    throw Error('division by zero');
+  } else if (this.isZero()) {
+    return Long.ZERO;
+  }
+
+  if (this.equals(Long.MIN_VALUE)) {
+    if (other.equals(Long.ONE) ||
+        other.equals(Long.NEG_ONE)) {
+      return Long.MIN_VALUE;  // recall that -MIN_VALUE == MIN_VALUE
+    } else if (other.equals(Long.MIN_VALUE)) {
+      return Long.ONE;
+    } else {
+      // At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|.
+      var halfThis = this.shiftRight(1);
+      var approx = halfThis.div(other).shiftLeft(1);
+      if (approx.equals(Long.ZERO)) {
+        return other.isNegative() ? Long.ONE : Long.NEG_ONE;
+      } else {
+        var rem = this.subtract(other.multiply(approx));
+        var result = approx.add(rem.div(other));
+        return result;
+      }
+    }
+  } else if (other.equals(Long.MIN_VALUE)) {
+    return Long.ZERO;
+  }
+
+  if (this.isNegative()) {
+    if (other.isNegative()) {
+      return this.negate().div(other.negate());
+    } else {
+      return this.negate().div(other).negate();
+    }
+  } else if (other.isNegative()) {
+    return this.div(other.negate()).negate();
+  }
+
+  // Repeat the following until the remainder is less than other:  find a
+  // floating-point that approximates remainder / other *from below*, add this
+  // into the result, and subtract it from the remainder.  It is critical that
+  // the approximate value is less than or equal to the real value so that the
+  // remainder never becomes negative.
+  var res = Long.ZERO;
+  var rem = this;
+  while (rem.greaterThanOrEqual(other)) {
+    // Approximate the result of division. This may be a little greater or
+    // smaller than the actual value.
+    var approx = Math.max(1, Math.floor(rem.toNumber() / other.toNumber()));
+
+    // We will tweak the approximate result by changing it in the 48-th digit or
+    // the smallest non-fractional digit, whichever is larger.
+    var log2 = Math.ceil(Math.log(approx) / Math.LN2);
+    var delta = (log2 <= 48) ? 1 : Math.pow(2, log2 - 48);
+
+    // Decrease the approximation until it is smaller than the remainder.  Note
+    // that if it is too large, the product overflows and is negative.
+    var approxRes = Long.fromNumber(approx);
+    var approxRem = approxRes.multiply(other);
+    while (approxRem.isNegative() || approxRem.greaterThan(rem)) {
+      approx -= delta;
+      approxRes = Long.fromNumber(approx);
+      approxRem = approxRes.multiply(other);
+    }
+
+    // We know the answer can't be zero... and actually, zero would cause
+    // infinite recursion since we would make no progress.
+    if (approxRes.isZero()) {
+      approxRes = Long.ONE;
+    }
+
+    res = res.add(approxRes);
+    rem = rem.subtract(approxRem);
+  }
+  return res;
+};
+
+
+/**
+ * Returns this Long modulo the given one.
+ * @param {Long} other Long by which to mod.
+ * @return {!Long} This Long modulo the given one.
+ */
+Long.prototype.modulo = function(other) {
+  return this.subtract(this.div(other).multiply(other));
+};
+
+
+/** @return {!Long} The bitwise-NOT of this value. */
+Long.prototype.not = function() {
+  return Long.fromBits(~this.low_, ~this.high_);
+};
+
+
+/**
+ * Returns the bitwise-AND of this Long and the given one.
+ * @param {Long} other The Long with which to AND.
+ * @return {!Long} The bitwise-AND of this and the other.
+ */
+Long.prototype.and = function(other) {
+  return Long.fromBits(this.low_ & other.low_,
+                                 this.high_ & other.high_);
+};
+
+
+/**
+ * Returns the bitwise-OR of this Long and the given one.
+ * @param {Long} other The Long with which to OR.
+ * @return {!Long} The bitwise-OR of this and the other.
+ */
+Long.prototype.or = function(other) {
+  return Long.fromBits(this.low_ | other.low_,
+                                 this.high_ | other.high_);
+};
+
+
+/**
+ * Returns the bitwise-XOR of this Long and the given one.
+ * @param {Long} other The Long with which to XOR.
+ * @return {!Long} The bitwise-XOR of this and the other.
+ */
+Long.prototype.xor = function(other) {
+  return Long.fromBits(this.low_ ^ other.low_,
+                                 this.high_ ^ other.high_);
+};
+
+
+/**
+ * Returns this Long with bits shifted to the left by the given amount.
+ * @param {number} numBits The number of bits by which to shift.
+ * @return {!Long} This shifted to the left by the given amount.
+ */
+Long.prototype.shiftLeft = function(numBits) {
+  numBits &= 63;
+  if (numBits == 0) {
+    return this;
+  } else {
+    var low = this.low_;
+    if (numBits < 32) {
+      var high = this.high_;
+      return Long.fromBits(
+          low << numBits,
+          (high << numBits) | (low >>> (32 - numBits)));
+    } else {
+      return Long.fromBits(0, low << (numBits - 32));
+    }
+  }
+};
+
+
+/**
+ * Returns this Long with bits shifted to the right by the given amount.
+ * @param {number} numBits The number of bits by which to shift.
+ * @return {!Long} This shifted to the right by the given amount.
+ */
+Long.prototype.shiftRight = function(numBits) {
+  numBits &= 63;
+  if (numBits == 0) {
+    return this;
+  } else {
+    var high = this.high_;
+    if (numBits < 32) {
+      var low = this.low_;
+      return Long.fromBits(
+          (low >>> numBits) | (high << (32 - numBits)),
+          high >> numBits);
+    } else {
+      return Long.fromBits(
+          high >> (numBits - 32),
+          high >= 0 ? 0 : -1);
+    }
+  }
+};
+
+
+/**
+ * Returns this Long with bits shifted to the right by the given amount, with
+ * the new top bits matching the current sign bit.
+ * @param {number} numBits The number of bits by which to shift.
+ * @return {!Long} This shifted to the right by the given amount, with
+ *     zeros placed into the new leading bits.
+ */
+Long.prototype.shiftRightUnsigned = function(numBits) {
+  numBits &= 63;
+  if (numBits == 0) {
+    return this;
+  } else {
+    var high = this.high_;
+    if (numBits < 32) {
+      var low = this.low_;
+      return Long.fromBits(
+          (low >>> numBits) | (high << (32 - numBits)),
+          high >>> numBits);
+    } else if (numBits == 32) {
+      return Long.fromBits(high, 0);
+    } else {
+      return Long.fromBits(high >>> (numBits - 32), 0);
+    }
+  }
+};
+
+function hs_eqInt64(x, y) {return x.equals(y);}
+function hs_neInt64(x, y) {return !x.equals(y);}
+function hs_ltInt64(x, y) {return x.compare(y) < 0;}
+function hs_leInt64(x, y) {return x.compare(y) <= 0;}
+function hs_gtInt64(x, y) {return x.compare(y) > 0;}
+function hs_geInt64(x, y) {return x.compare(y) >= 0;}
+function hs_quotInt64(x, y) {return x.div(y);}
+function hs_remInt64(x, y) {return x.modulo(y);}
+function hs_plusInt64(x, y) {return x.add(y);}
+function hs_minusInt64(x, y) {return x.subtract(y);}
+function hs_timesInt64(x, y) {return x.multiply(y);}
+function hs_negateInt64(x) {return x.negate();}
+function hs_uncheckedIShiftL64(x, bits) {x.shiftLeft(bits);}
+function hs_uncheckedIShiftRA64(x, bits) {x.shiftRight(bits);}
+function hs_uncheckedIShiftRL64(x, bits) {x.shiftRightUnsigned(bits);}
+function hs_intToInt64(x) {return new Long(x, 0);}
+function hs_int64ToInt(x) {return x.toInt();}
+
+
+
+// Word64
+function hs_wordToWord64(x) {
+    return I_fromInt(x);
+}
+function hs_word64ToWord(x) {
+    return I_toInt(x);
+}
+function hs_mkWord64(low, high) {
+    return I_fromBits([low, high]);
+}
+
+var hs_and64 = I_and;
+var hs_or64 = I_or;
+var hs_xor64 = I_xor;
+var __i64_all_ones = I_fromBits([0xffffffff, 0xffffffff]);
+function hs_not64(x) {
+    return I_xor(x, __i64_all_ones);
+}
+var hs_eqWord64 = I_equals;
+var hs_neWord64 = I_notEquals;
+var hs_ltWord64 = I_lessThan;
+var hs_leWord64 = I_lessThanOrEqual;
+var hs_gtWord64 = I_greaterThan;
+var hs_geWord64 = I_greaterThanOrEqual;
+var hs_quotWord64 = I_quot;
+var hs_remWord64 = I_rem;
+var __w64_max = I_fromBits([0,0,1]);
+function hs_uncheckedShiftL64(x, bits) {
+    return I_rem(I_shiftLeft(x, bits), __w64_max);
+}
+var hs_uncheckedShiftRL64 = I_shiftRight;
+function hs_int64ToWord64(x) {
+    var tmp = I_add(__w64_max, I_fromBits([x.getLowBits(), x.getHighBits()]));
+    return I_rem(tmp, __w64_max);
+}
+function hs_word64ToInt64(x) {
+    return Long.fromBits(I_getBits(x, 0), I_getBits(x, 1));
+}
diff --git a/lib/Integer.js b/lib/Integer.js
--- a/lib/Integer.js
+++ b/lib/Integer.js
@@ -45,7 +45,7 @@
   }
 };
 
-Integer.fromBits = function(bits) {
+I_fromBits = function(bits) {
   var high = bits[bits.length - 1];
   return new Integer(bits, high & (1 << 31) ? -1 : 0);
 };
@@ -104,14 +104,14 @@
     var val = 0;
     var pow = 1;
     for (var i = 0; i < self.bits_.length; i++) {
-      val += getBitsUnsigned(self, i) * pow;
+      val += I_getBitsUnsigned(self, i) * pow;
       pow *= Integer.TWO_PWR_32_DBL_;
     }
     return val;
   }
 };
 
-var getBits = function(self, index) {
+var I_getBits = function(self, index) {
   if (index < 0) {
     return 0;
   } else if (index < self.bits_.length) {
@@ -121,8 +121,8 @@
   }
 };
 
-var getBitsUnsigned = function(self, index) {
-  var val = getBits(self, index);
+var I_getBitsUnsigned = function(self, index) {
+  var val = I_getBits(self, index);
   return val >= 0 ? val : Integer.TWO_PWR_32_DBL_ + val;
 };
 
@@ -157,7 +157,7 @@
   }
   var len = Math.max(self.bits_.length, other.bits_.length);
   for (var i = 0; i < len; i++) {
-    if (getBits(self, i) != getBits(other, i)) {
+    if (I_getBits(self, i) != I_getBits(other, i)) {
       return false;
     }
   }
@@ -168,19 +168,19 @@
   return !I_equals(self, other);
 };
 
-var greaterThan = function(self, other) {
+var I_greaterThan = function(self, other) {
   return I_compare(self, other) > 0;
 };
 
-var greaterThanOrEqual = function(self, other) {
+var I_greaterThanOrEqual = function(self, other) {
   return I_compare(self, other) >= 0;
 };
 
-var lessThan = function(self, other) {
+var I_lessThan = function(self, other) {
   return I_compare(self, other) < 0;
 };
 
-var lessThanOrEqual = function(self, other) {
+var I_lessThanOrEqual = function(self, other) {
   return I_compare(self, other) <= 0;
 };
 
@@ -204,10 +204,10 @@
   var bit_index = (numBits - 1) % 32;
   var bits = [];
   for (var i = 0; i < arr_index; i++) {
-    bits[i] = getBits(self, i);
+    bits[i] = I_getBits(self, i);
   }
   var sigBits = bit_index == 31 ? 0xFFFFFFFF : (1 << (bit_index + 1)) - 1;
-  var val = getBits(self, arr_index) & sigBits;
+  var val = I_getBits(self, arr_index) & sigBits;
   if (val & (1 << bit_index)) {
     val |= 0xFFFFFFFF - sigBits;
     bits[arr_index] = val;
@@ -228,11 +228,11 @@
   var carry = 0;
 
   for (var i = 0; i <= len; i++) {
-    var a1 = getBits(self, i) >>> 16;
-    var a0 = getBits(self, i) & 0xFFFF;
+    var a1 = I_getBits(self, i) >>> 16;
+    var a0 = I_getBits(self, i) & 0xFFFF;
 
-    var b1 = getBits(other, i) >>> 16;
-    var b0 = getBits(other, i) & 0xFFFF;
+    var b1 = I_getBits(other, i) >>> 16;
+    var b0 = I_getBits(other, i) & 0xFFFF;
 
     var c0 = carry + a0 + b0;
     var c1 = (c0 >>> 16) + a1 + b1;
@@ -241,7 +241,7 @@
     c1 &= 0xFFFF;
     arr[i] = (c1 << 16) | c0;
   }
-  return Integer.fromBits(arr);
+  return I_fromBits(arr);
 };
 
 var I_sub = function(self, other) {
@@ -265,8 +265,8 @@
     return I_negate(I_mul(self, I_negate(other)));
   }
 
-  if (lessThan(self, Integer.TWO_PWR_24_) &&
-      lessThan(other, Integer.TWO_PWR_24_)) {
+  if (I_lessThan(self, Integer.TWO_PWR_24_) &&
+      I_lessThan(other, Integer.TWO_PWR_24_)) {
     return I_fromNumber(I_toNumber(self) * I_toNumber(other));
   }
 
@@ -277,11 +277,11 @@
   }
   for (var i = 0; i < self.bits_.length; i++) {
     for (var j = 0; j < other.bits_.length; j++) {
-      var a1 = getBits(self, i) >>> 16;
-      var a0 = getBits(self, i) & 0xFFFF;
+      var a1 = I_getBits(self, i) >>> 16;
+      var a0 = I_getBits(self, i) & 0xFFFF;
 
-      var b1 = getBits(other, j) >>> 16;
-      var b0 = getBits(other, j) & 0xFFFF;
+      var b1 = I_getBits(other, j) >>> 16;
+      var b0 = I_getBits(other, j) & 0xFFFF;
 
       arr[2 * i + 2 * j] += a0 * b0;
       Integer.carry16_(arr, 2 * i + 2 * j);
@@ -315,7 +315,7 @@
 }
 
 var I_div = function(self, other) {
-  if(greaterThan(self, Integer.ZERO) != greaterThan(other, Integer.ZERO)) {
+  if(I_greaterThan(self, Integer.ZERO) != I_greaterThan(other, Integer.ZERO)) {
     if(I_rem(self, other) != Integer.ZERO) {
       return I_sub(I_quot(self, other), Integer.ONE);
     }
@@ -350,13 +350,13 @@
 
   var res = Integer.ZERO;
   var rem = self;
-  while (greaterThanOrEqual(rem, other)) {
+  while (I_greaterThanOrEqual(rem, other)) {
     var approx = Math.max(1, Math.floor(I_toNumber(rem) / I_toNumber(other)));
     var log2 = Math.ceil(Math.log(approx) / Math.LN2);
     var delta = (log2 <= 48) ? 1 : Math.pow(2, log2 - 48);
     var approxRes = I_fromNumber(approx);
     var approxRem = I_mul(approxRes, other);
-    while (isNegative(approxRem) || greaterThan(approxRem, rem)) {
+    while (isNegative(approxRem) || I_greaterThan(approxRem, rem)) {
       approx -= delta;
       approxRes = I_fromNumber(approx);
       approxRem = I_mul(approxRes, other);
@@ -389,7 +389,7 @@
   var len = Math.max(self.bits_.length, other.bits_.length);
   var arr = [];
   for (var i = 0; i < len; i++) {
-    arr[i] = getBits(self, i) & getBits(other, i);
+    arr[i] = I_getBits(self, i) & I_getBits(other, i);
   }
   return new Integer(arr, self.sign_ & other.sign_);
 };
@@ -398,7 +398,7 @@
   var len = Math.max(self.bits_.length, other.bits_.length);
   var arr = [];
   for (var i = 0; i < len; i++) {
-    arr[i] = getBits(self, i) | getBits(other, i);
+    arr[i] = I_getBits(self, i) | I_getBits(other, i);
   }
   return new Integer(arr, self.sign_ | other.sign_);
 };
@@ -407,7 +407,7 @@
   var len = Math.max(self.bits_.length, other.bits_.length);
   var arr = [];
   for (var i = 0; i < len; i++) {
-    arr[i] = getBits(self, i) ^ getBits(other, i);
+    arr[i] = I_getBits(self, i) ^ I_getBits(other, i);
   }
   return new Integer(arr, self.sign_ ^ other.sign_);
 };
@@ -419,10 +419,10 @@
   var arr = [];
   for (var i = 0; i < len; i++) {
     if (bit_delta > 0) {
-      arr[i] = (getBits(self, i - arr_delta) << bit_delta) |
-               (getBits(self, i - arr_delta - 1) >>> (32 - bit_delta));
+      arr[i] = (I_getBits(self, i - arr_delta) << bit_delta) |
+               (I_getBits(self, i - arr_delta - 1) >>> (32 - bit_delta));
     } else {
-      arr[i] = getBits(self, i - arr_delta);
+      arr[i] = I_getBits(self, i - arr_delta);
     }
   }
   return new Integer(arr, self.sign_);
@@ -435,10 +435,10 @@
   var arr = [];
   for (var i = 0; i < len; i++) {
     if (bit_delta > 0) {
-      arr[i] = (getBits(self, i + arr_delta) >>> bit_delta) |
-               (getBits(self, i + arr_delta + 1) << (32 - bit_delta));
+      arr[i] = (I_getBits(self, i + arr_delta) >>> bit_delta) |
+               (I_getBits(self, i + arr_delta + 1) << (32 - bit_delta));
     } else {
-      arr[i] = getBits(self, i + arr_delta);
+      arr[i] = I_getBits(self, i + arr_delta);
     }
   }
   return new Integer(arr, self.sign_);
@@ -464,7 +464,7 @@
 
 var I_decodeDouble = function(x) {
   var dec = decodeDouble(x);
-  var mantissa = Integer.fromBits([dec[3], dec[2]]);
+  var mantissa = I_fromBits([dec[3], dec[2]]);
   if(dec[1] < 0) {
     mantissa = I_negate(mantissa);
   }
@@ -503,4 +503,20 @@
 
 var I_fromRat = function(a, b) {
     return I_toNumber(a) / I_toNumber(b);
+}
+
+function I_fromInt64(x) {
+    return I_fromBits([x.getLowBits(), x.getHighBits()]);
+}
+
+function I_toInt64(x) {
+    return Long.fromBits(I_getBits(x, 0), I_getBits(x, 1));
+}
+
+function I_fromWord64(x) {
+    return x;
+}
+
+function I_toWord64(x) {
+    return I_rem(I_add(__w64_max, x), __w64_max);
 }
diff --git a/lib/rts.js b/lib/rts.js
--- a/lib/rts.js
+++ b/lib/rts.js
@@ -253,19 +253,6 @@
     }
 }
 
-function hs_eqWord64(a, b) {
-    return (a[0] == b[0] && a[1] == b[1]);
-}
-
-// Word64# representation: (Word, Word)
-function hs_wordToWord64(low) {
-    return [0, low];
-}
-
-function hs_mkWord64(high, low) {
-    return [high, low];
-}
-
 var coercionToken = undefined;
 
 /* Haste represents constructors internally using 1 for the first constructor,
@@ -286,6 +273,13 @@
 
 var __word_encodeFloat = __word_encodeDouble;
 var jsRound = Math.round; // Stupid GHC doesn't like periods in FFI IDs...
+var realWorld = undefined;
 if(typeof _ == 'undefined') {
     var _ = undefined;
+}
+
+function popCnt(i) {
+    i = i - ((i >> 1) & 0x55555555);
+    i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
+    return (((i + (i >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;
 }
diff --git a/lib/stdlib.js b/lib/stdlib.js
--- a/lib/stdlib.js
+++ b/lib/stdlib.js
@@ -124,6 +124,14 @@
     elem[prop] = val;
 }
 
+function jsGetAttr(elem, prop) {
+    return elem.getAttribute(prop).toString();
+}
+
+function jsSetAttr(elem, prop, val) {
+    elem.setAttribute(prop, val);
+}
+
 function jsGetStyle(elem, prop) {
     return elem.style[prop].toString();
 }
@@ -223,7 +231,7 @@
 
 // Escape all double quotes in a string
 function jsUnquote(str) {
-    return str.replace(/"/, '\\"');
+    return str.replace(/"/g, '\\"');
 }
 
 // Parse a JSON message into a Haste.JSON.JSON value.
@@ -267,7 +275,7 @@
                 ks.unshift(k);
             }
             var xs = [0];
-            for(var i in ks) {
+            for(var i = 0; i < ks.length; i++) {
                 xs = [1, [0, [0,ks[i]], toHS(obj[ks[i]])], xs];
             }
             return [4, xs];
diff --git a/src/Data/JSTarget/Optimize.hs b/src/Data/JSTarget/Optimize.hs
--- a/src/Data/JSTarget/Optimize.hs
+++ b/src/Data/JSTarget/Optimize.hs
@@ -17,7 +17,7 @@
 optimizeFun f (AST ast js) =
   flip runTravM js $ do
     shrinkCase ast
-    >>= inlineAssigns True
+    >>= inlineAssigns
     >>= optimizeArrays
     >>= inlineReturns
     >>= zapJSStringConversions
@@ -29,7 +29,7 @@
 topLevelInline :: AST Stm -> AST Stm
 topLevelInline (AST ast js) =
   flip runTravM js $ do
-    inlineAssigns False ast
+    inlineAssigns ast
     >>= optimizeArrays
     >>= optimizeThunks
     >>= optimizeArrays
@@ -97,8 +97,8 @@
 --   care about the assignment side effect.
 --
 --   TODO: don't inline thunks into functions!
-inlineAssigns :: JSTrav ast => Bool -> ast -> TravM ast
-inlineAssigns blackholeOK ast = do
+inlineAssigns :: JSTrav ast => ast -> TravM ast
+inlineAssigns ast = do
     inlinable <- gatherInlinable ast
     mapJS (const True) return (inl inlinable) ast
   where
@@ -112,9 +112,6 @@
           case M.lookup lhs m of
             Just occ | occ == occursLocal ->
               case occ of
-                -- Never-used symbols don't need assignment.
-                Never | blackholeOK -> do
-                  return (Assign blackHole ex next)
                 -- Inline of any non-lambda value
                 Once | mayReorder -> do
                   replaceEx (not <$> isShared) (Var lhs) ex next
diff --git a/src/Data/JSTarget/Print.hs b/src/Data/JSTarget/Print.hs
--- a/src/Data/JSTarget/Print.hs
+++ b/src/Data/JSTarget/Print.hs
@@ -213,8 +213,8 @@
   opParens Add a (Lit (LNum (-n)))
 opParens Sub (Lit (LNum 0)) b =
   case b of
-    BinOp _ _ _ -> "-(" .+. pp b .+. ")"
-    _           -> "-" .+. pp b
+    BinOp _ _ _ -> " -(" .+. pp b .+. ")"
+    _           -> " -" .+. pp b
 opParens op a b = do
   let bparens = case b of
                   Lit (LNum n) | n < 0 -> \x -> "(".+. pp x .+. ")"
diff --git a/src/Haste/Builtins.hs b/src/Haste/Builtins.hs
--- a/src/Haste/Builtins.hs
+++ b/src/Haste/Builtins.hs
@@ -10,7 +10,7 @@
     (Just "GHC.Prim", "coercionToken#") ->
       Just $ foreignVar "coercionToken"
     (Just "GHC.Prim", "realWorld#") ->
-      Just $ foreignVar "realWorld"
+      Just $ foreignVar "_"
     (Just "GHC.Err", "error") ->
       Just $ foreignVar "err"
 
diff --git a/src/Haste/CodeGen.hs b/src/Haste/CodeGen.hs
--- a/src/Haste/CodeGen.hs
+++ b/src/Haste/CodeGen.hs
@@ -4,6 +4,7 @@
 import Control.Applicative
 import Control.Monad
 import Data.Int
+import Data.Bits
 import Data.Word
 import Data.Char
 import Data.List (partition, foldl')
@@ -29,7 +30,7 @@
 import TyCon
 import BasicTypes
 -- AST stuff
-import Data.JSTarget as J
+import Data.JSTarget as J hiding ((.&.))
 import Data.JSTarget.AST (Exp (..), Stm (..), LHS (..))
 -- General Haste stuff
 import Haste.Config
@@ -108,13 +109,26 @@
 genEx (StgLit l) = do
   genLit l
 genEx (StgConApp con args) = do
-  (tag, stricts) <- genDataCon con
-  (args', stricts') <- genArgsPair $ zip args stricts
-  -- Don't create unboxed tuples with a single element.
-  case (isUnboxedTupleCon con, args') of
-    (True, [arg]) -> return $ evaluate arg (head stricts')
-    _             -> mkCon tag args' stricts'
+  -- On 64 bit machines, GHC constructs small integers from Ints rather than
+  -- Int64, so we need to deal with it or be unable to reliably create Int64
+  -- or Integer values.
+  case (dataConNameModule con, args) of
+    (("S#", "GHC.Integer.Type"), [StgLitArg (MachInt n)]) | tooLarge n -> do
+      return $ mkInteger n
+    _ -> do
+      (tag, stricts) <- genDataCon con
+      (args', stricts') <- genArgsPair $ zip args stricts
+      -- Don't create unboxed tuples with a single element.
+      case (isUnboxedTupleCon con, args') of
+        (True, [arg]) -> return $ evaluate arg (head stricts')
+        _             -> mkCon tag args' stricts'
   where
+    mkInteger n =
+        array [litN 1, callForeign "I_fromBits" [array [lit lo, lit hi]]]
+      where
+        lo = n .&. 0xffffffff
+        hi = n `shiftR` 32
+    tooLarge n = n > 2147483647 || n < -2147483648
     -- Always inline bools
     mkCon l _ _ | isEnumerationDataCon con = return l
     mkCon tag as ss = return $ array (tag : zipWith evaluate as ss)
@@ -424,15 +438,20 @@
 --   IMPORTANT: remember to update the RTS if any changes are made to the
 --              constructor tag values!
 genDataConTag :: DataCon -> AST Exp
-genDataConTag d = do
-  let n = occNameString $ nameOccName $ dataConName d
-      m = moduleNameString $ moduleName $ nameModule $ dataConName d
-  case (n, m) of
+genDataConTag d =
+  case dataConNameModule d of
     ("True", "GHC.Types")  -> lit True
     ("False", "GHC.Types") -> lit False
     _                      ->
       lit (fromIntegral (dataConTag d - fIRST_TAG) :: Double)
 
+-- | Get the name and module of the given data constructor.
+dataConNameModule :: DataCon -> (String, String)
+dataConNameModule d =
+  (occNameString $ nameOccName $ dataConName d,
+   moduleNameString $ moduleName $ nameModule $ dataConName d)
+
+
 -- | Generate literals.
 genLit :: L.Literal -> JSGen Config (AST Exp)
 genLit l = do
@@ -450,16 +469,24 @@
       | w > 0xffffffff  -> do warn Verbose (constFail "Word" w)
                               return $ truncWord w
       | otherwise       -> return . litN $ fromIntegral w
-    MachWord64 w        -> return . litN $ fromIntegral w
+    MachWord64 w        -> return $ word64 w
     MachNullAddr        -> return $ litN 0
-    MachInt64 n         -> return . litN $ fromIntegral n
-    LitInteger n _      -> return . lit  $ n
+    MachInt64 n         -> return $ int64 n
+    LitInteger n _      -> return $ lit n
     MachLabel _ _ _     -> return $ lit ":(" -- Labels point to machine code - ignore!
   where
     constFail t n = t ++ " literal " ++ show n ++ " doesn't fit in 32 bits;"
                     ++ " truncating!"
     truncInt n  = litN . fromIntegral $ (fromIntegral n :: Int32)
     truncWord w = litN . fromIntegral $ (fromIntegral w :: Word32)
+    int64 n = callForeign "new Long" [lit lo, lit hi]
+      where
+        lo = n .&. 0xffffffff
+        hi = n `shiftR` 32
+    word64 n = callForeign "I_fromBits" [array [lit lo, lit hi]]
+      where
+        lo = n .&. 0xffffffff
+        hi = n `shiftR` 32
 
 -- | Generate a function application.
 genApp :: Var.Var -> [StgArg] -> JSGen Config (AST Exp)
diff --git a/src/Haste/Config.hs b/src/Haste/Config.hs
--- a/src/Haste/Config.hs
+++ b/src/Haste/Config.hs
@@ -13,8 +13,9 @@
 
 stdJSLibs :: [FilePath]
 stdJSLibs = map (jsDir </>)  [
-    "rts.js", "stdlib.js", "MVar.js", "StableName.js", "Integer.js", "md5.js",
-    "array.js", "pointers.js", "cheap-unicode.js", "Canvas.js", "Handle.js"
+    "rts.js", "stdlib.js", "MVar.js", "StableName.js", "Integer.js", "Int64.js",
+    "md5.js", "array.js", "pointers.js", "cheap-unicode.js", "Canvas.js",
+    "Handle.js"
   ]
 
 debugLib :: FilePath
diff --git a/src/Haste/PrimOps.hs b/src/Haste/PrimOps.hs
--- a/src/Haste/PrimOps.hs
+++ b/src/Haste/PrimOps.hs
@@ -298,6 +298,10 @@
     MaskStatus              -> Right $ litN 0
 
     -- Misc. ops
+    PopCntOp       -> Right $ callForeign "popCnt" [head xs]
+    PopCnt8Op      -> Right $ callForeign "popCnt" [head xs]
+    PopCnt16Op     -> Right $ callForeign "popCnt" [head xs]
+    PopCnt32Op     -> Right $ callForeign "popCnt" [head xs]
     DelayOp        -> Right $ defState
     SeqOp          -> Right $ callForeign "E" [head xs]
     AtomicallyOp   -> Right $ callSaturated (xs !! 0) []
diff --git a/src/Haste/Version.hs b/src/Haste/Version.hs
--- a/src/Haste/Version.hs
+++ b/src/Haste/Version.hs
@@ -10,7 +10,7 @@
 import Haste.Environment (hasteDir)
 
 hasteVersion :: Version
-hasteVersion = Version [0, 2, 9] []
+hasteVersion = Version [0, 2, 10] []
 
 ghcVersion :: String
 ghcVersion = cProjectVersion
diff --git a/src/haste-boot.hs b/src/haste-boot.hs
--- a/src/haste-boot.hs
+++ b/src/haste-boot.hs
@@ -111,7 +111,7 @@
           putStrLn "Couldn't unpack Closure compiler; continuing without."
   where
     closureURI =
-      "http://closure-compiler.googlecode.com/files/compiler-latest.zip"
+      "http://dl.google.com/closure-compiler/compiler-latest.zip"
 
 -- | Build haste's base libs.
 buildLibs :: IO ()
diff --git a/src/haste-inst.hs b/src/haste-inst.hs
--- a/src/haste-inst.hs
+++ b/src/haste-inst.hs
@@ -19,7 +19,8 @@
          "--with-hc-pkg=" ++ hastePkgBinary,
          "--with-hsc2hs=hsc2hs",
          "--prefix=" ++ hasteInstDir,
-         "--package-db=" ++ pkgDir]
+         "--package-db=" ++ pkgDir,
+         "-fhaste-inst"]
 
 main :: IO ()
 main = do
