diff --git a/src/js/OWNERS b/src/js/OWNERS
new file mode 100644
index 0000000..f7002c7
--- /dev/null
+++ b/src/js/OWNERS
@@ -0,0 +1,11 @@
+set noparent
+
+adamk@chromium.org
+bmeurer@chromium.org
+cbruni@chromium.org
+ishell@chromium.org
+jkummerow@chromium.org
+littledan@chromium.org
+rossberg@chromium.org
+verwaest@chromium.org
+yangguo@chromium.org
diff --git a/src/js/array-iterator.js b/src/js/array-iterator.js
new file mode 100644
index 0000000..2609ebd
--- /dev/null
+++ b/src/js/array-iterator.js
@@ -0,0 +1,154 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function(global, utils) {
+
+"use strict";
+
+%CheckIsBootstrapping();
+
+// -----------------------------------------------------------------------
+// Imports
+
+var arrayIterationKindSymbol =
+    utils.ImportNow("array_iteration_kind_symbol");
+var arrayIteratorNextIndexSymbol =
+    utils.ImportNow("array_iterator_next_symbol");
+var arrayIteratorObjectSymbol =
+    utils.ImportNow("array_iterator_object_symbol");
+var GlobalArray = global.Array;
+var IteratorPrototype = utils.ImportNow("IteratorPrototype");
+var iteratorSymbol = utils.ImportNow("iterator_symbol");
+var MakeTypeError;
+var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
+var GlobalTypedArray = global.Uint8Array.__proto__;
+
+utils.Import(function(from) {
+  MakeTypeError = from.MakeTypeError;
+})
+
+// -----------------------------------------------------------------------
+
+function ArrayIterator() {}
+
+
+// TODO(wingo): Update section numbers when ES6 has stabilized.  The
+// section numbers below are already out of date as of the May 2014
+// draft.
+
+
+// 15.4.5.1 CreateArrayIterator Abstract Operation
+function CreateArrayIterator(array, kind) {
+  var object = TO_OBJECT(array);
+  var iterator = new ArrayIterator;
+  SET_PRIVATE(iterator, arrayIteratorObjectSymbol, object);
+  SET_PRIVATE(iterator, arrayIteratorNextIndexSymbol, 0);
+  SET_PRIVATE(iterator, arrayIterationKindSymbol, kind);
+  return iterator;
+}
+
+
+// 22.1.5.2.2 %ArrayIteratorPrototype%[@@iterator]
+function ArrayIteratorIterator() {
+    return this;
+}
+
+
+// ES6 section 22.1.5.2.1 %ArrayIteratorPrototype%.next( )
+function ArrayIteratorNext() {
+  var iterator = this;
+  var value = UNDEFINED;
+  var done = true;
+
+  if (!IS_RECEIVER(iterator) ||
+      !HAS_DEFINED_PRIVATE(iterator, arrayIteratorNextIndexSymbol)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        'Array Iterator.prototype.next', this);
+  }
+
+  var array = GET_PRIVATE(iterator, arrayIteratorObjectSymbol);
+  if (!IS_UNDEFINED(array)) {
+    var index = GET_PRIVATE(iterator, arrayIteratorNextIndexSymbol);
+    var itemKind = GET_PRIVATE(iterator, arrayIterationKindSymbol);
+    var length = TO_UINT32(array.length);
+
+    // "sparse" is never used.
+
+    if (index >= length) {
+      SET_PRIVATE(iterator, arrayIteratorObjectSymbol, UNDEFINED);
+    } else {
+      SET_PRIVATE(iterator, arrayIteratorNextIndexSymbol, index + 1);
+
+      if (itemKind == ITERATOR_KIND_VALUES) {
+        value = array[index];
+      } else if (itemKind == ITERATOR_KIND_ENTRIES) {
+        value = [index, array[index]];
+      } else {
+        value = index;
+      }
+      done = false;
+    }
+  }
+
+  return %_CreateIterResultObject(value, done);
+}
+
+
+function ArrayEntries() {
+  return CreateArrayIterator(this, ITERATOR_KIND_ENTRIES);
+}
+
+
+function ArrayValues() {
+  return CreateArrayIterator(this, ITERATOR_KIND_VALUES);
+}
+
+
+function ArrayKeys() {
+  return CreateArrayIterator(this, ITERATOR_KIND_KEYS);
+}
+
+
+%FunctionSetPrototype(ArrayIterator, {__proto__: IteratorPrototype});
+%FunctionSetInstanceClassName(ArrayIterator, 'Array Iterator');
+
+utils.InstallFunctions(ArrayIterator.prototype, DONT_ENUM, [
+  'next', ArrayIteratorNext
+]);
+utils.SetFunctionName(ArrayIteratorIterator, iteratorSymbol);
+%AddNamedProperty(ArrayIterator.prototype, iteratorSymbol,
+                  ArrayIteratorIterator, DONT_ENUM);
+%AddNamedProperty(ArrayIterator.prototype, toStringTagSymbol,
+                  "Array Iterator", READ_ONLY | DONT_ENUM);
+
+utils.InstallFunctions(GlobalArray.prototype, DONT_ENUM, [
+  // No 'values' since it breaks webcompat: http://crbug.com/409858
+  'entries', ArrayEntries,
+  'keys', ArrayKeys
+]);
+
+// TODO(adam): Remove this call once 'values' is in the above
+// InstallFunctions block, as it'll be redundant.
+utils.SetFunctionName(ArrayValues, 'values');
+
+%AddNamedProperty(GlobalArray.prototype, iteratorSymbol, ArrayValues,
+                  DONT_ENUM);
+
+%AddNamedProperty(GlobalTypedArray.prototype,
+                  'entries', ArrayEntries, DONT_ENUM);
+%AddNamedProperty(GlobalTypedArray.prototype, 'values', ArrayValues, DONT_ENUM);
+%AddNamedProperty(GlobalTypedArray.prototype, 'keys', ArrayKeys, DONT_ENUM);
+%AddNamedProperty(GlobalTypedArray.prototype,
+                  iteratorSymbol, ArrayValues, DONT_ENUM);
+
+// -------------------------------------------------------------------
+// Exports
+
+utils.Export(function(to) {
+  to.ArrayValues = ArrayValues;
+});
+
+%InstallToContext(["array_values_iterator", ArrayValues]);
+
+})
diff --git a/src/js/array.js b/src/js/array.js
new file mode 100644
index 0000000..f9cf161
--- /dev/null
+++ b/src/js/array.js
@@ -0,0 +1,1983 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function(global, utils, extrasUtils) {
+
+"use strict";
+
+%CheckIsBootstrapping();
+
+// -------------------------------------------------------------------
+// Imports
+
+var AddIndexedProperty;
+var FLAG_harmony_tolength;
+var FLAG_harmony_species;
+var GetIterator;
+var GetMethod;
+var GlobalArray = global.Array;
+var InternalArray = utils.InternalArray;
+var InternalPackedArray = utils.InternalPackedArray;
+var MakeTypeError;
+var MaxSimple;
+var MinSimple;
+var ObjectDefineProperty;
+var ObjectHasOwnProperty;
+var ObjectToString = utils.ImportNow("object_to_string");
+var ObserveBeginPerformSplice;
+var ObserveEndPerformSplice;
+var ObserveEnqueueSpliceRecord;
+var SameValueZero;
+var iteratorSymbol = utils.ImportNow("iterator_symbol");
+var unscopablesSymbol = utils.ImportNow("unscopables_symbol");
+
+utils.Import(function(from) {
+  AddIndexedProperty = from.AddIndexedProperty;
+  GetIterator = from.GetIterator;
+  GetMethod = from.GetMethod;
+  MakeTypeError = from.MakeTypeError;
+  MaxSimple = from.MaxSimple;
+  MinSimple = from.MinSimple;
+  ObjectDefineProperty = from.ObjectDefineProperty;
+  ObjectHasOwnProperty = from.ObjectHasOwnProperty;
+  ObserveBeginPerformSplice = from.ObserveBeginPerformSplice;
+  ObserveEndPerformSplice = from.ObserveEndPerformSplice;
+  ObserveEnqueueSpliceRecord = from.ObserveEnqueueSpliceRecord;
+  SameValueZero = from.SameValueZero;
+});
+
+utils.ImportFromExperimental(function(from) {
+  FLAG_harmony_tolength = from.FLAG_harmony_tolength;
+  FLAG_harmony_species = from.FLAG_harmony_species;
+});
+
+// -------------------------------------------------------------------
+
+
+function ArraySpeciesCreate(array, length) {
+  var constructor;
+  if (FLAG_harmony_species) {
+    constructor = %ArraySpeciesConstructor(array);
+  } else {
+    constructor = GlobalArray;
+  }
+  return new constructor(length);
+}
+
+
+function DefineIndexedProperty(array, i, value) {
+  if (FLAG_harmony_species) {
+    var result = ObjectDefineProperty(array, i, {
+      value: value, writable: true, configurable: true, enumerable: true
+    });
+    if (!result) throw MakeTypeError(kStrictCannotAssign, i);
+  } else {
+    AddIndexedProperty(array, i, value);
+  }
+}
+
+
+// Global list of arrays visited during toString, toLocaleString and
+// join invocations.
+var visited_arrays = new InternalArray();
+
+
+// Gets a sorted array of array keys.  Useful for operations on sparse
+// arrays.  Dupes have not been removed.
+function GetSortedArrayKeys(array, indices) {
+  var keys = new InternalArray();
+  if (IS_NUMBER(indices)) {
+    // It's an interval
+    var limit = indices;
+    for (var i = 0; i < limit; ++i) {
+      var e = array[i];
+      if (!IS_UNDEFINED(e) || i in array) {
+        keys.push(i);
+      }
+    }
+  } else {
+    var length = indices.length;
+    for (var k = 0; k < length; ++k) {
+      var key = indices[k];
+      if (!IS_UNDEFINED(key)) {
+        var e = array[key];
+        if (!IS_UNDEFINED(e) || key in array) {
+          keys.push(key);
+        }
+      }
+    }
+    keys.sort(function(a, b) { return a - b; });
+  }
+  return keys;
+}
+
+
+function SparseJoinWithSeparatorJS(array, len, convert, separator) {
+  var keys = GetSortedArrayKeys(array, %GetArrayKeys(array, len));
+  var totalLength = 0;
+  var elements = new InternalArray(keys.length * 2);
+  var previousKey = -1;
+  for (var i = 0; i < keys.length; i++) {
+    var key = keys[i];
+    if (key != previousKey) {  // keys may contain duplicates.
+      var e = array[key];
+      if (!IS_STRING(e)) e = convert(e);
+      elements[i * 2] = key;
+      elements[i * 2 + 1] = e;
+      previousKey = key;
+    }
+  }
+  return %SparseJoinWithSeparator(elements, len, separator);
+}
+
+
+// Optimized for sparse arrays if separator is ''.
+function SparseJoin(array, len, convert) {
+  var keys = GetSortedArrayKeys(array, %GetArrayKeys(array, len));
+  var last_key = -1;
+  var keys_length = keys.length;
+
+  var elements = new InternalArray(keys_length);
+  var elements_length = 0;
+
+  for (var i = 0; i < keys_length; i++) {
+    var key = keys[i];
+    if (key != last_key) {
+      var e = array[key];
+      if (!IS_STRING(e)) e = convert(e);
+      elements[elements_length++] = e;
+      last_key = key;
+    }
+  }
+  return %StringBuilderConcat(elements, elements_length, '');
+}
+
+
+function UseSparseVariant(array, length, is_array, touched) {
+  // Only use the sparse variant on arrays that are likely to be sparse and the
+  // number of elements touched in the operation is relatively small compared to
+  // the overall size of the array.
+  if (!is_array || length < 1000 || %IsObserved(array) ||
+      %HasComplexElements(array)) {
+    return false;
+  }
+  if (!%_IsSmi(length)) {
+    return true;
+  }
+  var elements_threshold = length >> 2;  // No more than 75% holes
+  var estimated_elements = %EstimateNumberOfElements(array);
+  return (estimated_elements < elements_threshold) &&
+    (touched > estimated_elements * 4);
+}
+
+
+function Join(array, length, separator, convert) {
+  if (length == 0) return '';
+
+  var is_array = IS_ARRAY(array);
+
+  if (is_array) {
+    // If the array is cyclic, return the empty string for already
+    // visited arrays.
+    if (!%PushIfAbsent(visited_arrays, array)) return '';
+  }
+
+  // Attempt to convert the elements.
+  try {
+    if (UseSparseVariant(array, length, is_array, length)) {
+      %NormalizeElements(array);
+      if (separator.length == 0) {
+        return SparseJoin(array, length, convert);
+      } else {
+        return SparseJoinWithSeparatorJS(array, length, convert, separator);
+      }
+    }
+
+    // Fast case for one-element arrays.
+    if (length == 1) {
+      var e = array[0];
+      if (IS_STRING(e)) return e;
+      return convert(e);
+    }
+
+    // Construct an array for the elements.
+    var elements = new InternalArray(length);
+
+    // We pull the empty separator check outside the loop for speed!
+    if (separator.length == 0) {
+      var elements_length = 0;
+      for (var i = 0; i < length; i++) {
+        var e = array[i];
+        if (!IS_STRING(e)) e = convert(e);
+        elements[elements_length++] = e;
+      }
+      elements.length = elements_length;
+      var result = %_FastOneByteArrayJoin(elements, '');
+      if (!IS_UNDEFINED(result)) return result;
+      return %StringBuilderConcat(elements, elements_length, '');
+    }
+    // Non-empty separator case.
+    // If the first element is a number then use the heuristic that the
+    // remaining elements are also likely to be numbers.
+    if (!IS_NUMBER(array[0])) {
+      for (var i = 0; i < length; i++) {
+        var e = array[i];
+        if (!IS_STRING(e)) e = convert(e);
+        elements[i] = e;
+      }
+    } else {
+      for (var i = 0; i < length; i++) {
+        var e = array[i];
+        if (IS_NUMBER(e)) {
+          e = %_NumberToString(e);
+        } else if (!IS_STRING(e)) {
+          e = convert(e);
+        }
+        elements[i] = e;
+      }
+    }
+    var result = %_FastOneByteArrayJoin(elements, separator);
+    if (!IS_UNDEFINED(result)) return result;
+
+    return %StringBuilderJoin(elements, length, separator);
+  } finally {
+    // Make sure to remove the last element of the visited array no
+    // matter what happens.
+    if (is_array) visited_arrays.length = visited_arrays.length - 1;
+  }
+}
+
+
+function ConvertToString(x) {
+  if (IS_NULL_OR_UNDEFINED(x)) {
+    return '';
+  } else {
+    return TO_STRING(x);
+  }
+}
+
+
+function ConvertToLocaleString(e) {
+  if (IS_NULL_OR_UNDEFINED(e)) {
+    return '';
+  } else {
+    return TO_STRING(e.toLocaleString());
+  }
+}
+
+
+// This function implements the optimized splice implementation that can use
+// special array operations to handle sparse arrays in a sensible fashion.
+function SparseSlice(array, start_i, del_count, len, deleted_elements) {
+  // Move deleted elements to a new array (the return value from splice).
+  var indices = %GetArrayKeys(array, start_i + del_count);
+  if (IS_NUMBER(indices)) {
+    var limit = indices;
+    for (var i = start_i; i < limit; ++i) {
+      var current = array[i];
+      if (!IS_UNDEFINED(current) || i in array) {
+        DefineIndexedProperty(deleted_elements, i - start_i, current);
+      }
+    }
+  } else {
+    var length = indices.length;
+    for (var k = 0; k < length; ++k) {
+      var key = indices[k];
+      if (!IS_UNDEFINED(key)) {
+        if (key >= start_i) {
+          var current = array[key];
+          if (!IS_UNDEFINED(current) || key in array) {
+            DefineIndexedProperty(deleted_elements, key - start_i, current);
+          }
+        }
+      }
+    }
+  }
+}
+
+
+// This function implements the optimized splice implementation that can use
+// special array operations to handle sparse arrays in a sensible fashion.
+function SparseMove(array, start_i, del_count, len, num_additional_args) {
+  // Bail out if no moving is necessary.
+  if (num_additional_args === del_count) return;
+  // Move data to new array.
+  var new_array = new InternalArray(
+      // Clamp array length to 2^32-1 to avoid early RangeError.
+      MinSimple(len - del_count + num_additional_args, 0xffffffff));
+  var big_indices;
+  var indices = %GetArrayKeys(array, len);
+  if (IS_NUMBER(indices)) {
+    var limit = indices;
+    for (var i = 0; i < start_i && i < limit; ++i) {
+      var current = array[i];
+      if (!IS_UNDEFINED(current) || i in array) {
+        new_array[i] = current;
+      }
+    }
+    for (var i = start_i + del_count; i < limit; ++i) {
+      var current = array[i];
+      if (!IS_UNDEFINED(current) || i in array) {
+        new_array[i - del_count + num_additional_args] = current;
+      }
+    }
+  } else {
+    var length = indices.length;
+    for (var k = 0; k < length; ++k) {
+      var key = indices[k];
+      if (!IS_UNDEFINED(key)) {
+        if (key < start_i) {
+          var current = array[key];
+          if (!IS_UNDEFINED(current) || key in array) {
+            new_array[key] = current;
+          }
+        } else if (key >= start_i + del_count) {
+          var current = array[key];
+          if (!IS_UNDEFINED(current) || key in array) {
+            var new_key = key - del_count + num_additional_args;
+            new_array[new_key] = current;
+            if (new_key > 0xfffffffe) {
+              big_indices = big_indices || new InternalArray();
+              big_indices.push(new_key);
+            }
+          }
+        }
+      }
+    }
+  }
+  // Move contents of new_array into this array
+  %MoveArrayContents(new_array, array);
+  // Add any moved values that aren't elements anymore.
+  if (!IS_UNDEFINED(big_indices)) {
+    var length = big_indices.length;
+    for (var i = 0; i < length; ++i) {
+      var key = big_indices[i];
+      array[key] = new_array[key];
+    }
+  }
+}
+
+
+// This is part of the old simple-minded splice.  We are using it either
+// because the receiver is not an array (so we have no choice) or because we
+// know we are not deleting or moving a lot of elements.
+function SimpleSlice(array, start_i, del_count, len, deleted_elements) {
+  var is_array = IS_ARRAY(array);
+  for (var i = 0; i < del_count; i++) {
+    var index = start_i + i;
+    if (HAS_INDEX(array, index, is_array)) {
+      var current = array[index];
+      DefineIndexedProperty(deleted_elements, i, current);
+    }
+  }
+}
+
+
+function SimpleMove(array, start_i, del_count, len, num_additional_args) {
+  var is_array = IS_ARRAY(array);
+  if (num_additional_args !== del_count) {
+    // Move the existing elements after the elements to be deleted
+    // to the right position in the resulting array.
+    if (num_additional_args > del_count) {
+      for (var i = len - del_count; i > start_i; i--) {
+        var from_index = i + del_count - 1;
+        var to_index = i + num_additional_args - 1;
+        if (HAS_INDEX(array, from_index, is_array)) {
+          array[to_index] = array[from_index];
+        } else {
+          delete array[to_index];
+        }
+      }
+    } else {
+      for (var i = start_i; i < len - del_count; i++) {
+        var from_index = i + del_count;
+        var to_index = i + num_additional_args;
+        if (HAS_INDEX(array, from_index, is_array)) {
+          array[to_index] = array[from_index];
+        } else {
+          delete array[to_index];
+        }
+      }
+      for (var i = len; i > len - del_count + num_additional_args; i--) {
+        delete array[i - 1];
+      }
+    }
+  }
+}
+
+
+// -------------------------------------------------------------------
+
+
+function ArrayToString() {
+  var array;
+  var func;
+  if (IS_ARRAY(this)) {
+    func = this.join;
+    if (func === ArrayJoin) {
+      return Join(this, this.length, ',', ConvertToString);
+    }
+    array = this;
+  } else {
+    array = TO_OBJECT(this);
+    func = array.join;
+  }
+  if (!IS_CALLABLE(func)) {
+    return %_Call(ObjectToString, array);
+  }
+  return %_Call(func, array);
+}
+
+
+function InnerArrayToLocaleString(array, length) {
+  var len = TO_LENGTH_OR_UINT32(length);
+  if (len === 0) return "";
+  return Join(array, len, ',', ConvertToLocaleString);
+}
+
+
+function ArrayToLocaleString() {
+  var array = TO_OBJECT(this);
+  var arrayLen = array.length;
+  return InnerArrayToLocaleString(array, arrayLen);
+}
+
+
+function InnerArrayJoin(separator, array, length) {
+  if (IS_UNDEFINED(separator)) {
+    separator = ',';
+  } else {
+    separator = TO_STRING(separator);
+  }
+
+  var result = %_FastOneByteArrayJoin(array, separator);
+  if (!IS_UNDEFINED(result)) return result;
+
+  // Fast case for one-element arrays.
+  if (length === 1) {
+    var e = array[0];
+    if (IS_NULL_OR_UNDEFINED(e)) return '';
+    return TO_STRING(e);
+  }
+
+  return Join(array, length, separator, ConvertToString);
+}
+
+
+function ArrayJoin(separator) {
+  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.join");
+
+  var array = TO_OBJECT(this);
+  var length = TO_LENGTH_OR_UINT32(array.length);
+
+  return InnerArrayJoin(separator, array, length);
+}
+
+
+function ObservedArrayPop(n) {
+  n--;
+  var value = this[n];
+
+  try {
+    ObserveBeginPerformSplice(this);
+    delete this[n];
+    this.length = n;
+  } finally {
+    ObserveEndPerformSplice(this);
+    ObserveEnqueueSpliceRecord(this, n, [value], 0);
+  }
+
+  return value;
+}
+
+
+// Removes the last element from the array and returns it. See
+// ECMA-262, section 15.4.4.6.
+function ArrayPop() {
+  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.pop");
+
+  var array = TO_OBJECT(this);
+  var n = TO_LENGTH_OR_UINT32(array.length);
+  if (n == 0) {
+    array.length = n;
+    return;
+  }
+
+  if (%IsObserved(array))
+    return ObservedArrayPop.call(array, n);
+
+  n--;
+  var value = array[n];
+  %DeleteProperty_Strict(array, n);
+  array.length = n;
+  return value;
+}
+
+
+function ObservedArrayPush() {
+  var n = TO_LENGTH_OR_UINT32(this.length);
+  var m = %_ArgumentsLength();
+
+  try {
+    ObserveBeginPerformSplice(this);
+    for (var i = 0; i < m; i++) {
+      this[i+n] = %_Arguments(i);
+    }
+    var new_length = n + m;
+    this.length = new_length;
+  } finally {
+    ObserveEndPerformSplice(this);
+    ObserveEnqueueSpliceRecord(this, n, [], m);
+  }
+
+  return new_length;
+}
+
+
+// Appends the arguments to the end of the array and returns the new
+// length of the array. See ECMA-262, section 15.4.4.7.
+function ArrayPush() {
+  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.push");
+
+  if (%IsObserved(this))
+    return ObservedArrayPush.apply(this, arguments);
+
+  var array = TO_OBJECT(this);
+  var n = TO_LENGTH_OR_UINT32(array.length);
+  var m = %_ArgumentsLength();
+
+  // It appears that there is no enforced, absolute limit on the number of
+  // arguments, but it would surely blow the stack to use 2**30 or more.
+  // To avoid integer overflow, do the comparison to the max safe integer
+  // after subtracting 2**30 from both sides. (2**31 would seem like a
+  // natural value, but it is negative in JS, and 2**32 is 1.)
+  if (m > (1 << 30) || (n - (1 << 30)) + m > kMaxSafeInteger - (1 << 30)) {
+    throw MakeTypeError(kPushPastSafeLength, m, n);
+  }
+
+  for (var i = 0; i < m; i++) {
+    array[i+n] = %_Arguments(i);
+  }
+
+  var new_length = n + m;
+  array.length = new_length;
+  return new_length;
+}
+
+
+// For implementing reverse() on large, sparse arrays.
+function SparseReverse(array, len) {
+  var keys = GetSortedArrayKeys(array, %GetArrayKeys(array, len));
+  var high_counter = keys.length - 1;
+  var low_counter = 0;
+  while (low_counter <= high_counter) {
+    var i = keys[low_counter];
+    var j = keys[high_counter];
+
+    var j_complement = len - j - 1;
+    var low, high;
+
+    if (j_complement <= i) {
+      high = j;
+      while (keys[--high_counter] == j) { }
+      low = j_complement;
+    }
+    if (j_complement >= i) {
+      low = i;
+      while (keys[++low_counter] == i) { }
+      high = len - i - 1;
+    }
+
+    var current_i = array[low];
+    if (!IS_UNDEFINED(current_i) || low in array) {
+      var current_j = array[high];
+      if (!IS_UNDEFINED(current_j) || high in array) {
+        array[low] = current_j;
+        array[high] = current_i;
+      } else {
+        array[high] = current_i;
+        delete array[low];
+      }
+    } else {
+      var current_j = array[high];
+      if (!IS_UNDEFINED(current_j) || high in array) {
+        array[low] = current_j;
+        delete array[high];
+      }
+    }
+  }
+}
+
+function PackedArrayReverse(array, len) {
+  var j = len - 1;
+  for (var i = 0; i < j; i++, j--) {
+    var current_i = array[i];
+    var current_j = array[j];
+    array[i] = current_j;
+    array[j] = current_i;
+  }
+  return array;
+}
+
+
+function GenericArrayReverse(array, len) {
+  var j = len - 1;
+  for (var i = 0; i < j; i++, j--) {
+    if (i in array) {
+      var current_i = array[i];
+      if (j in array) {
+        var current_j = array[j];
+        array[i] = current_j;
+        array[j] = current_i;
+      } else {
+        array[j] = current_i;
+        delete array[i];
+      }
+    } else {
+      if (j in array) {
+        var current_j = array[j];
+        array[i] = current_j;
+        delete array[j];
+      }
+    }
+  }
+  return array;
+}
+
+
+function ArrayReverse() {
+  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reverse");
+
+  var array = TO_OBJECT(this);
+  var len = TO_LENGTH_OR_UINT32(array.length);
+  var isArray = IS_ARRAY(array);
+
+  if (UseSparseVariant(array, len, isArray, len)) {
+    %NormalizeElements(array);
+    SparseReverse(array, len);
+    return array;
+  } else if (isArray && %_HasFastPackedElements(array)) {
+    return PackedArrayReverse(array, len);
+  } else {
+    return GenericArrayReverse(array, len);
+  }
+}
+
+
+function ObservedArrayShift(len) {
+  var first = this[0];
+
+  try {
+    ObserveBeginPerformSplice(this);
+    SimpleMove(this, 0, 1, len, 0);
+    this.length = len - 1;
+  } finally {
+    ObserveEndPerformSplice(this);
+    ObserveEnqueueSpliceRecord(this, 0, [first], 0);
+  }
+
+  return first;
+}
+
+
+function ArrayShift() {
+  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.shift");
+
+  var array = TO_OBJECT(this);
+  var len = TO_LENGTH_OR_UINT32(array.length);
+
+  if (len === 0) {
+    array.length = 0;
+    return;
+  }
+
+  if (%object_is_sealed(array)) throw MakeTypeError(kArrayFunctionsOnSealed);
+
+  if (%IsObserved(array))
+    return ObservedArrayShift.call(array, len);
+
+  var first = array[0];
+
+  if (UseSparseVariant(array, len, IS_ARRAY(array), len)) {
+    SparseMove(array, 0, 1, len, 0);
+  } else {
+    SimpleMove(array, 0, 1, len, 0);
+  }
+
+  array.length = len - 1;
+
+  return first;
+}
+
+
+function ObservedArrayUnshift() {
+  var len = TO_LENGTH_OR_UINT32(this.length);
+  var num_arguments = %_ArgumentsLength();
+
+  try {
+    ObserveBeginPerformSplice(this);
+    SimpleMove(this, 0, 0, len, num_arguments);
+    for (var i = 0; i < num_arguments; i++) {
+      this[i] = %_Arguments(i);
+    }
+    var new_length = len + num_arguments;
+    this.length = new_length;
+  } finally {
+    ObserveEndPerformSplice(this);
+    ObserveEnqueueSpliceRecord(this, 0, [], num_arguments);
+  }
+
+  return new_length;
+}
+
+
+function ArrayUnshift(arg1) {  // length == 1
+  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.unshift");
+
+  if (%IsObserved(this))
+    return ObservedArrayUnshift.apply(this, arguments);
+
+  var array = TO_OBJECT(this);
+  var len = TO_LENGTH_OR_UINT32(array.length);
+  var num_arguments = %_ArgumentsLength();
+
+  if (len > 0 && UseSparseVariant(array, len, IS_ARRAY(array), len) &&
+      !%object_is_sealed(array)) {
+    SparseMove(array, 0, 0, len, num_arguments);
+  } else {
+    SimpleMove(array, 0, 0, len, num_arguments);
+  }
+
+  for (var i = 0; i < num_arguments; i++) {
+    array[i] = %_Arguments(i);
+  }
+
+  var new_length = len + num_arguments;
+  array.length = new_length;
+  return new_length;
+}
+
+
+function ArraySlice(start, end) {
+  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.slice");
+
+  var array = TO_OBJECT(this);
+  var len = TO_LENGTH_OR_UINT32(array.length);
+  var start_i = TO_INTEGER(start);
+  var end_i = len;
+
+  if (!IS_UNDEFINED(end)) end_i = TO_INTEGER(end);
+
+  if (start_i < 0) {
+    start_i += len;
+    if (start_i < 0) start_i = 0;
+  } else {
+    if (start_i > len) start_i = len;
+  }
+
+  if (end_i < 0) {
+    end_i += len;
+    if (end_i < 0) end_i = 0;
+  } else {
+    if (end_i > len) end_i = len;
+  }
+
+  var result = ArraySpeciesCreate(array, MaxSimple(end_i - start_i, 0));
+
+  if (end_i < start_i) return result;
+
+  if (UseSparseVariant(array, len, IS_ARRAY(array), end_i - start_i)) {
+    %NormalizeElements(array);
+    %NormalizeElements(result);
+    SparseSlice(array, start_i, end_i - start_i, len, result);
+  } else {
+    SimpleSlice(array, start_i, end_i - start_i, len, result);
+  }
+
+  result.length = end_i - start_i;
+
+  return result;
+}
+
+
+function ComputeSpliceStartIndex(start_i, len) {
+  if (start_i < 0) {
+    start_i += len;
+    return start_i < 0 ? 0 : start_i;
+  }
+
+  return start_i > len ? len : start_i;
+}
+
+
+function ComputeSpliceDeleteCount(delete_count, num_arguments, len, start_i) {
+  // SpiderMonkey, TraceMonkey and JSC treat the case where no delete count is
+  // given as a request to delete all the elements from the start.
+  // And it differs from the case of undefined delete count.
+  // This does not follow ECMA-262, but we do the same for
+  // compatibility.
+  var del_count = 0;
+  if (num_arguments == 1)
+    return len - start_i;
+
+  del_count = TO_INTEGER(delete_count);
+  if (del_count < 0)
+    return 0;
+
+  if (del_count > len - start_i)
+    return len - start_i;
+
+  return del_count;
+}
+
+
+function ObservedArraySplice(start, delete_count) {
+  var num_arguments = %_ArgumentsLength();
+  var len = TO_LENGTH_OR_UINT32(this.length);
+  var start_i = ComputeSpliceStartIndex(TO_INTEGER(start), len);
+  var del_count = ComputeSpliceDeleteCount(delete_count, num_arguments, len,
+                                           start_i);
+  var deleted_elements = [];
+  deleted_elements.length = del_count;
+  var num_elements_to_add = num_arguments > 2 ? num_arguments - 2 : 0;
+
+  try {
+    ObserveBeginPerformSplice(this);
+
+    SimpleSlice(this, start_i, del_count, len, deleted_elements);
+    SimpleMove(this, start_i, del_count, len, num_elements_to_add);
+
+    // Insert the arguments into the resulting array in
+    // place of the deleted elements.
+    var i = start_i;
+    var arguments_index = 2;
+    var arguments_length = %_ArgumentsLength();
+    while (arguments_index < arguments_length) {
+      this[i++] = %_Arguments(arguments_index++);
+    }
+    this.length = len - del_count + num_elements_to_add;
+
+  } finally {
+    ObserveEndPerformSplice(this);
+    if (deleted_elements.length || num_elements_to_add) {
+      ObserveEnqueueSpliceRecord(this,
+                                 start_i,
+                                 deleted_elements.slice(),
+                                 num_elements_to_add);
+    }
+  }
+
+  // Return the deleted elements.
+  return deleted_elements;
+}
+
+
+function ArraySplice(start, delete_count) {
+  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.splice");
+
+  if (%IsObserved(this))
+    return ObservedArraySplice.apply(this, arguments);
+
+  var num_arguments = %_ArgumentsLength();
+  var array = TO_OBJECT(this);
+  var len = TO_LENGTH_OR_UINT32(array.length);
+  var start_i = ComputeSpliceStartIndex(TO_INTEGER(start), len);
+  var del_count = ComputeSpliceDeleteCount(delete_count, num_arguments, len,
+                                           start_i);
+  var deleted_elements = ArraySpeciesCreate(array, del_count);
+  deleted_elements.length = del_count;
+  var num_elements_to_add = num_arguments > 2 ? num_arguments - 2 : 0;
+
+  if (del_count != num_elements_to_add && %object_is_sealed(array)) {
+    throw MakeTypeError(kArrayFunctionsOnSealed);
+  } else if (del_count > 0 && %object_is_frozen(array)) {
+    throw MakeTypeError(kArrayFunctionsOnFrozen);
+  }
+
+  var changed_elements = del_count;
+  if (num_elements_to_add != del_count) {
+    // If the slice needs to do a actually move elements after the insertion
+    // point, then include those in the estimate of changed elements.
+    changed_elements += len - start_i - del_count;
+  }
+  if (UseSparseVariant(array, len, IS_ARRAY(array), changed_elements)) {
+    %NormalizeElements(array);
+    %NormalizeElements(deleted_elements);
+    SparseSlice(array, start_i, del_count, len, deleted_elements);
+    SparseMove(array, start_i, del_count, len, num_elements_to_add);
+  } else {
+    SimpleSlice(array, start_i, del_count, len, deleted_elements);
+    SimpleMove(array, start_i, del_count, len, num_elements_to_add);
+  }
+
+  // Insert the arguments into the resulting array in
+  // place of the deleted elements.
+  var i = start_i;
+  var arguments_index = 2;
+  var arguments_length = %_ArgumentsLength();
+  while (arguments_index < arguments_length) {
+    array[i++] = %_Arguments(arguments_index++);
+  }
+  array.length = len - del_count + num_elements_to_add;
+
+  // Return the deleted elements.
+  return deleted_elements;
+}
+
+
+function InnerArraySort(array, length, comparefn) {
+  // In-place QuickSort algorithm.
+  // For short (length <= 22) arrays, insertion sort is used for efficiency.
+
+  if (!IS_CALLABLE(comparefn)) {
+    comparefn = function (x, y) {
+      if (x === y) return 0;
+      if (%_IsSmi(x) && %_IsSmi(y)) {
+        return %SmiLexicographicCompare(x, y);
+      }
+      x = TO_STRING(x);
+      y = TO_STRING(y);
+      if (x == y) return 0;
+      else return x < y ? -1 : 1;
+    };
+  }
+  var InsertionSort = function InsertionSort(a, from, to) {
+    for (var i = from + 1; i < to; i++) {
+      var element = a[i];
+      for (var j = i - 1; j >= from; j--) {
+        var tmp = a[j];
+        var order = comparefn(tmp, element);
+        if (order > 0) {
+          a[j + 1] = tmp;
+        } else {
+          break;
+        }
+      }
+      a[j + 1] = element;
+    }
+  };
+
+  var GetThirdIndex = function(a, from, to) {
+    var t_array = new InternalArray();
+    // Use both 'from' and 'to' to determine the pivot candidates.
+    var increment = 200 + ((to - from) & 15);
+    var j = 0;
+    from += 1;
+    to -= 1;
+    for (var i = from; i < to; i += increment) {
+      t_array[j] = [i, a[i]];
+      j++;
+    }
+    t_array.sort(function(a, b) {
+      return comparefn(a[1], b[1]);
+    });
+    var third_index = t_array[t_array.length >> 1][0];
+    return third_index;
+  }
+
+  var QuickSort = function QuickSort(a, from, to) {
+    var third_index = 0;
+    while (true) {
+      // Insertion sort is faster for short arrays.
+      if (to - from <= 10) {
+        InsertionSort(a, from, to);
+        return;
+      }
+      if (to - from > 1000) {
+        third_index = GetThirdIndex(a, from, to);
+      } else {
+        third_index = from + ((to - from) >> 1);
+      }
+      // Find a pivot as the median of first, last and middle element.
+      var v0 = a[from];
+      var v1 = a[to - 1];
+      var v2 = a[third_index];
+      var c01 = comparefn(v0, v1);
+      if (c01 > 0) {
+        // v1 < v0, so swap them.
+        var tmp = v0;
+        v0 = v1;
+        v1 = tmp;
+      } // v0 <= v1.
+      var c02 = comparefn(v0, v2);
+      if (c02 >= 0) {
+        // v2 <= v0 <= v1.
+        var tmp = v0;
+        v0 = v2;
+        v2 = v1;
+        v1 = tmp;
+      } else {
+        // v0 <= v1 && v0 < v2
+        var c12 = comparefn(v1, v2);
+        if (c12 > 0) {
+          // v0 <= v2 < v1
+          var tmp = v1;
+          v1 = v2;
+          v2 = tmp;
+        }
+      }
+      // v0 <= v1 <= v2
+      a[from] = v0;
+      a[to - 1] = v2;
+      var pivot = v1;
+      var low_end = from + 1;   // Upper bound of elements lower than pivot.
+      var high_start = to - 1;  // Lower bound of elements greater than pivot.
+      a[third_index] = a[low_end];
+      a[low_end] = pivot;
+
+      // From low_end to i are elements equal to pivot.
+      // From i to high_start are elements that haven't been compared yet.
+      partition: for (var i = low_end + 1; i < high_start; i++) {
+        var element = a[i];
+        var order = comparefn(element, pivot);
+        if (order < 0) {
+          a[i] = a[low_end];
+          a[low_end] = element;
+          low_end++;
+        } else if (order > 0) {
+          do {
+            high_start--;
+            if (high_start == i) break partition;
+            var top_elem = a[high_start];
+            order = comparefn(top_elem, pivot);
+          } while (order > 0);
+          a[i] = a[high_start];
+          a[high_start] = element;
+          if (order < 0) {
+            element = a[i];
+            a[i] = a[low_end];
+            a[low_end] = element;
+            low_end++;
+          }
+        }
+      }
+      if (to - high_start < low_end - from) {
+        QuickSort(a, high_start, to);
+        to = low_end;
+      } else {
+        QuickSort(a, from, low_end);
+        from = high_start;
+      }
+    }
+  };
+
+  // Copy elements in the range 0..length from obj's prototype chain
+  // to obj itself, if obj has holes. Return one more than the maximal index
+  // of a prototype property.
+  var CopyFromPrototype = function CopyFromPrototype(obj, length) {
+    var max = 0;
+    for (var proto = %_GetPrototype(obj); proto; proto = %_GetPrototype(proto)) {
+      var indices = %GetArrayKeys(proto, length);
+      if (IS_NUMBER(indices)) {
+        // It's an interval.
+        var proto_length = indices;
+        for (var i = 0; i < proto_length; i++) {
+          if (!HAS_OWN_PROPERTY(obj, i) && HAS_OWN_PROPERTY(proto, i)) {
+            obj[i] = proto[i];
+            if (i >= max) { max = i + 1; }
+          }
+        }
+      } else {
+        for (var i = 0; i < indices.length; i++) {
+          var index = indices[i];
+          if (!IS_UNDEFINED(index) && !HAS_OWN_PROPERTY(obj, index)
+              && HAS_OWN_PROPERTY(proto, index)) {
+            obj[index] = proto[index];
+            if (index >= max) { max = index + 1; }
+          }
+        }
+      }
+    }
+    return max;
+  };
+
+  // Set a value of "undefined" on all indices in the range from..to
+  // where a prototype of obj has an element. I.e., shadow all prototype
+  // elements in that range.
+  var ShadowPrototypeElements = function(obj, from, to) {
+    for (var proto = %_GetPrototype(obj); proto; proto = %_GetPrototype(proto)) {
+      var indices = %GetArrayKeys(proto, to);
+      if (IS_NUMBER(indices)) {
+        // It's an interval.
+        var proto_length = indices;
+        for (var i = from; i < proto_length; i++) {
+          if (HAS_OWN_PROPERTY(proto, i)) {
+            obj[i] = UNDEFINED;
+          }
+        }
+      } else {
+        for (var i = 0; i < indices.length; i++) {
+          var index = indices[i];
+          if (!IS_UNDEFINED(index) && from <= index &&
+              HAS_OWN_PROPERTY(proto, index)) {
+            obj[index] = UNDEFINED;
+          }
+        }
+      }
+    }
+  };
+
+  var SafeRemoveArrayHoles = function SafeRemoveArrayHoles(obj) {
+    // Copy defined elements from the end to fill in all holes and undefineds
+    // in the beginning of the array.  Write undefineds and holes at the end
+    // after loop is finished.
+    var first_undefined = 0;
+    var last_defined = length - 1;
+    var num_holes = 0;
+    while (first_undefined < last_defined) {
+      // Find first undefined element.
+      while (first_undefined < last_defined &&
+             !IS_UNDEFINED(obj[first_undefined])) {
+        first_undefined++;
+      }
+      // Maintain the invariant num_holes = the number of holes in the original
+      // array with indices <= first_undefined or > last_defined.
+      if (!HAS_OWN_PROPERTY(obj, first_undefined)) {
+        num_holes++;
+      }
+
+      // Find last defined element.
+      while (first_undefined < last_defined &&
+             IS_UNDEFINED(obj[last_defined])) {
+        if (!HAS_OWN_PROPERTY(obj, last_defined)) {
+          num_holes++;
+        }
+        last_defined--;
+      }
+      if (first_undefined < last_defined) {
+        // Fill in hole or undefined.
+        obj[first_undefined] = obj[last_defined];
+        obj[last_defined] = UNDEFINED;
+      }
+    }
+    // If there were any undefineds in the entire array, first_undefined
+    // points to one past the last defined element.  Make this true if
+    // there were no undefineds, as well, so that first_undefined == number
+    // of defined elements.
+    if (!IS_UNDEFINED(obj[first_undefined])) first_undefined++;
+    // Fill in the undefineds and the holes.  There may be a hole where
+    // an undefined should be and vice versa.
+    var i;
+    for (i = first_undefined; i < length - num_holes; i++) {
+      obj[i] = UNDEFINED;
+    }
+    for (i = length - num_holes; i < length; i++) {
+      // For compatability with Webkit, do not expose elements in the prototype.
+      if (i in %_GetPrototype(obj)) {
+        obj[i] = UNDEFINED;
+      } else {
+        delete obj[i];
+      }
+    }
+
+    // Return the number of defined elements.
+    return first_undefined;
+  };
+
+  if (length < 2) return array;
+
+  var is_array = IS_ARRAY(array);
+  var max_prototype_element;
+  if (!is_array) {
+    // For compatibility with JSC, we also sort elements inherited from
+    // the prototype chain on non-Array objects.
+    // We do this by copying them to this object and sorting only
+    // own elements. This is not very efficient, but sorting with
+    // inherited elements happens very, very rarely, if at all.
+    // The specification allows "implementation dependent" behavior
+    // if an element on the prototype chain has an element that
+    // might interact with sorting.
+    max_prototype_element = CopyFromPrototype(array, length);
+  }
+
+  // %RemoveArrayHoles returns -1 if fast removal is not supported.
+  var num_non_undefined = %RemoveArrayHoles(array, length);
+
+  if (num_non_undefined == -1) {
+    // The array is observed, or there were indexed accessors in the array.
+    // Move array holes and undefineds to the end using a Javascript function
+    // that is safe in the presence of accessors and is observable.
+    num_non_undefined = SafeRemoveArrayHoles(array);
+  }
+
+  QuickSort(array, 0, num_non_undefined);
+
+  if (!is_array && (num_non_undefined + 1 < max_prototype_element)) {
+    // For compatibility with JSC, we shadow any elements in the prototype
+    // chain that has become exposed by sort moving a hole to its position.
+    ShadowPrototypeElements(array, num_non_undefined, max_prototype_element);
+  }
+
+  return array;
+}
+
+
+function ArraySort(comparefn) {
+  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.sort");
+
+  var array = TO_OBJECT(this);
+  var length = TO_LENGTH_OR_UINT32(array.length);
+  return InnerArraySort(array, length, comparefn);
+}
+
+
+// The following functions cannot be made efficient on sparse arrays while
+// preserving the semantics, since the calls to the receiver function can add
+// or delete elements from the array.
+function InnerArrayFilter(f, receiver, array, length, result) {
+  var result_length = 0;
+  var is_array = IS_ARRAY(array);
+  for (var i = 0; i < length; i++) {
+    if (HAS_INDEX(array, i, is_array)) {
+      var element = array[i];
+      if (%_Call(f, receiver, element, i, array)) {
+        DefineIndexedProperty(result, result_length, element);
+        result_length++;
+      }
+    }
+  }
+  return result;
+}
+
+
+
+function ArrayFilter(f, receiver) {
+  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.filter");
+
+  // Pull out the length so that modifications to the length in the
+  // loop will not affect the looping and side effects are visible.
+  var array = TO_OBJECT(this);
+  var length = TO_LENGTH_OR_UINT32(array.length);
+  if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f);
+  var result = ArraySpeciesCreate(array, 0);
+  return InnerArrayFilter(f, receiver, array, length, result);
+}
+
+
+function InnerArrayForEach(f, receiver, array, length) {
+  if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f);
+
+  var is_array = IS_ARRAY(array);
+  for (var i = 0; i < length; i++) {
+    if (HAS_INDEX(array, i, is_array)) {
+      var element = array[i];
+      %_Call(f, receiver, element, i, array);
+    }
+  }
+}
+
+
+function ArrayForEach(f, receiver) {
+  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.forEach");
+
+  // Pull out the length so that modifications to the length in the
+  // loop will not affect the looping and side effects are visible.
+  var array = TO_OBJECT(this);
+  var length = TO_LENGTH_OR_UINT32(array.length);
+  InnerArrayForEach(f, receiver, array, length);
+}
+
+
+function InnerArraySome(f, receiver, array, length) {
+  if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f);
+
+  var is_array = IS_ARRAY(array);
+  for (var i = 0; i < length; i++) {
+    if (HAS_INDEX(array, i, is_array)) {
+      var element = array[i];
+      if (%_Call(f, receiver, element, i, array)) return true;
+    }
+  }
+  return false;
+}
+
+
+// Executes the function once for each element present in the
+// array until it finds one where callback returns true.
+function ArraySome(f, receiver) {
+  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.some");
+
+  // Pull out the length so that modifications to the length in the
+  // loop will not affect the looping and side effects are visible.
+  var array = TO_OBJECT(this);
+  var length = TO_LENGTH_OR_UINT32(array.length);
+  return InnerArraySome(f, receiver, array, length);
+}
+
+
+function InnerArrayEvery(f, receiver, array, length) {
+  if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f);
+
+  var is_array = IS_ARRAY(array);
+  for (var i = 0; i < length; i++) {
+    if (HAS_INDEX(array, i, is_array)) {
+      var element = array[i];
+      if (!%_Call(f, receiver, element, i, array)) return false;
+    }
+  }
+  return true;
+}
+
+function ArrayEvery(f, receiver) {
+  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.every");
+
+  // Pull out the length so that modifications to the length in the
+  // loop will not affect the looping and side effects are visible.
+  var array = TO_OBJECT(this);
+  var length = TO_LENGTH_OR_UINT32(array.length);
+  return InnerArrayEvery(f, receiver, array, length);
+}
+
+
+function ArrayMap(f, receiver) {
+  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.map");
+
+  // Pull out the length so that modifications to the length in the
+  // loop will not affect the looping and side effects are visible.
+  var array = TO_OBJECT(this);
+  var length = TO_LENGTH_OR_UINT32(array.length);
+  if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f);
+  var result = ArraySpeciesCreate(array, length);
+  var is_array = IS_ARRAY(array);
+  for (var i = 0; i < length; i++) {
+    if (HAS_INDEX(array, i, is_array)) {
+      var element = array[i];
+      DefineIndexedProperty(result, i, %_Call(f, receiver, element, i, array));
+    }
+  }
+  return result;
+}
+
+
+// For .indexOf, we don't need to pass in the number of arguments
+// at the callsite since ToInteger(undefined) == 0; however, for
+// .lastIndexOf, we need to pass it, since the behavior for passing
+// undefined is 0 but for not including the argument is length-1.
+function InnerArrayIndexOf(array, element, index, length) {
+  if (length == 0) return -1;
+  if (IS_UNDEFINED(index)) {
+    index = 0;
+  } else {
+    index = TO_INTEGER(index);
+    // If index is negative, index from the end of the array.
+    if (index < 0) {
+      index = length + index;
+      // If index is still negative, search the entire array.
+      if (index < 0) index = 0;
+    }
+  }
+  var min = index;
+  var max = length;
+  if (UseSparseVariant(array, length, IS_ARRAY(array), max - min)) {
+    %NormalizeElements(array);
+    var indices = %GetArrayKeys(array, length);
+    if (IS_NUMBER(indices)) {
+      // It's an interval.
+      max = indices;  // Capped by length already.
+      // Fall through to loop below.
+    } else {
+      if (indices.length == 0) return -1;
+      // Get all the keys in sorted order.
+      var sortedKeys = GetSortedArrayKeys(array, indices);
+      var n = sortedKeys.length;
+      var i = 0;
+      while (i < n && sortedKeys[i] < index) i++;
+      while (i < n) {
+        var key = sortedKeys[i];
+        if (!IS_UNDEFINED(key) && array[key] === element) return key;
+        i++;
+      }
+      return -1;
+    }
+  }
+  // Lookup through the array.
+  if (!IS_UNDEFINED(element)) {
+    for (var i = min; i < max; i++) {
+      if (array[i] === element) return i;
+    }
+    return -1;
+  }
+  // Lookup through the array.
+  for (var i = min; i < max; i++) {
+    if (IS_UNDEFINED(array[i]) && i in array) {
+      return i;
+    }
+  }
+  return -1;
+}
+
+
+function ArrayIndexOf(element, index) {
+  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.indexOf");
+
+  var length = TO_LENGTH_OR_UINT32(this.length);
+  return InnerArrayIndexOf(this, element, index, length);
+}
+
+
+function InnerArrayLastIndexOf(array, element, index, length, argumentsLength) {
+  if (length == 0) return -1;
+  if (argumentsLength < 2) {
+    index = length - 1;
+  } else {
+    index = TO_INTEGER(index);
+    // If index is negative, index from end of the array.
+    if (index < 0) index += length;
+    // If index is still negative, do not search the array.
+    if (index < 0) return -1;
+    else if (index >= length) index = length - 1;
+  }
+  var min = 0;
+  var max = index;
+  if (UseSparseVariant(array, length, IS_ARRAY(array), index)) {
+    %NormalizeElements(array);
+    var indices = %GetArrayKeys(array, index + 1);
+    if (IS_NUMBER(indices)) {
+      // It's an interval.
+      max = indices;  // Capped by index already.
+      // Fall through to loop below.
+    } else {
+      if (indices.length == 0) return -1;
+      // Get all the keys in sorted order.
+      var sortedKeys = GetSortedArrayKeys(array, indices);
+      var i = sortedKeys.length - 1;
+      while (i >= 0) {
+        var key = sortedKeys[i];
+        if (!IS_UNDEFINED(key) && array[key] === element) return key;
+        i--;
+      }
+      return -1;
+    }
+  }
+  // Lookup through the array.
+  if (!IS_UNDEFINED(element)) {
+    for (var i = max; i >= min; i--) {
+      if (array[i] === element) return i;
+    }
+    return -1;
+  }
+  for (var i = max; i >= min; i--) {
+    if (IS_UNDEFINED(array[i]) && i in array) {
+      return i;
+    }
+  }
+  return -1;
+}
+
+
+function ArrayLastIndexOf(element, index) {
+  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.lastIndexOf");
+
+  var length = TO_LENGTH_OR_UINT32(this.length);
+  return InnerArrayLastIndexOf(this, element, index, length,
+                        %_ArgumentsLength());
+}
+
+
+function InnerArrayReduce(callback, current, array, length, argumentsLength) {
+  if (!IS_CALLABLE(callback)) {
+    throw MakeTypeError(kCalledNonCallable, callback);
+  }
+
+  var is_array = IS_ARRAY(array);
+  var i = 0;
+  find_initial: if (argumentsLength < 2) {
+    for (; i < length; i++) {
+      if (HAS_INDEX(array, i, is_array)) {
+        current = array[i++];
+        break find_initial;
+      }
+    }
+    throw MakeTypeError(kReduceNoInitial);
+  }
+
+  for (; i < length; i++) {
+    if (HAS_INDEX(array, i, is_array)) {
+      var element = array[i];
+      current = callback(current, element, i, array);
+    }
+  }
+  return current;
+}
+
+
+function ArrayReduce(callback, current) {
+  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reduce");
+
+  // Pull out the length so that modifications to the length in the
+  // loop will not affect the looping and side effects are visible.
+  var array = TO_OBJECT(this);
+  var length = TO_LENGTH_OR_UINT32(array.length);
+  return InnerArrayReduce(callback, current, array, length,
+                          %_ArgumentsLength());
+}
+
+
+function InnerArrayReduceRight(callback, current, array, length,
+                               argumentsLength) {
+  if (!IS_CALLABLE(callback)) {
+    throw MakeTypeError(kCalledNonCallable, callback);
+  }
+
+  var is_array = IS_ARRAY(array);
+  var i = length - 1;
+  find_initial: if (argumentsLength < 2) {
+    for (; i >= 0; i--) {
+      if (HAS_INDEX(array, i, is_array)) {
+        current = array[i--];
+        break find_initial;
+      }
+    }
+    throw MakeTypeError(kReduceNoInitial);
+  }
+
+  for (; i >= 0; i--) {
+    if (HAS_INDEX(array, i, is_array)) {
+      var element = array[i];
+      current = callback(current, element, i, array);
+    }
+  }
+  return current;
+}
+
+
+function ArrayReduceRight(callback, current) {
+  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reduceRight");
+
+  // Pull out the length so that side effects are visible before the
+  // callback function is checked.
+  var array = TO_OBJECT(this);
+  var length = TO_LENGTH_OR_UINT32(array.length);
+  return InnerArrayReduceRight(callback, current, array, length,
+                               %_ArgumentsLength());
+}
+
+
+function InnerArrayCopyWithin(target, start, end, array, length) {
+  target = TO_INTEGER(target);
+  var to;
+  if (target < 0) {
+    to = MaxSimple(length + target, 0);
+  } else {
+    to = MinSimple(target, length);
+  }
+
+  start = TO_INTEGER(start);
+  var from;
+  if (start < 0) {
+    from = MaxSimple(length + start, 0);
+  } else {
+    from = MinSimple(start, length);
+  }
+
+  end = IS_UNDEFINED(end) ? length : TO_INTEGER(end);
+  var final;
+  if (end < 0) {
+    final = MaxSimple(length + end, 0);
+  } else {
+    final = MinSimple(end, length);
+  }
+
+  var count = MinSimple(final - from, length - to);
+  var direction = 1;
+  if (from < to && to < (from + count)) {
+    direction = -1;
+    from = from + count - 1;
+    to = to + count - 1;
+  }
+
+  while (count > 0) {
+    if (from in array) {
+      array[to] = array[from];
+    } else {
+      delete array[to];
+    }
+    from = from + direction;
+    to = to + direction;
+    count--;
+  }
+
+  return array;
+}
+
+
+// ES6 draft 03-17-15, section 22.1.3.3
+function ArrayCopyWithin(target, start, end) {
+  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.copyWithin");
+
+  var array = TO_OBJECT(this);
+  var length = TO_LENGTH(array.length);
+
+  return InnerArrayCopyWithin(target, start, end, array, length);
+}
+
+
+function InnerArrayFind(predicate, thisArg, array, length) {
+  if (!IS_CALLABLE(predicate)) {
+    throw MakeTypeError(kCalledNonCallable, predicate);
+  }
+
+  for (var i = 0; i < length; i++) {
+    var element = array[i];
+    if (%_Call(predicate, thisArg, element, i, array)) {
+      return element;
+    }
+  }
+
+  return;
+}
+
+
+// ES6 draft 07-15-13, section 15.4.3.23
+function ArrayFind(predicate, thisArg) {
+  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.find");
+
+  var array = TO_OBJECT(this);
+  var length = TO_INTEGER(array.length);
+
+  return InnerArrayFind(predicate, thisArg, array, length);
+}
+
+
+function InnerArrayFindIndex(predicate, thisArg, array, length) {
+  if (!IS_CALLABLE(predicate)) {
+    throw MakeTypeError(kCalledNonCallable, predicate);
+  }
+
+  for (var i = 0; i < length; i++) {
+    var element = array[i];
+    if (%_Call(predicate, thisArg, element, i, array)) {
+      return i;
+    }
+  }
+
+  return -1;
+}
+
+
+// ES6 draft 07-15-13, section 15.4.3.24
+function ArrayFindIndex(predicate, thisArg) {
+  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.findIndex");
+
+  var array = TO_OBJECT(this);
+  var length = TO_INTEGER(array.length);
+
+  return InnerArrayFindIndex(predicate, thisArg, array, length);
+}
+
+
+// ES6, draft 04-05-14, section 22.1.3.6
+function InnerArrayFill(value, start, end, array, length) {
+  var i = IS_UNDEFINED(start) ? 0 : TO_INTEGER(start);
+  var end = IS_UNDEFINED(end) ? length : TO_INTEGER(end);
+
+  if (i < 0) {
+    i += length;
+    if (i < 0) i = 0;
+  } else {
+    if (i > length) i = length;
+  }
+
+  if (end < 0) {
+    end += length;
+    if (end < 0) end = 0;
+  } else {
+    if (end > length) end = length;
+  }
+
+  if ((end - i) > 0 && %object_is_frozen(array)) {
+    throw MakeTypeError(kArrayFunctionsOnFrozen);
+  }
+
+  for (; i < end; i++)
+    array[i] = value;
+  return array;
+}
+
+
+// ES6, draft 04-05-14, section 22.1.3.6
+function ArrayFill(value, start, end) {
+  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.fill");
+
+  var array = TO_OBJECT(this);
+  var length = TO_LENGTH_OR_UINT32(array.length);
+
+  return InnerArrayFill(value, start, end, array, length);
+}
+
+
+function InnerArrayIncludes(searchElement, fromIndex, array, length) {
+  if (length === 0) {
+    return false;
+  }
+
+  var n = TO_INTEGER(fromIndex);
+
+  var k;
+  if (n >= 0) {
+    k = n;
+  } else {
+    k = length + n;
+    if (k < 0) {
+      k = 0;
+    }
+  }
+
+  while (k < length) {
+    var elementK = array[k];
+    if (SameValueZero(searchElement, elementK)) {
+      return true;
+    }
+
+    ++k;
+  }
+
+  return false;
+}
+
+
+// ES2016 draft, section 22.1.3.11
+function ArrayIncludes(searchElement, fromIndex) {
+  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.includes");
+
+  var array = TO_OBJECT(this);
+  var length = TO_LENGTH(array.length);
+
+  return InnerArrayIncludes(searchElement, fromIndex, array, length);
+}
+
+
+function AddArrayElement(constructor, array, i, value) {
+  if (constructor === GlobalArray) {
+    AddIndexedProperty(array, i, value);
+  } else {
+    ObjectDefineProperty(array, i, {
+      value: value, writable: true, configurable: true, enumerable: true
+    });
+  }
+}
+
+
+// ES6, draft 10-14-14, section 22.1.2.1
+function ArrayFrom(arrayLike, mapfn, receiver) {
+  var items = TO_OBJECT(arrayLike);
+  var mapping = !IS_UNDEFINED(mapfn);
+
+  if (mapping) {
+    if (!IS_CALLABLE(mapfn)) {
+      throw MakeTypeError(kCalledNonCallable, mapfn);
+    }
+  }
+
+  var iterable = GetMethod(items, iteratorSymbol);
+  var k;
+  var result;
+  var mappedValue;
+  var nextValue;
+
+  if (!IS_UNDEFINED(iterable)) {
+    result = %IsConstructor(this) ? new this() : [];
+
+    var iterator = GetIterator(items, iterable);
+
+    k = 0;
+    while (true) {
+      var next = iterator.next();
+
+      if (!IS_RECEIVER(next)) {
+        throw MakeTypeError(kIteratorResultNotAnObject, next);
+      }
+
+      if (next.done) {
+        result.length = k;
+        return result;
+      }
+
+      nextValue = next.value;
+      if (mapping) {
+        mappedValue = %_Call(mapfn, receiver, nextValue, k);
+      } else {
+        mappedValue = nextValue;
+      }
+      AddArrayElement(this, result, k, mappedValue);
+      k++;
+    }
+  } else {
+    var len = TO_LENGTH(items.length);
+    result = %IsConstructor(this) ? new this(len) : new GlobalArray(len);
+
+    for (k = 0; k < len; ++k) {
+      nextValue = items[k];
+      if (mapping) {
+        mappedValue = %_Call(mapfn, receiver, nextValue, k);
+      } else {
+        mappedValue = nextValue;
+      }
+      AddArrayElement(this, result, k, mappedValue);
+    }
+
+    result.length = k;
+    return result;
+  }
+}
+
+
+// ES6, draft 05-22-14, section 22.1.2.3
+function ArrayOf() {
+  var length = %_ArgumentsLength();
+  var constructor = this;
+  // TODO: Implement IsConstructor (ES6 section 7.2.5)
+  var array = %IsConstructor(constructor) ? new constructor(length) : [];
+  for (var i = 0; i < length; i++) {
+    AddArrayElement(constructor, array, i, %_Arguments(i));
+  }
+  array.length = length;
+  return array;
+}
+
+// -------------------------------------------------------------------
+
+// Set up non-enumerable constructor property on the Array.prototype
+// object.
+%AddNamedProperty(GlobalArray.prototype, "constructor", GlobalArray,
+                  DONT_ENUM);
+
+// Set up unscopable properties on the Array.prototype object.
+var unscopables = {
+  __proto__: null,
+  copyWithin: true,
+  entries: true,
+  fill: true,
+  find: true,
+  findIndex: true,
+  keys: true,
+};
+
+%AddNamedProperty(GlobalArray.prototype, unscopablesSymbol, unscopables,
+                  DONT_ENUM | READ_ONLY);
+
+%FunctionSetLength(ArrayFrom, 1);
+
+// Set up non-enumerable functions on the Array object.
+utils.InstallFunctions(GlobalArray, DONT_ENUM, [
+  "from", ArrayFrom,
+  "of", ArrayOf
+]);
+
+var specialFunctions = %SpecialArrayFunctions();
+
+var getFunction = function(name, jsBuiltin, len) {
+  var f = jsBuiltin;
+  if (specialFunctions.hasOwnProperty(name)) {
+    f = specialFunctions[name];
+  }
+  if (!IS_UNDEFINED(len)) {
+    %FunctionSetLength(f, len);
+  }
+  return f;
+};
+
+// Set up non-enumerable functions of the Array.prototype object and
+// set their names.
+// Manipulate the length of some of the functions to meet
+// expectations set by ECMA-262 or Mozilla.
+utils.InstallFunctions(GlobalArray.prototype, DONT_ENUM, [
+  "toString", getFunction("toString", ArrayToString),
+  "toLocaleString", getFunction("toLocaleString", ArrayToLocaleString),
+  "join", getFunction("join", ArrayJoin),
+  "pop", getFunction("pop", ArrayPop),
+  "push", getFunction("push", ArrayPush, 1),
+  "reverse", getFunction("reverse", ArrayReverse),
+  "shift", getFunction("shift", ArrayShift),
+  "unshift", getFunction("unshift", ArrayUnshift, 1),
+  "slice", getFunction("slice", ArraySlice, 2),
+  "splice", getFunction("splice", ArraySplice, 2),
+  "sort", getFunction("sort", ArraySort),
+  "filter", getFunction("filter", ArrayFilter, 1),
+  "forEach", getFunction("forEach", ArrayForEach, 1),
+  "some", getFunction("some", ArraySome, 1),
+  "every", getFunction("every", ArrayEvery, 1),
+  "map", getFunction("map", ArrayMap, 1),
+  "indexOf", getFunction("indexOf", ArrayIndexOf, 1),
+  "lastIndexOf", getFunction("lastIndexOf", ArrayLastIndexOf, 1),
+  "reduce", getFunction("reduce", ArrayReduce, 1),
+  "reduceRight", getFunction("reduceRight", ArrayReduceRight, 1),
+  "copyWithin", getFunction("copyWithin", ArrayCopyWithin, 2),
+  "find", getFunction("find", ArrayFind, 1),
+  "findIndex", getFunction("findIndex", ArrayFindIndex, 1),
+  "fill", getFunction("fill", ArrayFill, 1),
+  "includes", getFunction("includes", ArrayIncludes, 1),
+]);
+
+%FinishArrayPrototypeSetup(GlobalArray.prototype);
+
+// The internal Array prototype doesn't need to be fancy, since it's never
+// exposed to user code.
+// Adding only the functions that are actually used.
+utils.SetUpLockedPrototype(InternalArray, GlobalArray(), [
+  "indexOf", getFunction("indexOf", ArrayIndexOf),
+  "join", getFunction("join", ArrayJoin),
+  "pop", getFunction("pop", ArrayPop),
+  "push", getFunction("push", ArrayPush),
+  "shift", getFunction("shift", ArrayShift),
+  "sort", getFunction("sort", ArraySort),
+  "splice", getFunction("splice", ArraySplice)
+]);
+
+utils.SetUpLockedPrototype(InternalPackedArray, GlobalArray(), [
+  "join", getFunction("join", ArrayJoin),
+  "pop", getFunction("pop", ArrayPop),
+  "push", getFunction("push", ArrayPush),
+  "shift", getFunction("shift", ArrayShift)
+]);
+
+// V8 extras get a separate copy of InternalPackedArray. We give them the basic
+// manipulation methods.
+utils.SetUpLockedPrototype(extrasUtils.InternalPackedArray, GlobalArray(), [
+  "push", getFunction("push", ArrayPush),
+  "pop", getFunction("pop", ArrayPop),
+  "shift", getFunction("shift", ArrayShift),
+  "unshift", getFunction("unshift", ArrayUnshift),
+  "splice", getFunction("splice", ArraySplice),
+  "slice", getFunction("slice", ArraySlice)
+]);
+
+// -------------------------------------------------------------------
+// Exports
+
+utils.Export(function(to) {
+  to.ArrayFrom = ArrayFrom;
+  to.ArrayIndexOf = ArrayIndexOf;
+  to.ArrayJoin = ArrayJoin;
+  to.ArrayPush = ArrayPush;
+  to.ArrayToString = ArrayToString;
+  to.InnerArrayCopyWithin = InnerArrayCopyWithin;
+  to.InnerArrayEvery = InnerArrayEvery;
+  to.InnerArrayFill = InnerArrayFill;
+  to.InnerArrayFilter = InnerArrayFilter;
+  to.InnerArrayFind = InnerArrayFind;
+  to.InnerArrayFindIndex = InnerArrayFindIndex;
+  to.InnerArrayForEach = InnerArrayForEach;
+  to.InnerArrayIncludes = InnerArrayIncludes;
+  to.InnerArrayIndexOf = InnerArrayIndexOf;
+  to.InnerArrayJoin = InnerArrayJoin;
+  to.InnerArrayLastIndexOf = InnerArrayLastIndexOf;
+  to.InnerArrayReduce = InnerArrayReduce;
+  to.InnerArrayReduceRight = InnerArrayReduceRight;
+  to.InnerArraySome = InnerArraySome;
+  to.InnerArraySort = InnerArraySort;
+  to.InnerArrayToLocaleString = InnerArrayToLocaleString;
+  to.PackedArrayReverse = PackedArrayReverse;
+});
+
+%InstallToContext([
+  "array_pop", ArrayPop,
+  "array_push", ArrayPush,
+  "array_shift", ArrayShift,
+  "array_splice", ArraySplice,
+  "array_slice", ArraySlice,
+  "array_unshift", ArrayUnshift,
+]);
+
+});
diff --git a/src/js/arraybuffer.js b/src/js/arraybuffer.js
new file mode 100644
index 0000000..f0273c7
--- /dev/null
+++ b/src/js/arraybuffer.js
@@ -0,0 +1,92 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function(global, utils) {
+
+"use strict";
+
+%CheckIsBootstrapping();
+
+// -------------------------------------------------------------------
+// Imports
+
+var GlobalArrayBuffer = global.ArrayBuffer;
+var MakeTypeError;
+var MaxSimple;
+var MinSimple;
+var SpeciesConstructor;
+
+utils.Import(function(from) {
+  MakeTypeError = from.MakeTypeError;
+  MaxSimple = from.MaxSimple;
+  MinSimple = from.MinSimple;
+  SpeciesConstructor = from.SpeciesConstructor;
+});
+
+// -------------------------------------------------------------------
+
+function ArrayBufferGetByteLen() {
+  if (!IS_ARRAYBUFFER(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        'ArrayBuffer.prototype.byteLength', this);
+  }
+  return %_ArrayBufferGetByteLength(this);
+}
+
+// ES6 Draft 15.13.5.5.3
+function ArrayBufferSlice(start, end) {
+  if (!IS_ARRAYBUFFER(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        'ArrayBuffer.prototype.slice', this);
+  }
+
+  var relativeStart = TO_INTEGER(start);
+  if (!IS_UNDEFINED(end)) {
+    end = TO_INTEGER(end);
+  }
+  var first;
+  var byte_length = %_ArrayBufferGetByteLength(this);
+  if (relativeStart < 0) {
+    first = MaxSimple(byte_length + relativeStart, 0);
+  } else {
+    first = MinSimple(relativeStart, byte_length);
+  }
+  var relativeEnd = IS_UNDEFINED(end) ? byte_length : end;
+  var fin;
+  if (relativeEnd < 0) {
+    fin = MaxSimple(byte_length + relativeEnd, 0);
+  } else {
+    fin = MinSimple(relativeEnd, byte_length);
+  }
+
+  if (fin < first) {
+    fin = first;
+  }
+  var newLen = fin - first;
+  var constructor = SpeciesConstructor(this, GlobalArrayBuffer, true);
+  var result = new constructor(newLen);
+  if (!IS_ARRAYBUFFER(result)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        'ArrayBuffer.prototype.slice', result);
+  }
+  // TODO(littledan): Check for a detached ArrayBuffer
+  if (result === this) {
+    throw MakeTypeError(kArrayBufferSpeciesThis);
+  }
+  if (%_ArrayBufferGetByteLength(result) < newLen) {
+    throw MakeTypeError(kArrayBufferTooShort);
+  }
+
+  %ArrayBufferSliceImpl(this, result, first, newLen);
+  return result;
+}
+
+utils.InstallGetter(GlobalArrayBuffer.prototype, "byteLength",
+                    ArrayBufferGetByteLen);
+
+utils.InstallFunctions(GlobalArrayBuffer.prototype, DONT_ENUM, [
+  "slice", ArrayBufferSlice
+]);
+
+})
diff --git a/src/js/collection-iterator.js b/src/js/collection-iterator.js
new file mode 100644
index 0000000..621d726
--- /dev/null
+++ b/src/js/collection-iterator.js
@@ -0,0 +1,183 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function(global, utils) {
+
+"use strict";
+
+%CheckIsBootstrapping();
+
+// -------------------------------------------------------------------
+// Imports
+
+var GlobalMap = global.Map;
+var GlobalSet = global.Set;
+var iteratorSymbol = utils.ImportNow("iterator_symbol");
+var MakeTypeError;
+var MapIterator = utils.ImportNow("MapIterator");
+var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
+var SetIterator = utils.ImportNow("SetIterator");
+
+utils.Import(function(from) {
+  MakeTypeError = from.MakeTypeError;
+});
+
+// -------------------------------------------------------------------
+
+function SetIteratorConstructor(set, kind) {
+  %SetIteratorInitialize(this, set, kind);
+}
+
+
+function SetIteratorNextJS() {
+  if (!IS_SET_ITERATOR(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        'Set Iterator.prototype.next', this);
+  }
+
+  var value_array = [UNDEFINED, UNDEFINED];
+  var result = %_CreateIterResultObject(value_array, false);
+  switch (%SetIteratorNext(this, value_array)) {
+    case 0:
+      result.value = UNDEFINED;
+      result.done = true;
+      break;
+    case ITERATOR_KIND_VALUES:
+      result.value = value_array[0];
+      break;
+    case ITERATOR_KIND_ENTRIES:
+      value_array[1] = value_array[0];
+      break;
+  }
+
+  return result;
+}
+
+
+function SetEntries() {
+  if (!IS_SET(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        'Set.prototype.entries', this);
+  }
+  return new SetIterator(this, ITERATOR_KIND_ENTRIES);
+}
+
+
+function SetValues() {
+  if (!IS_SET(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        'Set.prototype.values', this);
+  }
+  return new SetIterator(this, ITERATOR_KIND_VALUES);
+}
+
+// -------------------------------------------------------------------
+
+%SetCode(SetIterator, SetIteratorConstructor);
+%FunctionSetInstanceClassName(SetIterator, 'Set Iterator');
+utils.InstallFunctions(SetIterator.prototype, DONT_ENUM, [
+  'next', SetIteratorNextJS
+]);
+
+%AddNamedProperty(SetIterator.prototype, toStringTagSymbol,
+    "Set Iterator", READ_ONLY | DONT_ENUM);
+
+utils.InstallFunctions(GlobalSet.prototype, DONT_ENUM, [
+  'entries', SetEntries,
+  'keys', SetValues,
+  'values', SetValues
+]);
+
+%AddNamedProperty(GlobalSet.prototype, iteratorSymbol, SetValues, DONT_ENUM);
+
+// -------------------------------------------------------------------
+
+function MapIteratorConstructor(map, kind) {
+  %MapIteratorInitialize(this, map, kind);
+}
+
+
+function MapIteratorNextJS() {
+  if (!IS_MAP_ITERATOR(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        'Map Iterator.prototype.next', this);
+  }
+
+  var value_array = [UNDEFINED, UNDEFINED];
+  var result = %_CreateIterResultObject(value_array, false);
+  switch (%MapIteratorNext(this, value_array)) {
+    case 0:
+      result.value = UNDEFINED;
+      result.done = true;
+      break;
+    case ITERATOR_KIND_KEYS:
+      result.value = value_array[0];
+      break;
+    case ITERATOR_KIND_VALUES:
+      result.value = value_array[1];
+      break;
+    // ITERATOR_KIND_ENTRIES does not need any processing.
+  }
+
+  return result;
+}
+
+
+function MapEntries() {
+  if (!IS_MAP(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        'Map.prototype.entries', this);
+  }
+  return new MapIterator(this, ITERATOR_KIND_ENTRIES);
+}
+
+
+function MapKeys() {
+  if (!IS_MAP(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        'Map.prototype.keys', this);
+  }
+  return new MapIterator(this, ITERATOR_KIND_KEYS);
+}
+
+
+function MapValues() {
+  if (!IS_MAP(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        'Map.prototype.values', this);
+  }
+  return new MapIterator(this, ITERATOR_KIND_VALUES);
+}
+
+// -------------------------------------------------------------------
+
+%SetCode(MapIterator, MapIteratorConstructor);
+%FunctionSetInstanceClassName(MapIterator, 'Map Iterator');
+utils.InstallFunctions(MapIterator.prototype, DONT_ENUM, [
+  'next', MapIteratorNextJS
+]);
+
+%AddNamedProperty(MapIterator.prototype, toStringTagSymbol,
+    "Map Iterator", READ_ONLY | DONT_ENUM);
+
+
+utils.InstallFunctions(GlobalMap.prototype, DONT_ENUM, [
+  'entries', MapEntries,
+  'keys', MapKeys,
+  'values', MapValues
+]);
+
+%AddNamedProperty(GlobalMap.prototype, iteratorSymbol, MapEntries, DONT_ENUM);
+
+// -------------------------------------------------------------------
+// Exports
+
+utils.Export(function(to) {
+  to.MapEntries = MapEntries;
+  to.MapIteratorNext = MapIteratorNextJS;
+  to.SetIteratorNext = SetIteratorNextJS;
+  to.SetValues = SetValues;
+});
+
+})
diff --git a/src/js/collection.js b/src/js/collection.js
new file mode 100644
index 0000000..0d7195d
--- /dev/null
+++ b/src/js/collection.js
@@ -0,0 +1,478 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function(global, utils) {
+"use strict";
+
+%CheckIsBootstrapping();
+
+// -------------------------------------------------------------------
+// Imports
+
+var GlobalMap = global.Map;
+var GlobalObject = global.Object;
+var GlobalSet = global.Set;
+var hashCodeSymbol = utils.ImportNow("hash_code_symbol");
+var IntRandom;
+var MakeTypeError;
+var MapIterator;
+var NumberIsNaN;
+var SetIterator;
+var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
+
+utils.Import(function(from) {
+  IntRandom = from.IntRandom;
+  MakeTypeError = from.MakeTypeError;
+  MapIterator = from.MapIterator;
+  NumberIsNaN = from.NumberIsNaN;
+  SetIterator = from.SetIterator;
+});
+
+// -------------------------------------------------------------------
+
+function HashToEntry(table, hash, numBuckets) {
+  var bucket = ORDERED_HASH_TABLE_HASH_TO_BUCKET(hash, numBuckets);
+  return ORDERED_HASH_TABLE_BUCKET_AT(table, bucket);
+}
+%SetForceInlineFlag(HashToEntry);
+
+
+function SetFindEntry(table, numBuckets, key, hash) {
+  var entry = HashToEntry(table, hash, numBuckets);
+  if (entry === NOT_FOUND) return entry;
+  var candidate = ORDERED_HASH_SET_KEY_AT(table, entry, numBuckets);
+  if (key === candidate) return entry;
+  var keyIsNaN = NumberIsNaN(key);
+  while (true) {
+    if (keyIsNaN && NumberIsNaN(candidate)) {
+      return entry;
+    }
+    entry = ORDERED_HASH_SET_CHAIN_AT(table, entry, numBuckets);
+    if (entry === NOT_FOUND) return entry;
+    candidate = ORDERED_HASH_SET_KEY_AT(table, entry, numBuckets);
+    if (key === candidate) return entry;
+  }
+  return NOT_FOUND;
+}
+%SetForceInlineFlag(SetFindEntry);
+
+
+function MapFindEntry(table, numBuckets, key, hash) {
+  var entry = HashToEntry(table, hash, numBuckets);
+  if (entry === NOT_FOUND) return entry;
+  var candidate = ORDERED_HASH_MAP_KEY_AT(table, entry, numBuckets);
+  if (key === candidate) return entry;
+  var keyIsNaN = NumberIsNaN(key);
+  while (true) {
+    if (keyIsNaN && NumberIsNaN(candidate)) {
+      return entry;
+    }
+    entry = ORDERED_HASH_MAP_CHAIN_AT(table, entry, numBuckets);
+    if (entry === NOT_FOUND) return entry;
+    candidate = ORDERED_HASH_MAP_KEY_AT(table, entry, numBuckets);
+    if (key === candidate) return entry;
+  }
+  return NOT_FOUND;
+}
+%SetForceInlineFlag(MapFindEntry);
+
+
+function ComputeIntegerHash(key, seed) {
+  var hash = key;
+  hash = hash ^ seed;
+  hash = ~hash + (hash << 15);  // hash = (hash << 15) - hash - 1;
+  hash = hash ^ (hash >>> 12);
+  hash = hash + (hash << 2);
+  hash = hash ^ (hash >>> 4);
+  hash = (hash * 2057) | 0;  // hash = (hash + (hash << 3)) + (hash << 11);
+  hash = hash ^ (hash >>> 16);
+  return hash & 0x3fffffff;
+}
+%SetForceInlineFlag(ComputeIntegerHash);
+
+function GetExistingHash(key) {
+  if (%_IsSmi(key)) {
+    return ComputeIntegerHash(key, 0);
+  }
+  if (IS_STRING(key)) {
+    var field = %_StringGetRawHashField(key);
+    if ((field & 1 /* Name::kHashNotComputedMask */) === 0) {
+      return field >>> 2 /* Name::kHashShift */;
+    }
+  } else if (IS_RECEIVER(key) && !IS_PROXY(key) && !IS_GLOBAL(key)) {
+    var hash = GET_PRIVATE(key, hashCodeSymbol);
+    return hash;
+  }
+  return %GenericHash(key);
+}
+%SetForceInlineFlag(GetExistingHash);
+
+
+function GetHash(key) {
+  var hash = GetExistingHash(key);
+  if (IS_UNDEFINED(hash)) {
+    hash = IntRandom() | 0;
+    if (hash === 0) hash = 1;
+    SET_PRIVATE(key, hashCodeSymbol, hash);
+  }
+  return hash;
+}
+%SetForceInlineFlag(GetHash);
+
+
+// -------------------------------------------------------------------
+// Harmony Set
+
+function SetConstructor(iterable) {
+  if (IS_UNDEFINED(new.target)) {
+    throw MakeTypeError(kConstructorNotFunction, "Set");
+  }
+
+  %_SetInitialize(this);
+
+  if (!IS_NULL_OR_UNDEFINED(iterable)) {
+    var adder = this.add;
+    if (!IS_CALLABLE(adder)) {
+      throw MakeTypeError(kPropertyNotFunction, adder, 'add', this);
+    }
+
+    for (var value of iterable) {
+      %_Call(adder, this, value);
+    }
+  }
+}
+
+
+function SetAdd(key) {
+  if (!IS_SET(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver, 'Set.prototype.add', this);
+  }
+  // Normalize -0 to +0 as required by the spec.
+  // Even though we use SameValueZero as the comparison for the keys we don't
+  // want to ever store -0 as the key since the key is directly exposed when
+  // doing iteration.
+  if (key === 0) {
+    key = 0;
+  }
+  var table = %_JSCollectionGetTable(this);
+  var numBuckets = ORDERED_HASH_TABLE_BUCKET_COUNT(table);
+  var hash = GetHash(key);
+  if (SetFindEntry(table, numBuckets, key, hash) !== NOT_FOUND) return this;
+
+  var nof = ORDERED_HASH_TABLE_ELEMENT_COUNT(table);
+  var nod = ORDERED_HASH_TABLE_DELETED_COUNT(table);
+  var capacity = numBuckets << 1;
+  if ((nof + nod) >= capacity) {
+    // Need to grow, bail out to runtime.
+    %SetGrow(this);
+    // Re-load state from the grown backing store.
+    table = %_JSCollectionGetTable(this);
+    numBuckets = ORDERED_HASH_TABLE_BUCKET_COUNT(table);
+    nof = ORDERED_HASH_TABLE_ELEMENT_COUNT(table);
+    nod = ORDERED_HASH_TABLE_DELETED_COUNT(table);
+  }
+  var entry = nof + nod;
+  var index = ORDERED_HASH_SET_ENTRY_TO_INDEX(entry, numBuckets);
+  var bucket = ORDERED_HASH_TABLE_HASH_TO_BUCKET(hash, numBuckets);
+  var chainEntry = ORDERED_HASH_TABLE_BUCKET_AT(table, bucket);
+  ORDERED_HASH_TABLE_SET_BUCKET_AT(table, bucket, entry);
+  ORDERED_HASH_TABLE_SET_ELEMENT_COUNT(table, nof + 1);
+  FIXED_ARRAY_SET(table, index, key);
+  FIXED_ARRAY_SET_SMI(table, index + 1, chainEntry);
+  return this;
+}
+
+
+function SetHas(key) {
+  if (!IS_SET(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver, 'Set.prototype.has', this);
+  }
+  var table = %_JSCollectionGetTable(this);
+  var numBuckets = ORDERED_HASH_TABLE_BUCKET_COUNT(table);
+  var hash = GetExistingHash(key);
+  if (IS_UNDEFINED(hash)) return false;
+  return SetFindEntry(table, numBuckets, key, hash) !== NOT_FOUND;
+}
+
+
+function SetDelete(key) {
+  if (!IS_SET(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        'Set.prototype.delete', this);
+  }
+  var table = %_JSCollectionGetTable(this);
+  var numBuckets = ORDERED_HASH_TABLE_BUCKET_COUNT(table);
+  var hash = GetExistingHash(key);
+  if (IS_UNDEFINED(hash)) return false;
+  var entry = SetFindEntry(table, numBuckets, key, hash);
+  if (entry === NOT_FOUND) return false;
+
+  var nof = ORDERED_HASH_TABLE_ELEMENT_COUNT(table) - 1;
+  var nod = ORDERED_HASH_TABLE_DELETED_COUNT(table) + 1;
+  var index = ORDERED_HASH_SET_ENTRY_TO_INDEX(entry, numBuckets);
+  FIXED_ARRAY_SET(table, index, %_TheHole());
+  ORDERED_HASH_TABLE_SET_ELEMENT_COUNT(table, nof);
+  ORDERED_HASH_TABLE_SET_DELETED_COUNT(table, nod);
+  if (nof < (numBuckets >>> 1)) %SetShrink(this);
+  return true;
+}
+
+
+function SetGetSize() {
+  if (!IS_SET(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        'Set.prototype.size', this);
+  }
+  var table = %_JSCollectionGetTable(this);
+  return ORDERED_HASH_TABLE_ELEMENT_COUNT(table);
+}
+
+
+function SetClearJS() {
+  if (!IS_SET(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        'Set.prototype.clear', this);
+  }
+  %_SetClear(this);
+}
+
+
+function SetForEach(f, receiver) {
+  if (!IS_SET(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        'Set.prototype.forEach', this);
+  }
+
+  if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f);
+
+  var iterator = new SetIterator(this, ITERATOR_KIND_VALUES);
+  var key;
+  var value_array = [UNDEFINED];
+  while (%SetIteratorNext(iterator, value_array)) {
+    key = value_array[0];
+    %_Call(f, receiver, key, key, this);
+  }
+}
+
+// -------------------------------------------------------------------
+
+%SetCode(GlobalSet, SetConstructor);
+%FunctionSetLength(GlobalSet, 0);
+%FunctionSetPrototype(GlobalSet, new GlobalObject());
+%AddNamedProperty(GlobalSet.prototype, "constructor", GlobalSet, DONT_ENUM);
+%AddNamedProperty(GlobalSet.prototype, toStringTagSymbol, "Set",
+                  DONT_ENUM | READ_ONLY);
+
+%FunctionSetLength(SetForEach, 1);
+
+// Set up the non-enumerable functions on the Set prototype object.
+utils.InstallGetter(GlobalSet.prototype, "size", SetGetSize);
+utils.InstallFunctions(GlobalSet.prototype, DONT_ENUM, [
+  "add", SetAdd,
+  "has", SetHas,
+  "delete", SetDelete,
+  "clear", SetClearJS,
+  "forEach", SetForEach
+]);
+
+
+// -------------------------------------------------------------------
+// Harmony Map
+
+function MapConstructor(iterable) {
+  if (IS_UNDEFINED(new.target)) {
+    throw MakeTypeError(kConstructorNotFunction, "Map");
+  }
+
+  %_MapInitialize(this);
+
+  if (!IS_NULL_OR_UNDEFINED(iterable)) {
+    var adder = this.set;
+    if (!IS_CALLABLE(adder)) {
+      throw MakeTypeError(kPropertyNotFunction, adder, 'set', this);
+    }
+
+    for (var nextItem of iterable) {
+      if (!IS_RECEIVER(nextItem)) {
+        throw MakeTypeError(kIteratorValueNotAnObject, nextItem);
+      }
+      %_Call(adder, this, nextItem[0], nextItem[1]);
+    }
+  }
+}
+
+
+function MapGet(key) {
+  if (!IS_MAP(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        'Map.prototype.get', this);
+  }
+  var table = %_JSCollectionGetTable(this);
+  var numBuckets = ORDERED_HASH_TABLE_BUCKET_COUNT(table);
+  var hash = GetExistingHash(key);
+  if (IS_UNDEFINED(hash)) return UNDEFINED;
+  var entry = MapFindEntry(table, numBuckets, key, hash);
+  if (entry === NOT_FOUND) return UNDEFINED;
+  return ORDERED_HASH_MAP_VALUE_AT(table, entry, numBuckets);
+}
+
+
+function MapSet(key, value) {
+  if (!IS_MAP(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        'Map.prototype.set', this);
+  }
+  // Normalize -0 to +0 as required by the spec.
+  // Even though we use SameValueZero as the comparison for the keys we don't
+  // want to ever store -0 as the key since the key is directly exposed when
+  // doing iteration.
+  if (key === 0) {
+    key = 0;
+  }
+
+  var table = %_JSCollectionGetTable(this);
+  var numBuckets = ORDERED_HASH_TABLE_BUCKET_COUNT(table);
+  var hash = GetHash(key);
+  var entry = MapFindEntry(table, numBuckets, key, hash);
+  if (entry !== NOT_FOUND) {
+    var existingIndex = ORDERED_HASH_MAP_ENTRY_TO_INDEX(entry, numBuckets);
+    FIXED_ARRAY_SET(table, existingIndex + 1, value);
+    return this;
+  }
+
+  var nof = ORDERED_HASH_TABLE_ELEMENT_COUNT(table);
+  var nod = ORDERED_HASH_TABLE_DELETED_COUNT(table);
+  var capacity = numBuckets << 1;
+  if ((nof + nod) >= capacity) {
+    // Need to grow, bail out to runtime.
+    %MapGrow(this);
+    // Re-load state from the grown backing store.
+    table = %_JSCollectionGetTable(this);
+    numBuckets = ORDERED_HASH_TABLE_BUCKET_COUNT(table);
+    nof = ORDERED_HASH_TABLE_ELEMENT_COUNT(table);
+    nod = ORDERED_HASH_TABLE_DELETED_COUNT(table);
+  }
+  entry = nof + nod;
+  var index = ORDERED_HASH_MAP_ENTRY_TO_INDEX(entry, numBuckets);
+  var bucket = ORDERED_HASH_TABLE_HASH_TO_BUCKET(hash, numBuckets);
+  var chainEntry = ORDERED_HASH_TABLE_BUCKET_AT(table, bucket);
+  ORDERED_HASH_TABLE_SET_BUCKET_AT(table, bucket, entry);
+  ORDERED_HASH_TABLE_SET_ELEMENT_COUNT(table, nof + 1);
+  FIXED_ARRAY_SET(table, index, key);
+  FIXED_ARRAY_SET(table, index + 1, value);
+  FIXED_ARRAY_SET(table, index + 2, chainEntry);
+  return this;
+}
+
+
+function MapHas(key) {
+  if (!IS_MAP(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        'Map.prototype.has', this);
+  }
+  var table = %_JSCollectionGetTable(this);
+  var numBuckets = ORDERED_HASH_TABLE_BUCKET_COUNT(table);
+  var hash = GetHash(key);
+  return MapFindEntry(table, numBuckets, key, hash) !== NOT_FOUND;
+}
+
+
+function MapDelete(key) {
+  if (!IS_MAP(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        'Map.prototype.delete', this);
+  }
+  var table = %_JSCollectionGetTable(this);
+  var numBuckets = ORDERED_HASH_TABLE_BUCKET_COUNT(table);
+  var hash = GetHash(key);
+  var entry = MapFindEntry(table, numBuckets, key, hash);
+  if (entry === NOT_FOUND) return false;
+
+  var nof = ORDERED_HASH_TABLE_ELEMENT_COUNT(table) - 1;
+  var nod = ORDERED_HASH_TABLE_DELETED_COUNT(table) + 1;
+  var index = ORDERED_HASH_MAP_ENTRY_TO_INDEX(entry, numBuckets);
+  FIXED_ARRAY_SET(table, index, %_TheHole());
+  FIXED_ARRAY_SET(table, index + 1, %_TheHole());
+  ORDERED_HASH_TABLE_SET_ELEMENT_COUNT(table, nof);
+  ORDERED_HASH_TABLE_SET_DELETED_COUNT(table, nod);
+  if (nof < (numBuckets >>> 1)) %MapShrink(this);
+  return true;
+}
+
+
+function MapGetSize() {
+  if (!IS_MAP(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        'Map.prototype.size', this);
+  }
+  var table = %_JSCollectionGetTable(this);
+  return ORDERED_HASH_TABLE_ELEMENT_COUNT(table);
+}
+
+
+function MapClearJS() {
+  if (!IS_MAP(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        'Map.prototype.clear', this);
+  }
+  %_MapClear(this);
+}
+
+
+function MapForEach(f, receiver) {
+  if (!IS_MAP(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        'Map.prototype.forEach', this);
+  }
+
+  if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f);
+
+  var iterator = new MapIterator(this, ITERATOR_KIND_ENTRIES);
+  var value_array = [UNDEFINED, UNDEFINED];
+  while (%MapIteratorNext(iterator, value_array)) {
+    %_Call(f, receiver, value_array[1], value_array[0], this);
+  }
+}
+
+// -------------------------------------------------------------------
+
+%SetCode(GlobalMap, MapConstructor);
+%FunctionSetLength(GlobalMap, 0);
+%FunctionSetPrototype(GlobalMap, new GlobalObject());
+%AddNamedProperty(GlobalMap.prototype, "constructor", GlobalMap, DONT_ENUM);
+%AddNamedProperty(
+    GlobalMap.prototype, toStringTagSymbol, "Map", DONT_ENUM | READ_ONLY);
+
+%FunctionSetLength(MapForEach, 1);
+
+// Set up the non-enumerable functions on the Map prototype object.
+utils.InstallGetter(GlobalMap.prototype, "size", MapGetSize);
+utils.InstallFunctions(GlobalMap.prototype, DONT_ENUM, [
+  "get", MapGet,
+  "set", MapSet,
+  "has", MapHas,
+  "delete", MapDelete,
+  "clear", MapClearJS,
+  "forEach", MapForEach
+]);
+
+// -----------------------------------------------------------------------
+// Exports
+
+%InstallToContext([
+  "map_get", MapGet,
+  "map_set", MapSet,
+  "map_has", MapHas,
+  "map_delete", MapDelete,
+  "set_add", SetAdd,
+  "set_has", SetHas,
+  "set_delete", SetDelete,
+]);
+
+utils.Export(function(to) {
+  to.GetExistingHash = GetExistingHash;
+  to.GetHash = GetHash;
+});
+
+})
diff --git a/src/js/generator.js b/src/js/generator.js
new file mode 100644
index 0000000..7f43656
--- /dev/null
+++ b/src/js/generator.js
@@ -0,0 +1,104 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function(global, utils) {
+
+"use strict";
+
+%CheckIsBootstrapping();
+
+// -------------------------------------------------------------------
+// Imports
+
+var GeneratorFunctionPrototype = utils.ImportNow("GeneratorFunctionPrototype");
+var GeneratorFunction = utils.ImportNow("GeneratorFunction");
+var GlobalFunction = global.Function;
+var MakeTypeError;
+var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
+
+utils.Import(function(from) {
+  MakeTypeError = from.MakeTypeError;
+});
+
+// ----------------------------------------------------------------------------
+
+// Generator functions and objects are specified by ES6, sections 15.19.3 and
+// 15.19.4.
+
+function GeneratorObjectNext(value) {
+  if (!IS_GENERATOR(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        '[Generator].prototype.next', this);
+  }
+
+  var continuation = %GeneratorGetContinuation(this);
+  if (continuation > 0) {
+    // Generator is suspended.
+    DEBUG_PREPARE_STEP_IN_IF_STEPPING(this);
+    try {
+      return %_GeneratorNext(this, value);
+    } catch (e) {
+      %GeneratorClose(this);
+      throw e;
+    }
+  } else if (continuation == 0) {
+    // Generator is already closed.
+    return { value: void 0, done: true };
+  } else {
+    // Generator is running.
+    throw MakeTypeError(kGeneratorRunning);
+  }
+}
+
+
+function GeneratorObjectThrow(exn) {
+  if (!IS_GENERATOR(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        '[Generator].prototype.throw', this);
+  }
+
+  var continuation = %GeneratorGetContinuation(this);
+  if (continuation > 0) {
+    // Generator is suspended.
+    try {
+      return %_GeneratorThrow(this, exn);
+    } catch (e) {
+      %GeneratorClose(this);
+      throw e;
+    }
+  } else if (continuation == 0) {
+    // Generator is already closed.
+    throw exn;
+  } else {
+    // Generator is running.
+    throw MakeTypeError(kGeneratorRunning);
+  }
+}
+
+// ----------------------------------------------------------------------------
+
+// Both Runtime_GeneratorNext and Runtime_GeneratorThrow are supported by
+// neither Crankshaft nor TurboFan, disable optimization of wrappers here.
+%NeverOptimizeFunction(GeneratorObjectNext);
+%NeverOptimizeFunction(GeneratorObjectThrow);
+
+// Set up non-enumerable functions on the generator prototype object.
+var GeneratorObjectPrototype = GeneratorFunctionPrototype.prototype;
+utils.InstallFunctions(GeneratorObjectPrototype,
+                       DONT_ENUM,
+                      ["next", GeneratorObjectNext,
+                       "throw", GeneratorObjectThrow]);
+
+%AddNamedProperty(GeneratorObjectPrototype, "constructor",
+    GeneratorFunctionPrototype, DONT_ENUM | READ_ONLY);
+%AddNamedProperty(GeneratorObjectPrototype,
+    toStringTagSymbol, "Generator", DONT_ENUM | READ_ONLY);
+%InternalSetPrototype(GeneratorFunctionPrototype, GlobalFunction.prototype);
+%AddNamedProperty(GeneratorFunctionPrototype,
+    toStringTagSymbol, "GeneratorFunction", DONT_ENUM | READ_ONLY);
+%AddNamedProperty(GeneratorFunctionPrototype, "constructor",
+    GeneratorFunction, DONT_ENUM | READ_ONLY);
+%InternalSetPrototype(GeneratorFunction, GlobalFunction);
+
+})
diff --git a/src/js/harmony-atomics.js b/src/js/harmony-atomics.js
new file mode 100644
index 0000000..b861a2a
--- /dev/null
+++ b/src/js/harmony-atomics.js
@@ -0,0 +1,215 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function(global, utils) {
+
+"use strict";
+
+%CheckIsBootstrapping();
+
+// -------------------------------------------------------------------
+// Imports
+
+var GlobalObject = global.Object;
+var MakeTypeError;
+var MaxSimple;
+var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
+
+utils.Import(function(from) {
+  MakeTypeError = from.MakeTypeError;
+  MaxSimple = from.MaxSimple;
+});
+
+// -------------------------------------------------------------------
+
+
+function CheckSharedIntegerTypedArray(ia) {
+  if (!%IsSharedIntegerTypedArray(ia)) {
+    throw MakeTypeError(kNotIntegerSharedTypedArray, ia);
+  }
+}
+
+function CheckSharedInteger32TypedArray(ia) {
+  CheckSharedIntegerTypedArray(ia);
+  if (!%IsSharedInteger32TypedArray(ia)) {
+    throw MakeTypeError(kNotInt32SharedTypedArray, ia);
+  }
+}
+
+//-------------------------------------------------------------------
+
+function AtomicsCompareExchangeJS(sta, index, oldValue, newValue) {
+  CheckSharedIntegerTypedArray(sta);
+  index = TO_INTEGER(index);
+  if (index < 0 || index >= %_TypedArrayGetLength(sta)) {
+    return UNDEFINED;
+  }
+  oldValue = TO_NUMBER(oldValue);
+  newValue = TO_NUMBER(newValue);
+  return %_AtomicsCompareExchange(sta, index, oldValue, newValue);
+}
+
+function AtomicsLoadJS(sta, index) {
+  CheckSharedIntegerTypedArray(sta);
+  index = TO_INTEGER(index);
+  if (index < 0 || index >= %_TypedArrayGetLength(sta)) {
+    return UNDEFINED;
+  }
+  return %_AtomicsLoad(sta, index);
+}
+
+function AtomicsStoreJS(sta, index, value) {
+  CheckSharedIntegerTypedArray(sta);
+  index = TO_INTEGER(index);
+  if (index < 0 || index >= %_TypedArrayGetLength(sta)) {
+    return UNDEFINED;
+  }
+  value = TO_NUMBER(value);
+  return %_AtomicsStore(sta, index, value);
+}
+
+function AtomicsAddJS(ia, index, value) {
+  CheckSharedIntegerTypedArray(ia);
+  index = TO_INTEGER(index);
+  if (index < 0 || index >= %_TypedArrayGetLength(ia)) {
+    return UNDEFINED;
+  }
+  value = TO_NUMBER(value);
+  return %_AtomicsAdd(ia, index, value);
+}
+
+function AtomicsSubJS(ia, index, value) {
+  CheckSharedIntegerTypedArray(ia);
+  index = TO_INTEGER(index);
+  if (index < 0 || index >= %_TypedArrayGetLength(ia)) {
+    return UNDEFINED;
+  }
+  value = TO_NUMBER(value);
+  return %_AtomicsSub(ia, index, value);
+}
+
+function AtomicsAndJS(ia, index, value) {
+  CheckSharedIntegerTypedArray(ia);
+  index = TO_INTEGER(index);
+  if (index < 0 || index >= %_TypedArrayGetLength(ia)) {
+    return UNDEFINED;
+  }
+  value = TO_NUMBER(value);
+  return %_AtomicsAnd(ia, index, value);
+}
+
+function AtomicsOrJS(ia, index, value) {
+  CheckSharedIntegerTypedArray(ia);
+  index = TO_INTEGER(index);
+  if (index < 0 || index >= %_TypedArrayGetLength(ia)) {
+    return UNDEFINED;
+  }
+  value = TO_NUMBER(value);
+  return %_AtomicsOr(ia, index, value);
+}
+
+function AtomicsXorJS(ia, index, value) {
+  CheckSharedIntegerTypedArray(ia);
+  index = TO_INTEGER(index);
+  if (index < 0 || index >= %_TypedArrayGetLength(ia)) {
+    return UNDEFINED;
+  }
+  value = TO_NUMBER(value);
+  return %_AtomicsXor(ia, index, value);
+}
+
+function AtomicsExchangeJS(ia, index, value) {
+  CheckSharedIntegerTypedArray(ia);
+  index = TO_INTEGER(index);
+  if (index < 0 || index >= %_TypedArrayGetLength(ia)) {
+    return UNDEFINED;
+  }
+  value = TO_NUMBER(value);
+  return %_AtomicsExchange(ia, index, value);
+}
+
+function AtomicsIsLockFreeJS(size) {
+  return %_AtomicsIsLockFree(size);
+}
+
+// Futexes
+
+function AtomicsFutexWaitJS(ia, index, value, timeout) {
+  CheckSharedInteger32TypedArray(ia);
+  index = TO_INTEGER(index);
+  if (index < 0 || index >= %_TypedArrayGetLength(ia)) {
+    return UNDEFINED;
+  }
+  if (IS_UNDEFINED(timeout)) {
+    timeout = INFINITY;
+  } else {
+    timeout = TO_NUMBER(timeout);
+    if (NUMBER_IS_NAN(timeout)) {
+      timeout = INFINITY;
+    } else {
+      timeout = MaxSimple(0, timeout);
+    }
+  }
+  return %AtomicsFutexWait(ia, index, value, timeout);
+}
+
+function AtomicsFutexWakeJS(ia, index, count) {
+  CheckSharedInteger32TypedArray(ia);
+  index = TO_INTEGER(index);
+  if (index < 0 || index >= %_TypedArrayGetLength(ia)) {
+    return UNDEFINED;
+  }
+  count = MaxSimple(0, TO_INTEGER(count));
+  return %AtomicsFutexWake(ia, index, count);
+}
+
+function AtomicsFutexWakeOrRequeueJS(ia, index1, count, value, index2) {
+  CheckSharedInteger32TypedArray(ia);
+  index1 = TO_INTEGER(index1);
+  count = MaxSimple(0, TO_INTEGER(count));
+  value = TO_INT32(value);
+  index2 = TO_INTEGER(index2);
+  if (index1 < 0 || index1 >= %_TypedArrayGetLength(ia) ||
+      index2 < 0 || index2 >= %_TypedArrayGetLength(ia)) {
+    return UNDEFINED;
+  }
+  return %AtomicsFutexWakeOrRequeue(ia, index1, count, value, index2);
+}
+
+// -------------------------------------------------------------------
+
+function AtomicsConstructor() {}
+
+var Atomics = new AtomicsConstructor();
+
+%InternalSetPrototype(Atomics, GlobalObject.prototype);
+%AddNamedProperty(global, "Atomics", Atomics, DONT_ENUM);
+%FunctionSetInstanceClassName(AtomicsConstructor, 'Atomics');
+
+%AddNamedProperty(Atomics, toStringTagSymbol, "Atomics", READ_ONLY | DONT_ENUM);
+
+// These must match the values in src/futex-emulation.h
+utils.InstallConstants(Atomics, [
+  "OK", 0,
+  "NOTEQUAL", -1,
+  "TIMEDOUT", -2,
+]);
+
+utils.InstallFunctions(Atomics, DONT_ENUM, [
+  "compareExchange", AtomicsCompareExchangeJS,
+  "load", AtomicsLoadJS,
+  "store", AtomicsStoreJS,
+  "add", AtomicsAddJS,
+  "sub", AtomicsSubJS,
+  "and", AtomicsAndJS,
+  "or", AtomicsOrJS,
+  "xor", AtomicsXorJS,
+  "exchange", AtomicsExchangeJS,
+  "isLockFree", AtomicsIsLockFreeJS,
+  "futexWait", AtomicsFutexWaitJS,
+  "futexWake", AtomicsFutexWakeJS,
+  "futexWakeOrRequeue", AtomicsFutexWakeOrRequeueJS,
+]);
+
+})
diff --git a/src/js/harmony-object-observe.js b/src/js/harmony-object-observe.js
new file mode 100644
index 0000000..95dd298
--- /dev/null
+++ b/src/js/harmony-object-observe.js
@@ -0,0 +1,17 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function(global, utils) {
+
+"use strict";
+
+%CheckIsBootstrapping();
+
+var ObserveArrayMethods = utils.ImportNow("ObserveArrayMethods");
+var ObserveObjectMethods = utils.ImportNow("ObserveObjectMethods");;
+
+utils.InstallFunctions(global.Object, DONT_ENUM, ObserveObjectMethods);
+utils.InstallFunctions(global.Array, DONT_ENUM, ObserveArrayMethods);
+
+})
diff --git a/src/js/harmony-reflect.js b/src/js/harmony-reflect.js
new file mode 100644
index 0000000..dcadad5
--- /dev/null
+++ b/src/js/harmony-reflect.js
@@ -0,0 +1,37 @@
+// Copyright 2013-2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function(global, utils) {
+
+'use strict';
+
+%CheckIsBootstrapping();
+
+// -------------------------------------------------------------------
+// Imports
+
+var GlobalReflect = global.Reflect;
+var MakeTypeError;
+var ReflectApply = utils.ImportNow("reflect_apply");
+var ReflectConstruct = utils.ImportNow("reflect_construct");
+
+utils.Import(function(from) {
+  MakeTypeError = from.MakeTypeError;
+});
+
+// -------------------------------------------------------------------
+
+function ReflectEnumerate(obj) {
+  if (!IS_RECEIVER(obj))
+    throw MakeTypeError(kCalledOnNonObject, "Reflect.enumerate")
+  return (function* () { for (var x in obj) yield x })();
+}
+
+utils.InstallFunctions(GlobalReflect, DONT_ENUM, [
+  "apply", ReflectApply,
+  "construct", ReflectConstruct,
+  "enumerate", ReflectEnumerate
+]);
+
+})
diff --git a/src/js/harmony-regexp.js b/src/js/harmony-regexp.js
new file mode 100644
index 0000000..f76ef86
--- /dev/null
+++ b/src/js/harmony-regexp.js
@@ -0,0 +1,60 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function(global, utils) {
+
+'use strict';
+
+%CheckIsBootstrapping();
+
+// -------------------------------------------------------------------
+// Imports
+
+var GlobalRegExp = global.RegExp;
+var GlobalRegExpPrototype = GlobalRegExp.prototype;
+var MakeTypeError;
+var regExpFlagsSymbol = utils.ImportNow("regexp_flags_symbol");
+
+utils.Import(function(from) {
+  MakeTypeError = from.MakeTypeError;
+});
+
+// -------------------------------------------------------------------
+
+// ES6 draft 12-06-13, section 21.2.5.3
+// + https://bugs.ecmascript.org/show_bug.cgi?id=3423
+function RegExpGetFlags() {
+  if (!IS_RECEIVER(this)) {
+    throw MakeTypeError(
+        kRegExpNonObject, "RegExp.prototype.flags", TO_STRING(this));
+  }
+  var result = '';
+  if (this.global) result += 'g';
+  if (this.ignoreCase) result += 'i';
+  if (this.multiline) result += 'm';
+  if (this.unicode) result += 'u';
+  if (this.sticky) result += 'y';
+  return result;
+}
+
+// ES6 21.2.5.12.
+function RegExpGetSticky() {
+  if (!IS_REGEXP(this)) {
+    // Compat fix: RegExp.prototype.sticky == undefined; UseCounter tracks it
+    // TODO(littledan): Remove this workaround or standardize it
+    if (this === GlobalRegExpPrototype) {
+      %IncrementUseCounter(kRegExpPrototypeStickyGetter);
+      return UNDEFINED;
+    }
+    throw MakeTypeError(kRegExpNonRegExp, "RegExp.prototype.sticky");
+  }
+  return !!REGEXP_STICKY(this);
+}
+%FunctionSetName(RegExpGetSticky, "RegExp.prototype.sticky");
+%SetNativeFlag(RegExpGetSticky);
+
+utils.InstallGetter(GlobalRegExp.prototype, 'flags', RegExpGetFlags);
+utils.InstallGetter(GlobalRegExp.prototype, 'sticky', RegExpGetSticky);
+
+})
diff --git a/src/js/harmony-sharedarraybuffer.js b/src/js/harmony-sharedarraybuffer.js
new file mode 100644
index 0000000..10ceb70
--- /dev/null
+++ b/src/js/harmony-sharedarraybuffer.js
@@ -0,0 +1,31 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function(global, utils) {
+
+"use strict";
+
+%CheckIsBootstrapping();
+
+var GlobalSharedArrayBuffer = global.SharedArrayBuffer;
+var MakeTypeError;
+
+utils.Import(function(from) {
+  MakeTypeError = from.MakeTypeError;
+})
+
+// -------------------------------------------------------------------
+
+function SharedArrayBufferGetByteLen() {
+  if (!IS_SHAREDARRAYBUFFER(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        'SharedArrayBuffer.prototype.byteLength', this);
+  }
+  return %_ArrayBufferGetByteLength(this);
+}
+
+utils.InstallGetter(GlobalSharedArrayBuffer.prototype, "byteLength",
+                    SharedArrayBufferGetByteLen);
+
+})
diff --git a/src/js/harmony-simd.js b/src/js/harmony-simd.js
new file mode 100644
index 0000000..4df2f43
--- /dev/null
+++ b/src/js/harmony-simd.js
@@ -0,0 +1,941 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function(global, utils) {
+
+"use strict";
+
+%CheckIsBootstrapping();
+
+// -------------------------------------------------------------------
+// Imports
+
+var GlobalSIMD = global.SIMD;
+var MakeTypeError;
+var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
+
+utils.Import(function(from) {
+  MakeTypeError = from.MakeTypeError;
+});
+
+// -------------------------------------------------------------------
+
+macro SIMD_FLOAT_TYPES(FUNCTION)
+FUNCTION(Float32x4, float32x4, 4)
+endmacro
+
+macro SIMD_INT_TYPES(FUNCTION)
+FUNCTION(Int32x4, int32x4, 4)
+FUNCTION(Int16x8, int16x8, 8)
+FUNCTION(Int8x16, int8x16, 16)
+endmacro
+
+macro SIMD_UINT_TYPES(FUNCTION)
+FUNCTION(Uint32x4, uint32x4, 4)
+FUNCTION(Uint16x8, uint16x8, 8)
+FUNCTION(Uint8x16, uint8x16, 16)
+endmacro
+
+macro SIMD_BOOL_TYPES(FUNCTION)
+FUNCTION(Bool32x4, bool32x4, 4)
+FUNCTION(Bool16x8, bool16x8, 8)
+FUNCTION(Bool8x16, bool8x16, 16)
+endmacro
+
+macro SIMD_ALL_TYPES(FUNCTION)
+SIMD_FLOAT_TYPES(FUNCTION)
+SIMD_INT_TYPES(FUNCTION)
+SIMD_UINT_TYPES(FUNCTION)
+SIMD_BOOL_TYPES(FUNCTION)
+endmacro
+
+macro DECLARE_GLOBALS(NAME, TYPE, LANES)
+var GlobalNAME = GlobalSIMD.NAME;
+endmacro
+
+SIMD_ALL_TYPES(DECLARE_GLOBALS)
+
+macro DECLARE_COMMON_FUNCTIONS(NAME, TYPE, LANES)
+function NAMECheckJS(a) {
+  return %NAMECheck(a);
+}
+
+function NAMEToString() {
+  var value = %_ValueOf(this);
+  if (typeof(value) !== 'TYPE') {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        "NAME.prototype.toString", this);
+  }
+  var str = "SIMD.NAME(";
+  str += %NAMEExtractLane(value, 0);
+  for (var i = 1; i < LANES; i++) {
+    str += ", " + %NAMEExtractLane(value, i);
+  }
+  return str + ")";
+}
+
+function NAMEToLocaleString() {
+  var value = %_ValueOf(this);
+  if (typeof(value) !== 'TYPE') {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        "NAME.prototype.toLocaleString", this);
+  }
+  var str = "SIMD.NAME(";
+  str += %NAMEExtractLane(value, 0).toLocaleString();
+  for (var i = 1; i < LANES; i++) {
+    str += ", " + %NAMEExtractLane(value, i).toLocaleString();
+  }
+  return str + ")";
+}
+
+function NAMEValueOf() {
+  var value = %_ValueOf(this);
+  if (typeof(value) !== 'TYPE') {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        "NAME.prototype.valueOf", this);
+  }
+  return value;
+}
+
+function NAMEExtractLaneJS(instance, lane) {
+  return %NAMEExtractLane(instance, lane);
+}
+endmacro
+
+SIMD_ALL_TYPES(DECLARE_COMMON_FUNCTIONS)
+
+macro DECLARE_SHIFT_FUNCTIONS(NAME, TYPE, LANES)
+function NAMEShiftLeftByScalarJS(instance, shift) {
+  return %NAMEShiftLeftByScalar(instance, shift);
+}
+
+function NAMEShiftRightByScalarJS(instance, shift) {
+  return %NAMEShiftRightByScalar(instance, shift);
+}
+endmacro
+
+SIMD_INT_TYPES(DECLARE_SHIFT_FUNCTIONS)
+SIMD_UINT_TYPES(DECLARE_SHIFT_FUNCTIONS)
+
+macro SIMD_SMALL_INT_TYPES(FUNCTION)
+FUNCTION(Int16x8)
+FUNCTION(Int8x16)
+FUNCTION(Uint8x16)
+FUNCTION(Uint16x8)
+endmacro
+
+macro DECLARE_SMALL_INT_FUNCTIONS(NAME)
+function NAMEAddSaturateJS(a, b) {
+  return %NAMEAddSaturate(a, b);
+}
+
+function NAMESubSaturateJS(a, b) {
+  return %NAMESubSaturate(a, b);
+}
+endmacro
+
+SIMD_SMALL_INT_TYPES(DECLARE_SMALL_INT_FUNCTIONS)
+
+macro DECLARE_SIGNED_FUNCTIONS(NAME, TYPE, LANES)
+function NAMENegJS(a) {
+  return %NAMENeg(a);
+}
+endmacro
+
+SIMD_FLOAT_TYPES(DECLARE_SIGNED_FUNCTIONS)
+SIMD_INT_TYPES(DECLARE_SIGNED_FUNCTIONS)
+
+macro DECLARE_BOOL_FUNCTIONS(NAME, TYPE, LANES)
+function NAMEReplaceLaneJS(instance, lane, value) {
+  return %NAMEReplaceLane(instance, lane, value);
+}
+
+function NAMEAnyTrueJS(s) {
+  return %NAMEAnyTrue(s);
+}
+
+function NAMEAllTrueJS(s) {
+  return %NAMEAllTrue(s);
+}
+endmacro
+
+SIMD_BOOL_TYPES(DECLARE_BOOL_FUNCTIONS)
+
+macro SIMD_NUMERIC_TYPES(FUNCTION)
+SIMD_FLOAT_TYPES(FUNCTION)
+SIMD_INT_TYPES(FUNCTION)
+SIMD_UINT_TYPES(FUNCTION)
+endmacro
+
+macro DECLARE_NUMERIC_FUNCTIONS(NAME, TYPE, LANES)
+function NAMEReplaceLaneJS(instance, lane, value) {
+  return %NAMEReplaceLane(instance, lane, TO_NUMBER(value));
+}
+
+function NAMESelectJS(selector, a, b) {
+  return %NAMESelect(selector, a, b);
+}
+
+function NAMEAddJS(a, b) {
+  return %NAMEAdd(a, b);
+}
+
+function NAMESubJS(a, b) {
+  return %NAMESub(a, b);
+}
+
+function NAMEMulJS(a, b) {
+  return %NAMEMul(a, b);
+}
+
+function NAMEMinJS(a, b) {
+  return %NAMEMin(a, b);
+}
+
+function NAMEMaxJS(a, b) {
+  return %NAMEMax(a, b);
+}
+
+function NAMEEqualJS(a, b) {
+  return %NAMEEqual(a, b);
+}
+
+function NAMENotEqualJS(a, b) {
+  return %NAMENotEqual(a, b);
+}
+
+function NAMELessThanJS(a, b) {
+  return %NAMELessThan(a, b);
+}
+
+function NAMELessThanOrEqualJS(a, b) {
+  return %NAMELessThanOrEqual(a, b);
+}
+
+function NAMEGreaterThanJS(a, b) {
+  return %NAMEGreaterThan(a, b);
+}
+
+function NAMEGreaterThanOrEqualJS(a, b) {
+  return %NAMEGreaterThanOrEqual(a, b);
+}
+
+function NAMELoadJS(tarray, index) {
+  return %NAMELoad(tarray, index);
+}
+
+function NAMEStoreJS(tarray, index, a) {
+  return %NAMEStore(tarray, index, a);
+}
+endmacro
+
+SIMD_NUMERIC_TYPES(DECLARE_NUMERIC_FUNCTIONS)
+
+macro SIMD_LOGICAL_TYPES(FUNCTION)
+SIMD_INT_TYPES(FUNCTION)
+SIMD_UINT_TYPES(FUNCTION)
+SIMD_BOOL_TYPES(FUNCTION)
+endmacro
+
+macro DECLARE_LOGICAL_FUNCTIONS(NAME, TYPE, LANES)
+function NAMEAndJS(a, b) {
+  return %NAMEAnd(a, b);
+}
+
+function NAMEOrJS(a, b) {
+  return %NAMEOr(a, b);
+}
+
+function NAMEXorJS(a, b) {
+  return %NAMEXor(a, b);
+}
+
+function NAMENotJS(a) {
+  return %NAMENot(a);
+}
+endmacro
+
+SIMD_LOGICAL_TYPES(DECLARE_LOGICAL_FUNCTIONS)
+
+macro SIMD_FROM_TYPES(FUNCTION)
+FUNCTION(Float32x4, Int32x4)
+FUNCTION(Float32x4, Uint32x4)
+FUNCTION(Int32x4, Float32x4)
+FUNCTION(Int32x4, Uint32x4)
+FUNCTION(Uint32x4, Float32x4)
+FUNCTION(Uint32x4, Int32x4)
+FUNCTION(Int16x8, Uint16x8)
+FUNCTION(Uint16x8, Int16x8)
+FUNCTION(Int8x16, Uint8x16)
+FUNCTION(Uint8x16, Int8x16)
+endmacro
+
+macro DECLARE_FROM_FUNCTIONS(TO, FROM)
+function TOFromFROMJS(a) {
+  return %TOFromFROM(a);
+}
+endmacro
+
+SIMD_FROM_TYPES(DECLARE_FROM_FUNCTIONS)
+
+macro SIMD_FROM_BITS_TYPES(FUNCTION)
+FUNCTION(Float32x4, Int32x4)
+FUNCTION(Float32x4, Uint32x4)
+FUNCTION(Float32x4, Int16x8)
+FUNCTION(Float32x4, Uint16x8)
+FUNCTION(Float32x4, Int8x16)
+FUNCTION(Float32x4, Uint8x16)
+FUNCTION(Int32x4, Float32x4)
+FUNCTION(Int32x4, Uint32x4)
+FUNCTION(Int32x4, Int16x8)
+FUNCTION(Int32x4, Uint16x8)
+FUNCTION(Int32x4, Int8x16)
+FUNCTION(Int32x4, Uint8x16)
+FUNCTION(Uint32x4, Float32x4)
+FUNCTION(Uint32x4, Int32x4)
+FUNCTION(Uint32x4, Int16x8)
+FUNCTION(Uint32x4, Uint16x8)
+FUNCTION(Uint32x4, Int8x16)
+FUNCTION(Uint32x4, Uint8x16)
+FUNCTION(Int16x8, Float32x4)
+FUNCTION(Int16x8, Int32x4)
+FUNCTION(Int16x8, Uint32x4)
+FUNCTION(Int16x8, Uint16x8)
+FUNCTION(Int16x8, Int8x16)
+FUNCTION(Int16x8, Uint8x16)
+FUNCTION(Uint16x8, Float32x4)
+FUNCTION(Uint16x8, Int32x4)
+FUNCTION(Uint16x8, Uint32x4)
+FUNCTION(Uint16x8, Int16x8)
+FUNCTION(Uint16x8, Int8x16)
+FUNCTION(Uint16x8, Uint8x16)
+FUNCTION(Int8x16, Float32x4)
+FUNCTION(Int8x16, Int32x4)
+FUNCTION(Int8x16, Uint32x4)
+FUNCTION(Int8x16, Int16x8)
+FUNCTION(Int8x16, Uint16x8)
+FUNCTION(Int8x16, Uint8x16)
+FUNCTION(Uint8x16, Float32x4)
+FUNCTION(Uint8x16, Int32x4)
+FUNCTION(Uint8x16, Uint32x4)
+FUNCTION(Uint8x16, Int16x8)
+FUNCTION(Uint8x16, Uint16x8)
+FUNCTION(Uint8x16, Int8x16)
+endmacro
+
+macro DECLARE_FROM_BITS_FUNCTIONS(TO, FROM)
+function TOFromFROMBitsJS(a) {
+  return %TOFromFROMBits(a);
+}
+endmacro
+
+SIMD_FROM_BITS_TYPES(DECLARE_FROM_BITS_FUNCTIONS)
+
+
+macro SIMD_LOADN_STOREN_TYPES(FUNCTION)
+FUNCTION(Float32x4, 1)
+FUNCTION(Float32x4, 2)
+FUNCTION(Float32x4, 3)
+FUNCTION(Int32x4, 1)
+FUNCTION(Int32x4, 2)
+FUNCTION(Int32x4, 3)
+FUNCTION(Uint32x4, 1)
+FUNCTION(Uint32x4, 2)
+FUNCTION(Uint32x4, 3)
+endmacro
+
+macro DECLARE_LOADN_STOREN_FUNCTIONS(NAME, COUNT)
+function NAMELoadCOUNTJS(tarray, index) {
+  return %NAMELoadCOUNT(tarray, index);
+}
+
+function NAMEStoreCOUNTJS(tarray, index, a) {
+  return %NAMEStoreCOUNT(tarray, index, a);
+}
+endmacro
+
+SIMD_LOADN_STOREN_TYPES(DECLARE_LOADN_STOREN_FUNCTIONS)
+
+//-------------------------------------------------------------------
+
+macro SIMD_X4_TYPES(FUNCTION)
+FUNCTION(Float32x4)
+FUNCTION(Int32x4)
+FUNCTION(Uint32x4)
+FUNCTION(Bool32x4)
+endmacro
+
+macro DECLARE_X4_FUNCTIONS(NAME)
+function NAMESplat(s) {
+  return %CreateNAME(s, s, s, s);
+}
+
+function NAMESwizzleJS(a, c0, c1, c2, c3) {
+  return %NAMESwizzle(a, c0, c1, c2, c3);
+}
+
+function NAMEShuffleJS(a, b, c0, c1, c2, c3) {
+  return %NAMEShuffle(a, b, c0, c1, c2, c3);
+}
+endmacro
+
+SIMD_X4_TYPES(DECLARE_X4_FUNCTIONS)
+
+macro SIMD_X8_TYPES(FUNCTION)
+FUNCTION(Int16x8)
+FUNCTION(Uint16x8)
+FUNCTION(Bool16x8)
+endmacro
+
+macro DECLARE_X8_FUNCTIONS(NAME)
+function NAMESplat(s) {
+  return %CreateNAME(s, s, s, s, s, s, s, s);
+}
+
+function NAMESwizzleJS(a, c0, c1, c2, c3, c4, c5, c6, c7) {
+  return %NAMESwizzle(a, c0, c1, c2, c3, c4, c5, c6, c7);
+}
+
+function NAMEShuffleJS(a, b, c0, c1, c2, c3, c4, c5, c6, c7) {
+  return %NAMEShuffle(a, b, c0, c1, c2, c3, c4, c5, c6, c7);
+}
+endmacro
+
+SIMD_X8_TYPES(DECLARE_X8_FUNCTIONS)
+
+macro SIMD_X16_TYPES(FUNCTION)
+FUNCTION(Int8x16)
+FUNCTION(Uint8x16)
+FUNCTION(Bool8x16)
+endmacro
+
+macro DECLARE_X16_FUNCTIONS(NAME)
+function NAMESplat(s) {
+  return %CreateNAME(s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s);
+}
+
+function NAMESwizzleJS(a, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11,
+                          c12, c13, c14, c15) {
+  return %NAMESwizzle(a, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11,
+                         c12, c13, c14, c15);
+}
+
+function NAMEShuffleJS(a, b, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10,
+                             c11, c12, c13, c14, c15) {
+  return %NAMEShuffle(a, b, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10,
+                            c11, c12, c13, c14, c15);
+}
+endmacro
+
+SIMD_X16_TYPES(DECLARE_X16_FUNCTIONS)
+
+//-------------------------------------------------------------------
+
+function Float32x4Constructor(c0, c1, c2, c3) {
+  if (!IS_UNDEFINED(new.target)) {
+    throw MakeTypeError(kNotConstructor, "Float32x4");
+  }
+  return %CreateFloat32x4(TO_NUMBER(c0), TO_NUMBER(c1),
+                          TO_NUMBER(c2), TO_NUMBER(c3));
+}
+
+
+function Int32x4Constructor(c0, c1, c2, c3) {
+  if (!IS_UNDEFINED(new.target)) {
+    throw MakeTypeError(kNotConstructor, "Int32x4");
+  }
+  return %CreateInt32x4(TO_NUMBER(c0), TO_NUMBER(c1),
+                        TO_NUMBER(c2), TO_NUMBER(c3));
+}
+
+
+function Uint32x4Constructor(c0, c1, c2, c3) {
+  if (!IS_UNDEFINED(new.target)) {
+    throw MakeTypeError(kNotConstructor, "Uint32x4");
+  }
+  return %CreateUint32x4(TO_NUMBER(c0), TO_NUMBER(c1),
+                         TO_NUMBER(c2), TO_NUMBER(c3));
+}
+
+
+function Bool32x4Constructor(c0, c1, c2, c3) {
+  if (!IS_UNDEFINED(new.target)) {
+    throw MakeTypeError(kNotConstructor, "Bool32x4");
+  }
+  return %CreateBool32x4(c0, c1, c2, c3);
+}
+
+
+function Int16x8Constructor(c0, c1, c2, c3, c4, c5, c6, c7) {
+  if (!IS_UNDEFINED(new.target)) {
+    throw MakeTypeError(kNotConstructor, "Int16x8");
+  }
+  return %CreateInt16x8(TO_NUMBER(c0), TO_NUMBER(c1),
+                        TO_NUMBER(c2), TO_NUMBER(c3),
+                        TO_NUMBER(c4), TO_NUMBER(c5),
+                        TO_NUMBER(c6), TO_NUMBER(c7));
+}
+
+
+function Uint16x8Constructor(c0, c1, c2, c3, c4, c5, c6, c7) {
+  if (!IS_UNDEFINED(new.target)) {
+    throw MakeTypeError(kNotConstructor, "Uint16x8");
+  }
+  return %CreateUint16x8(TO_NUMBER(c0), TO_NUMBER(c1),
+                         TO_NUMBER(c2), TO_NUMBER(c3),
+                         TO_NUMBER(c4), TO_NUMBER(c5),
+                         TO_NUMBER(c6), TO_NUMBER(c7));
+}
+
+
+function Bool16x8Constructor(c0, c1, c2, c3, c4, c5, c6, c7) {
+  if (!IS_UNDEFINED(new.target)) {
+    throw MakeTypeError(kNotConstructor, "Bool16x8");
+  }
+  return %CreateBool16x8(c0, c1, c2, c3, c4, c5, c6, c7);
+}
+
+
+function Int8x16Constructor(c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11,
+                            c12, c13, c14, c15) {
+  if (!IS_UNDEFINED(new.target)) {
+    throw MakeTypeError(kNotConstructor, "Int8x16");
+  }
+  return %CreateInt8x16(TO_NUMBER(c0), TO_NUMBER(c1),
+                        TO_NUMBER(c2), TO_NUMBER(c3),
+                        TO_NUMBER(c4), TO_NUMBER(c5),
+                        TO_NUMBER(c6), TO_NUMBER(c7),
+                        TO_NUMBER(c8), TO_NUMBER(c9),
+                        TO_NUMBER(c10), TO_NUMBER(c11),
+                        TO_NUMBER(c12), TO_NUMBER(c13),
+                        TO_NUMBER(c14), TO_NUMBER(c15));
+}
+
+
+function Uint8x16Constructor(c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11,
+                             c12, c13, c14, c15) {
+  if (!IS_UNDEFINED(new.target)) {
+    throw MakeTypeError(kNotConstructor, "Uint8x16");
+  }
+  return %CreateUint8x16(TO_NUMBER(c0), TO_NUMBER(c1),
+                         TO_NUMBER(c2), TO_NUMBER(c3),
+                         TO_NUMBER(c4), TO_NUMBER(c5),
+                         TO_NUMBER(c6), TO_NUMBER(c7),
+                         TO_NUMBER(c8), TO_NUMBER(c9),
+                         TO_NUMBER(c10), TO_NUMBER(c11),
+                         TO_NUMBER(c12), TO_NUMBER(c13),
+                         TO_NUMBER(c14), TO_NUMBER(c15));
+}
+
+
+function Bool8x16Constructor(c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11,
+                             c12, c13, c14, c15) {
+  if (!IS_UNDEFINED(new.target)) {
+    throw MakeTypeError(kNotConstructor, "Bool8x16");
+  }
+  return %CreateBool8x16(c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12,
+                         c13, c14, c15);
+}
+
+
+function Float32x4AbsJS(a) {
+  return %Float32x4Abs(a);
+}
+
+
+function Float32x4SqrtJS(a) {
+  return %Float32x4Sqrt(a);
+}
+
+
+function Float32x4RecipApproxJS(a) {
+  return %Float32x4RecipApprox(a);
+}
+
+
+function Float32x4RecipSqrtApproxJS(a) {
+  return %Float32x4RecipSqrtApprox(a);
+}
+
+
+function Float32x4DivJS(a, b) {
+  return %Float32x4Div(a, b);
+}
+
+
+function Float32x4MinNumJS(a, b) {
+  return %Float32x4MinNum(a, b);
+}
+
+
+function Float32x4MaxNumJS(a, b) {
+  return %Float32x4MaxNum(a, b);
+}
+
+
+%AddNamedProperty(GlobalSIMD, toStringTagSymbol, 'SIMD', READ_ONLY | DONT_ENUM);
+
+macro SETUP_SIMD_TYPE(NAME, TYPE, LANES)
+%SetCode(GlobalNAME, NAMEConstructor);
+%FunctionSetPrototype(GlobalNAME, {});
+%AddNamedProperty(GlobalNAME.prototype, 'constructor', GlobalNAME,
+    DONT_ENUM);
+%AddNamedProperty(GlobalNAME.prototype, toStringTagSymbol, 'NAME',
+    DONT_ENUM | READ_ONLY);
+utils.InstallFunctions(GlobalNAME.prototype, DONT_ENUM, [
+  'toLocaleString', NAMEToLocaleString,
+  'toString', NAMEToString,
+  'valueOf', NAMEValueOf,
+]);
+endmacro
+
+SIMD_ALL_TYPES(SETUP_SIMD_TYPE)
+
+//-------------------------------------------------------------------
+
+utils.InstallFunctions(GlobalFloat32x4, DONT_ENUM, [
+  'splat', Float32x4Splat,
+  'check', Float32x4CheckJS,
+  'extractLane', Float32x4ExtractLaneJS,
+  'replaceLane', Float32x4ReplaceLaneJS,
+  'neg', Float32x4NegJS,
+  'abs', Float32x4AbsJS,
+  'sqrt', Float32x4SqrtJS,
+  'reciprocalApproximation', Float32x4RecipApproxJS,
+  'reciprocalSqrtApproximation', Float32x4RecipSqrtApproxJS,
+  'add', Float32x4AddJS,
+  'sub', Float32x4SubJS,
+  'mul', Float32x4MulJS,
+  'div', Float32x4DivJS,
+  'min', Float32x4MinJS,
+  'max', Float32x4MaxJS,
+  'minNum', Float32x4MinNumJS,
+  'maxNum', Float32x4MaxNumJS,
+  'lessThan', Float32x4LessThanJS,
+  'lessThanOrEqual', Float32x4LessThanOrEqualJS,
+  'greaterThan', Float32x4GreaterThanJS,
+  'greaterThanOrEqual', Float32x4GreaterThanOrEqualJS,
+  'equal', Float32x4EqualJS,
+  'notEqual', Float32x4NotEqualJS,
+  'select', Float32x4SelectJS,
+  'swizzle', Float32x4SwizzleJS,
+  'shuffle', Float32x4ShuffleJS,
+  'fromInt32x4', Float32x4FromInt32x4JS,
+  'fromUint32x4', Float32x4FromUint32x4JS,
+  'fromInt32x4Bits', Float32x4FromInt32x4BitsJS,
+  'fromUint32x4Bits', Float32x4FromUint32x4BitsJS,
+  'fromInt16x8Bits', Float32x4FromInt16x8BitsJS,
+  'fromUint16x8Bits', Float32x4FromUint16x8BitsJS,
+  'fromInt8x16Bits', Float32x4FromInt8x16BitsJS,
+  'fromUint8x16Bits', Float32x4FromUint8x16BitsJS,
+  'load', Float32x4LoadJS,
+  'load1', Float32x4Load1JS,
+  'load2', Float32x4Load2JS,
+  'load3', Float32x4Load3JS,
+  'store', Float32x4StoreJS,
+  'store1', Float32x4Store1JS,
+  'store2', Float32x4Store2JS,
+  'store3', Float32x4Store3JS,
+]);
+
+utils.InstallFunctions(GlobalInt32x4, DONT_ENUM, [
+  'splat', Int32x4Splat,
+  'check', Int32x4CheckJS,
+  'extractLane', Int32x4ExtractLaneJS,
+  'replaceLane', Int32x4ReplaceLaneJS,
+  'neg', Int32x4NegJS,
+  'add', Int32x4AddJS,
+  'sub', Int32x4SubJS,
+  'mul', Int32x4MulJS,
+  'min', Int32x4MinJS,
+  'max', Int32x4MaxJS,
+  'and', Int32x4AndJS,
+  'or', Int32x4OrJS,
+  'xor', Int32x4XorJS,
+  'not', Int32x4NotJS,
+  'shiftLeftByScalar', Int32x4ShiftLeftByScalarJS,
+  'shiftRightByScalar', Int32x4ShiftRightByScalarJS,
+  'lessThan', Int32x4LessThanJS,
+  'lessThanOrEqual', Int32x4LessThanOrEqualJS,
+  'greaterThan', Int32x4GreaterThanJS,
+  'greaterThanOrEqual', Int32x4GreaterThanOrEqualJS,
+  'equal', Int32x4EqualJS,
+  'notEqual', Int32x4NotEqualJS,
+  'select', Int32x4SelectJS,
+  'swizzle', Int32x4SwizzleJS,
+  'shuffle', Int32x4ShuffleJS,
+  'fromFloat32x4', Int32x4FromFloat32x4JS,
+  'fromUint32x4', Int32x4FromUint32x4JS,
+  'fromFloat32x4Bits', Int32x4FromFloat32x4BitsJS,
+  'fromUint32x4Bits', Int32x4FromUint32x4BitsJS,
+  'fromInt16x8Bits', Int32x4FromInt16x8BitsJS,
+  'fromUint16x8Bits', Int32x4FromUint16x8BitsJS,
+  'fromInt8x16Bits', Int32x4FromInt8x16BitsJS,
+  'fromUint8x16Bits', Int32x4FromUint8x16BitsJS,
+  'load', Int32x4LoadJS,
+  'load1', Int32x4Load1JS,
+  'load2', Int32x4Load2JS,
+  'load3', Int32x4Load3JS,
+  'store', Int32x4StoreJS,
+  'store1', Int32x4Store1JS,
+  'store2', Int32x4Store2JS,
+  'store3', Int32x4Store3JS,
+]);
+
+utils.InstallFunctions(GlobalUint32x4, DONT_ENUM, [
+  'splat', Uint32x4Splat,
+  'check', Uint32x4CheckJS,
+  'extractLane', Uint32x4ExtractLaneJS,
+  'replaceLane', Uint32x4ReplaceLaneJS,
+  'add', Uint32x4AddJS,
+  'sub', Uint32x4SubJS,
+  'mul', Uint32x4MulJS,
+  'min', Uint32x4MinJS,
+  'max', Uint32x4MaxJS,
+  'and', Uint32x4AndJS,
+  'or', Uint32x4OrJS,
+  'xor', Uint32x4XorJS,
+  'not', Uint32x4NotJS,
+  'shiftLeftByScalar', Uint32x4ShiftLeftByScalarJS,
+  'shiftRightByScalar', Uint32x4ShiftRightByScalarJS,
+  'lessThan', Uint32x4LessThanJS,
+  'lessThanOrEqual', Uint32x4LessThanOrEqualJS,
+  'greaterThan', Uint32x4GreaterThanJS,
+  'greaterThanOrEqual', Uint32x4GreaterThanOrEqualJS,
+  'equal', Uint32x4EqualJS,
+  'notEqual', Uint32x4NotEqualJS,
+  'select', Uint32x4SelectJS,
+  'swizzle', Uint32x4SwizzleJS,
+  'shuffle', Uint32x4ShuffleJS,
+  'fromFloat32x4', Uint32x4FromFloat32x4JS,
+  'fromInt32x4', Uint32x4FromInt32x4JS,
+  'fromFloat32x4Bits', Uint32x4FromFloat32x4BitsJS,
+  'fromInt32x4Bits', Uint32x4FromInt32x4BitsJS,
+  'fromInt16x8Bits', Uint32x4FromInt16x8BitsJS,
+  'fromUint16x8Bits', Uint32x4FromUint16x8BitsJS,
+  'fromInt8x16Bits', Uint32x4FromInt8x16BitsJS,
+  'fromUint8x16Bits', Uint32x4FromUint8x16BitsJS,
+  'load', Uint32x4LoadJS,
+  'load1', Uint32x4Load1JS,
+  'load2', Uint32x4Load2JS,
+  'load3', Uint32x4Load3JS,
+  'store', Uint32x4StoreJS,
+  'store1', Uint32x4Store1JS,
+  'store2', Uint32x4Store2JS,
+  'store3', Uint32x4Store3JS,
+]);
+
+utils.InstallFunctions(GlobalBool32x4, DONT_ENUM, [
+  'splat', Bool32x4Splat,
+  'check', Bool32x4CheckJS,
+  'extractLane', Bool32x4ExtractLaneJS,
+  'replaceLane', Bool32x4ReplaceLaneJS,
+  'and', Bool32x4AndJS,
+  'or', Bool32x4OrJS,
+  'xor', Bool32x4XorJS,
+  'not', Bool32x4NotJS,
+  'anyTrue', Bool32x4AnyTrueJS,
+  'allTrue', Bool32x4AllTrueJS,
+  'swizzle', Bool32x4SwizzleJS,
+  'shuffle', Bool32x4ShuffleJS,
+]);
+
+utils.InstallFunctions(GlobalInt16x8, DONT_ENUM, [
+  'splat', Int16x8Splat,
+  'check', Int16x8CheckJS,
+  'extractLane', Int16x8ExtractLaneJS,
+  'replaceLane', Int16x8ReplaceLaneJS,
+  'neg', Int16x8NegJS,
+  'add', Int16x8AddJS,
+  'sub', Int16x8SubJS,
+  'addSaturate', Int16x8AddSaturateJS,
+  'subSaturate', Int16x8SubSaturateJS,
+  'mul', Int16x8MulJS,
+  'min', Int16x8MinJS,
+  'max', Int16x8MaxJS,
+  'and', Int16x8AndJS,
+  'or', Int16x8OrJS,
+  'xor', Int16x8XorJS,
+  'not', Int16x8NotJS,
+  'shiftLeftByScalar', Int16x8ShiftLeftByScalarJS,
+  'shiftRightByScalar', Int16x8ShiftRightByScalarJS,
+  'lessThan', Int16x8LessThanJS,
+  'lessThanOrEqual', Int16x8LessThanOrEqualJS,
+  'greaterThan', Int16x8GreaterThanJS,
+  'greaterThanOrEqual', Int16x8GreaterThanOrEqualJS,
+  'equal', Int16x8EqualJS,
+  'notEqual', Int16x8NotEqualJS,
+  'select', Int16x8SelectJS,
+  'swizzle', Int16x8SwizzleJS,
+  'shuffle', Int16x8ShuffleJS,
+  'fromUint16x8', Int16x8FromUint16x8JS,
+  'fromFloat32x4Bits', Int16x8FromFloat32x4BitsJS,
+  'fromInt32x4Bits', Int16x8FromInt32x4BitsJS,
+  'fromUint32x4Bits', Int16x8FromUint32x4BitsJS,
+  'fromUint16x8Bits', Int16x8FromUint16x8BitsJS,
+  'fromInt8x16Bits', Int16x8FromInt8x16BitsJS,
+  'fromUint8x16Bits', Int16x8FromUint8x16BitsJS,
+  'load', Int16x8LoadJS,
+  'store', Int16x8StoreJS,
+]);
+
+utils.InstallFunctions(GlobalUint16x8, DONT_ENUM, [
+  'splat', Uint16x8Splat,
+  'check', Uint16x8CheckJS,
+  'extractLane', Uint16x8ExtractLaneJS,
+  'replaceLane', Uint16x8ReplaceLaneJS,
+  'add', Uint16x8AddJS,
+  'sub', Uint16x8SubJS,
+  'addSaturate', Uint16x8AddSaturateJS,
+  'subSaturate', Uint16x8SubSaturateJS,
+  'mul', Uint16x8MulJS,
+  'min', Uint16x8MinJS,
+  'max', Uint16x8MaxJS,
+  'and', Uint16x8AndJS,
+  'or', Uint16x8OrJS,
+  'xor', Uint16x8XorJS,
+  'not', Uint16x8NotJS,
+  'shiftLeftByScalar', Uint16x8ShiftLeftByScalarJS,
+  'shiftRightByScalar', Uint16x8ShiftRightByScalarJS,
+  'lessThan', Uint16x8LessThanJS,
+  'lessThanOrEqual', Uint16x8LessThanOrEqualJS,
+  'greaterThan', Uint16x8GreaterThanJS,
+  'greaterThanOrEqual', Uint16x8GreaterThanOrEqualJS,
+  'equal', Uint16x8EqualJS,
+  'notEqual', Uint16x8NotEqualJS,
+  'select', Uint16x8SelectJS,
+  'swizzle', Uint16x8SwizzleJS,
+  'shuffle', Uint16x8ShuffleJS,
+  'fromInt16x8', Uint16x8FromInt16x8JS,
+  'fromFloat32x4Bits', Uint16x8FromFloat32x4BitsJS,
+  'fromInt32x4Bits', Uint16x8FromInt32x4BitsJS,
+  'fromUint32x4Bits', Uint16x8FromUint32x4BitsJS,
+  'fromInt16x8Bits', Uint16x8FromInt16x8BitsJS,
+  'fromInt8x16Bits', Uint16x8FromInt8x16BitsJS,
+  'fromUint8x16Bits', Uint16x8FromUint8x16BitsJS,
+  'load', Uint16x8LoadJS,
+  'store', Uint16x8StoreJS,
+]);
+
+utils.InstallFunctions(GlobalBool16x8, DONT_ENUM, [
+  'splat', Bool16x8Splat,
+  'check', Bool16x8CheckJS,
+  'extractLane', Bool16x8ExtractLaneJS,
+  'replaceLane', Bool16x8ReplaceLaneJS,
+  'and', Bool16x8AndJS,
+  'or', Bool16x8OrJS,
+  'xor', Bool16x8XorJS,
+  'not', Bool16x8NotJS,
+  'anyTrue', Bool16x8AnyTrueJS,
+  'allTrue', Bool16x8AllTrueJS,
+  'swizzle', Bool16x8SwizzleJS,
+  'shuffle', Bool16x8ShuffleJS,
+]);
+
+utils.InstallFunctions(GlobalInt8x16, DONT_ENUM, [
+  'splat', Int8x16Splat,
+  'check', Int8x16CheckJS,
+  'extractLane', Int8x16ExtractLaneJS,
+  'replaceLane', Int8x16ReplaceLaneJS,
+  'neg', Int8x16NegJS,
+  'add', Int8x16AddJS,
+  'sub', Int8x16SubJS,
+  'addSaturate', Int8x16AddSaturateJS,
+  'subSaturate', Int8x16SubSaturateJS,
+  'mul', Int8x16MulJS,
+  'min', Int8x16MinJS,
+  'max', Int8x16MaxJS,
+  'and', Int8x16AndJS,
+  'or', Int8x16OrJS,
+  'xor', Int8x16XorJS,
+  'not', Int8x16NotJS,
+  'shiftLeftByScalar', Int8x16ShiftLeftByScalarJS,
+  'shiftRightByScalar', Int8x16ShiftRightByScalarJS,
+  'lessThan', Int8x16LessThanJS,
+  'lessThanOrEqual', Int8x16LessThanOrEqualJS,
+  'greaterThan', Int8x16GreaterThanJS,
+  'greaterThanOrEqual', Int8x16GreaterThanOrEqualJS,
+  'equal', Int8x16EqualJS,
+  'notEqual', Int8x16NotEqualJS,
+  'select', Int8x16SelectJS,
+  'swizzle', Int8x16SwizzleJS,
+  'shuffle', Int8x16ShuffleJS,
+  'fromUint8x16', Int8x16FromUint8x16JS,
+  'fromFloat32x4Bits', Int8x16FromFloat32x4BitsJS,
+  'fromInt32x4Bits', Int8x16FromInt32x4BitsJS,
+  'fromUint32x4Bits', Int8x16FromUint32x4BitsJS,
+  'fromInt16x8Bits', Int8x16FromInt16x8BitsJS,
+  'fromUint16x8Bits', Int8x16FromUint16x8BitsJS,
+  'fromUint8x16Bits', Int8x16FromUint8x16BitsJS,
+  'load', Int8x16LoadJS,
+  'store', Int8x16StoreJS,
+]);
+
+utils.InstallFunctions(GlobalUint8x16, DONT_ENUM, [
+  'splat', Uint8x16Splat,
+  'check', Uint8x16CheckJS,
+  'extractLane', Uint8x16ExtractLaneJS,
+  'replaceLane', Uint8x16ReplaceLaneJS,
+  'add', Uint8x16AddJS,
+  'sub', Uint8x16SubJS,
+  'addSaturate', Uint8x16AddSaturateJS,
+  'subSaturate', Uint8x16SubSaturateJS,
+  'mul', Uint8x16MulJS,
+  'min', Uint8x16MinJS,
+  'max', Uint8x16MaxJS,
+  'and', Uint8x16AndJS,
+  'or', Uint8x16OrJS,
+  'xor', Uint8x16XorJS,
+  'not', Uint8x16NotJS,
+  'shiftLeftByScalar', Uint8x16ShiftLeftByScalarJS,
+  'shiftRightByScalar', Uint8x16ShiftRightByScalarJS,
+  'lessThan', Uint8x16LessThanJS,
+  'lessThanOrEqual', Uint8x16LessThanOrEqualJS,
+  'greaterThan', Uint8x16GreaterThanJS,
+  'greaterThanOrEqual', Uint8x16GreaterThanOrEqualJS,
+  'equal', Uint8x16EqualJS,
+  'notEqual', Uint8x16NotEqualJS,
+  'select', Uint8x16SelectJS,
+  'swizzle', Uint8x16SwizzleJS,
+  'shuffle', Uint8x16ShuffleJS,
+  'fromInt8x16', Uint8x16FromInt8x16JS,
+  'fromFloat32x4Bits', Uint8x16FromFloat32x4BitsJS,
+  'fromInt32x4Bits', Uint8x16FromInt32x4BitsJS,
+  'fromUint32x4Bits', Uint8x16FromUint32x4BitsJS,
+  'fromInt16x8Bits', Uint8x16FromInt16x8BitsJS,
+  'fromUint16x8Bits', Uint8x16FromUint16x8BitsJS,
+  'fromInt8x16Bits', Uint8x16FromInt8x16BitsJS,
+  'load', Uint8x16LoadJS,
+  'store', Uint8x16StoreJS,
+]);
+
+utils.InstallFunctions(GlobalBool8x16, DONT_ENUM, [
+  'splat', Bool8x16Splat,
+  'check', Bool8x16CheckJS,
+  'extractLane', Bool8x16ExtractLaneJS,
+  'replaceLane', Bool8x16ReplaceLaneJS,
+  'and', Bool8x16AndJS,
+  'or', Bool8x16OrJS,
+  'xor', Bool8x16XorJS,
+  'not', Bool8x16NotJS,
+  'anyTrue', Bool8x16AnyTrueJS,
+  'allTrue', Bool8x16AllTrueJS,
+  'swizzle', Bool8x16SwizzleJS,
+  'shuffle', Bool8x16ShuffleJS,
+]);
+
+utils.Export(function(to) {
+  to.Float32x4ToString = Float32x4ToString;
+  to.Int32x4ToString = Int32x4ToString;
+  to.Uint32x4ToString = Uint32x4ToString;
+  to.Bool32x4ToString = Bool32x4ToString;
+  to.Int16x8ToString = Int16x8ToString;
+  to.Uint16x8ToString = Uint16x8ToString;
+  to.Bool16x8ToString = Bool16x8ToString;
+  to.Int8x16ToString = Int8x16ToString;
+  to.Uint8x16ToString = Uint8x16ToString;
+  to.Bool8x16ToString = Bool8x16ToString;
+});
+
+})
diff --git a/src/js/harmony-species.js b/src/js/harmony-species.js
new file mode 100644
index 0000000..426ac46
--- /dev/null
+++ b/src/js/harmony-species.js
@@ -0,0 +1,60 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function(global, utils, extrasUtils) {
+
+"use strict";
+
+%CheckIsBootstrapping();
+
+var GlobalArray = global.Array;
+// It is important that this file is run after src/js/typedarray.js,
+// otherwise GlobalTypedArray would be Object, and we would break
+// old versions of Zepto.
+var GlobalTypedArray = global.Uint8Array.__proto__;
+var GlobalMap = global.Map;
+var GlobalSet = global.Set;
+var GlobalArrayBuffer = global.ArrayBuffer;
+var GlobalPromise = global.Promise;
+var GlobalRegExp = global.RegExp;
+var speciesSymbol = utils.ImportNow("species_symbol");
+
+function ArraySpecies() {
+  return this;
+}
+
+function TypedArraySpecies() {
+  return this;
+}
+
+function MapSpecies() {
+  return this;
+}
+
+function SetSpecies() {
+  return this;
+}
+
+function ArrayBufferSpecies() {
+  return this;
+}
+
+function PromiseSpecies() {
+  return this;
+}
+
+function RegExpSpecies() {
+  return this;
+}
+
+utils.InstallGetter(GlobalArray, speciesSymbol, ArraySpecies, DONT_ENUM);
+utils.InstallGetter(GlobalTypedArray, speciesSymbol, TypedArraySpecies, DONT_ENUM);
+utils.InstallGetter(GlobalMap, speciesSymbol, MapSpecies, DONT_ENUM);
+utils.InstallGetter(GlobalSet, speciesSymbol, SetSpecies, DONT_ENUM);
+utils.InstallGetter(GlobalArrayBuffer, speciesSymbol, ArrayBufferSpecies,
+                    DONT_ENUM);
+utils.InstallGetter(GlobalPromise, speciesSymbol, PromiseSpecies, DONT_ENUM);
+utils.InstallGetter(GlobalRegExp, speciesSymbol, RegExpSpecies, DONT_ENUM);
+
+});
diff --git a/src/js/harmony-unicode-regexps.js b/src/js/harmony-unicode-regexps.js
new file mode 100644
index 0000000..b24bbdf
--- /dev/null
+++ b/src/js/harmony-unicode-regexps.js
@@ -0,0 +1,41 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function(global, utils) {
+
+'use strict';
+
+%CheckIsBootstrapping();
+
+// -------------------------------------------------------------------
+// Imports
+
+var GlobalRegExp = global.RegExp;
+var GlobalRegExpPrototype = GlobalRegExp.prototype;
+var MakeTypeError;
+
+utils.Import(function(from) {
+  MakeTypeError = from.MakeTypeError;
+});
+
+// -------------------------------------------------------------------
+
+// ES6 21.2.5.15.
+function RegExpGetUnicode() {
+  if (!IS_REGEXP(this)) {
+    // TODO(littledan): Remove this RegExp compat workaround
+    if (this === GlobalRegExpPrototype) {
+      %IncrementUseCounter(kRegExpPrototypeUnicodeGetter);
+      return UNDEFINED;
+    }
+    throw MakeTypeError(kRegExpNonRegExp, "RegExp.prototype.unicode");
+  }
+  return !!REGEXP_UNICODE(this);
+}
+%FunctionSetName(RegExpGetUnicode, "RegExp.prototype.unicode");
+%SetNativeFlag(RegExpGetUnicode);
+
+utils.InstallGetter(GlobalRegExp.prototype, 'unicode', RegExpGetUnicode);
+
+})
diff --git a/src/js/i18n.js b/src/js/i18n.js
new file mode 100644
index 0000000..7e00fcd
--- /dev/null
+++ b/src/js/i18n.js
@@ -0,0 +1,2197 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// ECMAScript 402 API implementation.
+
+/**
+ * Intl object is a single object that has some named properties,
+ * all of which are constructors.
+ */
+(function(global, utils) {
+
+"use strict";
+
+%CheckIsBootstrapping();
+
+// -------------------------------------------------------------------
+// Imports
+
+var ArrayIndexOf;
+var ArrayJoin;
+var ArrayPush;
+var IsFinite;
+var IsNaN;
+var GlobalBoolean = global.Boolean;
+var GlobalDate = global.Date;
+var GlobalNumber = global.Number;
+var GlobalRegExp = global.RegExp;
+var GlobalString = global.String;
+var MakeError;
+var MakeRangeError;
+var MakeTypeError;
+var MathFloor;
+var ObjectDefineProperties = utils.ImportNow("ObjectDefineProperties");
+var ObjectDefineProperty = utils.ImportNow("ObjectDefineProperty");
+var patternSymbol = utils.ImportNow("intl_pattern_symbol");
+var RegExpTest;
+var resolvedSymbol = utils.ImportNow("intl_resolved_symbol");
+var StringIndexOf;
+var StringLastIndexOf;
+var StringMatch;
+var StringReplace;
+var StringSplit;
+var StringSubstr;
+var StringSubstring;
+
+utils.Import(function(from) {
+  ArrayIndexOf = from.ArrayIndexOf;
+  ArrayJoin = from.ArrayJoin;
+  ArrayPush = from.ArrayPush;
+  IsFinite = from.IsFinite;
+  IsNaN = from.IsNaN;
+  MakeError = from.MakeError;
+  MakeRangeError = from.MakeRangeError;
+  MakeTypeError = from.MakeTypeError;
+  MathFloor = from.MathFloor;
+  RegExpTest = from.RegExpTest;
+  StringIndexOf = from.StringIndexOf;
+  StringLastIndexOf = from.StringLastIndexOf;
+  StringMatch = from.StringMatch;
+  StringReplace = from.StringReplace;
+  StringSplit = from.StringSplit;
+  StringSubstr = from.StringSubstr;
+  StringSubstring = from.StringSubstring;
+});
+
+// -------------------------------------------------------------------
+
+var Intl = {};
+
+%AddNamedProperty(global, "Intl", Intl, DONT_ENUM);
+
+/**
+ * Caches available locales for each service.
+ */
+var AVAILABLE_LOCALES = {
+  'collator': UNDEFINED,
+  'numberformat': UNDEFINED,
+  'dateformat': UNDEFINED,
+  'breakiterator': UNDEFINED
+};
+
+/**
+ * Caches default ICU locale.
+ */
+var DEFAULT_ICU_LOCALE = UNDEFINED;
+
+/**
+ * Unicode extension regular expression.
+ */
+var UNICODE_EXTENSION_RE = UNDEFINED;
+
+function GetUnicodeExtensionRE() {
+  if (IS_UNDEFINED(UNDEFINED)) {
+    UNICODE_EXTENSION_RE = new GlobalRegExp('-u(-[a-z0-9]{2,8})+', 'g');
+  }
+  return UNICODE_EXTENSION_RE;
+}
+
+/**
+ * Matches any Unicode extension.
+ */
+var ANY_EXTENSION_RE = UNDEFINED;
+
+function GetAnyExtensionRE() {
+  if (IS_UNDEFINED(ANY_EXTENSION_RE)) {
+    ANY_EXTENSION_RE = new GlobalRegExp('-[a-z0-9]{1}-.*', 'g');
+  }
+  return ANY_EXTENSION_RE;
+}
+
+/**
+ * Replace quoted text (single quote, anything but the quote and quote again).
+ */
+var QUOTED_STRING_RE = UNDEFINED;
+
+function GetQuotedStringRE() {
+  if (IS_UNDEFINED(QUOTED_STRING_RE)) {
+    QUOTED_STRING_RE = new GlobalRegExp("'[^']+'", 'g');
+  }
+  return QUOTED_STRING_RE;
+}
+
+/**
+ * Matches valid service name.
+ */
+var SERVICE_RE = UNDEFINED;
+
+function GetServiceRE() {
+  if (IS_UNDEFINED(SERVICE_RE)) {
+    SERVICE_RE =
+        new GlobalRegExp('^(collator|numberformat|dateformat|breakiterator)$');
+  }
+  return SERVICE_RE;
+}
+
+/**
+ * Validates a language tag against bcp47 spec.
+ * Actual value is assigned on first run.
+ */
+var LANGUAGE_TAG_RE = UNDEFINED;
+
+function GetLanguageTagRE() {
+  if (IS_UNDEFINED(LANGUAGE_TAG_RE)) {
+    BuildLanguageTagREs();
+  }
+  return LANGUAGE_TAG_RE;
+}
+
+/**
+ * Helps find duplicate variants in the language tag.
+ */
+var LANGUAGE_VARIANT_RE = UNDEFINED;
+
+function GetLanguageVariantRE() {
+  if (IS_UNDEFINED(LANGUAGE_VARIANT_RE)) {
+    BuildLanguageTagREs();
+  }
+  return LANGUAGE_VARIANT_RE;
+}
+
+/**
+ * Helps find duplicate singletons in the language tag.
+ */
+var LANGUAGE_SINGLETON_RE = UNDEFINED;
+
+function GetLanguageSingletonRE() {
+  if (IS_UNDEFINED(LANGUAGE_SINGLETON_RE)) {
+    BuildLanguageTagREs();
+  }
+  return LANGUAGE_SINGLETON_RE;
+}
+
+/**
+ * Matches valid IANA time zone names.
+ */
+var TIMEZONE_NAME_CHECK_RE = UNDEFINED;
+
+function GetTimezoneNameCheckRE() {
+  if (IS_UNDEFINED(TIMEZONE_NAME_CHECK_RE)) {
+    TIMEZONE_NAME_CHECK_RE = new GlobalRegExp(
+        '^([A-Za-z]+)/([A-Za-z_-]+)((?:\/[A-Za-z_-]+)+)*$');
+  }
+  return TIMEZONE_NAME_CHECK_RE;
+}
+
+/**
+ * Matches valid location parts of IANA time zone names.
+ */
+var TIMEZONE_NAME_LOCATION_PART_RE = UNDEFINED;
+
+function GetTimezoneNameLocationPartRE() {
+  if (IS_UNDEFINED(TIMEZONE_NAME_LOCATION_PART_RE)) {
+    TIMEZONE_NAME_LOCATION_PART_RE =
+        new GlobalRegExp('^([A-Za-z]+)((?:[_-][A-Za-z]+)+)*$');
+  }
+  return TIMEZONE_NAME_LOCATION_PART_RE;
+}
+
+/**
+ * Adds bound method to the prototype of the given object.
+ */
+function addBoundMethod(obj, methodName, implementation, length) {
+  %CheckIsBootstrapping();
+  function getter() {
+    if (!%IsInitializedIntlObject(this)) {
+      throw MakeTypeError(kMethodCalledOnWrongObject, methodName);
+    }
+    var internalName = '__bound' + methodName + '__';
+    if (IS_UNDEFINED(this[internalName])) {
+      var that = this;
+      var boundMethod;
+      if (IS_UNDEFINED(length) || length === 2) {
+        boundMethod = function(x, y) {
+          if (!IS_UNDEFINED(new.target)) {
+            throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
+          }
+          return implementation(that, x, y);
+        }
+      } else if (length === 1) {
+        boundMethod = function(x) {
+          if (!IS_UNDEFINED(new.target)) {
+            throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
+          }
+          return implementation(that, x);
+        }
+      } else {
+        boundMethod = function() {
+          if (!IS_UNDEFINED(new.target)) {
+            throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
+          }
+          // DateTimeFormat.format needs to be 0 arg method, but can stil
+          // receive optional dateValue param. If one was provided, pass it
+          // along.
+          if (%_ArgumentsLength() > 0) {
+            return implementation(that, %_Arguments(0));
+          } else {
+            return implementation(that);
+          }
+        }
+      }
+      %FunctionSetName(boundMethod, internalName);
+      %FunctionRemovePrototype(boundMethod);
+      %SetNativeFlag(boundMethod);
+      this[internalName] = boundMethod;
+    }
+    return this[internalName];
+  }
+
+  %FunctionSetName(getter, methodName);
+  %FunctionRemovePrototype(getter);
+  %SetNativeFlag(getter);
+
+  ObjectDefineProperty(obj.prototype, methodName, {
+    get: getter,
+    enumerable: false,
+    configurable: true
+  });
+}
+
+
+/**
+ * Returns an intersection of locales and service supported locales.
+ * Parameter locales is treated as a priority list.
+ */
+function supportedLocalesOf(service, locales, options) {
+  if (IS_NULL(%_Call(StringMatch, service, GetServiceRE()))) {
+    throw MakeError(kWrongServiceType, service);
+  }
+
+  // Provide defaults if matcher was not specified.
+  if (IS_UNDEFINED(options)) {
+    options = {};
+  } else {
+    options = TO_OBJECT(options);
+  }
+
+  var matcher = options.localeMatcher;
+  if (!IS_UNDEFINED(matcher)) {
+    matcher = GlobalString(matcher);
+    if (matcher !== 'lookup' && matcher !== 'best fit') {
+      throw MakeRangeError(kLocaleMatcher, matcher);
+    }
+  } else {
+    matcher = 'best fit';
+  }
+
+  var requestedLocales = initializeLocaleList(locales);
+
+  // Cache these, they don't ever change per service.
+  if (IS_UNDEFINED(AVAILABLE_LOCALES[service])) {
+    AVAILABLE_LOCALES[service] = getAvailableLocalesOf(service);
+  }
+
+  // Use either best fit or lookup algorithm to match locales.
+  if (matcher === 'best fit') {
+    return initializeLocaleList(bestFitSupportedLocalesOf(
+        requestedLocales, AVAILABLE_LOCALES[service]));
+  }
+
+  return initializeLocaleList(lookupSupportedLocalesOf(
+      requestedLocales, AVAILABLE_LOCALES[service]));
+}
+
+
+/**
+ * Returns the subset of the provided BCP 47 language priority list for which
+ * this service has a matching locale when using the BCP 47 Lookup algorithm.
+ * Locales appear in the same order in the returned list as in the input list.
+ */
+function lookupSupportedLocalesOf(requestedLocales, availableLocales) {
+  var matchedLocales = [];
+  for (var i = 0; i < requestedLocales.length; ++i) {
+    // Remove -u- extension.
+    var locale = %_Call(StringReplace,
+                        requestedLocales[i],
+                        GetUnicodeExtensionRE(),
+                        '');
+    do {
+      if (!IS_UNDEFINED(availableLocales[locale])) {
+        // Push requested locale not the resolved one.
+        %_Call(ArrayPush, matchedLocales, requestedLocales[i]);
+        break;
+      }
+      // Truncate locale if possible, if not break.
+      var pos = %_Call(StringLastIndexOf, locale, '-');
+      if (pos === -1) {
+        break;
+      }
+      locale = %_Call(StringSubstring, locale, 0, pos);
+    } while (true);
+  }
+
+  return matchedLocales;
+}
+
+
+/**
+ * Returns the subset of the provided BCP 47 language priority list for which
+ * this service has a matching locale when using the implementation
+ * dependent algorithm.
+ * Locales appear in the same order in the returned list as in the input list.
+ */
+function bestFitSupportedLocalesOf(requestedLocales, availableLocales) {
+  // TODO(cira): implement better best fit algorithm.
+  return lookupSupportedLocalesOf(requestedLocales, availableLocales);
+}
+
+
+/**
+ * Returns a getOption function that extracts property value for given
+ * options object. If property is missing it returns defaultValue. If value
+ * is out of range for that property it throws RangeError.
+ */
+function getGetOption(options, caller) {
+  if (IS_UNDEFINED(options)) throw MakeError(kDefaultOptionsMissing, caller);
+
+  var getOption = function getOption(property, type, values, defaultValue) {
+    if (!IS_UNDEFINED(options[property])) {
+      var value = options[property];
+      switch (type) {
+        case 'boolean':
+          value = GlobalBoolean(value);
+          break;
+        case 'string':
+          value = GlobalString(value);
+          break;
+        case 'number':
+          value = GlobalNumber(value);
+          break;
+        default:
+          throw MakeError(kWrongValueType);
+      }
+
+      if (!IS_UNDEFINED(values) && %_Call(ArrayIndexOf, values, value) === -1) {
+        throw MakeRangeError(kValueOutOfRange, value, caller, property);
+      }
+
+      return value;
+    }
+
+    return defaultValue;
+  }
+
+  return getOption;
+}
+
+
+/**
+ * Compares a BCP 47 language priority list requestedLocales against the locales
+ * in availableLocales and determines the best available language to meet the
+ * request. Two algorithms are available to match the locales: the Lookup
+ * algorithm described in RFC 4647 section 3.4, and an implementation dependent
+ * best-fit algorithm. Independent of the locale matching algorithm, options
+ * specified through Unicode locale extension sequences are negotiated
+ * separately, taking the caller's relevant extension keys and locale data as
+ * well as client-provided options into consideration. Returns an object with
+ * a locale property whose value is the language tag of the selected locale,
+ * and properties for each key in relevantExtensionKeys providing the selected
+ * value for that key.
+ */
+function resolveLocale(service, requestedLocales, options) {
+  requestedLocales = initializeLocaleList(requestedLocales);
+
+  var getOption = getGetOption(options, service);
+  var matcher = getOption('localeMatcher', 'string',
+                          ['lookup', 'best fit'], 'best fit');
+  var resolved;
+  if (matcher === 'lookup') {
+    resolved = lookupMatcher(service, requestedLocales);
+  } else {
+    resolved = bestFitMatcher(service, requestedLocales);
+  }
+
+  return resolved;
+}
+
+
+/**
+ * Returns best matched supported locale and extension info using basic
+ * lookup algorithm.
+ */
+function lookupMatcher(service, requestedLocales) {
+  if (IS_NULL(%_Call(StringMatch, service, GetServiceRE()))) {
+    throw MakeError(kWrongServiceType, service);
+  }
+
+  // Cache these, they don't ever change per service.
+  if (IS_UNDEFINED(AVAILABLE_LOCALES[service])) {
+    AVAILABLE_LOCALES[service] = getAvailableLocalesOf(service);
+  }
+
+  for (var i = 0; i < requestedLocales.length; ++i) {
+    // Remove all extensions.
+    var locale = %_Call(StringReplace, requestedLocales[i],
+                        GetAnyExtensionRE(), '');
+    do {
+      if (!IS_UNDEFINED(AVAILABLE_LOCALES[service][locale])) {
+        // Return the resolved locale and extension.
+        var extensionMatch =
+            %_Call(StringMatch, requestedLocales[i], GetUnicodeExtensionRE());
+        var extension = IS_NULL(extensionMatch) ? '' : extensionMatch[0];
+        return {'locale': locale, 'extension': extension, 'position': i};
+      }
+      // Truncate locale if possible.
+      var pos = %_Call(StringLastIndexOf, locale, '-');
+      if (pos === -1) {
+        break;
+      }
+      locale = %_Call(StringSubstring, locale, 0, pos);
+    } while (true);
+  }
+
+  // Didn't find a match, return default.
+  if (IS_UNDEFINED(DEFAULT_ICU_LOCALE)) {
+    DEFAULT_ICU_LOCALE = %GetDefaultICULocale();
+  }
+
+  return {'locale': DEFAULT_ICU_LOCALE, 'extension': '', 'position': -1};
+}
+
+
+/**
+ * Returns best matched supported locale and extension info using
+ * implementation dependend algorithm.
+ */
+function bestFitMatcher(service, requestedLocales) {
+  // TODO(cira): implement better best fit algorithm.
+  return lookupMatcher(service, requestedLocales);
+}
+
+
+/**
+ * Parses Unicode extension into key - value map.
+ * Returns empty object if the extension string is invalid.
+ * We are not concerned with the validity of the values at this point.
+ */
+function parseExtension(extension) {
+  var extensionSplit = %_Call(StringSplit, extension, '-');
+
+  // Assume ['', 'u', ...] input, but don't throw.
+  if (extensionSplit.length <= 2 ||
+      (extensionSplit[0] !== '' && extensionSplit[1] !== 'u')) {
+    return {};
+  }
+
+  // Key is {2}alphanum, value is {3,8}alphanum.
+  // Some keys may not have explicit values (booleans).
+  var extensionMap = {};
+  var previousKey = UNDEFINED;
+  for (var i = 2; i < extensionSplit.length; ++i) {
+    var length = extensionSplit[i].length;
+    var element = extensionSplit[i];
+    if (length === 2) {
+      extensionMap[element] = UNDEFINED;
+      previousKey = element;
+    } else if (length >= 3 && length <=8 && !IS_UNDEFINED(previousKey)) {
+      extensionMap[previousKey] = element;
+      previousKey = UNDEFINED;
+    } else {
+      // There is a value that's too long, or that doesn't have a key.
+      return {};
+    }
+  }
+
+  return extensionMap;
+}
+
+
+/**
+ * Populates internalOptions object with boolean key-value pairs
+ * from extensionMap and options.
+ * Returns filtered extension (number and date format constructors use
+ * Unicode extensions for passing parameters to ICU).
+ * It's used for extension-option pairs only, e.g. kn-normalization, but not
+ * for 'sensitivity' since it doesn't have extension equivalent.
+ * Extensions like nu and ca don't have options equivalent, so we place
+ * undefined in the map.property to denote that.
+ */
+function setOptions(inOptions, extensionMap, keyValues, getOption, outOptions) {
+  var extension = '';
+
+  var updateExtension = function updateExtension(key, value) {
+    return '-' + key + '-' + GlobalString(value);
+  }
+
+  var updateProperty = function updateProperty(property, type, value) {
+    if (type === 'boolean' && (typeof value === 'string')) {
+      value = (value === 'true') ? true : false;
+    }
+
+    if (!IS_UNDEFINED(property)) {
+      defineWEProperty(outOptions, property, value);
+    }
+  }
+
+  for (var key in keyValues) {
+    if (%HasOwnProperty(keyValues, key)) {
+      var value = UNDEFINED;
+      var map = keyValues[key];
+      if (!IS_UNDEFINED(map.property)) {
+        // This may return true if user specifies numeric: 'false', since
+        // Boolean('nonempty') === true.
+        value = getOption(map.property, map.type, map.values);
+      }
+      if (!IS_UNDEFINED(value)) {
+        updateProperty(map.property, map.type, value);
+        extension += updateExtension(key, value);
+        continue;
+      }
+      // User options didn't have it, check Unicode extension.
+      // Here we want to convert strings 'true', 'false' into proper Boolean
+      // values (not a user error).
+      if (%HasOwnProperty(extensionMap, key)) {
+        value = extensionMap[key];
+        if (!IS_UNDEFINED(value)) {
+          updateProperty(map.property, map.type, value);
+          extension += updateExtension(key, value);
+        } else if (map.type === 'boolean') {
+          // Boolean keys are allowed not to have values in Unicode extension.
+          // Those default to true.
+          updateProperty(map.property, map.type, true);
+          extension += updateExtension(key, true);
+        }
+      }
+    }
+  }
+
+  return extension === ''? '' : '-u' + extension;
+}
+
+
+/**
+ * Converts all OwnProperties into
+ * configurable: false, writable: false, enumerable: true.
+ */
+function freezeArray(array) {
+  var l = array.length;
+  for (var i = 0; i < l; i++) {
+    if (i in array) {
+      ObjectDefineProperty(array, i, {value: array[i],
+                                      configurable: false,
+                                      writable: false,
+                                      enumerable: true});
+    }
+  }
+
+  ObjectDefineProperty(array, 'length', {value: l, writable: false});
+  return array;
+}
+
+
+/**
+ * It's sometimes desireable to leave user requested locale instead of ICU
+ * supported one (zh-TW is equivalent to zh-Hant-TW, so we should keep shorter
+ * one, if that was what user requested).
+ * This function returns user specified tag if its maximized form matches ICU
+ * resolved locale. If not we return ICU result.
+ */
+function getOptimalLanguageTag(original, resolved) {
+  // Returns Array<Object>, where each object has maximized and base properties.
+  // Maximized: zh -> zh-Hans-CN
+  // Base: zh-CN-u-ca-gregory -> zh-CN
+  // Take care of grandfathered or simple cases.
+  if (original === resolved) {
+    return original;
+  }
+
+  var locales = %GetLanguageTagVariants([original, resolved]);
+  if (locales[0].maximized !== locales[1].maximized) {
+    return resolved;
+  }
+
+  // Preserve extensions of resolved locale, but swap base tags with original.
+  var resolvedBase = new GlobalRegExp('^' + locales[1].base);
+  return %_Call(StringReplace, resolved, resolvedBase, locales[0].base);
+}
+
+
+/**
+ * Returns an Object that contains all of supported locales for a given
+ * service.
+ * In addition to the supported locales we add xx-ZZ locale for each xx-Yyyy-ZZ
+ * that is supported. This is required by the spec.
+ */
+function getAvailableLocalesOf(service) {
+  var available = %AvailableLocalesOf(service);
+
+  for (var i in available) {
+    if (%HasOwnProperty(available, i)) {
+      var parts =
+          %_Call(StringMatch, i, /^([a-z]{2,3})-([A-Z][a-z]{3})-([A-Z]{2})$/);
+      if (parts !== null) {
+        // Build xx-ZZ. We don't care about the actual value,
+        // as long it's not undefined.
+        available[parts[1] + '-' + parts[3]] = null;
+      }
+    }
+  }
+
+  return available;
+}
+
+
+/**
+ * Defines a property and sets writable and enumerable to true.
+ * Configurable is false by default.
+ */
+function defineWEProperty(object, property, value) {
+  ObjectDefineProperty(object, property,
+                       {value: value, writable: true, enumerable: true});
+}
+
+
+/**
+ * Adds property to an object if the value is not undefined.
+ * Sets configurable descriptor to false.
+ */
+function addWEPropertyIfDefined(object, property, value) {
+  if (!IS_UNDEFINED(value)) {
+    defineWEProperty(object, property, value);
+  }
+}
+
+
+/**
+ * Defines a property and sets writable, enumerable and configurable to true.
+ */
+function defineWECProperty(object, property, value) {
+  ObjectDefineProperty(object, property, {value: value,
+                                          writable: true,
+                                          enumerable: true,
+                                          configurable: true});
+}
+
+
+/**
+ * Adds property to an object if the value is not undefined.
+ * Sets all descriptors to true.
+ */
+function addWECPropertyIfDefined(object, property, value) {
+  if (!IS_UNDEFINED(value)) {
+    defineWECProperty(object, property, value);
+  }
+}
+
+
+/**
+ * Returns titlecased word, aMeRricA -> America.
+ */
+function toTitleCaseWord(word) {
+  return %StringToUpperCase(%_Call(StringSubstr, word, 0, 1)) +
+         %StringToLowerCase(%_Call(StringSubstr, word, 1));
+}
+
+/**
+ * Returns titlecased location, bueNos_airES -> Buenos_Aires
+ * or ho_cHi_minH -> Ho_Chi_Minh. It is locale-agnostic and only
+ * deals with ASCII only characters.
+ * 'of', 'au' and 'es' are special-cased and lowercased.
+ */
+function toTitleCaseTimezoneLocation(location) {
+  var match = %_Call(StringMatch, location, GetTimezoneNameLocationPartRE());
+  if (IS_NULL(match)) throw MakeRangeError(kExpectedLocation, location);
+
+  var result = toTitleCaseWord(match[1]);
+  if (!IS_UNDEFINED(match[2]) && 2 < match.length) {
+    // The first character is a separator, '_' or '-'.
+    // None of IANA zone names has both '_' and '-'.
+    var separator = %_Call(StringSubstring, match[2], 0, 1);
+    var parts = %_Call(StringSplit, match[2], separator);
+    for (var i = 1; i < parts.length; i++) {
+      var part = parts[i]
+      var lowercasedPart = %StringToLowerCase(part);
+      result = result + separator +
+          ((lowercasedPart !== 'es' &&
+            lowercasedPart !== 'of' && lowercasedPart !== 'au') ?
+          toTitleCaseWord(part) : lowercasedPart);
+    }
+  }
+  return result;
+}
+
+/**
+ * Canonicalizes the language tag, or throws in case the tag is invalid.
+ */
+function canonicalizeLanguageTag(localeID) {
+  // null is typeof 'object' so we have to do extra check.
+  if (typeof localeID !== 'string' && typeof localeID !== 'object' ||
+      IS_NULL(localeID)) {
+    throw MakeTypeError(kLanguageID);
+  }
+
+  var localeString = GlobalString(localeID);
+
+  if (isValidLanguageTag(localeString) === false) {
+    throw MakeRangeError(kInvalidLanguageTag, localeString);
+  }
+
+  // This call will strip -kn but not -kn-true extensions.
+  // ICU bug filled - http://bugs.icu-project.org/trac/ticket/9265.
+  // TODO(cira): check if -u-kn-true-kc-true-kh-true still throws after
+  // upgrade to ICU 4.9.
+  var tag = %CanonicalizeLanguageTag(localeString);
+  if (tag === 'invalid-tag') {
+    throw MakeRangeError(kInvalidLanguageTag, localeString);
+  }
+
+  return tag;
+}
+
+
+/**
+ * Returns an array where all locales are canonicalized and duplicates removed.
+ * Throws on locales that are not well formed BCP47 tags.
+ */
+function initializeLocaleList(locales) {
+  var seen = [];
+  if (IS_UNDEFINED(locales)) {
+    // Constructor is called without arguments.
+    seen = [];
+  } else {
+    // We allow single string localeID.
+    if (typeof locales === 'string') {
+      %_Call(ArrayPush, seen, canonicalizeLanguageTag(locales));
+      return freezeArray(seen);
+    }
+
+    var o = TO_OBJECT(locales);
+    var len = TO_UINT32(o.length);
+
+    for (var k = 0; k < len; k++) {
+      if (k in o) {
+        var value = o[k];
+
+        var tag = canonicalizeLanguageTag(value);
+
+        if (%_Call(ArrayIndexOf, seen, tag) === -1) {
+          %_Call(ArrayPush, seen, tag);
+        }
+      }
+    }
+  }
+
+  return freezeArray(seen);
+}
+
+
+/**
+ * Validates the language tag. Section 2.2.9 of the bcp47 spec
+ * defines a valid tag.
+ *
+ * ICU is too permissible and lets invalid tags, like
+ * hant-cmn-cn, through.
+ *
+ * Returns false if the language tag is invalid.
+ */
+function isValidLanguageTag(locale) {
+  // Check if it's well-formed, including grandfadered tags.
+  if (!%_Call(RegExpTest, GetLanguageTagRE(), locale)) {
+    return false;
+  }
+
+  // Just return if it's a x- form. It's all private.
+  if (%_Call(StringIndexOf, locale, 'x-') === 0) {
+    return true;
+  }
+
+  // Check if there are any duplicate variants or singletons (extensions).
+
+  // Remove private use section.
+  locale = %_Call(StringSplit, locale, /-x-/)[0];
+
+  // Skip language since it can match variant regex, so we start from 1.
+  // We are matching i-klingon here, but that's ok, since i-klingon-klingon
+  // is not valid and would fail LANGUAGE_TAG_RE test.
+  var variants = [];
+  var extensions = [];
+  var parts = %_Call(StringSplit, locale, /-/);
+  for (var i = 1; i < parts.length; i++) {
+    var value = parts[i];
+    if (%_Call(RegExpTest, GetLanguageVariantRE(), value) &&
+        extensions.length === 0) {
+      if (%_Call(ArrayIndexOf, variants, value) === -1) {
+        %_Call(ArrayPush, variants, value);
+      } else {
+        return false;
+      }
+    }
+
+    if (%_Call(RegExpTest, GetLanguageSingletonRE(), value)) {
+      if (%_Call(ArrayIndexOf, extensions, value) === -1) {
+        %_Call(ArrayPush, extensions, value);
+      } else {
+        return false;
+      }
+    }
+  }
+
+  return true;
+ }
+
+
+/**
+ * Builds a regular expresion that validates the language tag
+ * against bcp47 spec.
+ * Uses http://tools.ietf.org/html/bcp47, section 2.1, ABNF.
+ * Runs on load and initializes the global REs.
+ */
+function BuildLanguageTagREs() {
+  var alpha = '[a-zA-Z]';
+  var digit = '[0-9]';
+  var alphanum = '(' + alpha + '|' + digit + ')';
+  var regular = '(art-lojban|cel-gaulish|no-bok|no-nyn|zh-guoyu|zh-hakka|' +
+                'zh-min|zh-min-nan|zh-xiang)';
+  var irregular = '(en-GB-oed|i-ami|i-bnn|i-default|i-enochian|i-hak|' +
+                  'i-klingon|i-lux|i-mingo|i-navajo|i-pwn|i-tao|i-tay|' +
+                  'i-tsu|sgn-BE-FR|sgn-BE-NL|sgn-CH-DE)';
+  var grandfathered = '(' + irregular + '|' + regular + ')';
+  var privateUse = '(x(-' + alphanum + '{1,8})+)';
+
+  var singleton = '(' + digit + '|[A-WY-Za-wy-z])';
+  LANGUAGE_SINGLETON_RE = new GlobalRegExp('^' + singleton + '$', 'i');
+
+  var extension = '(' + singleton + '(-' + alphanum + '{2,8})+)';
+
+  var variant = '(' + alphanum + '{5,8}|(' + digit + alphanum + '{3}))';
+  LANGUAGE_VARIANT_RE = new GlobalRegExp('^' + variant + '$', 'i');
+
+  var region = '(' + alpha + '{2}|' + digit + '{3})';
+  var script = '(' + alpha + '{4})';
+  var extLang = '(' + alpha + '{3}(-' + alpha + '{3}){0,2})';
+  var language = '(' + alpha + '{2,3}(-' + extLang + ')?|' + alpha + '{4}|' +
+                 alpha + '{5,8})';
+  var langTag = language + '(-' + script + ')?(-' + region + ')?(-' +
+                variant + ')*(-' + extension + ')*(-' + privateUse + ')?';
+
+  var languageTag =
+      '^(' + langTag + '|' + privateUse + '|' + grandfathered + ')$';
+  LANGUAGE_TAG_RE = new GlobalRegExp(languageTag, 'i');
+}
+
+var resolvedAccessor = {
+  get() {
+    %IncrementUseCounter(kIntlResolved);
+    return this[resolvedSymbol];
+  },
+  set(value) {
+    this[resolvedSymbol] = value;
+  }
+};
+
+/**
+ * Initializes the given object so it's a valid Collator instance.
+ * Useful for subclassing.
+ */
+function initializeCollator(collator, locales, options) {
+  if (%IsInitializedIntlObject(collator)) {
+    throw MakeTypeError(kReinitializeIntl, "Collator");
+  }
+
+  if (IS_UNDEFINED(options)) {
+    options = {};
+  }
+
+  var getOption = getGetOption(options, 'collator');
+
+  var internalOptions = {};
+
+  defineWEProperty(internalOptions, 'usage', getOption(
+    'usage', 'string', ['sort', 'search'], 'sort'));
+
+  var sensitivity = getOption('sensitivity', 'string',
+                              ['base', 'accent', 'case', 'variant']);
+  if (IS_UNDEFINED(sensitivity) && internalOptions.usage === 'sort') {
+    sensitivity = 'variant';
+  }
+  defineWEProperty(internalOptions, 'sensitivity', sensitivity);
+
+  defineWEProperty(internalOptions, 'ignorePunctuation', getOption(
+    'ignorePunctuation', 'boolean', UNDEFINED, false));
+
+  var locale = resolveLocale('collator', locales, options);
+
+  // ICU can't take kb, kc... parameters through localeID, so we need to pass
+  // them as options.
+  // One exception is -co- which has to be part of the extension, but only for
+  // usage: sort, and its value can't be 'standard' or 'search'.
+  var extensionMap = parseExtension(locale.extension);
+
+  /**
+   * Map of Unicode extensions to option properties, and their values and types,
+   * for a collator.
+   */
+  var COLLATOR_KEY_MAP = {
+    'kn': {'property': 'numeric', 'type': 'boolean'},
+    'kf': {'property': 'caseFirst', 'type': 'string',
+           'values': ['false', 'lower', 'upper']}
+  };
+
+  setOptions(
+      options, extensionMap, COLLATOR_KEY_MAP, getOption, internalOptions);
+
+  var collation = 'default';
+  var extension = '';
+  if (%HasOwnProperty(extensionMap, 'co') && internalOptions.usage === 'sort') {
+
+    /**
+     * Allowed -u-co- values. List taken from:
+     * http://unicode.org/repos/cldr/trunk/common/bcp47/collation.xml
+     */
+    var ALLOWED_CO_VALUES = [
+      'big5han', 'dict', 'direct', 'ducet', 'gb2312', 'phonebk', 'phonetic',
+      'pinyin', 'reformed', 'searchjl', 'stroke', 'trad', 'unihan', 'zhuyin'
+    ];
+
+    if (%_Call(ArrayIndexOf, ALLOWED_CO_VALUES, extensionMap.co) !== -1) {
+      extension = '-u-co-' + extensionMap.co;
+      // ICU can't tell us what the collation is, so save user's input.
+      collation = extensionMap.co;
+    }
+  } else if (internalOptions.usage === 'search') {
+    extension = '-u-co-search';
+  }
+  defineWEProperty(internalOptions, 'collation', collation);
+
+  var requestedLocale = locale.locale + extension;
+
+  // We define all properties C++ code may produce, to prevent security
+  // problems. If malicious user decides to redefine Object.prototype.locale
+  // we can't just use plain x.locale = 'us' or in C++ Set("locale", "us").
+  // ObjectDefineProperties will either succeed defining or throw an error.
+  var resolved = ObjectDefineProperties({}, {
+    caseFirst: {writable: true},
+    collation: {value: internalOptions.collation, writable: true},
+    ignorePunctuation: {writable: true},
+    locale: {writable: true},
+    numeric: {writable: true},
+    requestedLocale: {value: requestedLocale, writable: true},
+    sensitivity: {writable: true},
+    strength: {writable: true},
+    usage: {value: internalOptions.usage, writable: true}
+  });
+
+  var internalCollator = %CreateCollator(requestedLocale,
+                                         internalOptions,
+                                         resolved);
+
+  // Writable, configurable and enumerable are set to false by default.
+  %MarkAsInitializedIntlObjectOfType(collator, 'collator', internalCollator);
+  collator[resolvedSymbol] = resolved;
+  ObjectDefineProperty(collator, 'resolved', resolvedAccessor);
+
+  return collator;
+}
+
+
+/**
+ * Constructs Intl.Collator object given optional locales and options
+ * parameters.
+ *
+ * @constructor
+ */
+%AddNamedProperty(Intl, 'Collator', function() {
+    var locales = %_Arguments(0);
+    var options = %_Arguments(1);
+
+    if (!this || this === Intl) {
+      // Constructor is called as a function.
+      return new Intl.Collator(locales, options);
+    }
+
+    return initializeCollator(TO_OBJECT(this), locales, options);
+  },
+  DONT_ENUM
+);
+
+
+/**
+ * Collator resolvedOptions method.
+ */
+%AddNamedProperty(Intl.Collator.prototype, 'resolvedOptions', function() {
+    if (!IS_UNDEFINED(new.target)) {
+      throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
+    }
+
+    if (!%IsInitializedIntlObjectOfType(this, 'collator')) {
+      throw MakeTypeError(kResolvedOptionsCalledOnNonObject, "Collator");
+    }
+
+    var coll = this;
+    var locale = getOptimalLanguageTag(coll[resolvedSymbol].requestedLocale,
+                                       coll[resolvedSymbol].locale);
+
+    return {
+      locale: locale,
+      usage: coll[resolvedSymbol].usage,
+      sensitivity: coll[resolvedSymbol].sensitivity,
+      ignorePunctuation: coll[resolvedSymbol].ignorePunctuation,
+      numeric: coll[resolvedSymbol].numeric,
+      caseFirst: coll[resolvedSymbol].caseFirst,
+      collation: coll[resolvedSymbol].collation
+    };
+  },
+  DONT_ENUM
+);
+%FunctionSetName(Intl.Collator.prototype.resolvedOptions, 'resolvedOptions');
+%FunctionRemovePrototype(Intl.Collator.prototype.resolvedOptions);
+%SetNativeFlag(Intl.Collator.prototype.resolvedOptions);
+
+
+/**
+ * Returns the subset of the given locale list for which this locale list
+ * has a matching (possibly fallback) locale. Locales appear in the same
+ * order in the returned list as in the input list.
+ * Options are optional parameter.
+ */
+%AddNamedProperty(Intl.Collator, 'supportedLocalesOf', function(locales) {
+    if (!IS_UNDEFINED(new.target)) {
+      throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
+    }
+
+    return supportedLocalesOf('collator', locales, %_Arguments(1));
+  },
+  DONT_ENUM
+);
+%FunctionSetName(Intl.Collator.supportedLocalesOf, 'supportedLocalesOf');
+%FunctionRemovePrototype(Intl.Collator.supportedLocalesOf);
+%SetNativeFlag(Intl.Collator.supportedLocalesOf);
+
+
+/**
+ * When the compare method is called with two arguments x and y, it returns a
+ * Number other than NaN that represents the result of a locale-sensitive
+ * String comparison of x with y.
+ * The result is intended to order String values in the sort order specified
+ * by the effective locale and collation options computed during construction
+ * of this Collator object, and will be negative, zero, or positive, depending
+ * on whether x comes before y in the sort order, the Strings are equal under
+ * the sort order, or x comes after y in the sort order, respectively.
+ */
+function compare(collator, x, y) {
+  return %InternalCompare(%GetImplFromInitializedIntlObject(collator),
+                          GlobalString(x), GlobalString(y));
+};
+
+
+addBoundMethod(Intl.Collator, 'compare', compare, 2);
+
+/**
+ * Verifies that the input is a well-formed ISO 4217 currency code.
+ * Don't uppercase to test. It could convert invalid code into a valid one.
+ * For example \u00DFP (Eszett+P) becomes SSP.
+ */
+function isWellFormedCurrencyCode(currency) {
+  return typeof currency == "string" &&
+      currency.length == 3 &&
+      %_Call(StringMatch, currency, /[^A-Za-z]/) == null;
+}
+
+
+/**
+ * Returns the valid digit count for a property, or throws RangeError on
+ * a value out of the range.
+ */
+function getNumberOption(options, property, min, max, fallback) {
+  var value = options[property];
+  if (!IS_UNDEFINED(value)) {
+    value = GlobalNumber(value);
+    if (IsNaN(value) || value < min || value > max) {
+      throw MakeRangeError(kPropertyValueOutOfRange, property);
+    }
+    return MathFloor(value);
+  }
+
+  return fallback;
+}
+
+var patternAccessor = {
+  get() {
+    %IncrementUseCounter(kIntlPattern);
+    return this[patternSymbol];
+  },
+  set(value) {
+    this[patternSymbol] = value;
+  }
+};
+
+/**
+ * Initializes the given object so it's a valid NumberFormat instance.
+ * Useful for subclassing.
+ */
+function initializeNumberFormat(numberFormat, locales, options) {
+  if (%IsInitializedIntlObject(numberFormat)) {
+    throw MakeTypeError(kReinitializeIntl, "NumberFormat");
+  }
+
+  if (IS_UNDEFINED(options)) {
+    options = {};
+  }
+
+  var getOption = getGetOption(options, 'numberformat');
+
+  var locale = resolveLocale('numberformat', locales, options);
+
+  var internalOptions = {};
+  defineWEProperty(internalOptions, 'style', getOption(
+    'style', 'string', ['decimal', 'percent', 'currency'], 'decimal'));
+
+  var currency = getOption('currency', 'string');
+  if (!IS_UNDEFINED(currency) && !isWellFormedCurrencyCode(currency)) {
+    throw MakeRangeError(kInvalidCurrencyCode, currency);
+  }
+
+  if (internalOptions.style === 'currency' && IS_UNDEFINED(currency)) {
+    throw MakeTypeError(kCurrencyCode);
+  }
+
+  var currencyDisplay = getOption(
+      'currencyDisplay', 'string', ['code', 'symbol', 'name'], 'symbol');
+  if (internalOptions.style === 'currency') {
+    defineWEProperty(internalOptions, 'currency', %StringToUpperCase(currency));
+    defineWEProperty(internalOptions, 'currencyDisplay', currencyDisplay);
+  }
+
+  // Digit ranges.
+  var mnid = getNumberOption(options, 'minimumIntegerDigits', 1, 21, 1);
+  defineWEProperty(internalOptions, 'minimumIntegerDigits', mnid);
+
+  var mnfd = options['minimumFractionDigits'];
+  var mxfd = options['maximumFractionDigits'];
+  if (!IS_UNDEFINED(mnfd) || internalOptions.style !== 'currency') {
+    mnfd = getNumberOption(options, 'minimumFractionDigits', 0, 20, 0);
+    defineWEProperty(internalOptions, 'minimumFractionDigits', mnfd);
+  }
+
+  if (!IS_UNDEFINED(mxfd) || internalOptions.style !== 'currency') {
+    var min_mxfd = internalOptions.style === 'percent' ? 0 : 3;
+    mnfd = IS_UNDEFINED(mnfd) ? 0 : mnfd;
+    var fallback_limit = (mnfd > min_mxfd) ? mnfd : min_mxfd;
+    mxfd = getNumberOption(options, 'maximumFractionDigits', mnfd, 20, fallback_limit);
+    defineWEProperty(internalOptions, 'maximumFractionDigits', mxfd);
+  }
+
+  var mnsd = options['minimumSignificantDigits'];
+  var mxsd = options['maximumSignificantDigits'];
+  if (!IS_UNDEFINED(mnsd) || !IS_UNDEFINED(mxsd)) {
+    mnsd = getNumberOption(options, 'minimumSignificantDigits', 1, 21, 0);
+    defineWEProperty(internalOptions, 'minimumSignificantDigits', mnsd);
+
+    mxsd = getNumberOption(options, 'maximumSignificantDigits', mnsd, 21, 21);
+    defineWEProperty(internalOptions, 'maximumSignificantDigits', mxsd);
+  }
+
+  // Grouping.
+  defineWEProperty(internalOptions, 'useGrouping', getOption(
+    'useGrouping', 'boolean', UNDEFINED, true));
+
+  // ICU prefers options to be passed using -u- extension key/values for
+  // number format, so we need to build that.
+  var extensionMap = parseExtension(locale.extension);
+
+  /**
+   * Map of Unicode extensions to option properties, and their values and types,
+   * for a number format.
+   */
+  var NUMBER_FORMAT_KEY_MAP = {
+    'nu': {'property': UNDEFINED, 'type': 'string'}
+  };
+
+  var extension = setOptions(options, extensionMap, NUMBER_FORMAT_KEY_MAP,
+                             getOption, internalOptions);
+
+  var requestedLocale = locale.locale + extension;
+  var resolved = ObjectDefineProperties({}, {
+    currency: {writable: true},
+    currencyDisplay: {writable: true},
+    locale: {writable: true},
+    maximumFractionDigits: {writable: true},
+    minimumFractionDigits: {writable: true},
+    minimumIntegerDigits: {writable: true},
+    numberingSystem: {writable: true},
+    pattern: patternAccessor,
+    requestedLocale: {value: requestedLocale, writable: true},
+    style: {value: internalOptions.style, writable: true},
+    useGrouping: {writable: true}
+  });
+  if (%HasOwnProperty(internalOptions, 'minimumSignificantDigits')) {
+    defineWEProperty(resolved, 'minimumSignificantDigits', UNDEFINED);
+  }
+  if (%HasOwnProperty(internalOptions, 'maximumSignificantDigits')) {
+    defineWEProperty(resolved, 'maximumSignificantDigits', UNDEFINED);
+  }
+  var formatter = %CreateNumberFormat(requestedLocale,
+                                      internalOptions,
+                                      resolved);
+
+  if (internalOptions.style === 'currency') {
+    ObjectDefineProperty(resolved, 'currencyDisplay', {value: currencyDisplay,
+                                                       writable: true});
+  }
+
+  %MarkAsInitializedIntlObjectOfType(numberFormat, 'numberformat', formatter);
+  numberFormat[resolvedSymbol] = resolved;
+  ObjectDefineProperty(numberFormat, 'resolved', resolvedAccessor);
+
+  return numberFormat;
+}
+
+
+/**
+ * Constructs Intl.NumberFormat object given optional locales and options
+ * parameters.
+ *
+ * @constructor
+ */
+%AddNamedProperty(Intl, 'NumberFormat', function() {
+    var locales = %_Arguments(0);
+    var options = %_Arguments(1);
+
+    if (!this || this === Intl) {
+      // Constructor is called as a function.
+      return new Intl.NumberFormat(locales, options);
+    }
+
+    return initializeNumberFormat(TO_OBJECT(this), locales, options);
+  },
+  DONT_ENUM
+);
+
+
+/**
+ * NumberFormat resolvedOptions method.
+ */
+%AddNamedProperty(Intl.NumberFormat.prototype, 'resolvedOptions', function() {
+    if (!IS_UNDEFINED(new.target)) {
+      throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
+    }
+
+    if (!%IsInitializedIntlObjectOfType(this, 'numberformat')) {
+      throw MakeTypeError(kResolvedOptionsCalledOnNonObject, "NumberFormat");
+    }
+
+    var format = this;
+    var locale = getOptimalLanguageTag(format[resolvedSymbol].requestedLocale,
+                                       format[resolvedSymbol].locale);
+
+    var result = {
+      locale: locale,
+      numberingSystem: format[resolvedSymbol].numberingSystem,
+      style: format[resolvedSymbol].style,
+      useGrouping: format[resolvedSymbol].useGrouping,
+      minimumIntegerDigits: format[resolvedSymbol].minimumIntegerDigits,
+      minimumFractionDigits: format[resolvedSymbol].minimumFractionDigits,
+      maximumFractionDigits: format[resolvedSymbol].maximumFractionDigits,
+    };
+
+    if (result.style === 'currency') {
+      defineWECProperty(result, 'currency', format[resolvedSymbol].currency);
+      defineWECProperty(result, 'currencyDisplay',
+                        format[resolvedSymbol].currencyDisplay);
+    }
+
+    if (%HasOwnProperty(format[resolvedSymbol], 'minimumSignificantDigits')) {
+      defineWECProperty(result, 'minimumSignificantDigits',
+                        format[resolvedSymbol].minimumSignificantDigits);
+    }
+
+    if (%HasOwnProperty(format[resolvedSymbol], 'maximumSignificantDigits')) {
+      defineWECProperty(result, 'maximumSignificantDigits',
+                        format[resolvedSymbol].maximumSignificantDigits);
+    }
+
+    return result;
+  },
+  DONT_ENUM
+);
+%FunctionSetName(Intl.NumberFormat.prototype.resolvedOptions,
+                 'resolvedOptions');
+%FunctionRemovePrototype(Intl.NumberFormat.prototype.resolvedOptions);
+%SetNativeFlag(Intl.NumberFormat.prototype.resolvedOptions);
+
+
+/**
+ * Returns the subset of the given locale list for which this locale list
+ * has a matching (possibly fallback) locale. Locales appear in the same
+ * order in the returned list as in the input list.
+ * Options are optional parameter.
+ */
+%AddNamedProperty(Intl.NumberFormat, 'supportedLocalesOf', function(locales) {
+    if (!IS_UNDEFINED(new.target)) {
+      throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
+    }
+
+    return supportedLocalesOf('numberformat', locales, %_Arguments(1));
+  },
+  DONT_ENUM
+);
+%FunctionSetName(Intl.NumberFormat.supportedLocalesOf, 'supportedLocalesOf');
+%FunctionRemovePrototype(Intl.NumberFormat.supportedLocalesOf);
+%SetNativeFlag(Intl.NumberFormat.supportedLocalesOf);
+
+
+/**
+ * Returns a String value representing the result of calling ToNumber(value)
+ * according to the effective locale and the formatting options of this
+ * NumberFormat.
+ */
+function formatNumber(formatter, value) {
+  // Spec treats -0 and +0 as 0.
+  var number = TO_NUMBER(value) + 0;
+
+  return %InternalNumberFormat(%GetImplFromInitializedIntlObject(formatter),
+                               number);
+}
+
+
+/**
+ * Returns a Number that represents string value that was passed in.
+ */
+function parseNumber(formatter, value) {
+  return %InternalNumberParse(%GetImplFromInitializedIntlObject(formatter),
+                              GlobalString(value));
+}
+
+
+addBoundMethod(Intl.NumberFormat, 'format', formatNumber, 1);
+addBoundMethod(Intl.NumberFormat, 'v8Parse', parseNumber, 1);
+
+/**
+ * Returns a string that matches LDML representation of the options object.
+ */
+function toLDMLString(options) {
+  var getOption = getGetOption(options, 'dateformat');
+
+  var ldmlString = '';
+
+  var option = getOption('weekday', 'string', ['narrow', 'short', 'long']);
+  ldmlString += appendToLDMLString(
+      option, {narrow: 'EEEEE', short: 'EEE', long: 'EEEE'});
+
+  option = getOption('era', 'string', ['narrow', 'short', 'long']);
+  ldmlString += appendToLDMLString(
+      option, {narrow: 'GGGGG', short: 'GGG', long: 'GGGG'});
+
+  option = getOption('year', 'string', ['2-digit', 'numeric']);
+  ldmlString += appendToLDMLString(option, {'2-digit': 'yy', 'numeric': 'y'});
+
+  option = getOption('month', 'string',
+                     ['2-digit', 'numeric', 'narrow', 'short', 'long']);
+  ldmlString += appendToLDMLString(option, {'2-digit': 'MM', 'numeric': 'M',
+          'narrow': 'MMMMM', 'short': 'MMM', 'long': 'MMMM'});
+
+  option = getOption('day', 'string', ['2-digit', 'numeric']);
+  ldmlString += appendToLDMLString(
+      option, {'2-digit': 'dd', 'numeric': 'd'});
+
+  var hr12 = getOption('hour12', 'boolean');
+  option = getOption('hour', 'string', ['2-digit', 'numeric']);
+  if (IS_UNDEFINED(hr12)) {
+    ldmlString += appendToLDMLString(option, {'2-digit': 'jj', 'numeric': 'j'});
+  } else if (hr12 === true) {
+    ldmlString += appendToLDMLString(option, {'2-digit': 'hh', 'numeric': 'h'});
+  } else {
+    ldmlString += appendToLDMLString(option, {'2-digit': 'HH', 'numeric': 'H'});
+  }
+
+  option = getOption('minute', 'string', ['2-digit', 'numeric']);
+  ldmlString += appendToLDMLString(option, {'2-digit': 'mm', 'numeric': 'm'});
+
+  option = getOption('second', 'string', ['2-digit', 'numeric']);
+  ldmlString += appendToLDMLString(option, {'2-digit': 'ss', 'numeric': 's'});
+
+  option = getOption('timeZoneName', 'string', ['short', 'long']);
+  ldmlString += appendToLDMLString(option, {short: 'z', long: 'zzzz'});
+
+  return ldmlString;
+}
+
+
+/**
+ * Returns either LDML equivalent of the current option or empty string.
+ */
+function appendToLDMLString(option, pairs) {
+  if (!IS_UNDEFINED(option)) {
+    return pairs[option];
+  } else {
+    return '';
+  }
+}
+
+
+/**
+ * Returns object that matches LDML representation of the date.
+ */
+function fromLDMLString(ldmlString) {
+  // First remove '' quoted text, so we lose 'Uhr' strings.
+  ldmlString = %_Call(StringReplace, ldmlString, GetQuotedStringRE(), '');
+
+  var options = {};
+  var match = %_Call(StringMatch, ldmlString, /E{3,5}/g);
+  options = appendToDateTimeObject(
+      options, 'weekday', match, {EEEEE: 'narrow', EEE: 'short', EEEE: 'long'});
+
+  match = %_Call(StringMatch, ldmlString, /G{3,5}/g);
+  options = appendToDateTimeObject(
+      options, 'era', match, {GGGGG: 'narrow', GGG: 'short', GGGG: 'long'});
+
+  match = %_Call(StringMatch, ldmlString, /y{1,2}/g);
+  options = appendToDateTimeObject(
+      options, 'year', match, {y: 'numeric', yy: '2-digit'});
+
+  match = %_Call(StringMatch, ldmlString, /M{1,5}/g);
+  options = appendToDateTimeObject(options, 'month', match, {MM: '2-digit',
+      M: 'numeric', MMMMM: 'narrow', MMM: 'short', MMMM: 'long'});
+
+  // Sometimes we get L instead of M for month - standalone name.
+  match = %_Call(StringMatch, ldmlString, /L{1,5}/g);
+  options = appendToDateTimeObject(options, 'month', match, {LL: '2-digit',
+      L: 'numeric', LLLLL: 'narrow', LLL: 'short', LLLL: 'long'});
+
+  match = %_Call(StringMatch, ldmlString, /d{1,2}/g);
+  options = appendToDateTimeObject(
+      options, 'day', match, {d: 'numeric', dd: '2-digit'});
+
+  match = %_Call(StringMatch, ldmlString, /h{1,2}/g);
+  if (match !== null) {
+    options['hour12'] = true;
+  }
+  options = appendToDateTimeObject(
+      options, 'hour', match, {h: 'numeric', hh: '2-digit'});
+
+  match = %_Call(StringMatch, ldmlString, /H{1,2}/g);
+  if (match !== null) {
+    options['hour12'] = false;
+  }
+  options = appendToDateTimeObject(
+      options, 'hour', match, {H: 'numeric', HH: '2-digit'});
+
+  match = %_Call(StringMatch, ldmlString, /m{1,2}/g);
+  options = appendToDateTimeObject(
+      options, 'minute', match, {m: 'numeric', mm: '2-digit'});
+
+  match = %_Call(StringMatch, ldmlString, /s{1,2}/g);
+  options = appendToDateTimeObject(
+      options, 'second', match, {s: 'numeric', ss: '2-digit'});
+
+  match = %_Call(StringMatch, ldmlString, /z|zzzz/g);
+  options = appendToDateTimeObject(
+      options, 'timeZoneName', match, {z: 'short', zzzz: 'long'});
+
+  return options;
+}
+
+
+function appendToDateTimeObject(options, option, match, pairs) {
+  if (IS_NULL(match)) {
+    if (!%HasOwnProperty(options, option)) {
+      defineWEProperty(options, option, UNDEFINED);
+    }
+    return options;
+  }
+
+  var property = match[0];
+  defineWEProperty(options, option, pairs[property]);
+
+  return options;
+}
+
+
+/**
+ * Returns options with at least default values in it.
+ */
+function toDateTimeOptions(options, required, defaults) {
+  if (IS_UNDEFINED(options)) {
+    options = {};
+  } else {
+    options = TO_OBJECT(options);
+  }
+
+  var needsDefault = true;
+  if ((required === 'date' || required === 'any') &&
+      (!IS_UNDEFINED(options.weekday) || !IS_UNDEFINED(options.year) ||
+       !IS_UNDEFINED(options.month) || !IS_UNDEFINED(options.day))) {
+    needsDefault = false;
+  }
+
+  if ((required === 'time' || required === 'any') &&
+      (!IS_UNDEFINED(options.hour) || !IS_UNDEFINED(options.minute) ||
+       !IS_UNDEFINED(options.second))) {
+    needsDefault = false;
+  }
+
+  if (needsDefault && (defaults === 'date' || defaults === 'all')) {
+    ObjectDefineProperty(options, 'year', {value: 'numeric',
+                                           writable: true,
+                                           enumerable: true,
+                                           configurable: true});
+    ObjectDefineProperty(options, 'month', {value: 'numeric',
+                                            writable: true,
+                                            enumerable: true,
+                                            configurable: true});
+    ObjectDefineProperty(options, 'day', {value: 'numeric',
+                                          writable: true,
+                                          enumerable: true,
+                                          configurable: true});
+  }
+
+  if (needsDefault && (defaults === 'time' || defaults === 'all')) {
+    ObjectDefineProperty(options, 'hour', {value: 'numeric',
+                                           writable: true,
+                                           enumerable: true,
+                                           configurable: true});
+    ObjectDefineProperty(options, 'minute', {value: 'numeric',
+                                             writable: true,
+                                             enumerable: true,
+                                             configurable: true});
+    ObjectDefineProperty(options, 'second', {value: 'numeric',
+                                             writable: true,
+                                             enumerable: true,
+                                             configurable: true});
+  }
+
+  return options;
+}
+
+
+/**
+ * Initializes the given object so it's a valid DateTimeFormat instance.
+ * Useful for subclassing.
+ */
+function initializeDateTimeFormat(dateFormat, locales, options) {
+
+  if (%IsInitializedIntlObject(dateFormat)) {
+    throw MakeTypeError(kReinitializeIntl, "DateTimeFormat");
+  }
+
+  if (IS_UNDEFINED(options)) {
+    options = {};
+  }
+
+  var locale = resolveLocale('dateformat', locales, options);
+
+  options = toDateTimeOptions(options, 'any', 'date');
+
+  var getOption = getGetOption(options, 'dateformat');
+
+  // We implement only best fit algorithm, but still need to check
+  // if the formatMatcher values are in range.
+  var matcher = getOption('formatMatcher', 'string',
+                          ['basic', 'best fit'], 'best fit');
+
+  // Build LDML string for the skeleton that we pass to the formatter.
+  var ldmlString = toLDMLString(options);
+
+  // Filter out supported extension keys so we know what to put in resolved
+  // section later on.
+  // We need to pass calendar and number system to the method.
+  var tz = canonicalizeTimeZoneID(options.timeZone);
+
+  // ICU prefers options to be passed using -u- extension key/values, so
+  // we need to build that.
+  var internalOptions = {};
+  var extensionMap = parseExtension(locale.extension);
+
+  /**
+   * Map of Unicode extensions to option properties, and their values and types,
+   * for a date/time format.
+   */
+  var DATETIME_FORMAT_KEY_MAP = {
+    'ca': {'property': UNDEFINED, 'type': 'string'},
+    'nu': {'property': UNDEFINED, 'type': 'string'}
+  };
+
+  var extension = setOptions(options, extensionMap, DATETIME_FORMAT_KEY_MAP,
+                             getOption, internalOptions);
+
+  var requestedLocale = locale.locale + extension;
+  var resolved = ObjectDefineProperties({}, {
+    calendar: {writable: true},
+    day: {writable: true},
+    era: {writable: true},
+    hour12: {writable: true},
+    hour: {writable: true},
+    locale: {writable: true},
+    minute: {writable: true},
+    month: {writable: true},
+    numberingSystem: {writable: true},
+    [patternSymbol]: {writable: true},
+    pattern: patternAccessor,
+    requestedLocale: {value: requestedLocale, writable: true},
+    second: {writable: true},
+    timeZone: {writable: true},
+    timeZoneName: {writable: true},
+    tz: {value: tz, writable: true},
+    weekday: {writable: true},
+    year: {writable: true}
+  });
+
+  var formatter = %CreateDateTimeFormat(
+    requestedLocale, {skeleton: ldmlString, timeZone: tz}, resolved);
+
+  if (resolved.timeZone === "Etc/Unknown") {
+    throw MakeRangeError(kUnsupportedTimeZone, tz);
+  }
+
+  %MarkAsInitializedIntlObjectOfType(dateFormat, 'dateformat', formatter);
+  dateFormat[resolvedSymbol] = resolved;
+  ObjectDefineProperty(dateFormat, 'resolved', resolvedAccessor);
+
+  return dateFormat;
+}
+
+
+/**
+ * Constructs Intl.DateTimeFormat object given optional locales and options
+ * parameters.
+ *
+ * @constructor
+ */
+%AddNamedProperty(Intl, 'DateTimeFormat', function() {
+    var locales = %_Arguments(0);
+    var options = %_Arguments(1);
+
+    if (!this || this === Intl) {
+      // Constructor is called as a function.
+      return new Intl.DateTimeFormat(locales, options);
+    }
+
+    return initializeDateTimeFormat(TO_OBJECT(this), locales, options);
+  },
+  DONT_ENUM
+);
+
+
+/**
+ * DateTimeFormat resolvedOptions method.
+ */
+%AddNamedProperty(Intl.DateTimeFormat.prototype, 'resolvedOptions', function() {
+    if (!IS_UNDEFINED(new.target)) {
+      throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
+    }
+
+    if (!%IsInitializedIntlObjectOfType(this, 'dateformat')) {
+      throw MakeTypeError(kResolvedOptionsCalledOnNonObject, "DateTimeFormat");
+    }
+
+    /**
+     * Maps ICU calendar names into LDML type.
+     */
+    var ICU_CALENDAR_MAP = {
+      'gregorian': 'gregory',
+      'japanese': 'japanese',
+      'buddhist': 'buddhist',
+      'roc': 'roc',
+      'persian': 'persian',
+      'islamic-civil': 'islamicc',
+      'islamic': 'islamic',
+      'hebrew': 'hebrew',
+      'chinese': 'chinese',
+      'indian': 'indian',
+      'coptic': 'coptic',
+      'ethiopic': 'ethiopic',
+      'ethiopic-amete-alem': 'ethioaa'
+    };
+
+    var format = this;
+    var fromPattern = fromLDMLString(format[resolvedSymbol][patternSymbol]);
+    var userCalendar = ICU_CALENDAR_MAP[format[resolvedSymbol].calendar];
+    if (IS_UNDEFINED(userCalendar)) {
+      // Use ICU name if we don't have a match. It shouldn't happen, but
+      // it would be too strict to throw for this.
+      userCalendar = format[resolvedSymbol].calendar;
+    }
+
+    var locale = getOptimalLanguageTag(format[resolvedSymbol].requestedLocale,
+                                       format[resolvedSymbol].locale);
+
+    var result = {
+      locale: locale,
+      numberingSystem: format[resolvedSymbol].numberingSystem,
+      calendar: userCalendar,
+      timeZone: format[resolvedSymbol].timeZone
+    };
+
+    addWECPropertyIfDefined(result, 'timeZoneName', fromPattern.timeZoneName);
+    addWECPropertyIfDefined(result, 'era', fromPattern.era);
+    addWECPropertyIfDefined(result, 'year', fromPattern.year);
+    addWECPropertyIfDefined(result, 'month', fromPattern.month);
+    addWECPropertyIfDefined(result, 'day', fromPattern.day);
+    addWECPropertyIfDefined(result, 'weekday', fromPattern.weekday);
+    addWECPropertyIfDefined(result, 'hour12', fromPattern.hour12);
+    addWECPropertyIfDefined(result, 'hour', fromPattern.hour);
+    addWECPropertyIfDefined(result, 'minute', fromPattern.minute);
+    addWECPropertyIfDefined(result, 'second', fromPattern.second);
+
+    return result;
+  },
+  DONT_ENUM
+);
+%FunctionSetName(Intl.DateTimeFormat.prototype.resolvedOptions,
+                 'resolvedOptions');
+%FunctionRemovePrototype(Intl.DateTimeFormat.prototype.resolvedOptions);
+%SetNativeFlag(Intl.DateTimeFormat.prototype.resolvedOptions);
+
+
+/**
+ * Returns the subset of the given locale list for which this locale list
+ * has a matching (possibly fallback) locale. Locales appear in the same
+ * order in the returned list as in the input list.
+ * Options are optional parameter.
+ */
+%AddNamedProperty(Intl.DateTimeFormat, 'supportedLocalesOf', function(locales) {
+    if (!IS_UNDEFINED(new.target)) {
+      throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
+    }
+
+    return supportedLocalesOf('dateformat', locales, %_Arguments(1));
+  },
+  DONT_ENUM
+);
+%FunctionSetName(Intl.DateTimeFormat.supportedLocalesOf, 'supportedLocalesOf');
+%FunctionRemovePrototype(Intl.DateTimeFormat.supportedLocalesOf);
+%SetNativeFlag(Intl.DateTimeFormat.supportedLocalesOf);
+
+
+/**
+ * Returns a String value representing the result of calling ToNumber(date)
+ * according to the effective locale and the formatting options of this
+ * DateTimeFormat.
+ */
+function formatDate(formatter, dateValue) {
+  var dateMs;
+  if (IS_UNDEFINED(dateValue)) {
+    dateMs = %DateCurrentTime();
+  } else {
+    dateMs = TO_NUMBER(dateValue);
+  }
+
+  if (!IsFinite(dateMs)) throw MakeRangeError(kDateRange);
+
+  return %InternalDateFormat(%GetImplFromInitializedIntlObject(formatter),
+                             new GlobalDate(dateMs));
+}
+
+
+/**
+ * Returns a Date object representing the result of calling ToString(value)
+ * according to the effective locale and the formatting options of this
+ * DateTimeFormat.
+ * Returns undefined if date string cannot be parsed.
+ */
+function parseDate(formatter, value) {
+  return %InternalDateParse(%GetImplFromInitializedIntlObject(formatter),
+                            GlobalString(value));
+}
+
+
+// 0 because date is optional argument.
+addBoundMethod(Intl.DateTimeFormat, 'format', formatDate, 0);
+addBoundMethod(Intl.DateTimeFormat, 'v8Parse', parseDate, 1);
+
+
+/**
+ * Returns canonical Area/Location(/Location) name, or throws an exception
+ * if the zone name is invalid IANA name.
+ */
+function canonicalizeTimeZoneID(tzID) {
+  // Skip undefined zones.
+  if (IS_UNDEFINED(tzID)) {
+    return tzID;
+  }
+
+  // Special case handling (UTC, GMT).
+  var upperID = %StringToUpperCase(tzID);
+  if (upperID === 'UTC' || upperID === 'GMT' ||
+      upperID === 'ETC/UTC' || upperID === 'ETC/GMT') {
+    return 'UTC';
+  }
+
+  // TODO(jshin): Add support for Etc/GMT[+-]([1-9]|1[0-2])
+
+  // We expect only _, '-' and / beside ASCII letters.
+  // All inputs should conform to Area/Location(/Location)* from now on.
+  var match = %_Call(StringMatch, tzID, GetTimezoneNameCheckRE());
+  if (IS_NULL(match)) throw MakeRangeError(kExpectedTimezoneID, tzID);
+
+  var result = toTitleCaseTimezoneLocation(match[1]) + '/' +
+               toTitleCaseTimezoneLocation(match[2]);
+
+  if (!IS_UNDEFINED(match[3]) && 3 < match.length) {
+    var locations = %_Call(StringSplit, match[3], '/');
+    // The 1st element is empty. Starts with i=1.
+    for (var i = 1; i < locations.length; i++) {
+      result = result + '/' + toTitleCaseTimezoneLocation(locations[i]);
+    }
+  }
+
+  return result;
+}
+
+/**
+ * Initializes the given object so it's a valid BreakIterator instance.
+ * Useful for subclassing.
+ */
+function initializeBreakIterator(iterator, locales, options) {
+  if (%IsInitializedIntlObject(iterator)) {
+    throw MakeTypeError(kReinitializeIntl, "v8BreakIterator");
+  }
+
+  if (IS_UNDEFINED(options)) {
+    options = {};
+  }
+
+  var getOption = getGetOption(options, 'breakiterator');
+
+  var internalOptions = {};
+
+  defineWEProperty(internalOptions, 'type', getOption(
+    'type', 'string', ['character', 'word', 'sentence', 'line'], 'word'));
+
+  var locale = resolveLocale('breakiterator', locales, options);
+  var resolved = ObjectDefineProperties({}, {
+    requestedLocale: {value: locale.locale, writable: true},
+    type: {value: internalOptions.type, writable: true},
+    locale: {writable: true}
+  });
+
+  var internalIterator = %CreateBreakIterator(locale.locale,
+                                              internalOptions,
+                                              resolved);
+
+  %MarkAsInitializedIntlObjectOfType(iterator, 'breakiterator',
+                                     internalIterator);
+  iterator[resolvedSymbol] = resolved;
+  ObjectDefineProperty(iterator, 'resolved', resolvedAccessor);
+
+  return iterator;
+}
+
+
+/**
+ * Constructs Intl.v8BreakIterator object given optional locales and options
+ * parameters.
+ *
+ * @constructor
+ */
+%AddNamedProperty(Intl, 'v8BreakIterator', function() {
+    var locales = %_Arguments(0);
+    var options = %_Arguments(1);
+
+    if (!this || this === Intl) {
+      // Constructor is called as a function.
+      return new Intl.v8BreakIterator(locales, options);
+    }
+
+    return initializeBreakIterator(TO_OBJECT(this), locales, options);
+  },
+  DONT_ENUM
+);
+
+
+/**
+ * BreakIterator resolvedOptions method.
+ */
+%AddNamedProperty(Intl.v8BreakIterator.prototype, 'resolvedOptions',
+  function() {
+    if (!IS_UNDEFINED(new.target)) {
+      throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
+    }
+
+    if (!%IsInitializedIntlObjectOfType(this, 'breakiterator')) {
+      throw MakeTypeError(kResolvedOptionsCalledOnNonObject, "v8BreakIterator");
+    }
+
+    var segmenter = this;
+    var locale =
+        getOptimalLanguageTag(segmenter[resolvedSymbol].requestedLocale,
+                              segmenter[resolvedSymbol].locale);
+
+    return {
+      locale: locale,
+      type: segmenter[resolvedSymbol].type
+    };
+  },
+  DONT_ENUM
+);
+%FunctionSetName(Intl.v8BreakIterator.prototype.resolvedOptions,
+                 'resolvedOptions');
+%FunctionRemovePrototype(Intl.v8BreakIterator.prototype.resolvedOptions);
+%SetNativeFlag(Intl.v8BreakIterator.prototype.resolvedOptions);
+
+
+/**
+ * Returns the subset of the given locale list for which this locale list
+ * has a matching (possibly fallback) locale. Locales appear in the same
+ * order in the returned list as in the input list.
+ * Options are optional parameter.
+ */
+%AddNamedProperty(Intl.v8BreakIterator, 'supportedLocalesOf',
+  function(locales) {
+    if (!IS_UNDEFINED(new.target)) {
+      throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
+    }
+
+    return supportedLocalesOf('breakiterator', locales, %_Arguments(1));
+  },
+  DONT_ENUM
+);
+%FunctionSetName(Intl.v8BreakIterator.supportedLocalesOf, 'supportedLocalesOf');
+%FunctionRemovePrototype(Intl.v8BreakIterator.supportedLocalesOf);
+%SetNativeFlag(Intl.v8BreakIterator.supportedLocalesOf);
+
+
+/**
+ * Adopts text to segment using the iterator. Old text, if present,
+ * gets discarded.
+ */
+function adoptText(iterator, text) {
+  %BreakIteratorAdoptText(%GetImplFromInitializedIntlObject(iterator),
+                          GlobalString(text));
+}
+
+
+/**
+ * Returns index of the first break in the string and moves current pointer.
+ */
+function first(iterator) {
+  return %BreakIteratorFirst(%GetImplFromInitializedIntlObject(iterator));
+}
+
+
+/**
+ * Returns the index of the next break and moves the pointer.
+ */
+function next(iterator) {
+  return %BreakIteratorNext(%GetImplFromInitializedIntlObject(iterator));
+}
+
+
+/**
+ * Returns index of the current break.
+ */
+function current(iterator) {
+  return %BreakIteratorCurrent(%GetImplFromInitializedIntlObject(iterator));
+}
+
+
+/**
+ * Returns type of the current break.
+ */
+function breakType(iterator) {
+  return %BreakIteratorBreakType(%GetImplFromInitializedIntlObject(iterator));
+}
+
+
+addBoundMethod(Intl.v8BreakIterator, 'adoptText', adoptText, 1);
+addBoundMethod(Intl.v8BreakIterator, 'first', first, 0);
+addBoundMethod(Intl.v8BreakIterator, 'next', next, 0);
+addBoundMethod(Intl.v8BreakIterator, 'current', current, 0);
+addBoundMethod(Intl.v8BreakIterator, 'breakType', breakType, 0);
+
+// Save references to Intl objects and methods we use, for added security.
+var savedObjects = {
+  'collator': Intl.Collator,
+  'numberformat': Intl.NumberFormat,
+  'dateformatall': Intl.DateTimeFormat,
+  'dateformatdate': Intl.DateTimeFormat,
+  'dateformattime': Intl.DateTimeFormat
+};
+
+
+// Default (created with undefined locales and options parameters) collator,
+// number and date format instances. They'll be created as needed.
+var defaultObjects = {
+  'collator': UNDEFINED,
+  'numberformat': UNDEFINED,
+  'dateformatall': UNDEFINED,
+  'dateformatdate': UNDEFINED,
+  'dateformattime': UNDEFINED,
+};
+
+
+/**
+ * Returns cached or newly created instance of a given service.
+ * We cache only default instances (where no locales or options are provided).
+ */
+function cachedOrNewService(service, locales, options, defaults) {
+  var useOptions = (IS_UNDEFINED(defaults)) ? options : defaults;
+  if (IS_UNDEFINED(locales) && IS_UNDEFINED(options)) {
+    if (IS_UNDEFINED(defaultObjects[service])) {
+      defaultObjects[service] = new savedObjects[service](locales, useOptions);
+    }
+    return defaultObjects[service];
+  }
+  return new savedObjects[service](locales, useOptions);
+}
+
+
+function OverrideFunction(object, name, f) {
+  %CheckIsBootstrapping();
+  ObjectDefineProperty(object, name, { value: f,
+                                       writeable: true,
+                                       configurable: true,
+                                       enumerable: false });
+  %FunctionSetName(f, name);
+  %FunctionRemovePrototype(f);
+  %SetNativeFlag(f);
+}
+
+/**
+ * Compares this and that, and returns less than 0, 0 or greater than 0 value.
+ * Overrides the built-in method.
+ */
+OverrideFunction(GlobalString.prototype, 'localeCompare', function(that) {
+    if (!IS_UNDEFINED(new.target)) {
+      throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
+    }
+
+    if (IS_NULL_OR_UNDEFINED(this)) {
+      throw MakeTypeError(kMethodInvokedOnNullOrUndefined);
+    }
+
+    var locales = %_Arguments(1);
+    var options = %_Arguments(2);
+    var collator = cachedOrNewService('collator', locales, options);
+    return compare(collator, this, that);
+  }
+);
+
+
+/**
+ * Unicode normalization. This method is called with one argument that
+ * specifies the normalization form.
+ * If none is specified, "NFC" is assumed.
+ * If the form is not one of "NFC", "NFD", "NFKC", or "NFKD", then throw
+ * a RangeError Exception.
+ */
+
+OverrideFunction(GlobalString.prototype, 'normalize', function() {
+    if (!IS_UNDEFINED(new.target)) {
+      throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
+    }
+
+    CHECK_OBJECT_COERCIBLE(this, "String.prototype.normalize");
+    var s = TO_STRING(this);
+
+    var formArg = %_Arguments(0);
+    var form = IS_UNDEFINED(formArg) ? 'NFC' : TO_STRING(formArg);
+
+    var NORMALIZATION_FORMS = ['NFC', 'NFD', 'NFKC', 'NFKD'];
+
+    var normalizationForm = %_Call(ArrayIndexOf, NORMALIZATION_FORMS, form);
+    if (normalizationForm === -1) {
+      throw MakeRangeError(kNormalizationForm,
+          %_Call(ArrayJoin, NORMALIZATION_FORMS, ', '));
+    }
+
+    return %StringNormalize(s, normalizationForm);
+  }
+);
+
+
+/**
+ * Formats a Number object (this) using locale and options values.
+ * If locale or options are omitted, defaults are used.
+ */
+OverrideFunction(GlobalNumber.prototype, 'toLocaleString', function() {
+    if (!IS_UNDEFINED(new.target)) {
+      throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
+    }
+
+    if (!(this instanceof GlobalNumber) && typeof(this) !== 'number') {
+      throw MakeTypeError(kMethodInvokedOnWrongType, "Number");
+    }
+
+    var locales = %_Arguments(0);
+    var options = %_Arguments(1);
+    var numberFormat = cachedOrNewService('numberformat', locales, options);
+    return formatNumber(numberFormat, this);
+  }
+);
+
+
+/**
+ * Returns actual formatted date or fails if date parameter is invalid.
+ */
+function toLocaleDateTime(date, locales, options, required, defaults, service) {
+  if (!(date instanceof GlobalDate)) {
+    throw MakeTypeError(kMethodInvokedOnWrongType, "Date");
+  }
+
+  if (IsNaN(date)) return 'Invalid Date';
+
+  var internalOptions = toDateTimeOptions(options, required, defaults);
+
+  var dateFormat =
+      cachedOrNewService(service, locales, options, internalOptions);
+
+  return formatDate(dateFormat, date);
+}
+
+
+/**
+ * Formats a Date object (this) using locale and options values.
+ * If locale or options are omitted, defaults are used - both date and time are
+ * present in the output.
+ */
+OverrideFunction(GlobalDate.prototype, 'toLocaleString', function() {
+    if (!IS_UNDEFINED(new.target)) {
+      throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
+    }
+
+    var locales = %_Arguments(0);
+    var options = %_Arguments(1);
+    return toLocaleDateTime(
+        this, locales, options, 'any', 'all', 'dateformatall');
+  }
+);
+
+
+/**
+ * Formats a Date object (this) using locale and options values.
+ * If locale or options are omitted, defaults are used - only date is present
+ * in the output.
+ */
+OverrideFunction(GlobalDate.prototype, 'toLocaleDateString', function() {
+    if (!IS_UNDEFINED(new.target)) {
+      throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
+    }
+
+    var locales = %_Arguments(0);
+    var options = %_Arguments(1);
+    return toLocaleDateTime(
+        this, locales, options, 'date', 'date', 'dateformatdate');
+  }
+);
+
+
+/**
+ * Formats a Date object (this) using locale and options values.
+ * If locale or options are omitted, defaults are used - only time is present
+ * in the output.
+ */
+OverrideFunction(GlobalDate.prototype, 'toLocaleTimeString', function() {
+    if (!IS_UNDEFINED(new.target)) {
+      throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
+    }
+
+    var locales = %_Arguments(0);
+    var options = %_Arguments(1);
+    return toLocaleDateTime(
+        this, locales, options, 'time', 'time', 'dateformattime');
+  }
+);
+
+})
diff --git a/src/js/iterator-prototype.js b/src/js/iterator-prototype.js
new file mode 100644
index 0000000..6f25019
--- /dev/null
+++ b/src/js/iterator-prototype.js
@@ -0,0 +1,21 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function(global, utils) {
+  "use strict";
+  %CheckIsBootstrapping();
+
+  var GlobalObject = global.Object;
+  var IteratorPrototype = utils.ImportNow("IteratorPrototype");
+  var iteratorSymbol = utils.ImportNow("iterator_symbol");
+
+  // 25.1.2.1 %IteratorPrototype% [ @@iterator ] ( )
+  function IteratorPrototypeIterator() {
+    return this;
+  }
+
+  utils.SetFunctionName(IteratorPrototypeIterator, iteratorSymbol);
+  %AddNamedProperty(IteratorPrototype, iteratorSymbol,
+      IteratorPrototypeIterator, DONT_ENUM);
+})
diff --git a/src/js/json.js b/src/js/json.js
new file mode 100644
index 0000000..b8836ea
--- /dev/null
+++ b/src/js/json.js
@@ -0,0 +1,280 @@
+// Copyright 2009 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function(global, utils) {
+
+"use strict";
+
+%CheckIsBootstrapping();
+
+// -------------------------------------------------------------------
+// Imports
+
+var GlobalDate = global.Date;
+var GlobalJSON = global.JSON;
+var GlobalSet = global.Set;
+var InternalArray = utils.InternalArray;
+var MakeTypeError;
+var MaxSimple;
+var MinSimple;
+var ObjectHasOwnProperty;
+var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
+
+utils.Import(function(from) {
+  MakeTypeError = from.MakeTypeError;
+  MaxSimple = from.MaxSimple;
+  MinSimple = from.MinSimple;
+  ObjectHasOwnProperty = from.ObjectHasOwnProperty;
+});
+
+// -------------------------------------------------------------------
+
+function CreateDataProperty(o, p, v) {
+  var desc = {value: v, enumerable: true, writable: true, configurable: true};
+  return %reflect_define_property(o, p, desc);
+}
+
+
+function InternalizeJSONProperty(holder, name, reviver) {
+  var val = holder[name];
+  if (IS_RECEIVER(val)) {
+    if (%is_arraylike(val)) {
+      var length = TO_LENGTH(val.length);
+      for (var i = 0; i < length; i++) {
+        var newElement =
+            InternalizeJSONProperty(val, %_NumberToString(i), reviver);
+        if (IS_UNDEFINED(newElement)) {
+          %reflect_delete_property(val, i);
+        } else {
+          CreateDataProperty(val, i, newElement);
+        }
+      }
+    } else {
+      for (var p of %object_keys(val)) {
+        var newElement = InternalizeJSONProperty(val, p, reviver);
+        if (IS_UNDEFINED(newElement)) {
+          %reflect_delete_property(val, p);
+        } else {
+          CreateDataProperty(val, p, newElement);
+        }
+      }
+    }
+  }
+  return %_Call(reviver, holder, name, val);
+}
+
+
+function JSONParse(text, reviver) {
+  var unfiltered = %ParseJson(text);
+  if (IS_CALLABLE(reviver)) {
+    return InternalizeJSONProperty({'': unfiltered}, '', reviver);
+  } else {
+    return unfiltered;
+  }
+}
+
+
+function SerializeArray(value, replacer, stack, indent, gap) {
+  if (!%PushIfAbsent(stack, value)) throw MakeTypeError(kCircularStructure);
+  var stepback = indent;
+  indent += gap;
+  var partial = new InternalArray();
+  var len = TO_LENGTH(value.length);
+  for (var i = 0; i < len; i++) {
+    var strP = JSONSerialize(%_NumberToString(i), value, replacer, stack,
+                             indent, gap);
+    if (IS_UNDEFINED(strP)) {
+      strP = "null";
+    }
+    partial.push(strP);
+  }
+  var final;
+  if (gap == "") {
+    final = "[" + partial.join(",") + "]";
+  } else if (partial.length > 0) {
+    var separator = ",\n" + indent;
+    final = "[\n" + indent + partial.join(separator) + "\n" +
+        stepback + "]";
+  } else {
+    final = "[]";
+  }
+  stack.pop();
+  return final;
+}
+
+
+function SerializeObject(value, replacer, stack, indent, gap) {
+  if (!%PushIfAbsent(stack, value)) throw MakeTypeError(kCircularStructure);
+  var stepback = indent;
+  indent += gap;
+  var partial = new InternalArray();
+  if (IS_ARRAY(replacer)) {
+    var length = replacer.length;
+    for (var i = 0; i < length; i++) {
+      var p = replacer[i];
+      var strP = JSONSerialize(p, value, replacer, stack, indent, gap);
+      if (!IS_UNDEFINED(strP)) {
+        var member = %QuoteJSONString(p) + ":";
+        if (gap != "") member += " ";
+        member += strP;
+        partial.push(member);
+      }
+    }
+  } else {
+    for (var p of %object_keys(value)) {
+      var strP = JSONSerialize(p, value, replacer, stack, indent, gap);
+      if (!IS_UNDEFINED(strP)) {
+        var member = %QuoteJSONString(p) + ":";
+        if (gap != "") member += " ";
+        member += strP;
+        partial.push(member);
+      }
+    }
+  }
+  var final;
+  if (gap == "") {
+    final = "{" + partial.join(",") + "}";
+  } else if (partial.length > 0) {
+    var separator = ",\n" + indent;
+    final = "{\n" + indent + partial.join(separator) + "\n" +
+        stepback + "}";
+  } else {
+    final = "{}";
+  }
+  stack.pop();
+  return final;
+}
+
+
+function JSONSerialize(key, holder, replacer, stack, indent, gap) {
+  var value = holder[key];
+  if (IS_RECEIVER(value)) {
+    var toJSON = value.toJSON;
+    if (IS_CALLABLE(toJSON)) {
+      value = %_Call(toJSON, value, key);
+    }
+  }
+  if (IS_CALLABLE(replacer)) {
+    value = %_Call(replacer, holder, key, value);
+  }
+  if (IS_STRING(value)) {
+    return %QuoteJSONString(value);
+  } else if (IS_NUMBER(value)) {
+    return JSON_NUMBER_TO_STRING(value);
+  } else if (IS_BOOLEAN(value)) {
+    return value ? "true" : "false";
+  } else if (IS_NULL(value)) {
+    return "null";
+  } else if (IS_RECEIVER(value) && !IS_CALLABLE(value)) {
+    // Non-callable object. If it's a primitive wrapper, it must be unwrapped.
+    if (%is_arraylike(value)) {
+      return SerializeArray(value, replacer, stack, indent, gap);
+    } else if (IS_NUMBER_WRAPPER(value)) {
+      value = TO_NUMBER(value);
+      return JSON_NUMBER_TO_STRING(value);
+    } else if (IS_STRING_WRAPPER(value)) {
+      return %QuoteJSONString(TO_STRING(value));
+    } else if (IS_BOOLEAN_WRAPPER(value)) {
+      return %_ValueOf(value) ? "true" : "false";
+    } else {
+      return SerializeObject(value, replacer, stack, indent, gap);
+    }
+  }
+  // Undefined or a callable object.
+  return UNDEFINED;
+}
+
+
+function JSONStringify(value, replacer, space) {
+  if (%_ArgumentsLength() == 1 && !IS_PROXY(value)) {
+    return %BasicJSONStringify(value);
+  }
+  if (!IS_CALLABLE(replacer) && %is_arraylike(replacer)) {
+    var property_list = new InternalArray();
+    var seen_properties = new GlobalSet();
+    var length = TO_LENGTH(replacer.length);
+    for (var i = 0; i < length; i++) {
+      var v = replacer[i];
+      var item;
+      if (IS_STRING(v)) {
+        item = v;
+      } else if (IS_NUMBER(v)) {
+        item = %_NumberToString(v);
+      } else if (IS_STRING_WRAPPER(v) || IS_NUMBER_WRAPPER(v)) {
+        item = TO_STRING(v);
+      } else {
+        continue;
+      }
+      if (!seen_properties.has(item)) {
+        property_list.push(item);
+        seen_properties.add(item);
+      }
+    }
+    replacer = property_list;
+  }
+  if (IS_OBJECT(space)) {
+    // Unwrap 'space' if it is wrapped
+    if (IS_NUMBER_WRAPPER(space)) {
+      space = TO_NUMBER(space);
+    } else if (IS_STRING_WRAPPER(space)) {
+      space = TO_STRING(space);
+    }
+  }
+  var gap;
+  if (IS_NUMBER(space)) {
+    space = MaxSimple(0, MinSimple(TO_INTEGER(space), 10));
+    gap = %_SubString("          ", 0, space);
+  } else if (IS_STRING(space)) {
+    if (space.length > 10) {
+      gap = %_SubString(space, 0, 10);
+    } else {
+      gap = space;
+    }
+  } else {
+    gap = "";
+  }
+  return JSONSerialize('', {'': value}, replacer, new InternalArray(), "", gap);
+}
+
+// -------------------------------------------------------------------
+
+%AddNamedProperty(GlobalJSON, toStringTagSymbol, "JSON", READ_ONLY | DONT_ENUM);
+
+// Set up non-enumerable properties of the JSON object.
+utils.InstallFunctions(GlobalJSON, DONT_ENUM, [
+  "parse", JSONParse,
+  "stringify", JSONStringify
+]);
+
+// -------------------------------------------------------------------
+// Date.toJSON
+
+// 20.3.4.37 Date.prototype.toJSON ( key )
+function DateToJSON(key) {
+  var o = TO_OBJECT(this);
+  var tv = TO_PRIMITIVE_NUMBER(o);
+  if (IS_NUMBER(tv) && !NUMBER_IS_FINITE(tv)) {
+    return null;
+  }
+  return o.toISOString();
+}
+
+// Set up non-enumerable functions of the Date prototype object.
+utils.InstallFunctions(GlobalDate.prototype, DONT_ENUM, [
+  "toJSON", DateToJSON
+]);
+
+// -------------------------------------------------------------------
+// JSON Builtins
+
+function JsonSerializeAdapter(key, object) {
+  var holder = {};
+  holder[key] = object;
+  // No need to pass the actual holder since there is no replacer function.
+  return JSONSerialize(key, holder, UNDEFINED, new InternalArray(), "", "");
+}
+
+%InstallToContext(["json_serialize_adapter", JsonSerializeAdapter]);
+
+})
diff --git a/src/js/macros.py b/src/js/macros.py
new file mode 100644
index 0000000..3bcc8c1
--- /dev/null
+++ b/src/js/macros.py
@@ -0,0 +1,269 @@
+# Copyright 2006-2009 the V8 project authors. All rights reserved.
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+#       copyright notice, this list of conditions and the following
+#       disclaimer in the documentation and/or other materials provided
+#       with the distribution.
+#     * Neither the name of Google Inc. nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Dictionary that is passed as defines for js2c.py.
+# Used for defines that must be defined for all native JS files.
+
+define NONE        = 0;
+define READ_ONLY   = 1;
+define DONT_ENUM   = 2;
+define DONT_DELETE = 4;
+define NEW_ONE_BYTE_STRING = true;
+define NEW_TWO_BYTE_STRING = false;
+
+# Constants used for getter and setter operations.
+define GETTER = 0;
+define SETTER = 1;
+
+# Safe maximum number of arguments to push to stack, when multiplied by
+# pointer size. Used by Function.prototype.apply(), Reflect.apply() and
+# Reflect.construct().
+define kSafeArgumentsLength = 0x800000;
+
+# 2^53 - 1
+define kMaxSafeInteger = 9007199254740991;
+
+# 2^32 - 1
+define kMaxUint32 = 4294967295;
+
+# Strict mode flags for passing to %SetProperty
+define kSloppyMode = 0;
+define kStrictMode = 1;
+
+# Native cache ids.
+define STRING_TO_REGEXP_CACHE_ID = 0;
+
+# Type query macros.
+#
+# Note: We have special support for typeof(foo) === 'bar' in the compiler.
+#       It will *not* generate a runtime typeof call for the most important
+#       values of 'bar'.
+macro IS_ARRAY(arg)             = (%_IsArray(arg));
+macro IS_ARRAYBUFFER(arg)       = (%_ClassOf(arg) === 'ArrayBuffer');
+macro IS_BOOLEAN(arg)           = (typeof(arg) === 'boolean');
+macro IS_BOOLEAN_WRAPPER(arg)   = (%_ClassOf(arg) === 'Boolean');
+macro IS_DATAVIEW(arg)          = (%_ClassOf(arg) === 'DataView');
+macro IS_DATE(arg)              = (%_IsDate(arg));
+macro IS_ERROR(arg)             = (%_ClassOf(arg) === 'Error');
+macro IS_FUNCTION(arg)          = (%_IsFunction(arg));
+macro IS_GENERATOR(arg)         = (%_ClassOf(arg) === 'Generator');
+macro IS_GLOBAL(arg)            = (%_ClassOf(arg) === 'global');
+macro IS_MAP(arg)               = (%_ClassOf(arg) === 'Map');
+macro IS_MAP_ITERATOR(arg)      = (%_ClassOf(arg) === 'Map Iterator');
+macro IS_NULL(arg)              = (arg === null);
+macro IS_NULL_OR_UNDEFINED(arg) = (arg == null);
+macro IS_NUMBER(arg)            = (typeof(arg) === 'number');
+macro IS_NUMBER_WRAPPER(arg)    = (%_ClassOf(arg) === 'Number');
+macro IS_OBJECT(arg)            = (typeof(arg) === 'object');
+macro IS_PROXY(arg)             = (%_IsJSProxy(arg));
+macro IS_REGEXP(arg)            = (%_IsRegExp(arg));
+macro IS_SCRIPT(arg)            = (%_ClassOf(arg) === 'Script');
+macro IS_SET(arg)               = (%_ClassOf(arg) === 'Set');
+macro IS_SET_ITERATOR(arg)      = (%_ClassOf(arg) === 'Set Iterator');
+macro IS_SHAREDARRAYBUFFER(arg) = (%_ClassOf(arg) === 'SharedArrayBuffer');
+macro IS_SIMD_VALUE(arg)        = (%_IsSimdValue(arg));
+macro IS_STRING(arg)            = (typeof(arg) === 'string');
+macro IS_STRING_WRAPPER(arg)    = (%_ClassOf(arg) === 'String');
+macro IS_STRONG(arg)            = (%IsStrong(arg));
+macro IS_SYMBOL(arg)            = (typeof(arg) === 'symbol');
+macro IS_SYMBOL_WRAPPER(arg)    = (%_ClassOf(arg) === 'Symbol');
+macro IS_UNDEFINED(arg)         = (arg === (void 0));
+macro IS_WEAKMAP(arg)           = (%_ClassOf(arg) === 'WeakMap');
+macro IS_WEAKSET(arg)           = (%_ClassOf(arg) === 'WeakSet');
+
+# Macro for ES queries of the type: "Type(O) is Object."
+macro IS_RECEIVER(arg) = (%_IsJSReceiver(arg));
+
+# Macro for ES queries of the type: "IsCallable(O)"
+macro IS_CALLABLE(arg) = (typeof(arg) === 'function');
+
+# Macro for ES6 CheckObjectCoercible
+# Will throw a TypeError of the form "[functionName] called on null or undefined".
+macro CHECK_OBJECT_COERCIBLE(arg, functionName) = if (IS_NULL(%IS_VAR(arg)) || IS_UNDEFINED(arg)) throw MakeTypeError(kCalledOnNullOrUndefined, functionName);
+
+# Inline macros. Use %IS_VAR to make sure arg is evaluated only once.
+macro NUMBER_IS_NAN(arg) = (!%_IsSmi(%IS_VAR(arg)) && !(arg == arg));
+macro NUMBER_IS_FINITE(arg) = (%_IsSmi(%IS_VAR(arg)) || ((arg == arg) && (arg != 1/0) && (arg != -1/0)));
+macro TO_BOOLEAN(arg) = (!!(arg));
+macro TO_INTEGER(arg) = (%_ToInteger(arg));
+macro TO_INTEGER_MAP_MINUS_ZERO(arg) = (%_IsSmi(%IS_VAR(arg)) ? arg : %NumberToIntegerMapMinusZero(arg));
+macro TO_INT32(arg) = ((arg) | 0);
+macro TO_UINT32(arg) = ((arg) >>> 0);
+macro TO_LENGTH(arg) = (%_ToLength(arg));
+macro TO_LENGTH_OR_UINT32(arg) = (FLAG_harmony_tolength ? TO_LENGTH(arg) : TO_UINT32(arg));
+macro TO_LENGTH_OR_INTEGER(arg) = (FLAG_harmony_tolength ? TO_LENGTH(arg) : TO_INTEGER(arg));
+macro TO_STRING(arg) = (%_ToString(arg));
+macro TO_NUMBER(arg) = (%_ToNumber(arg));
+macro TO_OBJECT(arg) = (%_ToObject(arg));
+macro TO_PRIMITIVE(arg) = (%_ToPrimitive(arg));
+macro TO_PRIMITIVE_NUMBER(arg) = (%_ToPrimitive_Number(arg));
+macro TO_PRIMITIVE_STRING(arg) = (%_ToPrimitive_String(arg));
+macro TO_NAME(arg) = (%_ToName(arg));
+macro JSON_NUMBER_TO_STRING(arg) = ((%_IsSmi(%IS_VAR(arg)) || arg - arg == 0) ? %_NumberToString(arg) : "null");
+macro HAS_OWN_PROPERTY(arg, index) = (%_Call(ObjectHasOwnProperty, arg, index));
+macro HAS_INDEX(array, index, is_array) = ((is_array && %_HasFastPackedElements(%IS_VAR(array))) ? (index < array.length) : (index in array));
+
+# Private names.
+macro IS_PRIVATE(sym) = (%SymbolIsPrivate(sym));
+macro HAS_PRIVATE(obj, sym) = (%HasOwnProperty(obj, sym));
+macro HAS_DEFINED_PRIVATE(obj, sym) = (!IS_UNDEFINED(obj[sym]));
+macro GET_PRIVATE(obj, sym) = (obj[sym]);
+macro SET_PRIVATE(obj, sym, val) = (obj[sym] = val);
+
+# Constants.  The compiler constant folds them.
+define INFINITY = (1/0);
+define UNDEFINED = (void 0);
+
+# Macros implemented in Python.
+python macro CHAR_CODE(str) = ord(str[1]);
+
+# Constants used on an array to implement the properties of the RegExp object.
+define REGEXP_NUMBER_OF_CAPTURES = 0;
+define REGEXP_FIRST_CAPTURE = 3;
+
+# Macros for internal slot access.
+macro REGEXP_GLOBAL(regexp) = (%_RegExpFlags(regexp) & 1);
+macro REGEXP_IGNORE_CASE(regexp) = (%_RegExpFlags(regexp) & 2);
+macro REGEXP_MULTILINE(regexp) = (%_RegExpFlags(regexp) & 4);
+macro REGEXP_STICKY(regexp) = (%_RegExpFlags(regexp) & 8);
+macro REGEXP_UNICODE(regexp) = (%_RegExpFlags(regexp) & 16);
+macro REGEXP_SOURCE(regexp) = (%_RegExpSource(regexp));
+
+# We can't put macros in macros so we use constants here.
+# REGEXP_NUMBER_OF_CAPTURES
+macro NUMBER_OF_CAPTURES(array) = ((array)[0]);
+
+# Last input and last subject of regexp matches.
+define LAST_SUBJECT_INDEX = 1;
+macro LAST_SUBJECT(array) = ((array)[1]);
+macro LAST_INPUT(array) = ((array)[2]);
+
+# REGEXP_FIRST_CAPTURE
+macro CAPTURE(index) = (3 + (index));
+define CAPTURE0 = 3;
+define CAPTURE1 = 4;
+
+# For the regexp capture override array.  This has the same
+# format as the arguments to a function called from
+# String.prototype.replace.
+macro OVERRIDE_MATCH(override) = ((override)[0]);
+macro OVERRIDE_POS(override) = ((override)[(override).length - 2]);
+macro OVERRIDE_SUBJECT(override) = ((override)[(override).length - 1]);
+# 1-based so index of 1 returns the first capture
+macro OVERRIDE_CAPTURE(override, index) = ((override)[(index)]);
+
+# PropertyDescriptor return value indices - must match
+# PropertyDescriptorIndices in runtime-object.cc.
+define IS_ACCESSOR_INDEX = 0;
+define VALUE_INDEX = 1;
+define GETTER_INDEX = 2;
+define SETTER_INDEX = 3;
+define WRITABLE_INDEX = 4;
+define ENUMERABLE_INDEX = 5;
+define CONFIGURABLE_INDEX = 6;
+
+# For messages.js
+# Matches Script::Type from objects.h
+define TYPE_NATIVE = 0;
+define TYPE_EXTENSION = 1;
+define TYPE_NORMAL = 2;
+
+# Matches Script::CompilationType from objects.h
+define COMPILATION_TYPE_HOST = 0;
+define COMPILATION_TYPE_EVAL = 1;
+define COMPILATION_TYPE_JSON = 2;
+
+# Matches Messages::kNoLineNumberInfo from v8.h
+define kNoLineNumberInfo = 0;
+
+# Must match PropertyFilter in property-details.h
+define PROPERTY_FILTER_NONE = 0;
+define PROPERTY_FILTER_ONLY_ENUMERABLE = 2;
+define PROPERTY_FILTER_SKIP_STRINGS = 8;
+define PROPERTY_FILTER_SKIP_SYMBOLS = 16;
+
+# Use for keys, values and entries iterators.
+define ITERATOR_KIND_KEYS = 1;
+define ITERATOR_KIND_VALUES = 2;
+define ITERATOR_KIND_ENTRIES = 3;
+
+macro FIXED_ARRAY_GET(array, index) = (%_FixedArrayGet(array, (index) | 0));
+macro FIXED_ARRAY_SET(array, index, value) = (%_FixedArraySet(array, (index) | 0, value));
+# TODO(adamk): Find a more robust way to force Smi representation.
+macro FIXED_ARRAY_SET_SMI(array, index, value) = (FIXED_ARRAY_SET(array, index, (value) | 0));
+
+macro ORDERED_HASH_TABLE_BUCKET_COUNT(table) = (FIXED_ARRAY_GET(table, 0));
+macro ORDERED_HASH_TABLE_ELEMENT_COUNT(table) = (FIXED_ARRAY_GET(table, 1));
+macro ORDERED_HASH_TABLE_SET_ELEMENT_COUNT(table, count) = (FIXED_ARRAY_SET_SMI(table, 1, count));
+macro ORDERED_HASH_TABLE_DELETED_COUNT(table) = (FIXED_ARRAY_GET(table, 2));
+macro ORDERED_HASH_TABLE_SET_DELETED_COUNT(table, count) = (FIXED_ARRAY_SET_SMI(table, 2, count));
+macro ORDERED_HASH_TABLE_BUCKET_AT(table, bucket) = (FIXED_ARRAY_GET(table, 3 + (bucket)));
+macro ORDERED_HASH_TABLE_SET_BUCKET_AT(table, bucket, entry) = (FIXED_ARRAY_SET(table, 3 + (bucket), entry));
+
+macro ORDERED_HASH_TABLE_HASH_TO_BUCKET(hash, numBuckets) = (hash & ((numBuckets) - 1));
+
+macro ORDERED_HASH_SET_ENTRY_TO_INDEX(entry, numBuckets) = (3 + (numBuckets) + ((entry) << 1));
+macro ORDERED_HASH_SET_KEY_AT(table, entry, numBuckets) = (FIXED_ARRAY_GET(table, ORDERED_HASH_SET_ENTRY_TO_INDEX(entry, numBuckets)));
+macro ORDERED_HASH_SET_CHAIN_AT(table, entry, numBuckets) = (FIXED_ARRAY_GET(table, ORDERED_HASH_SET_ENTRY_TO_INDEX(entry, numBuckets) + 1));
+
+macro ORDERED_HASH_MAP_ENTRY_TO_INDEX(entry, numBuckets) = (3 + (numBuckets) + ((entry) * 3));
+macro ORDERED_HASH_MAP_KEY_AT(table, entry, numBuckets) = (FIXED_ARRAY_GET(table, ORDERED_HASH_MAP_ENTRY_TO_INDEX(entry, numBuckets)));
+macro ORDERED_HASH_MAP_VALUE_AT(table, entry, numBuckets) = (FIXED_ARRAY_GET(table, ORDERED_HASH_MAP_ENTRY_TO_INDEX(entry, numBuckets) + 1));
+macro ORDERED_HASH_MAP_CHAIN_AT(table, entry, numBuckets) = (FIXED_ARRAY_GET(table, ORDERED_HASH_MAP_ENTRY_TO_INDEX(entry, numBuckets) + 2));
+
+# Must match OrderedHashTable::kNotFound.
+define NOT_FOUND = -1;
+
+# Check whether debug is active.
+define DEBUG_IS_ACTIVE = (%_DebugIsActive() != 0);
+macro DEBUG_PREPARE_STEP_IN_IF_STEPPING(function) = if (%_DebugIsActive() != 0) %DebugPrepareStepInIfStepping(function);
+
+# SharedFlag equivalents
+define kNotShared = false;
+define kShared = true;
+
+# UseCounters from include/v8.h
+define kUseAsm = 0;
+define kBreakIterator = 1;
+define kLegacyConst = 2;
+define kMarkDequeOverflow = 3;
+define kStoreBufferOverflow = 4;
+define kSlotsBufferOverflow = 5;
+define kObjectObserve = 6;
+define kForcedGC = 7;
+define kSloppyMode = 8;
+define kStrictMode = 9;
+define kStrongMode = 10;
+define kRegExpPrototypeStickyGetter = 11;
+define kRegExpPrototypeToString = 12;
+define kRegExpPrototypeUnicodeGetter = 13;
+define kIntlV8Parse = 14;
+define kIntlPattern = 15;
+define kIntlResolved = 16;
+define kPromiseChain = 17;
+define kPromiseAccept = 18;
+define kPromiseDefer = 19;
diff --git a/src/js/math.js b/src/js/math.js
new file mode 100644
index 0000000..990a7e9
--- /dev/null
+++ b/src/js/math.js
@@ -0,0 +1,356 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function(global, utils) {
+"use strict";
+
+%CheckIsBootstrapping();
+
+// -------------------------------------------------------------------
+// Imports
+
+define kRandomBatchSize = 64;
+// The first two slots are reserved to persist PRNG state.
+define kRandomNumberStart = 2;
+
+var GlobalFloat64Array = global.Float64Array;
+var GlobalMath = global.Math;
+var GlobalObject = global.Object;
+var InternalArray = utils.InternalArray;
+var NaN = %GetRootNaN();
+var nextRandomIndex = kRandomBatchSize;
+var randomNumbers = UNDEFINED;
+var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
+
+//-------------------------------------------------------------------
+
+// ECMA 262 - 15.8.2.1
+function MathAbs(x) {
+  x = +x;
+  return (x > 0) ? x : 0 - x;
+}
+
+// ECMA 262 - 15.8.2.2
+function MathAcosJS(x) {
+  return %_MathAcos(+x);
+}
+
+// ECMA 262 - 15.8.2.3
+function MathAsinJS(x) {
+  return %_MathAsin(+x);
+}
+
+// ECMA 262 - 15.8.2.4
+function MathAtanJS(x) {
+  return %_MathAtan(+x);
+}
+
+// ECMA 262 - 15.8.2.5
+// The naming of y and x matches the spec, as does the order in which
+// ToNumber (valueOf) is called.
+function MathAtan2JS(y, x) {
+  y = +y;
+  x = +x;
+  return %_MathAtan2(y, x);
+}
+
+// ECMA 262 - 15.8.2.6
+function MathCeil(x) {
+  return -%_MathFloor(-x);
+}
+
+// ECMA 262 - 15.8.2.8
+function MathExp(x) {
+  return %MathExpRT(TO_NUMBER(x));
+}
+
+// ECMA 262 - 15.8.2.9
+function MathFloorJS(x) {
+  return %_MathFloor(+x);
+}
+
+// ECMA 262 - 15.8.2.10
+function MathLog(x) {
+  return %_MathLogRT(TO_NUMBER(x));
+}
+
+// ECMA 262 - 15.8.2.11
+function MathMax(arg1, arg2) {  // length == 2
+  var length = %_ArgumentsLength();
+  if (length == 2) {
+    arg1 = TO_NUMBER(arg1);
+    arg2 = TO_NUMBER(arg2);
+    if (arg2 > arg1) return arg2;
+    if (arg1 > arg2) return arg1;
+    if (arg1 == arg2) {
+      // Make sure -0 is considered less than +0.
+      return (arg1 === 0 && %_IsMinusZero(arg1)) ? arg2 : arg1;
+    }
+    // All comparisons failed, one of the arguments must be NaN.
+    return NaN;
+  }
+  var r = -INFINITY;
+  for (var i = 0; i < length; i++) {
+    var n = %_Arguments(i);
+    n = TO_NUMBER(n);
+    // Make sure +0 is considered greater than -0.
+    if (NUMBER_IS_NAN(n) || n > r || (r === 0 && n === 0 && %_IsMinusZero(r))) {
+      r = n;
+    }
+  }
+  return r;
+}
+
+// ECMA 262 - 15.8.2.12
+function MathMin(arg1, arg2) {  // length == 2
+  var length = %_ArgumentsLength();
+  if (length == 2) {
+    arg1 = TO_NUMBER(arg1);
+    arg2 = TO_NUMBER(arg2);
+    if (arg2 > arg1) return arg1;
+    if (arg1 > arg2) return arg2;
+    if (arg1 == arg2) {
+      // Make sure -0 is considered less than +0.
+      return (arg1 === 0 && %_IsMinusZero(arg1)) ? arg1 : arg2;
+    }
+    // All comparisons failed, one of the arguments must be NaN.
+    return NaN;
+  }
+  var r = INFINITY;
+  for (var i = 0; i < length; i++) {
+    var n = %_Arguments(i);
+    n = TO_NUMBER(n);
+    // Make sure -0 is considered less than +0.
+    if (NUMBER_IS_NAN(n) || n < r || (r === 0 && n === 0 && %_IsMinusZero(n))) {
+      r = n;
+    }
+  }
+  return r;
+}
+
+// ECMA 262 - 15.8.2.13
+function MathPowJS(x, y) {
+  return %_MathPow(TO_NUMBER(x), TO_NUMBER(y));
+}
+
+// ECMA 262 - 15.8.2.14
+function MathRandom() {
+  if (nextRandomIndex >= kRandomBatchSize) {
+    randomNumbers = %GenerateRandomNumbers(randomNumbers);
+    nextRandomIndex = kRandomNumberStart;
+  }
+  return randomNumbers[nextRandomIndex++];
+}
+
+function MathRandomRaw() {
+  if (nextRandomIndex >= kRandomBatchSize) {
+    randomNumbers = %GenerateRandomNumbers(randomNumbers);
+    nextRandomIndex = kRandomNumberStart;
+  }
+  return %_DoubleLo(randomNumbers[nextRandomIndex++]) & 0x3FFFFFFF;
+}
+
+// ECMA 262 - 15.8.2.15
+function MathRound(x) {
+  return %RoundNumber(TO_NUMBER(x));
+}
+
+// ECMA 262 - 15.8.2.17
+function MathSqrtJS(x) {
+  return %_MathSqrt(+x);
+}
+
+// Non-standard extension.
+function MathImul(x, y) {
+  return %NumberImul(TO_NUMBER(x), TO_NUMBER(y));
+}
+
+// ES6 draft 09-27-13, section 20.2.2.28.
+function MathSign(x) {
+  x = +x;
+  if (x > 0) return 1;
+  if (x < 0) return -1;
+  // -0, 0 or NaN.
+  return x;
+}
+
+// ES6 draft 09-27-13, section 20.2.2.34.
+function MathTrunc(x) {
+  x = +x;
+  if (x > 0) return %_MathFloor(x);
+  if (x < 0) return -%_MathFloor(-x);
+  // -0, 0 or NaN.
+  return x;
+}
+
+// ES6 draft 09-27-13, section 20.2.2.5.
+function MathAsinh(x) {
+  x = TO_NUMBER(x);
+  // Idempotent for NaN, +/-0 and +/-Infinity.
+  if (x === 0 || !NUMBER_IS_FINITE(x)) return x;
+  if (x > 0) return MathLog(x + %_MathSqrt(x * x + 1));
+  // This is to prevent numerical errors caused by large negative x.
+  return -MathLog(-x + %_MathSqrt(x * x + 1));
+}
+
+// ES6 draft 09-27-13, section 20.2.2.3.
+function MathAcosh(x) {
+  x = TO_NUMBER(x);
+  if (x < 1) return NaN;
+  // Idempotent for NaN and +Infinity.
+  if (!NUMBER_IS_FINITE(x)) return x;
+  return MathLog(x + %_MathSqrt(x + 1) * %_MathSqrt(x - 1));
+}
+
+// ES6 draft 09-27-13, section 20.2.2.7.
+function MathAtanh(x) {
+  x = TO_NUMBER(x);
+  // Idempotent for +/-0.
+  if (x === 0) return x;
+  // Returns NaN for NaN and +/- Infinity.
+  if (!NUMBER_IS_FINITE(x)) return NaN;
+  return 0.5 * MathLog((1 + x) / (1 - x));
+}
+
+// ES6 draft 09-27-13, section 20.2.2.17.
+function MathHypot(x, y) {  // Function length is 2.
+  // We may want to introduce fast paths for two arguments and when
+  // normalization to avoid overflow is not necessary.  For now, we
+  // simply assume the general case.
+  var length = %_ArgumentsLength();
+  var args = new InternalArray(length);
+  var max = 0;
+  for (var i = 0; i < length; i++) {
+    var n = %_Arguments(i);
+    n = TO_NUMBER(n);
+    if (n === INFINITY || n === -INFINITY) return INFINITY;
+    n = MathAbs(n);
+    if (n > max) max = n;
+    args[i] = n;
+  }
+
+  // Kahan summation to avoid rounding errors.
+  // Normalize the numbers to the largest one to avoid overflow.
+  if (max === 0) max = 1;
+  var sum = 0;
+  var compensation = 0;
+  for (var i = 0; i < length; i++) {
+    var n = args[i] / max;
+    var summand = n * n - compensation;
+    var preliminary = sum + summand;
+    compensation = (preliminary - sum) - summand;
+    sum = preliminary;
+  }
+  return %_MathSqrt(sum) * max;
+}
+
+// ES6 draft 09-27-13, section 20.2.2.16.
+function MathFroundJS(x) {
+  return %MathFround(TO_NUMBER(x));
+}
+
+// ES6 draft 07-18-14, section 20.2.2.11
+function MathClz32JS(x) {
+  return %_MathClz32(x >>> 0);
+}
+
+// ES6 draft 09-27-13, section 20.2.2.9.
+// Cube root approximation, refer to: http://metamerist.com/cbrt/cbrt.htm
+// Using initial approximation adapted from Kahan's cbrt and 4 iterations
+// of Newton's method.
+function MathCbrt(x) {
+  x = TO_NUMBER(x);
+  if (x == 0 || !NUMBER_IS_FINITE(x)) return x;
+  return x >= 0 ? CubeRoot(x) : -CubeRoot(-x);
+}
+
+macro NEWTON_ITERATION_CBRT(x, approx)
+  (1.0 / 3.0) * (x / (approx * approx) + 2 * approx);
+endmacro
+
+function CubeRoot(x) {
+  var approx_hi = MathFloorJS(%_DoubleHi(x) / 3) + 0x2A9F7893;
+  var approx = %_ConstructDouble(approx_hi | 0, 0);
+  approx = NEWTON_ITERATION_CBRT(x, approx);
+  approx = NEWTON_ITERATION_CBRT(x, approx);
+  approx = NEWTON_ITERATION_CBRT(x, approx);
+  return NEWTON_ITERATION_CBRT(x, approx);
+}
+
+// -------------------------------------------------------------------
+
+%AddNamedProperty(GlobalMath, toStringTagSymbol, "Math", READ_ONLY | DONT_ENUM);
+
+// Set up math constants.
+utils.InstallConstants(GlobalMath, [
+  // ECMA-262, section 15.8.1.1.
+  "E", 2.7182818284590452354,
+  // ECMA-262, section 15.8.1.2.
+  "LN10", 2.302585092994046,
+  // ECMA-262, section 15.8.1.3.
+  "LN2", 0.6931471805599453,
+  // ECMA-262, section 15.8.1.4.
+  "LOG2E", 1.4426950408889634,
+  "LOG10E", 0.4342944819032518,
+  "PI", 3.1415926535897932,
+  "SQRT1_2", 0.7071067811865476,
+  "SQRT2", 1.4142135623730951
+]);
+
+// Set up non-enumerable functions of the Math object and
+// set their names.
+utils.InstallFunctions(GlobalMath, DONT_ENUM, [
+  "random", MathRandom,
+  "abs", MathAbs,
+  "acos", MathAcosJS,
+  "asin", MathAsinJS,
+  "atan", MathAtanJS,
+  "ceil", MathCeil,
+  "exp", MathExp,
+  "floor", MathFloorJS,
+  "log", MathLog,
+  "round", MathRound,
+  "sqrt", MathSqrtJS,
+  "atan2", MathAtan2JS,
+  "pow", MathPowJS,
+  "max", MathMax,
+  "min", MathMin,
+  "imul", MathImul,
+  "sign", MathSign,
+  "trunc", MathTrunc,
+  "asinh", MathAsinh,
+  "acosh", MathAcosh,
+  "atanh", MathAtanh,
+  "hypot", MathHypot,
+  "fround", MathFroundJS,
+  "clz32", MathClz32JS,
+  "cbrt", MathCbrt
+]);
+
+%SetForceInlineFlag(MathAbs);
+%SetForceInlineFlag(MathAcosJS);
+%SetForceInlineFlag(MathAsinJS);
+%SetForceInlineFlag(MathAtanJS);
+%SetForceInlineFlag(MathAtan2JS);
+%SetForceInlineFlag(MathCeil);
+%SetForceInlineFlag(MathClz32JS);
+%SetForceInlineFlag(MathFloorJS);
+%SetForceInlineFlag(MathRandom);
+%SetForceInlineFlag(MathSign);
+%SetForceInlineFlag(MathSqrtJS);
+%SetForceInlineFlag(MathTrunc);
+
+// -------------------------------------------------------------------
+// Exports
+
+utils.Export(function(to) {
+  to.MathAbs = MathAbs;
+  to.MathExp = MathExp;
+  to.MathFloor = MathFloorJS;
+  to.IntRandom = MathRandomRaw;
+  to.MathMax = MathMax;
+  to.MathMin = MathMin;
+});
+
+})
diff --git a/src/js/messages.js b/src/js/messages.js
new file mode 100644
index 0000000..feb14d3
--- /dev/null
+++ b/src/js/messages.js
@@ -0,0 +1,1014 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// -------------------------------------------------------------------
+
+(function(global, utils) {
+
+%CheckIsBootstrapping();
+
+// -------------------------------------------------------------------
+// Imports
+
+var ArrayJoin;
+var Bool16x8ToString;
+var Bool32x4ToString;
+var Bool8x16ToString;
+var callSiteReceiverSymbol =
+    utils.ImportNow("call_site_receiver_symbol");
+var callSiteFunctionSymbol =
+    utils.ImportNow("call_site_function_symbol");
+var callSitePositionSymbol =
+    utils.ImportNow("call_site_position_symbol");
+var callSiteStrictSymbol =
+    utils.ImportNow("call_site_strict_symbol");
+var FLAG_harmony_tostring;
+var Float32x4ToString;
+var formattedStackTraceSymbol =
+    utils.ImportNow("formatted_stack_trace_symbol");
+var GlobalObject = global.Object;
+var Int16x8ToString;
+var Int32x4ToString;
+var Int8x16ToString;
+var InternalArray = utils.InternalArray;
+var internalErrorSymbol = utils.ImportNow("internal_error_symbol");
+var ObjectDefineProperty;
+var ObjectToString = utils.ImportNow("object_to_string");
+var Script = utils.ImportNow("Script");
+var stackTraceSymbol = utils.ImportNow("stack_trace_symbol");
+var StringCharAt;
+var StringIndexOf;
+var StringSubstring;
+var SymbolToString;
+var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
+var Uint16x8ToString;
+var Uint32x4ToString;
+var Uint8x16ToString;
+
+utils.Import(function(from) {
+  ArrayJoin = from.ArrayJoin;
+  Bool16x8ToString = from.Bool16x8ToString;
+  Bool32x4ToString = from.Bool32x4ToString;
+  Bool8x16ToString = from.Bool8x16ToString;
+  Float32x4ToString = from.Float32x4ToString;
+  Int16x8ToString = from.Int16x8ToString;
+  Int32x4ToString = from.Int32x4ToString;
+  Int8x16ToString = from.Int8x16ToString;
+  ObjectDefineProperty = from.ObjectDefineProperty;
+  StringCharAt = from.StringCharAt;
+  StringIndexOf = from.StringIndexOf;
+  StringSubstring = from.StringSubstring;
+  SymbolToString = from.SymbolToString;
+  Uint16x8ToString = from.Uint16x8ToString;
+  Uint32x4ToString = from.Uint32x4ToString;
+  Uint8x16ToString = from.Uint8x16ToString;
+});
+
+utils.ImportFromExperimental(function(from) {
+  FLAG_harmony_tostring = from.FLAG_harmony_tostring;
+});
+
+// -------------------------------------------------------------------
+
+var GlobalError;
+var GlobalTypeError;
+var GlobalRangeError;
+var GlobalURIError;
+var GlobalSyntaxError;
+var GlobalReferenceError;
+var GlobalEvalError;
+
+
+function NoSideEffectsObjectToString() {
+  if (IS_UNDEFINED(this)) return "[object Undefined]";
+  if (IS_NULL(this)) return "[object Null]";
+  var O = TO_OBJECT(this);
+  var builtinTag = %_ClassOf(O);
+  var tag;
+  if (FLAG_harmony_tostring) {
+    tag = %GetDataProperty(O, toStringTagSymbol);
+    if (!IS_STRING(tag)) {
+      tag = builtinTag;
+    }
+  } else {
+    tag = builtinTag;
+  }
+  return `[object ${tag}]`;
+}
+
+function IsErrorObject(obj) {
+  return HAS_PRIVATE(obj, stackTraceSymbol);
+}
+
+function NoSideEffectsErrorToString() {
+  var name = %GetDataProperty(this, "name");
+  var message = %GetDataProperty(this, "message");
+  name = IS_UNDEFINED(name) ? "Error" : NoSideEffectsToString(name);
+  message = IS_UNDEFINED(message) ? "" : NoSideEffectsToString(message);
+  if (name == "") return message;
+  if (message == "") return name;
+  return `${name}: ${message}`;
+}
+
+function NoSideEffectsToString(obj) {
+  if (IS_STRING(obj)) return obj;
+  if (IS_NUMBER(obj)) return %_NumberToString(obj);
+  if (IS_BOOLEAN(obj)) return obj ? 'true' : 'false';
+  if (IS_UNDEFINED(obj)) return 'undefined';
+  if (IS_NULL(obj)) return 'null';
+  if (IS_FUNCTION(obj)) {
+    var str = %FunctionToString(obj);
+    if (str.length > 128) {
+      str = %_SubString(str, 0, 111) + "...<omitted>..." +
+            %_SubString(str, str.length - 2, str.length);
+    }
+    return str;
+  }
+  if (IS_SYMBOL(obj)) return %_Call(SymbolToString, obj);
+  if (IS_SIMD_VALUE(obj)) {
+    switch (typeof(obj)) {
+      case 'float32x4': return %_Call(Float32x4ToString, obj);
+      case 'int32x4':   return %_Call(Int32x4ToString, obj);
+      case 'int16x8':   return %_Call(Int16x8ToString, obj);
+      case 'int8x16':   return %_Call(Int8x16ToString, obj);
+      case 'uint32x4':   return %_Call(Uint32x4ToString, obj);
+      case 'uint16x8':   return %_Call(Uint16x8ToString, obj);
+      case 'uint8x16':   return %_Call(Uint8x16ToString, obj);
+      case 'bool32x4':  return %_Call(Bool32x4ToString, obj);
+      case 'bool16x8':  return %_Call(Bool16x8ToString, obj);
+      case 'bool8x16':  return %_Call(Bool8x16ToString, obj);
+    }
+  }
+
+  if (IS_RECEIVER(obj)) {
+    // When internally formatting error objects, use a side-effects-free version
+    // of Error.prototype.toString independent of the actually installed
+    // toString method.
+    if (IsErrorObject(obj) ||
+        %GetDataProperty(obj, "toString") === ErrorToString) {
+      return %_Call(NoSideEffectsErrorToString, obj);
+    }
+
+    if (%GetDataProperty(obj, "toString") === ObjectToString) {
+      var constructor = %GetDataProperty(obj, "constructor");
+      if (IS_FUNCTION(constructor)) {
+        var constructor_name = %FunctionGetName(constructor);
+        if (constructor_name != "") return `#<${constructor_name}>`;
+      }
+    }
+  }
+
+  return %_Call(NoSideEffectsObjectToString, obj);
+}
+
+
+function MakeGenericError(constructor, type, arg0, arg1, arg2) {
+  var error = new constructor(FormatMessage(type, arg0, arg1, arg2));
+  error[internalErrorSymbol] = true;
+  return error;
+}
+
+
+/**
+ * Set up the Script function and constructor.
+ */
+%FunctionSetInstanceClassName(Script, 'Script');
+%AddNamedProperty(Script.prototype, 'constructor', Script,
+                  DONT_ENUM | DONT_DELETE | READ_ONLY);
+%SetCode(Script, function(x) {
+  // Script objects can only be created by the VM.
+  throw MakeError(kUnsupported);
+});
+
+
+// Helper functions; called from the runtime system.
+function FormatMessage(type, arg0, arg1, arg2) {
+  var arg0 = NoSideEffectsToString(arg0);
+  var arg1 = NoSideEffectsToString(arg1);
+  var arg2 = NoSideEffectsToString(arg2);
+  try {
+    return %FormatMessageString(type, arg0, arg1, arg2);
+  } catch (e) {
+    return "<error>";
+  }
+}
+
+
+function GetLineNumber(message) {
+  var start_position = %MessageGetStartPosition(message);
+  if (start_position == -1) return kNoLineNumberInfo;
+  var script = %MessageGetScript(message);
+  var location = script.locationFromPosition(start_position, true);
+  if (location == null) return kNoLineNumberInfo;
+  return location.line + 1;
+}
+
+
+//Returns the offset of the given position within the containing line.
+function GetColumnNumber(message) {
+  var script = %MessageGetScript(message);
+  var start_position = %MessageGetStartPosition(message);
+  var location = script.locationFromPosition(start_position, true);
+  if (location == null) return -1;
+  return location.column;
+}
+
+
+// Returns the source code line containing the given source
+// position, or the empty string if the position is invalid.
+function GetSourceLine(message) {
+  var script = %MessageGetScript(message);
+  var start_position = %MessageGetStartPosition(message);
+  var location = script.locationFromPosition(start_position, true);
+  if (location == null) return "";
+  return location.sourceText();
+}
+
+
+/**
+ * Find a line number given a specific source position.
+ * @param {number} position The source position.
+ * @return {number} 0 if input too small, -1 if input too large,
+       else the line number.
+ */
+function ScriptLineFromPosition(position) {
+  var lower = 0;
+  var upper = this.lineCount() - 1;
+  var line_ends = this.line_ends;
+
+  // We'll never find invalid positions so bail right away.
+  if (position > line_ends[upper]) {
+    return -1;
+  }
+
+  // This means we don't have to safe-guard indexing line_ends[i - 1].
+  if (position <= line_ends[0]) {
+    return 0;
+  }
+
+  // Binary search to find line # from position range.
+  while (upper >= 1) {
+    var i = (lower + upper) >> 1;
+
+    if (position > line_ends[i]) {
+      lower = i + 1;
+    } else if (position <= line_ends[i - 1]) {
+      upper = i - 1;
+    } else {
+      return i;
+    }
+  }
+
+  return -1;
+}
+
+/**
+ * Get information on a specific source position.
+ * @param {number} position The source position
+ * @param {boolean} include_resource_offset Set to true to have the resource
+ *     offset added to the location
+ * @return {SourceLocation}
+ *     If line is negative or not in the source null is returned.
+ */
+function ScriptLocationFromPosition(position,
+                                    include_resource_offset) {
+  var line = this.lineFromPosition(position);
+  if (line == -1) return null;
+
+  // Determine start, end and column.
+  var line_ends = this.line_ends;
+  var start = line == 0 ? 0 : line_ends[line - 1] + 1;
+  var end = line_ends[line];
+  if (end > 0 && %_Call(StringCharAt, this.source, end - 1) == '\r') {
+    end--;
+  }
+  var column = position - start;
+
+  // Adjust according to the offset within the resource.
+  if (include_resource_offset) {
+    line += this.line_offset;
+    if (line == this.line_offset) {
+      column += this.column_offset;
+    }
+  }
+
+  return new SourceLocation(this, position, line, column, start, end);
+}
+
+
+/**
+ * Get information on a specific source line and column possibly offset by a
+ * fixed source position. This function is used to find a source position from
+ * a line and column position. The fixed source position offset is typically
+ * used to find a source position in a function based on a line and column in
+ * the source for the function alone. The offset passed will then be the
+ * start position of the source for the function within the full script source.
+ * @param {number} opt_line The line within the source. Default value is 0
+ * @param {number} opt_column The column in within the line. Default value is 0
+ * @param {number} opt_offset_position The offset from the begining of the
+ *     source from where the line and column calculation starts.
+ *     Default value is 0
+ * @return {SourceLocation}
+ *     If line is negative or not in the source null is returned.
+ */
+function ScriptLocationFromLine(opt_line, opt_column, opt_offset_position) {
+  // Default is the first line in the script. Lines in the script is relative
+  // to the offset within the resource.
+  var line = 0;
+  if (!IS_UNDEFINED(opt_line)) {
+    line = opt_line - this.line_offset;
+  }
+
+  // Default is first column. If on the first line add the offset within the
+  // resource.
+  var column = opt_column || 0;
+  if (line == 0) {
+    column -= this.column_offset;
+  }
+
+  var offset_position = opt_offset_position || 0;
+  if (line < 0 || column < 0 || offset_position < 0) return null;
+  if (line == 0) {
+    return this.locationFromPosition(offset_position + column, false);
+  } else {
+    // Find the line where the offset position is located.
+    var offset_line = this.lineFromPosition(offset_position);
+
+    if (offset_line == -1 || offset_line + line >= this.lineCount()) {
+      return null;
+    }
+
+    return this.locationFromPosition(
+        this.line_ends[offset_line + line - 1] + 1 + column);  // line > 0 here.
+  }
+}
+
+
+/**
+ * Get a slice of source code from the script. The boundaries for the slice is
+ * specified in lines.
+ * @param {number} opt_from_line The first line (zero bound) in the slice.
+ *     Default is 0
+ * @param {number} opt_to_column The last line (zero bound) in the slice (non
+ *     inclusive). Default is the number of lines in the script
+ * @return {SourceSlice} The source slice or null of the parameters where
+ *     invalid
+ */
+function ScriptSourceSlice(opt_from_line, opt_to_line) {
+  var from_line = IS_UNDEFINED(opt_from_line) ? this.line_offset
+                                              : opt_from_line;
+  var to_line = IS_UNDEFINED(opt_to_line) ? this.line_offset + this.lineCount()
+                                          : opt_to_line;
+
+  // Adjust according to the offset within the resource.
+  from_line -= this.line_offset;
+  to_line -= this.line_offset;
+  if (from_line < 0) from_line = 0;
+  if (to_line > this.lineCount()) to_line = this.lineCount();
+
+  // Check parameters.
+  if (from_line >= this.lineCount() ||
+      to_line < 0 ||
+      from_line > to_line) {
+    return null;
+  }
+
+  var line_ends = this.line_ends;
+  var from_position = from_line == 0 ? 0 : line_ends[from_line - 1] + 1;
+  var to_position = to_line == 0 ? 0 : line_ends[to_line - 1] + 1;
+
+  // Return a source slice with line numbers re-adjusted to the resource.
+  return new SourceSlice(this,
+                         from_line + this.line_offset,
+                         to_line + this.line_offset,
+                          from_position, to_position);
+}
+
+
+function ScriptSourceLine(opt_line) {
+  // Default is the first line in the script. Lines in the script are relative
+  // to the offset within the resource.
+  var line = 0;
+  if (!IS_UNDEFINED(opt_line)) {
+    line = opt_line - this.line_offset;
+  }
+
+  // Check parameter.
+  if (line < 0 || this.lineCount() <= line) {
+    return null;
+  }
+
+  // Return the source line.
+  var line_ends = this.line_ends;
+  var start = line == 0 ? 0 : line_ends[line - 1] + 1;
+  var end = line_ends[line];
+  return %_Call(StringSubstring, this.source, start, end);
+}
+
+
+/**
+ * Returns the number of source lines.
+ * @return {number}
+ *     Number of source lines.
+ */
+function ScriptLineCount() {
+  // Return number of source lines.
+  return this.line_ends.length;
+}
+
+
+/**
+ * Returns the position of the nth line end.
+ * @return {number}
+ *     Zero-based position of the nth line end in the script.
+ */
+function ScriptLineEnd(n) {
+  return this.line_ends[n];
+}
+
+
+/**
+ * If sourceURL comment is available returns sourceURL comment contents.
+ * Otherwise, script name is returned. See
+ * http://fbug.googlecode.com/svn/branches/firebug1.1/docs/ReleaseNotes_1.1.txt
+ * and Source Map Revision 3 proposal for details on using //# sourceURL and
+ * deprecated //@ sourceURL comment to identify scripts that don't have name.
+ *
+ * @return {?string} script name if present, value for //# sourceURL comment or
+ * deprecated //@ sourceURL comment otherwise.
+ */
+function ScriptNameOrSourceURL() {
+  if (this.source_url) return this.source_url;
+  return this.name;
+}
+
+
+utils.SetUpLockedPrototype(Script, [
+    "source",
+    "name",
+    "source_url",
+    "source_mapping_url",
+    "line_ends",
+    "line_offset",
+    "column_offset"
+  ], [
+    "lineFromPosition", ScriptLineFromPosition,
+    "locationFromPosition", ScriptLocationFromPosition,
+    "locationFromLine", ScriptLocationFromLine,
+    "sourceSlice", ScriptSourceSlice,
+    "sourceLine", ScriptSourceLine,
+    "lineCount", ScriptLineCount,
+    "nameOrSourceURL", ScriptNameOrSourceURL,
+    "lineEnd", ScriptLineEnd
+  ]
+);
+
+
+/**
+ * Class for source location. A source location is a position within some
+ * source with the following properties:
+ *   script   : script object for the source
+ *   line     : source line number
+ *   column   : source column within the line
+ *   position : position within the source
+ *   start    : position of start of source context (inclusive)
+ *   end      : position of end of source context (not inclusive)
+ * Source text for the source context is the character interval
+ * [start, end[. In most cases end will point to a newline character.
+ * It might point just past the final position of the source if the last
+ * source line does not end with a newline character.
+ * @param {Script} script The Script object for which this is a location
+ * @param {number} position Source position for the location
+ * @param {number} line The line number for the location
+ * @param {number} column The column within the line for the location
+ * @param {number} start Source position for start of source context
+ * @param {number} end Source position for end of source context
+ * @constructor
+ */
+function SourceLocation(script, position, line, column, start, end) {
+  this.script = script;
+  this.position = position;
+  this.line = line;
+  this.column = column;
+  this.start = start;
+  this.end = end;
+}
+
+
+/**
+ * Get the source text for a SourceLocation
+ * @return {String}
+ *     Source text for this location.
+ */
+function SourceLocationSourceText() {
+  return %_Call(StringSubstring, this.script.source, this.start, this.end);
+}
+
+
+utils.SetUpLockedPrototype(SourceLocation,
+  ["script", "position", "line", "column", "start", "end"],
+  ["sourceText", SourceLocationSourceText]
+);
+
+
+/**
+ * Class for a source slice. A source slice is a part of a script source with
+ * the following properties:
+ *   script        : script object for the source
+ *   from_line     : line number for the first line in the slice
+ *   to_line       : source line number for the last line in the slice
+ *   from_position : position of the first character in the slice
+ *   to_position   : position of the last character in the slice
+ * The to_line and to_position are not included in the slice, that is the lines
+ * in the slice are [from_line, to_line[. Likewise the characters in the slice
+ * are [from_position, to_position[.
+ * @param {Script} script The Script object for the source slice
+ * @param {number} from_line
+ * @param {number} to_line
+ * @param {number} from_position
+ * @param {number} to_position
+ * @constructor
+ */
+function SourceSlice(script, from_line, to_line, from_position, to_position) {
+  this.script = script;
+  this.from_line = from_line;
+  this.to_line = to_line;
+  this.from_position = from_position;
+  this.to_position = to_position;
+}
+
+/**
+ * Get the source text for a SourceSlice
+ * @return {String} Source text for this slice. The last line will include
+ *     the line terminating characters (if any)
+ */
+function SourceSliceSourceText() {
+  return %_Call(StringSubstring,
+                this.script.source,
+                this.from_position,
+                this.to_position);
+}
+
+utils.SetUpLockedPrototype(SourceSlice,
+  ["script", "from_line", "to_line", "from_position", "to_position"],
+  ["sourceText", SourceSliceSourceText]
+);
+
+
+function GetStackTraceLine(recv, fun, pos, isGlobal) {
+  return new CallSite(recv, fun, pos, false).toString();
+}
+
+// ----------------------------------------------------------------------------
+// Error implementation
+
+function CallSite(receiver, fun, pos, strict_mode) {
+  if (!IS_FUNCTION(fun)) {
+    throw MakeTypeError(kCallSiteExpectsFunction, typeof fun);
+  }
+
+  if (IS_UNDEFINED(new.target)) {
+    return new CallSite(receiver, fun, pos, strict_mode);
+  }
+
+  SET_PRIVATE(this, callSiteReceiverSymbol, receiver);
+  SET_PRIVATE(this, callSiteFunctionSymbol, fun);
+  SET_PRIVATE(this, callSitePositionSymbol, TO_INT32(pos));
+  SET_PRIVATE(this, callSiteStrictSymbol, TO_BOOLEAN(strict_mode));
+}
+
+function CallSiteGetThis() {
+  return GET_PRIVATE(this, callSiteStrictSymbol)
+      ? UNDEFINED : GET_PRIVATE(this, callSiteReceiverSymbol);
+}
+
+function CallSiteGetFunction() {
+  return GET_PRIVATE(this, callSiteStrictSymbol)
+      ? UNDEFINED : GET_PRIVATE(this, callSiteFunctionSymbol);
+}
+
+function CallSiteGetPosition() {
+  return GET_PRIVATE(this, callSitePositionSymbol);
+}
+
+function CallSiteGetTypeName() {
+  return GetTypeName(GET_PRIVATE(this, callSiteReceiverSymbol), false);
+}
+
+function CallSiteIsToplevel() {
+  return %CallSiteIsToplevelRT(this);
+}
+
+function CallSiteIsEval() {
+  return %CallSiteIsEvalRT(this);
+}
+
+function CallSiteGetEvalOrigin() {
+  var script = %FunctionGetScript(GET_PRIVATE(this, callSiteFunctionSymbol));
+  return FormatEvalOrigin(script);
+}
+
+function CallSiteGetScriptNameOrSourceURL() {
+  return %CallSiteGetScriptNameOrSourceUrlRT(this);
+}
+
+function CallSiteGetFunctionName() {
+  // See if the function knows its own name
+  return %CallSiteGetFunctionNameRT(this);
+}
+
+function CallSiteGetMethodName() {
+  // See if we can find a unique property on the receiver that holds
+  // this function.
+  return %CallSiteGetMethodNameRT(this);
+}
+
+function CallSiteGetFileName() {
+  return %CallSiteGetFileNameRT(this);
+}
+
+function CallSiteGetLineNumber() {
+  return %CallSiteGetLineNumberRT(this);
+}
+
+function CallSiteGetColumnNumber() {
+  return %CallSiteGetColumnNumberRT(this);
+}
+
+function CallSiteIsNative() {
+  return %CallSiteIsNativeRT(this);
+}
+
+function CallSiteIsConstructor() {
+  return %CallSiteIsConstructorRT(this);
+}
+
+function CallSiteToString() {
+  var fileName;
+  var fileLocation = "";
+  if (this.isNative()) {
+    fileLocation = "native";
+  } else {
+    fileName = this.getScriptNameOrSourceURL();
+    if (!fileName && this.isEval()) {
+      fileLocation = this.getEvalOrigin();
+      fileLocation += ", ";  // Expecting source position to follow.
+    }
+
+    if (fileName) {
+      fileLocation += fileName;
+    } else {
+      // Source code does not originate from a file and is not native, but we
+      // can still get the source position inside the source string, e.g. in
+      // an eval string.
+      fileLocation += "<anonymous>";
+    }
+    var lineNumber = this.getLineNumber();
+    if (lineNumber != null) {
+      fileLocation += ":" + lineNumber;
+      var columnNumber = this.getColumnNumber();
+      if (columnNumber) {
+        fileLocation += ":" + columnNumber;
+      }
+    }
+  }
+
+  var line = "";
+  var functionName = this.getFunctionName();
+  var addSuffix = true;
+  var isConstructor = this.isConstructor();
+  var isMethodCall = !(this.isToplevel() || isConstructor);
+  if (isMethodCall) {
+    var typeName = GetTypeName(GET_PRIVATE(this, callSiteReceiverSymbol), true);
+    var methodName = this.getMethodName();
+    if (functionName) {
+      if (typeName && %_Call(StringIndexOf, functionName, typeName) != 0) {
+        line += typeName + ".";
+      }
+      line += functionName;
+      if (methodName &&
+          (%_Call(StringIndexOf, functionName, "." + methodName) !=
+           functionName.length - methodName.length - 1)) {
+        line += " [as " + methodName + "]";
+      }
+    } else {
+      line += typeName + "." + (methodName || "<anonymous>");
+    }
+  } else if (isConstructor) {
+    line += "new " + (functionName || "<anonymous>");
+  } else if (functionName) {
+    line += functionName;
+  } else {
+    line += fileLocation;
+    addSuffix = false;
+  }
+  if (addSuffix) {
+    line += " (" + fileLocation + ")";
+  }
+  return line;
+}
+
+utils.SetUpLockedPrototype(CallSite, ["receiver", "fun", "pos"], [
+  "getThis", CallSiteGetThis,
+  "getTypeName", CallSiteGetTypeName,
+  "isToplevel", CallSiteIsToplevel,
+  "isEval", CallSiteIsEval,
+  "getEvalOrigin", CallSiteGetEvalOrigin,
+  "getScriptNameOrSourceURL", CallSiteGetScriptNameOrSourceURL,
+  "getFunction", CallSiteGetFunction,
+  "getFunctionName", CallSiteGetFunctionName,
+  "getMethodName", CallSiteGetMethodName,
+  "getFileName", CallSiteGetFileName,
+  "getLineNumber", CallSiteGetLineNumber,
+  "getColumnNumber", CallSiteGetColumnNumber,
+  "isNative", CallSiteIsNative,
+  "getPosition", CallSiteGetPosition,
+  "isConstructor", CallSiteIsConstructor,
+  "toString", CallSiteToString
+]);
+
+
+function FormatEvalOrigin(script) {
+  var sourceURL = script.nameOrSourceURL();
+  if (sourceURL) {
+    return sourceURL;
+  }
+
+  var eval_origin = "eval at ";
+  if (script.eval_from_function_name) {
+    eval_origin += script.eval_from_function_name;
+  } else {
+    eval_origin +=  "<anonymous>";
+  }
+
+  var eval_from_script = script.eval_from_script;
+  if (eval_from_script) {
+    if (eval_from_script.compilation_type == COMPILATION_TYPE_EVAL) {
+      // eval script originated from another eval.
+      eval_origin += " (" + FormatEvalOrigin(eval_from_script) + ")";
+    } else {
+      // eval script originated from "real" source.
+      if (eval_from_script.name) {
+        eval_origin += " (" + eval_from_script.name;
+        var location = eval_from_script.locationFromPosition(
+            script.eval_from_script_position, true);
+        if (location) {
+          eval_origin += ":" + (location.line + 1);
+          eval_origin += ":" + (location.column + 1);
+        }
+        eval_origin += ")";
+      } else {
+        eval_origin += " (unknown source)";
+      }
+    }
+  }
+
+  return eval_origin;
+}
+
+
+function FormatErrorString(error) {
+  try {
+    return %_Call(ErrorToString, error);
+  } catch (e) {
+    try {
+      return "<error: " + e + ">";
+    } catch (ee) {
+      return "<error>";
+    }
+  }
+}
+
+
+function GetStackFrames(raw_stack) {
+  var frames = new InternalArray();
+  var sloppy_frames = raw_stack[0];
+  for (var i = 1; i < raw_stack.length; i += 4) {
+    var recv = raw_stack[i];
+    var fun = raw_stack[i + 1];
+    var code = raw_stack[i + 2];
+    var pc = raw_stack[i + 3];
+    var pos = %_IsSmi(code) ? code : %FunctionGetPositionForOffset(code, pc);
+    sloppy_frames--;
+    frames.push(new CallSite(recv, fun, pos, (sloppy_frames < 0)));
+  }
+  return frames;
+}
+
+
+// Flag to prevent recursive call of Error.prepareStackTrace.
+var formatting_custom_stack_trace = false;
+
+
+function FormatStackTrace(obj, raw_stack) {
+  var frames = GetStackFrames(raw_stack);
+  if (IS_FUNCTION(GlobalError.prepareStackTrace) &&
+      !formatting_custom_stack_trace) {
+    var array = [];
+    %MoveArrayContents(frames, array);
+    formatting_custom_stack_trace = true;
+    var stack_trace = UNDEFINED;
+    try {
+      stack_trace = GlobalError.prepareStackTrace(obj, array);
+    } catch (e) {
+      throw e;  // The custom formatting function threw.  Rethrow.
+    } finally {
+      formatting_custom_stack_trace = false;
+    }
+    return stack_trace;
+  }
+
+  var lines = new InternalArray();
+  lines.push(FormatErrorString(obj));
+  for (var i = 0; i < frames.length; i++) {
+    var frame = frames[i];
+    var line;
+    try {
+      line = frame.toString();
+    } catch (e) {
+      try {
+        line = "<error: " + e + ">";
+      } catch (ee) {
+        // Any code that reaches this point is seriously nasty!
+        line = "<error>";
+      }
+    }
+    lines.push("    at " + line);
+  }
+  return %_Call(ArrayJoin, lines, "\n");
+}
+
+
+function GetTypeName(receiver, requireConstructor) {
+  if (IS_NULL_OR_UNDEFINED(receiver)) return null;
+  if (IS_PROXY(receiver)) return "Proxy";
+
+  var constructor = %GetDataProperty(TO_OBJECT(receiver), "constructor");
+  if (!IS_FUNCTION(constructor)) {
+    return requireConstructor ? null : %_Call(NoSideEffectsToString, receiver);
+  }
+  return %FunctionGetName(constructor);
+}
+
+
+// Format the stack trace if not yet done, and return it.
+// Cache the formatted stack trace on the holder.
+var StackTraceGetter = function() {
+  var formatted_stack_trace = UNDEFINED;
+  var holder = this;
+  while (holder) {
+    var formatted_stack_trace =
+      GET_PRIVATE(holder, formattedStackTraceSymbol);
+    if (IS_UNDEFINED(formatted_stack_trace)) {
+      // No formatted stack trace available.
+      var stack_trace = GET_PRIVATE(holder, stackTraceSymbol);
+      if (IS_UNDEFINED(stack_trace)) {
+        // Neither formatted nor structured stack trace available.
+        // Look further up the prototype chain.
+        holder = %_GetPrototype(holder);
+        continue;
+      }
+      formatted_stack_trace = FormatStackTrace(holder, stack_trace);
+      SET_PRIVATE(holder, stackTraceSymbol, UNDEFINED);
+      SET_PRIVATE(holder, formattedStackTraceSymbol, formatted_stack_trace);
+    }
+    return formatted_stack_trace;
+  }
+  return UNDEFINED;
+};
+
+
+// If the receiver equals the holder, set the formatted stack trace that the
+// getter returns.
+var StackTraceSetter = function(v) {
+  if (IsErrorObject(this)) {
+    SET_PRIVATE(this, stackTraceSymbol, UNDEFINED);
+    SET_PRIVATE(this, formattedStackTraceSymbol, v);
+  }
+};
+
+
+// Use a dummy function since we do not actually want to capture a stack trace
+// when constructing the initial Error prototytpes.
+var captureStackTrace = function() {};
+
+
+// Set up special error type constructors.
+function SetUpError(error_function) {
+  %FunctionSetInstanceClassName(error_function, 'Error');
+  var name = error_function.name;
+  var prototype = new GlobalObject();
+  if (name !== 'Error') {
+    %InternalSetPrototype(error_function, GlobalError);
+    %InternalSetPrototype(prototype, GlobalError.prototype);
+  }
+  %FunctionSetPrototype(error_function, prototype);
+
+  %AddNamedProperty(error_function.prototype, 'name', name, DONT_ENUM);
+  %AddNamedProperty(error_function.prototype, 'message', '', DONT_ENUM);
+  %AddNamedProperty(
+      error_function.prototype, 'constructor', error_function, DONT_ENUM);
+
+  %SetCode(error_function, function(m) {
+    if (IS_UNDEFINED(new.target)) return new error_function(m);
+
+    try { captureStackTrace(this, error_function); } catch (e) { }
+    // Define all the expected properties directly on the error
+    // object. This avoids going through getters and setters defined
+    // on prototype objects.
+    if (!IS_UNDEFINED(m)) {
+      %AddNamedProperty(this, 'message', TO_STRING(m), DONT_ENUM);
+    }
+  });
+
+  %SetNativeFlag(error_function);
+  return error_function;
+};
+
+GlobalError = SetUpError(global.Error);
+GlobalEvalError = SetUpError(global.EvalError);
+GlobalRangeError = SetUpError(global.RangeError);
+GlobalReferenceError = SetUpError(global.ReferenceError);
+GlobalSyntaxError = SetUpError(global.SyntaxError);
+GlobalTypeError = SetUpError(global.TypeError);
+GlobalURIError = SetUpError(global.URIError);
+
+utils.InstallFunctions(GlobalError.prototype, DONT_ENUM,
+                       ['toString', ErrorToString]);
+
+function ErrorToString() {
+  if (!IS_RECEIVER(this)) {
+    throw MakeTypeError(kCalledOnNonObject, "Error.prototype.toString");
+  }
+
+  var name = this.name;
+  name = IS_UNDEFINED(name) ? "Error" : TO_STRING(name);
+
+  var message = this.message;
+  message = IS_UNDEFINED(message) ? "" : TO_STRING(message);
+
+  if (name == "") return message;
+  if (message == "") return name;
+  return `${name}: ${message}`
+}
+
+function MakeError(type, arg0, arg1, arg2) {
+  return MakeGenericError(GlobalError, type, arg0, arg1, arg2);
+}
+
+function MakeRangeError(type, arg0, arg1, arg2) {
+  return MakeGenericError(GlobalRangeError, type, arg0, arg1, arg2);
+}
+
+function MakeSyntaxError(type, arg0, arg1, arg2) {
+  return MakeGenericError(GlobalSyntaxError, type, arg0, arg1, arg2);
+}
+
+function MakeTypeError(type, arg0, arg1, arg2) {
+  return MakeGenericError(GlobalTypeError, type, arg0, arg1, arg2);
+}
+
+function MakeURIError() {
+  return MakeGenericError(GlobalURIError, kURIMalformed);
+}
+
+// Boilerplate for exceptions for stack overflows. Used from
+// Isolate::StackOverflow().
+var StackOverflowBoilerplate = MakeRangeError(kStackOverflow);
+utils.InstallGetterSetter(StackOverflowBoilerplate, 'stack',
+                          StackTraceGetter, StackTraceSetter)
+
+// Define actual captureStackTrace function after everything has been set up.
+captureStackTrace = function captureStackTrace(obj, cons_opt) {
+  // Define accessors first, as this may fail and throw.
+  ObjectDefineProperty(obj, 'stack', { get: StackTraceGetter,
+                                       set: StackTraceSetter,
+                                       configurable: true });
+  %CollectStackTrace(obj, cons_opt ? cons_opt : captureStackTrace);
+};
+
+GlobalError.captureStackTrace = captureStackTrace;
+
+%InstallToContext([
+  "get_stack_trace_line_fun", GetStackTraceLine,
+  "make_error_function", MakeGenericError,
+  "make_range_error", MakeRangeError,
+  "make_type_error", MakeTypeError,
+  "message_get_column_number", GetColumnNumber,
+  "message_get_line_number", GetLineNumber,
+  "message_get_source_line", GetSourceLine,
+  "no_side_effects_to_string_fun", NoSideEffectsToString,
+  "stack_overflow_boilerplate", StackOverflowBoilerplate,
+]);
+
+utils.Export(function(to) {
+  to.ErrorToString = ErrorToString;
+  to.MakeError = MakeError;
+  to.MakeRangeError = MakeRangeError;
+  to.MakeSyntaxError = MakeSyntaxError;
+  to.MakeTypeError = MakeTypeError;
+  to.MakeURIError = MakeURIError;
+});
+
+});
diff --git a/src/js/object-observe.js b/src/js/object-observe.js
new file mode 100644
index 0000000..5e256bf
--- /dev/null
+++ b/src/js/object-observe.js
@@ -0,0 +1,717 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function(global, utils) {
+
+"use strict";
+
+%CheckIsBootstrapping();
+
+// -------------------------------------------------------------------
+// Imports
+
+var GetHash;
+var GlobalArray = global.Array;
+var GlobalObject = global.Object;
+var InternalArray = utils.InternalArray;
+var MakeTypeError;
+
+utils.Import(function(from) {
+  GetHash = from.GetHash;
+  MakeTypeError = from.MakeTypeError;
+});
+
+// -------------------------------------------------------------------
+
+// Overview:
+//
+// This file contains all of the routing and accounting for Object.observe.
+// User code will interact with these mechanisms via the Object.observe APIs
+// and, as a side effect of mutation objects which are observed. The V8 runtime
+// (both C++ and JS) will interact with these mechanisms primarily by enqueuing
+// proper change records for objects which were mutated. The Object.observe
+// routing and accounting consists primarily of three participants
+//
+// 1) ObjectInfo. This represents the observed state of a given object. It
+//    records what callbacks are observing the object, with what options, and
+//    what "change types" are in progress on the object (i.e. via
+//    notifier.performChange).
+//
+// 2) CallbackInfo. This represents a callback used for observation. It holds
+//    the records which must be delivered to the callback, as well as the global
+//    priority of the callback (which determines delivery order between
+//    callbacks).
+//
+// 3) observationState.pendingObservers. This is the set of observers which
+//    have change records which must be delivered. During "normal" delivery
+//    (i.e. not Object.deliverChangeRecords), this is the mechanism by which
+//    callbacks are invoked in the proper order until there are no more
+//    change records pending to a callback.
+//
+// Note that in order to reduce allocation and processing costs, the
+// implementation of (1) and (2) have "optimized" states which represent
+// common cases which can be handled more efficiently.
+
+var observationState;
+
+var notifierPrototype = {};
+
+// We have to wait until after bootstrapping to grab a reference to the
+// observationState object, since it's not possible to serialize that
+// reference into the snapshot.
+function GetObservationStateJS() {
+  if (IS_UNDEFINED(observationState)) {
+    observationState = %GetObservationState();
+  }
+
+  // TODO(adamk): Consider moving this code into heap.cc
+  if (IS_UNDEFINED(observationState.callbackInfoMap)) {
+    observationState.callbackInfoMap = %ObservationWeakMapCreate();
+    observationState.objectInfoMap = %ObservationWeakMapCreate();
+    observationState.notifierObjectInfoMap = %ObservationWeakMapCreate();
+    observationState.pendingObservers = null;
+    observationState.nextCallbackPriority = 0;
+    observationState.lastMicrotaskId = 0;
+  }
+
+  return observationState;
+}
+
+
+function GetPendingObservers() {
+  return GetObservationStateJS().pendingObservers;
+}
+
+
+function SetPendingObservers(pendingObservers) {
+  GetObservationStateJS().pendingObservers = pendingObservers;
+}
+
+
+function GetNextCallbackPriority() {
+  return GetObservationStateJS().nextCallbackPriority++;
+}
+
+
+function nullProtoObject() {
+  return { __proto__: null };
+}
+
+
+function TypeMapCreate() {
+  return nullProtoObject();
+}
+
+
+function TypeMapAddType(typeMap, type, ignoreDuplicate) {
+  typeMap[type] = ignoreDuplicate ? 1 : (typeMap[type] || 0) + 1;
+}
+
+
+function TypeMapRemoveType(typeMap, type) {
+  typeMap[type]--;
+}
+
+
+function TypeMapCreateFromList(typeList, length) {
+  var typeMap = TypeMapCreate();
+  for (var i = 0; i < length; i++) {
+    TypeMapAddType(typeMap, typeList[i], true);
+  }
+  return typeMap;
+}
+
+
+function TypeMapHasType(typeMap, type) {
+  return !!typeMap[type];
+}
+
+
+function TypeMapIsDisjointFrom(typeMap1, typeMap2) {
+  if (!typeMap1 || !typeMap2)
+    return true;
+
+  for (var type in typeMap1) {
+    if (TypeMapHasType(typeMap1, type) && TypeMapHasType(typeMap2, type))
+      return false;
+  }
+
+  return true;
+}
+
+
+var defaultAcceptTypes = (function() {
+  var defaultTypes = [
+    'add',
+    'update',
+    'delete',
+    'setPrototype',
+    'reconfigure',
+    'preventExtensions'
+  ];
+  return TypeMapCreateFromList(defaultTypes, defaultTypes.length);
+})();
+
+
+// An Observer is a registration to observe an object by a callback with
+// a given set of accept types. If the set of accept types is the default
+// set for Object.observe, the observer is represented as a direct reference
+// to the callback. An observer never changes its accept types and thus never
+// needs to "normalize".
+function ObserverCreate(callback, acceptList) {
+  if (IS_UNDEFINED(acceptList))
+    return callback;
+  var observer = nullProtoObject();
+  observer.callback = callback;
+  observer.accept = acceptList;
+  return observer;
+}
+
+
+function ObserverGetCallback(observer) {
+  return IS_CALLABLE(observer) ? observer : observer.callback;
+}
+
+
+function ObserverGetAcceptTypes(observer) {
+  return IS_CALLABLE(observer) ? defaultAcceptTypes : observer.accept;
+}
+
+
+function ObserverIsActive(observer, objectInfo) {
+  return TypeMapIsDisjointFrom(ObjectInfoGetPerformingTypes(objectInfo),
+                               ObserverGetAcceptTypes(observer));
+}
+
+
+function ObjectInfoGetOrCreate(object) {
+  var objectInfo = ObjectInfoGet(object);
+  if (IS_UNDEFINED(objectInfo)) {
+    if (!IS_PROXY(object)) {
+      %SetIsObserved(object);
+    }
+    objectInfo = {
+      object: object,
+      changeObservers: null,
+      notifier: null,
+      performing: null,
+      performingCount: 0,
+    };
+    %WeakCollectionSet(GetObservationStateJS().objectInfoMap,
+                       object, objectInfo, GetHash(object));
+  }
+  return objectInfo;
+}
+
+
+function ObjectInfoGet(object) {
+  return %WeakCollectionGet(GetObservationStateJS().objectInfoMap, object,
+                            GetHash(object));
+}
+
+
+function ObjectInfoGetFromNotifier(notifier) {
+  return %WeakCollectionGet(GetObservationStateJS().notifierObjectInfoMap,
+                            notifier, GetHash(notifier));
+}
+
+
+function ObjectInfoGetNotifier(objectInfo) {
+  if (IS_NULL(objectInfo.notifier)) {
+    var notifier = { __proto__: notifierPrototype };
+    objectInfo.notifier = notifier;
+    %WeakCollectionSet(GetObservationStateJS().notifierObjectInfoMap,
+                       notifier, objectInfo, GetHash(notifier));
+  }
+
+  return objectInfo.notifier;
+}
+
+
+function ChangeObserversIsOptimized(changeObservers) {
+  return IS_CALLABLE(changeObservers) ||
+         IS_CALLABLE(changeObservers.callback);
+}
+
+
+// The set of observers on an object is called 'changeObservers'. The first
+// observer is referenced directly via objectInfo.changeObservers. When a second
+// is added, changeObservers "normalizes" to become a mapping of callback
+// priority -> observer and is then stored on objectInfo.changeObservers.
+function ObjectInfoNormalizeChangeObservers(objectInfo) {
+  if (ChangeObserversIsOptimized(objectInfo.changeObservers)) {
+    var observer = objectInfo.changeObservers;
+    var callback = ObserverGetCallback(observer);
+    var callbackInfo = CallbackInfoGet(callback);
+    var priority = CallbackInfoGetPriority(callbackInfo);
+    objectInfo.changeObservers = nullProtoObject();
+    objectInfo.changeObservers[priority] = observer;
+  }
+}
+
+
+function ObjectInfoAddObserver(objectInfo, callback, acceptList) {
+  var callbackInfo = CallbackInfoGetOrCreate(callback);
+  var observer = ObserverCreate(callback, acceptList);
+
+  if (!objectInfo.changeObservers) {
+    objectInfo.changeObservers = observer;
+    return;
+  }
+
+  ObjectInfoNormalizeChangeObservers(objectInfo);
+  var priority = CallbackInfoGetPriority(callbackInfo);
+  objectInfo.changeObservers[priority] = observer;
+}
+
+function ObjectInfoRemoveObserver(objectInfo, callback) {
+  if (!objectInfo.changeObservers)
+    return;
+
+  if (ChangeObserversIsOptimized(objectInfo.changeObservers)) {
+    if (callback === ObserverGetCallback(objectInfo.changeObservers))
+      objectInfo.changeObservers = null;
+    return;
+  }
+
+  var callbackInfo = CallbackInfoGet(callback);
+  var priority = CallbackInfoGetPriority(callbackInfo);
+  objectInfo.changeObservers[priority] = null;
+}
+
+function ObjectInfoHasActiveObservers(objectInfo) {
+  if (IS_UNDEFINED(objectInfo) || !objectInfo.changeObservers)
+    return false;
+
+  if (ChangeObserversIsOptimized(objectInfo.changeObservers))
+    return ObserverIsActive(objectInfo.changeObservers, objectInfo);
+
+  for (var priority in objectInfo.changeObservers) {
+    var observer = objectInfo.changeObservers[priority];
+    if (!IS_NULL(observer) && ObserverIsActive(observer, objectInfo))
+      return true;
+  }
+
+  return false;
+}
+
+
+function ObjectInfoAddPerformingType(objectInfo, type) {
+  objectInfo.performing = objectInfo.performing || TypeMapCreate();
+  TypeMapAddType(objectInfo.performing, type);
+  objectInfo.performingCount++;
+}
+
+
+function ObjectInfoRemovePerformingType(objectInfo, type) {
+  objectInfo.performingCount--;
+  TypeMapRemoveType(objectInfo.performing, type);
+}
+
+
+function ObjectInfoGetPerformingTypes(objectInfo) {
+  return objectInfo.performingCount > 0 ? objectInfo.performing : null;
+}
+
+
+function ConvertAcceptListToTypeMap(arg) {
+  // We use undefined as a sentinel for the default accept list.
+  if (IS_UNDEFINED(arg))
+    return arg;
+
+  if (!IS_RECEIVER(arg)) throw MakeTypeError(kObserveInvalidAccept);
+
+  var len = TO_INTEGER(arg.length);
+  if (len < 0) len = 0;
+
+  return TypeMapCreateFromList(arg, len);
+}
+
+
+// CallbackInfo's optimized state is just a number which represents its global
+// priority. When a change record must be enqueued for the callback, it
+// normalizes. When delivery clears any pending change records, it re-optimizes.
+function CallbackInfoGet(callback) {
+  return %WeakCollectionGet(GetObservationStateJS().callbackInfoMap, callback,
+                            GetHash(callback));
+}
+
+
+function CallbackInfoSet(callback, callbackInfo) {
+  %WeakCollectionSet(GetObservationStateJS().callbackInfoMap,
+                     callback, callbackInfo, GetHash(callback));
+}
+
+
+function CallbackInfoGetOrCreate(callback) {
+  var callbackInfo = CallbackInfoGet(callback);
+  if (!IS_UNDEFINED(callbackInfo))
+    return callbackInfo;
+
+  var priority = GetNextCallbackPriority();
+  CallbackInfoSet(callback, priority);
+  return priority;
+}
+
+
+function CallbackInfoGetPriority(callbackInfo) {
+  if (IS_NUMBER(callbackInfo))
+    return callbackInfo;
+  else
+    return callbackInfo.priority;
+}
+
+
+function CallbackInfoNormalize(callback) {
+  var callbackInfo = CallbackInfoGet(callback);
+  if (IS_NUMBER(callbackInfo)) {
+    var priority = callbackInfo;
+    callbackInfo = new InternalArray;
+    callbackInfo.priority = priority;
+    CallbackInfoSet(callback, callbackInfo);
+  }
+  return callbackInfo;
+}
+
+
+function ObjectObserve(object, callback, acceptList) {
+  if (!IS_RECEIVER(object))
+    throw MakeTypeError(kObserveNonObject, "observe", "observe");
+  if (%IsJSGlobalProxy(object))
+    throw MakeTypeError(kObserveGlobalProxy, "observe");
+  if (%IsAccessCheckNeeded(object))
+    throw MakeTypeError(kObserveAccessChecked, "observe");
+  if (!IS_CALLABLE(callback))
+    throw MakeTypeError(kObserveNonFunction, "observe");
+  if (%object_is_frozen(callback))
+    throw MakeTypeError(kObserveCallbackFrozen);
+
+  var objectObserveFn = %GetObjectContextObjectObserve(object);
+  return objectObserveFn(object, callback, acceptList);
+}
+
+
+function NativeObjectObserve(object, callback, acceptList) {
+  var objectInfo = ObjectInfoGetOrCreate(object);
+  var typeList = ConvertAcceptListToTypeMap(acceptList);
+  ObjectInfoAddObserver(objectInfo, callback, typeList);
+  return object;
+}
+
+
+function ObjectUnobserve(object, callback) {
+  if (!IS_RECEIVER(object))
+    throw MakeTypeError(kObserveNonObject, "unobserve", "unobserve");
+  if (%IsJSGlobalProxy(object))
+    throw MakeTypeError(kObserveGlobalProxy, "unobserve");
+  if (!IS_CALLABLE(callback))
+    throw MakeTypeError(kObserveNonFunction, "unobserve");
+
+  var objectInfo = ObjectInfoGet(object);
+  if (IS_UNDEFINED(objectInfo))
+    return object;
+
+  ObjectInfoRemoveObserver(objectInfo, callback);
+  return object;
+}
+
+
+function ArrayObserve(object, callback) {
+  return ObjectObserve(object, callback, ['add',
+                                          'update',
+                                          'delete',
+                                          'splice']);
+}
+
+
+function ArrayUnobserve(object, callback) {
+  return ObjectUnobserve(object, callback);
+}
+
+
+function ObserverEnqueueIfActive(observer, objectInfo, changeRecord) {
+  if (!ObserverIsActive(observer, objectInfo) ||
+      !TypeMapHasType(ObserverGetAcceptTypes(observer), changeRecord.type)) {
+    return;
+  }
+
+  var callback = ObserverGetCallback(observer);
+  if (!%ObserverObjectAndRecordHaveSameOrigin(callback, changeRecord.object,
+                                              changeRecord)) {
+    return;
+  }
+
+  var callbackInfo = CallbackInfoNormalize(callback);
+  if (IS_NULL(GetPendingObservers())) {
+    SetPendingObservers(nullProtoObject());
+    if (DEBUG_IS_ACTIVE) {
+      var id = ++GetObservationStateJS().lastMicrotaskId;
+      var name = "Object.observe";
+      %EnqueueMicrotask(function() {
+        %DebugAsyncTaskEvent({ type: "willHandle", id: id, name: name });
+        ObserveMicrotaskRunner();
+        %DebugAsyncTaskEvent({ type: "didHandle", id: id, name: name });
+      });
+      %DebugAsyncTaskEvent({ type: "enqueue", id: id, name: name });
+    } else {
+      %EnqueueMicrotask(ObserveMicrotaskRunner);
+    }
+  }
+  GetPendingObservers()[callbackInfo.priority] = callback;
+  callbackInfo.push(changeRecord);
+}
+
+
+function ObjectInfoEnqueueExternalChangeRecord(objectInfo, changeRecord, type) {
+  if (!ObjectInfoHasActiveObservers(objectInfo))
+    return;
+
+  var hasType = !IS_UNDEFINED(type);
+  var newRecord = hasType ?
+      { object: objectInfo.object, type: type } :
+      { object: objectInfo.object };
+
+  for (var prop in changeRecord) {
+    if (prop === 'object' || (hasType && prop === 'type')) continue;
+    %DefineDataPropertyUnchecked(
+        newRecord, prop, changeRecord[prop], READ_ONLY + DONT_DELETE);
+  }
+  %object_freeze(newRecord);
+
+  ObjectInfoEnqueueInternalChangeRecord(objectInfo, newRecord);
+}
+
+
+function ObjectInfoEnqueueInternalChangeRecord(objectInfo, changeRecord) {
+  // TODO(rossberg): adjust once there is a story for symbols vs proxies.
+  if (IS_SYMBOL(changeRecord.name)) return;
+
+  if (ChangeObserversIsOptimized(objectInfo.changeObservers)) {
+    var observer = objectInfo.changeObservers;
+    ObserverEnqueueIfActive(observer, objectInfo, changeRecord);
+    return;
+  }
+
+  for (var priority in objectInfo.changeObservers) {
+    var observer = objectInfo.changeObservers[priority];
+    if (IS_NULL(observer))
+      continue;
+    ObserverEnqueueIfActive(observer, objectInfo, changeRecord);
+  }
+}
+
+
+function BeginPerformSplice(array) {
+  var objectInfo = ObjectInfoGet(array);
+  if (!IS_UNDEFINED(objectInfo))
+    ObjectInfoAddPerformingType(objectInfo, 'splice');
+}
+
+
+function EndPerformSplice(array) {
+  var objectInfo = ObjectInfoGet(array);
+  if (!IS_UNDEFINED(objectInfo))
+    ObjectInfoRemovePerformingType(objectInfo, 'splice');
+}
+
+
+function EnqueueSpliceRecord(array, index, removed, addedCount) {
+  var objectInfo = ObjectInfoGet(array);
+  if (!ObjectInfoHasActiveObservers(objectInfo))
+    return;
+
+  var changeRecord = {
+    type: 'splice',
+    object: array,
+    index: index,
+    removed: removed,
+    addedCount: addedCount
+  };
+
+  %object_freeze(changeRecord);
+  %object_freeze(changeRecord.removed);
+  ObjectInfoEnqueueInternalChangeRecord(objectInfo, changeRecord);
+}
+
+
+function NotifyChange(type, object, name, oldValue) {
+  var objectInfo = ObjectInfoGet(object);
+  if (!ObjectInfoHasActiveObservers(objectInfo))
+    return;
+
+  var changeRecord;
+  if (arguments.length == 2) {
+    changeRecord = { type: type, object: object };
+  } else if (arguments.length == 3) {
+    changeRecord = { type: type, object: object, name: name };
+  } else {
+    changeRecord = {
+      type: type,
+      object: object,
+      name: name,
+      oldValue: oldValue
+    };
+  }
+
+  %object_freeze(changeRecord);
+  ObjectInfoEnqueueInternalChangeRecord(objectInfo, changeRecord);
+}
+
+
+function ObjectNotifierNotify(changeRecord) {
+  if (!IS_RECEIVER(this))
+    throw MakeTypeError(kCalledOnNonObject, "notify");
+
+  var objectInfo = ObjectInfoGetFromNotifier(this);
+  if (IS_UNDEFINED(objectInfo))
+    throw MakeTypeError(kObserveNotifyNonNotifier);
+  if (!IS_STRING(changeRecord.type))
+    throw MakeTypeError(kObserveTypeNonString);
+
+  ObjectInfoEnqueueExternalChangeRecord(objectInfo, changeRecord);
+}
+
+
+function ObjectNotifierPerformChange(changeType, changeFn) {
+  if (!IS_RECEIVER(this))
+    throw MakeTypeError(kCalledOnNonObject, "performChange");
+
+  var objectInfo = ObjectInfoGetFromNotifier(this);
+  if (IS_UNDEFINED(objectInfo))
+    throw MakeTypeError(kObserveNotifyNonNotifier);
+  if (!IS_STRING(changeType))
+    throw MakeTypeError(kObservePerformNonString);
+  if (!IS_CALLABLE(changeFn))
+    throw MakeTypeError(kObservePerformNonFunction);
+
+  var performChangeFn = %GetObjectContextNotifierPerformChange(objectInfo);
+  performChangeFn(objectInfo, changeType, changeFn);
+}
+
+
+function NativeObjectNotifierPerformChange(objectInfo, changeType, changeFn) {
+  ObjectInfoAddPerformingType(objectInfo, changeType);
+
+  var changeRecord;
+  try {
+    changeRecord = changeFn();
+  } finally {
+    ObjectInfoRemovePerformingType(objectInfo, changeType);
+  }
+
+  if (IS_RECEIVER(changeRecord))
+    ObjectInfoEnqueueExternalChangeRecord(objectInfo, changeRecord, changeType);
+}
+
+
+function ObjectGetNotifier(object) {
+  if (!IS_RECEIVER(object))
+    throw MakeTypeError(kObserveNonObject, "getNotifier", "getNotifier");
+  if (%IsJSGlobalProxy(object))
+    throw MakeTypeError(kObserveGlobalProxy, "getNotifier");
+  if (%IsAccessCheckNeeded(object))
+    throw MakeTypeError(kObserveAccessChecked, "getNotifier");
+
+  if (%object_is_frozen(object)) return null;
+
+  if (!%ObjectWasCreatedInCurrentOrigin(object)) return null;
+
+  var getNotifierFn = %GetObjectContextObjectGetNotifier(object);
+  return getNotifierFn(object);
+}
+
+
+function NativeObjectGetNotifier(object) {
+  var objectInfo = ObjectInfoGetOrCreate(object);
+  return ObjectInfoGetNotifier(objectInfo);
+}
+
+
+function CallbackDeliverPending(callback) {
+  var callbackInfo = CallbackInfoGet(callback);
+  if (IS_UNDEFINED(callbackInfo) || IS_NUMBER(callbackInfo))
+    return false;
+
+  // Clear the pending change records from callback and return it to its
+  // "optimized" state.
+  var priority = callbackInfo.priority;
+  CallbackInfoSet(callback, priority);
+
+  var pendingObservers = GetPendingObservers();
+  if (!IS_NULL(pendingObservers))
+    delete pendingObservers[priority];
+
+  // TODO: combine the following runtime calls for perf optimization.
+  var delivered = [];
+  %MoveArrayContents(callbackInfo, delivered);
+  %DeliverObservationChangeRecords(callback, delivered);
+
+  return true;
+}
+
+
+function ObjectDeliverChangeRecords(callback) {
+  if (!IS_CALLABLE(callback))
+    throw MakeTypeError(kObserveNonFunction, "deliverChangeRecords");
+
+  while (CallbackDeliverPending(callback)) {}
+}
+
+
+function ObserveMicrotaskRunner() {
+  var pendingObservers = GetPendingObservers();
+  if (!IS_NULL(pendingObservers)) {
+    SetPendingObservers(null);
+    for (var i in pendingObservers) {
+      CallbackDeliverPending(pendingObservers[i]);
+    }
+  }
+}
+
+// -------------------------------------------------------------------
+
+utils.InstallFunctions(notifierPrototype, DONT_ENUM, [
+  "notify", ObjectNotifierNotify,
+  "performChange", ObjectNotifierPerformChange
+]);
+
+var ObserveObjectMethods = [
+  "deliverChangeRecords", ObjectDeliverChangeRecords,
+  "getNotifier", ObjectGetNotifier,
+  "observe", ObjectObserve,
+  "unobserve", ObjectUnobserve
+];
+
+var ObserveArrayMethods = [
+  "observe", ArrayObserve,
+  "unobserve", ArrayUnobserve
+];
+
+// TODO(adamk): Figure out why this prototype removal has to
+// happen as part of initial snapshotting.
+var removePrototypeFn = function(f, i) {
+  if (i % 2 === 1) %FunctionRemovePrototype(f);
+};
+ObserveObjectMethods.forEach(removePrototypeFn);
+ObserveArrayMethods.forEach(removePrototypeFn);
+
+%InstallToContext([
+  "native_object_get_notifier", NativeObjectGetNotifier,
+  "native_object_notifier_perform_change", NativeObjectNotifierPerformChange,
+  "native_object_observe", NativeObjectObserve,
+  "observers_begin_perform_splice", BeginPerformSplice,
+  "observers_end_perform_splice", EndPerformSplice,
+  "observers_enqueue_splice", EnqueueSpliceRecord,
+  "observers_notify_change", NotifyChange,
+]);
+
+utils.Export(function(to) {
+  to.ObserveArrayMethods = ObserveArrayMethods;
+  to.ObserveBeginPerformSplice = BeginPerformSplice;
+  to.ObserveEndPerformSplice = EndPerformSplice;
+  to.ObserveEnqueueSpliceRecord = EnqueueSpliceRecord;
+  to.ObserveObjectMethods = ObserveObjectMethods;
+});
+
+})
diff --git a/src/js/prologue.js b/src/js/prologue.js
new file mode 100644
index 0000000..2779393
--- /dev/null
+++ b/src/js/prologue.js
@@ -0,0 +1,342 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function(global, utils, extrasUtils) {
+
+"use strict";
+
+%CheckIsBootstrapping();
+
+// -----------------------------------------------------------------------
+// Utils
+
+var imports = UNDEFINED;
+var imports_from_experimental = UNDEFINED;
+var exports_container = %ExportFromRuntime({});
+var typed_array_setup = UNDEFINED;
+
+// Register context value to be initialized with a typed array in
+// Genesis::InitializeBuiltinTypedArrays.
+function SetupTypedArray(f) {
+  f.next = typed_array_setup;
+  typed_array_setup = f;
+}
+
+// Export to other scripts.
+// In normal natives, this exports functions to other normal natives.
+// In experimental natives, this exports to other experimental natives and
+// to normal natives that import using utils.ImportFromExperimental.
+function Export(f) {
+  f(exports_container);
+}
+
+
+// Import from other scripts. The actual importing happens in PostNatives and
+// PostExperimental so that we can import from scripts executed later. However,
+// that means that the import is not available until the very end. If the
+// import needs to be available immediate, use ImportNow.
+// In normal natives, this imports from other normal natives.
+// In experimental natives, this imports from other experimental natives and
+// whitelisted exports from normal natives.
+function Import(f) {
+  f.next = imports;
+  imports = f;
+}
+
+
+// Import immediately from exports of previous scripts. We need this for
+// functions called during bootstrapping. Hooking up imports in PostNatives
+// would be too late.
+function ImportNow(name) {
+  return exports_container[name];
+}
+
+
+// In normal natives, import from experimental natives.
+// Not callable from experimental natives.
+function ImportFromExperimental(f) {
+  f.next = imports_from_experimental;
+  imports_from_experimental = f;
+}
+
+
+function SetFunctionName(f, name, prefix) {
+  if (IS_SYMBOL(name)) {
+    name = "[" + %SymbolDescription(name) + "]";
+  }
+  if (IS_UNDEFINED(prefix)) {
+    %FunctionSetName(f, name);
+  } else {
+    %FunctionSetName(f, prefix + " " + name);
+  }
+}
+
+
+function InstallConstants(object, constants) {
+  %CheckIsBootstrapping();
+  %OptimizeObjectForAddingMultipleProperties(object, constants.length >> 1);
+  var attributes = DONT_ENUM | DONT_DELETE | READ_ONLY;
+  for (var i = 0; i < constants.length; i += 2) {
+    var name = constants[i];
+    var k = constants[i + 1];
+    %AddNamedProperty(object, name, k, attributes);
+  }
+  %ToFastProperties(object);
+}
+
+
+function InstallFunctions(object, attributes, functions) {
+  %CheckIsBootstrapping();
+  %OptimizeObjectForAddingMultipleProperties(object, functions.length >> 1);
+  for (var i = 0; i < functions.length; i += 2) {
+    var key = functions[i];
+    var f = functions[i + 1];
+    SetFunctionName(f, key);
+    %FunctionRemovePrototype(f);
+    %AddNamedProperty(object, key, f, attributes);
+    %SetNativeFlag(f);
+  }
+  %ToFastProperties(object);
+}
+
+
+// Helper function to install a getter-only accessor property.
+function InstallGetter(object, name, getter, attributes, prefix) {
+  %CheckIsBootstrapping();
+  if (IS_UNDEFINED(attributes)) attributes = DONT_ENUM;
+  SetFunctionName(getter, name, IS_UNDEFINED(prefix) ? "get" : prefix);
+  %FunctionRemovePrototype(getter);
+  %DefineGetterPropertyUnchecked(object, name, getter, attributes);
+  %SetNativeFlag(getter);
+}
+
+
+// Helper function to install a getter/setter accessor property.
+function InstallGetterSetter(object, name, getter, setter, attributes) {
+  %CheckIsBootstrapping();
+  if (IS_UNDEFINED(attributes)) attributes = DONT_ENUM;
+  SetFunctionName(getter, name, "get");
+  SetFunctionName(setter, name, "set");
+  %FunctionRemovePrototype(getter);
+  %FunctionRemovePrototype(setter);
+  %DefineAccessorPropertyUnchecked(object, name, getter, setter, DONT_ENUM);
+  %SetNativeFlag(getter);
+  %SetNativeFlag(setter);
+}
+
+
+// Prevents changes to the prototype of a built-in function.
+// The "prototype" property of the function object is made non-configurable,
+// and the prototype object is made non-extensible. The latter prevents
+// changing the __proto__ property.
+function SetUpLockedPrototype(
+    constructor, fields, methods) {
+  %CheckIsBootstrapping();
+  var prototype = constructor.prototype;
+  // Install functions first, because this function is used to initialize
+  // PropertyDescriptor itself.
+  var property_count = (methods.length >> 1) + (fields ? fields.length : 0);
+  if (property_count >= 4) {
+    %OptimizeObjectForAddingMultipleProperties(prototype, property_count);
+  }
+  if (fields) {
+    for (var i = 0; i < fields.length; i++) {
+      %AddNamedProperty(prototype, fields[i],
+                        UNDEFINED, DONT_ENUM | DONT_DELETE);
+    }
+  }
+  for (var i = 0; i < methods.length; i += 2) {
+    var key = methods[i];
+    var f = methods[i + 1];
+    %AddNamedProperty(prototype, key, f, DONT_ENUM | DONT_DELETE | READ_ONLY);
+    %SetNativeFlag(f);
+  }
+  %InternalSetPrototype(prototype, null);
+  %ToFastProperties(prototype);
+}
+
+
+// -----------------------------------------------------------------------
+// To be called by bootstrapper
+
+function PostNatives(utils) {
+  %CheckIsBootstrapping();
+
+  for ( ; !IS_UNDEFINED(imports); imports = imports.next) {
+    imports(exports_container);
+  }
+
+  // Whitelist of exports from normal natives to experimental natives and debug.
+  var expose_list = [
+    "ArrayToString",
+    "ErrorToString",
+    "GetIterator",
+    "GetMethod",
+    "IsNaN",
+    "MakeError",
+    "MakeTypeError",
+    "MapEntries",
+    "MapIterator",
+    "MapIteratorNext",
+    "MathMax",
+    "MathMin",
+    "MaxSimple",
+    "MinSimple",
+    "ObjectDefineProperty",
+    "ObserveArrayMethods",
+    "ObserveObjectMethods",
+    "PromiseChain",
+    "PromiseDeferred",
+    "PromiseResolved",
+    "SameValueZero",
+    "SetIterator",
+    "SetIteratorNext",
+    "SetValues",
+    "SymbolToString",
+    "ToPositiveInteger",
+    // From runtime:
+    "is_concat_spreadable_symbol",
+    "iterator_symbol",
+    "promise_status_symbol",
+    "promise_value_symbol",
+    "object_freeze",
+    "object_is_frozen",
+    "object_is_sealed",
+    "reflect_apply",
+    "reflect_construct",
+    "regexp_flags_symbol",
+    "to_string_tag_symbol",
+    "object_to_string",
+    "species_symbol",
+  ];
+
+  var filtered_exports = {};
+  %OptimizeObjectForAddingMultipleProperties(
+      filtered_exports, expose_list.length);
+  for (var key of expose_list) {
+    filtered_exports[key] = exports_container[key];
+  }
+  %ToFastProperties(filtered_exports);
+  exports_container = filtered_exports;
+
+  utils.PostNatives = UNDEFINED;
+  utils.ImportFromExperimental = UNDEFINED;
+}
+
+
+function PostExperimentals(utils) {
+  %CheckIsBootstrapping();
+  %ExportExperimentalFromRuntime(exports_container);
+  for ( ; !IS_UNDEFINED(imports); imports = imports.next) {
+    imports(exports_container);
+  }
+  for ( ; !IS_UNDEFINED(imports_from_experimental);
+          imports_from_experimental = imports_from_experimental.next) {
+    imports_from_experimental(exports_container);
+  }
+
+  utils.CreateDoubleResultArray();
+  utils.CreateDoubleResultArray = UNDEFINED;
+
+  utils.Export = UNDEFINED;
+  utils.PostDebug = UNDEFINED;
+  utils.PostExperimentals = UNDEFINED;
+  typed_array_setup = UNDEFINED;
+}
+
+
+function PostDebug(utils) {
+  for ( ; !IS_UNDEFINED(imports); imports = imports.next) {
+    imports(exports_container);
+  }
+
+  utils.CreateDoubleResultArray();
+  utils.CreateDoubleResultArray = UNDEFINED;
+
+  exports_container = UNDEFINED;
+
+  utils.Export = UNDEFINED;
+  utils.Import = UNDEFINED;
+  utils.ImportNow = UNDEFINED;
+  utils.PostDebug = UNDEFINED;
+  utils.PostExperimentals = UNDEFINED;
+  typed_array_setup = UNDEFINED;
+}
+
+
+function InitializeBuiltinTypedArrays(utils, rng_state, rempio2result) {
+  var setup_list =  typed_array_setup;
+
+  for ( ; !IS_UNDEFINED(setup_list); setup_list = setup_list.next) {
+    setup_list(rng_state, rempio2result);
+  }
+}
+
+
+// -----------------------------------------------------------------------
+
+%OptimizeObjectForAddingMultipleProperties(utils, 14);
+
+utils.Import = Import;
+utils.ImportNow = ImportNow;
+utils.Export = Export;
+utils.ImportFromExperimental = ImportFromExperimental;
+utils.SetFunctionName = SetFunctionName;
+utils.InstallConstants = InstallConstants;
+utils.InstallFunctions = InstallFunctions;
+utils.InstallGetter = InstallGetter;
+utils.InstallGetterSetter = InstallGetterSetter;
+utils.SetUpLockedPrototype = SetUpLockedPrototype;
+utils.PostNatives = PostNatives;
+utils.PostExperimentals = PostExperimentals;
+utils.PostDebug = PostDebug;
+
+%ToFastProperties(utils);
+
+// -----------------------------------------------------------------------
+
+%OptimizeObjectForAddingMultipleProperties(extrasUtils, 5);
+
+extrasUtils.logStackTrace = function logStackTrace() {
+  %DebugTrace();
+};
+
+extrasUtils.log = function log() {
+  let message = '';
+  for (const arg of arguments) {
+    message += arg;
+  }
+
+  %GlobalPrint(message);
+};
+
+// Extras need the ability to store private state on their objects without
+// exposing it to the outside world.
+
+extrasUtils.createPrivateSymbol = function createPrivateSymbol(name) {
+  return %CreatePrivateSymbol(name);
+};
+
+// These functions are key for safe meta-programming:
+// http://wiki.ecmascript.org/doku.php?id=conventions:safe_meta_programming
+//
+// Technically they could all be derived from combinations of
+// Function.prototype.{bind,call,apply} but that introduces lots of layers of
+// indirection and slowness given how un-optimized bind is.
+
+extrasUtils.simpleBind = function simpleBind(func, thisArg) {
+  return function() {
+    return %Apply(func, thisArg, arguments, 0, arguments.length);
+  };
+};
+
+extrasUtils.uncurryThis = function uncurryThis(func) {
+  return function(thisArg) {
+    return %Apply(func, thisArg, arguments, 1, arguments.length - 1);
+  };
+};
+
+%ToFastProperties(extrasUtils);
+
+})
diff --git a/src/js/promise-extra.js b/src/js/promise-extra.js
new file mode 100644
index 0000000..f6f7959
--- /dev/null
+++ b/src/js/promise-extra.js
@@ -0,0 +1,26 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function(global, utils) {
+
+"use strict";
+
+%CheckIsBootstrapping();
+
+var GlobalPromise = global.Promise;
+
+var PromiseChain = utils.ImportNow("PromiseChain");
+var PromiseDeferred = utils.ImportNow("PromiseDeferred");
+var PromiseResolved = utils.ImportNow("PromiseResolved");
+
+utils.InstallFunctions(GlobalPromise.prototype, DONT_ENUM, [
+  "chain", PromiseChain,
+]);
+
+utils.InstallFunctions(GlobalPromise, DONT_ENUM, [
+  "defer", PromiseDeferred,
+  "accept", PromiseResolved,
+]);
+
+})
diff --git a/src/js/promise.js b/src/js/promise.js
new file mode 100644
index 0000000..8cf6a36
--- /dev/null
+++ b/src/js/promise.js
@@ -0,0 +1,480 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function(global, utils, extrasUtils) {
+
+"use strict";
+
+%CheckIsBootstrapping();
+
+// -------------------------------------------------------------------
+// Imports
+
+var InternalArray = utils.InternalArray;
+var MakeTypeError;
+var promiseCombinedDeferredSymbol =
+    utils.ImportNow("promise_combined_deferred_symbol");
+var promiseHasHandlerSymbol =
+    utils.ImportNow("promise_has_handler_symbol");
+var promiseOnRejectSymbol = utils.ImportNow("promise_on_reject_symbol");
+var promiseOnResolveSymbol =
+    utils.ImportNow("promise_on_resolve_symbol");
+var promiseRawSymbol = utils.ImportNow("promise_raw_symbol");
+var promiseStatusSymbol = utils.ImportNow("promise_status_symbol");
+var promiseValueSymbol = utils.ImportNow("promise_value_symbol");
+var SpeciesConstructor;
+var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
+
+utils.Import(function(from) {
+  MakeTypeError = from.MakeTypeError;
+  SpeciesConstructor = from.SpeciesConstructor;
+});
+
+// -------------------------------------------------------------------
+
+// Status values: 0 = pending, +1 = resolved, -1 = rejected
+var lastMicrotaskId = 0;
+
+function CreateResolvingFunctions(promise) {
+  var alreadyResolved = false;
+
+  var resolve = value => {
+    if (alreadyResolved === true) return;
+    alreadyResolved = true;
+    PromiseResolve(promise, value);
+  };
+
+  var reject = reason => {
+    if (alreadyResolved === true) return;
+    alreadyResolved = true;
+    PromiseReject(promise, reason);
+  };
+
+  return {
+    __proto__: null,
+    resolve: resolve,
+    reject: reject
+  };
+}
+
+
+var GlobalPromise = function Promise(resolver) {
+  if (resolver === promiseRawSymbol) {
+    return %NewObject(GlobalPromise, new.target);
+  }
+  if (IS_UNDEFINED(new.target)) throw MakeTypeError(kNotAPromise, this);
+  if (!IS_CALLABLE(resolver))
+    throw MakeTypeError(kResolverNotAFunction, resolver);
+
+  var promise = PromiseInit(%NewObject(GlobalPromise, new.target));
+  var callbacks = CreateResolvingFunctions(promise);
+
+  try {
+    %DebugPushPromise(promise, Promise);
+    resolver(callbacks.resolve, callbacks.reject);
+  } catch (e) {
+    %_Call(callbacks.reject, UNDEFINED, e);
+  } finally {
+    %DebugPopPromise();
+  }
+
+  return promise;
+}
+
+// Core functionality.
+
+function PromiseSet(promise, status, value, onResolve, onReject) {
+  SET_PRIVATE(promise, promiseStatusSymbol, status);
+  SET_PRIVATE(promise, promiseValueSymbol, value);
+  SET_PRIVATE(promise, promiseOnResolveSymbol, onResolve);
+  SET_PRIVATE(promise, promiseOnRejectSymbol, onReject);
+  if (DEBUG_IS_ACTIVE) {
+    %DebugPromiseEvent({ promise: promise, status: status, value: value });
+  }
+  return promise;
+}
+
+function PromiseCreateAndSet(status, value) {
+  var promise = new GlobalPromise(promiseRawSymbol);
+  // If debug is active, notify about the newly created promise first.
+  if (DEBUG_IS_ACTIVE) PromiseSet(promise, 0, UNDEFINED);
+  return PromiseSet(promise, status, value);
+}
+
+function PromiseInit(promise) {
+  return PromiseSet(
+      promise, 0, UNDEFINED, new InternalArray, new InternalArray)
+}
+
+function PromiseDone(promise, status, value, promiseQueue) {
+  if (GET_PRIVATE(promise, promiseStatusSymbol) === 0) {
+    var tasks = GET_PRIVATE(promise, promiseQueue);
+    if (tasks.length) PromiseEnqueue(value, tasks, status);
+    PromiseSet(promise, status, value);
+  }
+}
+
+function PromiseHandle(value, handler, deferred) {
+  try {
+    %DebugPushPromise(deferred.promise, PromiseHandle);
+    var result = handler(value);
+    deferred.resolve(result);
+  } catch (exception) {
+    try { deferred.reject(exception); } catch (e) { }
+  } finally {
+    %DebugPopPromise();
+  }
+}
+
+function PromiseEnqueue(value, tasks, status) {
+  var id, name, instrumenting = DEBUG_IS_ACTIVE;
+  %EnqueueMicrotask(function() {
+    if (instrumenting) {
+      %DebugAsyncTaskEvent({ type: "willHandle", id: id, name: name });
+    }
+    for (var i = 0; i < tasks.length; i += 2) {
+      PromiseHandle(value, tasks[i], tasks[i + 1])
+    }
+    if (instrumenting) {
+      %DebugAsyncTaskEvent({ type: "didHandle", id: id, name: name });
+    }
+  });
+  if (instrumenting) {
+    id = ++lastMicrotaskId;
+    name = status > 0 ? "Promise.resolve" : "Promise.reject";
+    %DebugAsyncTaskEvent({ type: "enqueue", id: id, name: name });
+  }
+}
+
+function PromiseIdResolveHandler(x) { return x }
+function PromiseIdRejectHandler(r) { throw r }
+
+function PromiseNopResolver() {}
+
+// -------------------------------------------------------------------
+// Define exported functions.
+
+// For bootstrapper.
+
+function IsPromise(x) {
+  return IS_RECEIVER(x) && HAS_DEFINED_PRIVATE(x, promiseStatusSymbol);
+}
+
+function PromiseCreate() {
+  return new GlobalPromise(PromiseNopResolver)
+}
+
+function PromiseResolve(promise, x) {
+  if (x === promise) {
+    return PromiseReject(promise, MakeTypeError(kPromiseCyclic, x));
+  }
+  if (IS_RECEIVER(x)) {
+    // 25.4.1.3.2 steps 8-12
+    try {
+      var then = x.then;
+    } catch (e) {
+      return PromiseReject(promise, e);
+    }
+    if (IS_CALLABLE(then)) {
+      // PromiseResolveThenableJob
+      var id, name, instrumenting = DEBUG_IS_ACTIVE;
+      %EnqueueMicrotask(function() {
+        if (instrumenting) {
+          %DebugAsyncTaskEvent({ type: "willHandle", id: id, name: name });
+        }
+        var callbacks = CreateResolvingFunctions(promise);
+        try {
+          %_Call(then, x, callbacks.resolve, callbacks.reject);
+        } catch (e) {
+          %_Call(callbacks.reject, UNDEFINED, e);
+        }
+        if (instrumenting) {
+          %DebugAsyncTaskEvent({ type: "didHandle", id: id, name: name });
+        }
+      });
+      if (instrumenting) {
+        id = ++lastMicrotaskId;
+        name = "PromseResolveThenableJob";
+        %DebugAsyncTaskEvent({ type: "enqueue", id: id, name: name });
+      }
+      return;
+    }
+  }
+  PromiseDone(promise, +1, x, promiseOnResolveSymbol);
+}
+
+function PromiseReject(promise, r) {
+  // Check promise status to confirm that this reject has an effect.
+  // Call runtime for callbacks to the debugger or for unhandled reject.
+  if (GET_PRIVATE(promise, promiseStatusSymbol) == 0) {
+    var debug_is_active = DEBUG_IS_ACTIVE;
+    if (debug_is_active ||
+        !HAS_DEFINED_PRIVATE(promise, promiseHasHandlerSymbol)) {
+      %PromiseRejectEvent(promise, r, debug_is_active);
+    }
+  }
+  PromiseDone(promise, -1, r, promiseOnRejectSymbol)
+}
+
+// Convenience.
+
+function NewPromiseCapability(C) {
+  if (C === GlobalPromise) {
+    // Optimized case, avoid extra closure.
+    var promise = PromiseInit(new GlobalPromise(promiseRawSymbol));
+    var callbacks = CreateResolvingFunctions(promise);
+    return {
+      promise: promise,
+      resolve: callbacks.resolve,
+      reject: callbacks.reject
+    };
+  }
+
+  var result = {promise: UNDEFINED, resolve: UNDEFINED, reject: UNDEFINED };
+  result.promise = new C((resolve, reject) => {
+    if (!IS_UNDEFINED(result.resolve) || !IS_UNDEFINED(result.reject))
+        throw MakeTypeError(kPromiseExecutorAlreadyInvoked);
+    result.resolve = resolve;
+    result.reject = reject;
+  });
+
+  return result;
+}
+
+function PromiseDeferred() {
+  %IncrementUseCounter(kPromiseDefer);
+  return NewPromiseCapability(this);
+}
+
+function PromiseResolved(x) {
+  %IncrementUseCounter(kPromiseAccept);
+  return %_Call(PromiseCast, this, x);
+}
+
+function PromiseRejected(r) {
+  if (!IS_RECEIVER(this)) {
+    throw MakeTypeError(kCalledOnNonObject, PromiseRejected);
+  }
+  if (this === GlobalPromise) {
+    // Optimized case, avoid extra closure.
+    var promise = PromiseCreateAndSet(-1, r);
+    // The debug event for this would always be an uncaught promise reject,
+    // which is usually simply noise. Do not trigger that debug event.
+    %PromiseRejectEvent(promise, r, false);
+    return promise;
+  } else {
+    var promiseCapability = NewPromiseCapability(this);
+    %_Call(promiseCapability.reject, UNDEFINED, r);
+    return promiseCapability.promise;
+  }
+}
+
+// Multi-unwrapped chaining with thenable coercion.
+
+function PromiseThen(onResolve, onReject) {
+  var status = GET_PRIVATE(this, promiseStatusSymbol);
+  if (IS_UNDEFINED(status)) {
+    throw MakeTypeError(kNotAPromise, this);
+  }
+
+  var constructor = SpeciesConstructor(this, GlobalPromise);
+  onResolve = IS_CALLABLE(onResolve) ? onResolve : PromiseIdResolveHandler;
+  onReject = IS_CALLABLE(onReject) ? onReject : PromiseIdRejectHandler;
+  var deferred = NewPromiseCapability(constructor);
+  switch (status) {
+    case 0:  // Pending
+      GET_PRIVATE(this, promiseOnResolveSymbol).push(onResolve, deferred);
+      GET_PRIVATE(this, promiseOnRejectSymbol).push(onReject, deferred);
+      break;
+    case +1:  // Resolved
+      PromiseEnqueue(GET_PRIVATE(this, promiseValueSymbol),
+                     [onResolve, deferred],
+                     +1);
+      break;
+    case -1:  // Rejected
+      if (!HAS_DEFINED_PRIVATE(this, promiseHasHandlerSymbol)) {
+        // Promise has already been rejected, but had no handler.
+        // Revoke previously triggered reject event.
+        %PromiseRevokeReject(this);
+      }
+      PromiseEnqueue(GET_PRIVATE(this, promiseValueSymbol),
+                     [onReject, deferred],
+                     -1);
+      break;
+  }
+  // Mark this promise as having handler.
+  SET_PRIVATE(this, promiseHasHandlerSymbol, true);
+  if (DEBUG_IS_ACTIVE) {
+    %DebugPromiseEvent({ promise: deferred.promise, parentPromise: this });
+  }
+  return deferred.promise;
+}
+
+// Chain is left around for now as an alias for then
+function PromiseChain(onResolve, onReject) {
+  %IncrementUseCounter(kPromiseChain);
+  return %_Call(PromiseThen, this, onResolve, onReject);
+}
+
+function PromiseCatch(onReject) {
+  return this.then(UNDEFINED, onReject);
+}
+
+// Combinators.
+
+function PromiseCast(x) {
+  if (!IS_RECEIVER(this)) {
+    throw MakeTypeError(kCalledOnNonObject, PromiseCast);
+  }
+  if (IsPromise(x) && x.constructor === this) return x;
+
+  var promiseCapability = NewPromiseCapability(this);
+  var resolveResult = %_Call(promiseCapability.resolve, UNDEFINED, x);
+  return promiseCapability.promise;
+}
+
+function PromiseAll(iterable) {
+  if (!IS_RECEIVER(this)) {
+    throw MakeTypeError(kCalledOnNonObject, "Promise.all");
+  }
+
+  var deferred = NewPromiseCapability(this);
+  var resolutions = new InternalArray();
+  var count;
+
+  function CreateResolveElementFunction(index, values, promiseCapability) {
+    var alreadyCalled = false;
+    return (x) => {
+      if (alreadyCalled === true) return;
+      alreadyCalled = true;
+      values[index] = x;
+      if (--count === 0) {
+        var valuesArray = [];
+        %MoveArrayContents(values, valuesArray);
+        %_Call(promiseCapability.resolve, UNDEFINED, valuesArray);
+      }
+    };
+  }
+
+  try {
+    var i = 0;
+    count = 1;
+    for (var value of iterable) {
+      var nextPromise = this.resolve(value);
+      ++count;
+      nextPromise.then(
+          CreateResolveElementFunction(i, resolutions, deferred),
+          deferred.reject);
+      SET_PRIVATE(deferred.reject, promiseCombinedDeferredSymbol, deferred);
+      ++i;
+    }
+
+    // 6.d
+    if (--count === 0) {
+      var valuesArray = [];
+      %MoveArrayContents(resolutions, valuesArray);
+      %_Call(deferred.resolve, UNDEFINED, valuesArray);
+    }
+
+  } catch (e) {
+    %_Call(deferred.reject, UNDEFINED, e);
+  }
+  return deferred.promise;
+}
+
+function PromiseRace(iterable) {
+  if (!IS_RECEIVER(this)) {
+    throw MakeTypeError(kCalledOnNonObject, PromiseRace);
+  }
+
+  var deferred = NewPromiseCapability(this);
+  try {
+    for (var value of iterable) {
+      this.resolve(value).then(deferred.resolve, deferred.reject);
+      SET_PRIVATE(deferred.reject, promiseCombinedDeferredSymbol, deferred);
+    }
+  } catch (e) {
+    deferred.reject(e)
+  }
+  return deferred.promise;
+}
+
+
+// Utility for debugger
+
+function PromiseHasUserDefinedRejectHandlerRecursive(promise) {
+  var queue = GET_PRIVATE(promise, promiseOnRejectSymbol);
+  if (IS_UNDEFINED(queue)) return false;
+  for (var i = 0; i < queue.length; i += 2) {
+    var handler = queue[i];
+    if (handler !== PromiseIdRejectHandler) {
+      var deferred = GET_PRIVATE(handler, promiseCombinedDeferredSymbol);
+      if (IS_UNDEFINED(deferred)) return true;
+      if (PromiseHasUserDefinedRejectHandlerRecursive(deferred.promise)) {
+        return true;
+      }
+    } else if (PromiseHasUserDefinedRejectHandlerRecursive(
+                   queue[i + 1].promise)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+// Return whether the promise will be handled by a user-defined reject
+// handler somewhere down the promise chain. For this, we do a depth-first
+// search for a reject handler that's not the default PromiseIdRejectHandler.
+function PromiseHasUserDefinedRejectHandler() {
+  return PromiseHasUserDefinedRejectHandlerRecursive(this);
+};
+
+// -------------------------------------------------------------------
+// Install exported functions.
+
+%AddNamedProperty(global, 'Promise', GlobalPromise, DONT_ENUM);
+%AddNamedProperty(GlobalPromise.prototype, toStringTagSymbol, "Promise",
+                  DONT_ENUM | READ_ONLY);
+
+utils.InstallFunctions(GlobalPromise, DONT_ENUM, [
+  "reject", PromiseRejected,
+  "all", PromiseAll,
+  "race", PromiseRace,
+  "resolve", PromiseCast
+]);
+
+utils.InstallFunctions(GlobalPromise.prototype, DONT_ENUM, [
+  "then", PromiseThen,
+  "catch", PromiseCatch
+]);
+
+%InstallToContext([
+  "promise_catch", PromiseCatch,
+  "promise_chain", PromiseChain,
+  "promise_create", PromiseCreate,
+  "promise_has_user_defined_reject_handler", PromiseHasUserDefinedRejectHandler,
+  "promise_reject", PromiseReject,
+  "promise_resolve", PromiseResolve,
+  "promise_then", PromiseThen,
+]);
+
+// This allows extras to create promises quickly without building extra
+// resolve/reject closures, and allows them to later resolve and reject any
+// promise without having to hold on to those closures forever.
+utils.InstallFunctions(extrasUtils, 0, [
+  "createPromise", PromiseCreate,
+  "resolvePromise", PromiseResolve,
+  "rejectPromise", PromiseReject
+]);
+
+// TODO(v8:4567): Allow experimental natives to remove function prototype
+[PromiseChain, PromiseDeferred, PromiseResolved].forEach(
+    fn => %FunctionRemovePrototype(fn));
+
+utils.Export(function(to) {
+  to.PromiseChain = PromiseChain;
+  to.PromiseDeferred = PromiseDeferred;
+  to.PromiseResolved = PromiseResolved;
+});
+
+})
diff --git a/src/js/proxy.js b/src/js/proxy.js
new file mode 100644
index 0000000..842bac0
--- /dev/null
+++ b/src/js/proxy.js
@@ -0,0 +1,69 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function(global, utils) {
+
+"use strict";
+
+%CheckIsBootstrapping();
+
+// ----------------------------------------------------------------------------
+// Imports
+//
+var GlobalProxy = global.Proxy;
+var MakeTypeError;
+
+utils.Import(function(from) {
+  MakeTypeError = from.MakeTypeError;
+});
+
+//----------------------------------------------------------------------------
+
+function ProxyCreateRevocable(target, handler) {
+  var p = new GlobalProxy(target, handler);
+  return {proxy: p, revoke: () => %JSProxyRevoke(p)};
+}
+
+// -------------------------------------------------------------------
+// Proxy Builtins
+
+// Implements part of ES6 9.5.11 Proxy.[[Enumerate]]:
+// Call the trap, which should return an iterator, exhaust the iterator,
+// and return an array containing the values.
+function ProxyEnumerate(trap, handler, target) {
+  // 7. Let trapResult be ? Call(trap, handler, «target»).
+  var trap_result = %_Call(trap, handler, target);
+  // 8. If Type(trapResult) is not Object, throw a TypeError exception.
+  if (!IS_RECEIVER(trap_result)) {
+    throw MakeTypeError(kProxyEnumerateNonObject);
+  }
+  // 9. Return trapResult.
+  var result = [];
+  for (var it = trap_result.next(); !it.done; it = trap_result.next()) {
+    var key = it.value;
+    // Not yet spec'ed as of 2015-11-25, but will be spec'ed soon:
+    // If the iterator returns a non-string value, throw a TypeError.
+    if (!IS_STRING(key)) {
+      throw MakeTypeError(kProxyEnumerateNonString);
+    }
+    result.push(key);
+  }
+  return result;
+}
+
+//-------------------------------------------------------------------
+
+//Set up non-enumerable properties of the Proxy object.
+utils.InstallFunctions(GlobalProxy, DONT_ENUM, [
+  "revocable", ProxyCreateRevocable
+]);
+
+// -------------------------------------------------------------------
+// Exports
+
+%InstallToContext([
+  "proxy_enumerate", ProxyEnumerate,
+]);
+
+})
diff --git a/src/js/regexp.js b/src/js/regexp.js
new file mode 100644
index 0000000..eeacd6e
--- /dev/null
+++ b/src/js/regexp.js
@@ -0,0 +1,600 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function(global, utils) {
+
+%CheckIsBootstrapping();
+
+// -------------------------------------------------------------------
+// Imports
+
+var FLAG_harmony_tolength;
+var GlobalObject = global.Object;
+var GlobalRegExp = global.RegExp;
+var GlobalRegExpPrototype;
+var InternalArray = utils.InternalArray;
+var InternalPackedArray = utils.InternalPackedArray;
+var MakeTypeError;
+var matchSymbol = utils.ImportNow("match_symbol");
+var searchSymbol = utils.ImportNow("search_symbol");
+var splitSymbol = utils.ImportNow("split_symbol");
+
+utils.ImportFromExperimental(function(from) {
+  FLAG_harmony_tolength = from.FLAG_harmony_tolength;
+});
+
+utils.Import(function(from) {
+  MakeTypeError = from.MakeTypeError;
+});
+
+// -------------------------------------------------------------------
+
+// Property of the builtins object for recording the result of the last
+// regexp match.  The property RegExpLastMatchInfo includes the matchIndices
+// array of the last successful regexp match (an array of start/end index
+// pairs for the match and all the captured substrings), the invariant is
+// that there are at least two capture indeces.  The array also contains
+// the subject string for the last successful match.
+var RegExpLastMatchInfo = new InternalPackedArray(
+ 2,                 // REGEXP_NUMBER_OF_CAPTURES
+ "",                // Last subject.
+ UNDEFINED,         // Last input - settable with RegExpSetInput.
+ 0,                 // REGEXP_FIRST_CAPTURE + 0
+ 0                  // REGEXP_FIRST_CAPTURE + 1
+);
+
+// -------------------------------------------------------------------
+
+function IsRegExp(o) {
+  if (!IS_RECEIVER(o)) return false;
+  var is_regexp = o[matchSymbol];
+  if (!IS_UNDEFINED(is_regexp)) return TO_BOOLEAN(is_regexp);
+  return IS_REGEXP(o);
+}
+
+
+// ES6 section 21.2.3.2.2
+function RegExpInitialize(object, pattern, flags) {
+  pattern = IS_UNDEFINED(pattern) ? '' : TO_STRING(pattern);
+  flags = IS_UNDEFINED(flags) ? '' : TO_STRING(flags);
+  %RegExpInitializeAndCompile(object, pattern, flags);
+  return object;
+}
+
+
+function PatternFlags(pattern) {
+  return (REGEXP_GLOBAL(pattern) ? 'g' : '') +
+         (REGEXP_IGNORE_CASE(pattern) ? 'i' : '') +
+         (REGEXP_MULTILINE(pattern) ? 'm' : '') +
+         (REGEXP_UNICODE(pattern) ? 'u' : '') +
+         (REGEXP_STICKY(pattern) ? 'y' : '');
+}
+
+
+function RegExpConstructor(pattern, flags) {
+  var newtarget = new.target;
+  var pattern_is_regexp = IsRegExp(pattern);
+
+  if (IS_UNDEFINED(newtarget)) {
+    newtarget = GlobalRegExp;
+
+    // ES6 section 21.2.3.1 step 3.b
+    if (pattern_is_regexp && IS_UNDEFINED(flags) &&
+        pattern.constructor === newtarget) {
+      return pattern;
+    }
+  }
+
+  if (IS_REGEXP(pattern)) {
+    if (IS_UNDEFINED(flags)) flags = PatternFlags(pattern);
+    pattern = REGEXP_SOURCE(pattern);
+
+  } else if (pattern_is_regexp) {
+    var input_pattern = pattern;
+    pattern = pattern.source;
+    if (IS_UNDEFINED(flags)) flags = input_pattern.flags;
+  }
+
+  var object = %NewObject(GlobalRegExp, newtarget);
+  return RegExpInitialize(object, pattern, flags);
+}
+
+
+function RegExpCompileJS(pattern, flags) {
+  if (!IS_REGEXP(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        "RegExp.prototype.compile", this);
+  }
+
+  if (IS_REGEXP(pattern)) {
+    if (!IS_UNDEFINED(flags)) throw MakeTypeError(kRegExpFlags);
+
+    flags = PatternFlags(pattern);
+    pattern = REGEXP_SOURCE(pattern);
+  }
+
+  RegExpInitialize(this, pattern, flags);
+
+  // Return undefined for compatibility with JSC.
+  // See http://crbug.com/585775 for web compat details.
+}
+
+
+function DoRegExpExec(regexp, string, index) {
+  return %_RegExpExec(regexp, string, index, RegExpLastMatchInfo);
+}
+
+
+// This is kind of performance sensitive, so we want to avoid unnecessary
+// type checks on inputs. But we also don't want to inline it several times
+// manually, so we use a macro :-)
+macro RETURN_NEW_RESULT_FROM_MATCH_INFO(MATCHINFO, STRING)
+  var numResults = NUMBER_OF_CAPTURES(MATCHINFO) >> 1;
+  var start = MATCHINFO[CAPTURE0];
+  var end = MATCHINFO[CAPTURE1];
+  // Calculate the substring of the first match before creating the result array
+  // to avoid an unnecessary write barrier storing the first result.
+  var first = %_SubString(STRING, start, end);
+  var result = %_RegExpConstructResult(numResults, start, STRING);
+  result[0] = first;
+  if (numResults == 1) return result;
+  var j = REGEXP_FIRST_CAPTURE + 2;
+  for (var i = 1; i < numResults; i++) {
+    start = MATCHINFO[j++];
+    if (start != -1) {
+      end = MATCHINFO[j];
+      result[i] = %_SubString(STRING, start, end);
+    }
+    j++;
+  }
+  return result;
+endmacro
+
+
+function RegExpExecNoTests(regexp, string, start) {
+  // Must be called with RegExp, string and positive integer as arguments.
+  var matchInfo = %_RegExpExec(regexp, string, start, RegExpLastMatchInfo);
+  if (matchInfo !== null) {
+    // ES6 21.2.5.2.2 step 18.
+    if (REGEXP_STICKY(regexp)) regexp.lastIndex = matchInfo[CAPTURE1];
+    RETURN_NEW_RESULT_FROM_MATCH_INFO(matchInfo, string);
+  }
+  regexp.lastIndex = 0;
+  return null;
+}
+
+
+function RegExpExecJS(string) {
+  if (!IS_REGEXP(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        'RegExp.prototype.exec', this);
+  }
+
+  string = TO_STRING(string);
+  var lastIndex = this.lastIndex;
+
+  // Conversion is required by the ES2015 specification (RegExpBuiltinExec
+  // algorithm, step 4) even if the value is discarded for non-global RegExps.
+  var i = TO_LENGTH_OR_INTEGER(lastIndex);
+
+  var updateLastIndex = REGEXP_GLOBAL(this) || REGEXP_STICKY(this);
+  if (updateLastIndex) {
+    if (i < 0 || i > string.length) {
+      this.lastIndex = 0;
+      return null;
+    }
+  } else {
+    i = 0;
+  }
+
+  // matchIndices is either null or the RegExpLastMatchInfo array.
+  var matchIndices = %_RegExpExec(this, string, i, RegExpLastMatchInfo);
+
+  if (IS_NULL(matchIndices)) {
+    this.lastIndex = 0;
+    return null;
+  }
+
+  // Successful match.
+  if (updateLastIndex) {
+    this.lastIndex = RegExpLastMatchInfo[CAPTURE1];
+  }
+  RETURN_NEW_RESULT_FROM_MATCH_INFO(matchIndices, string);
+}
+
+
+// One-element cache for the simplified test regexp.
+var regexp_key;
+var regexp_val;
+
+// Section 15.10.6.3 doesn't actually make sense, but the intention seems to be
+// that test is defined in terms of String.prototype.exec. However, it probably
+// means the original value of String.prototype.exec, which is what everybody
+// else implements.
+function RegExpTest(string) {
+  if (!IS_REGEXP(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        'RegExp.prototype.test', this);
+  }
+  string = TO_STRING(string);
+
+  var lastIndex = this.lastIndex;
+
+  // Conversion is required by the ES2015 specification (RegExpBuiltinExec
+  // algorithm, step 4) even if the value is discarded for non-global RegExps.
+  var i = TO_LENGTH_OR_INTEGER(lastIndex);
+
+  if (REGEXP_GLOBAL(this) || REGEXP_STICKY(this)) {
+    if (i < 0 || i > string.length) {
+      this.lastIndex = 0;
+      return false;
+    }
+    // matchIndices is either null or the RegExpLastMatchInfo array.
+    var matchIndices = %_RegExpExec(this, string, i, RegExpLastMatchInfo);
+    if (IS_NULL(matchIndices)) {
+      this.lastIndex = 0;
+      return false;
+    }
+    this.lastIndex = RegExpLastMatchInfo[CAPTURE1];
+    return true;
+  } else {
+    // Non-global, non-sticky regexp.
+    // Remove irrelevant preceeding '.*' in a test regexp.  The expression
+    // checks whether this.source starts with '.*' and that the third char is
+    // not a '?'.  But see https://code.google.com/p/v8/issues/detail?id=3560
+    var regexp = this;
+    var source = REGEXP_SOURCE(regexp);
+    if (regexp.length >= 3 &&
+        %_StringCharCodeAt(regexp, 0) == 46 &&  // '.'
+        %_StringCharCodeAt(regexp, 1) == 42 &&  // '*'
+        %_StringCharCodeAt(regexp, 2) != 63) {  // '?'
+      regexp = TrimRegExp(regexp);
+    }
+    // matchIndices is either null or the RegExpLastMatchInfo array.
+    var matchIndices = %_RegExpExec(regexp, string, 0, RegExpLastMatchInfo);
+    if (IS_NULL(matchIndices)) {
+      this.lastIndex = 0;
+      return false;
+    }
+    return true;
+  }
+}
+
+function TrimRegExp(regexp) {
+  if (!%_ObjectEquals(regexp_key, regexp)) {
+    regexp_key = regexp;
+    regexp_val =
+      new GlobalRegExp(
+          %_SubString(REGEXP_SOURCE(regexp), 2, REGEXP_SOURCE(regexp).length),
+          (REGEXP_IGNORE_CASE(regexp) ? REGEXP_MULTILINE(regexp) ? "im" : "i"
+                                      : REGEXP_MULTILINE(regexp) ? "m" : ""));
+  }
+  return regexp_val;
+}
+
+
+function RegExpToString() {
+  if (!IS_REGEXP(this)) {
+    // RegExp.prototype.toString() returns '/(?:)/' as a compatibility fix;
+    // a UseCounter is incremented to track it.
+    // TODO(littledan): Remove this workaround or standardize it
+    if (this === GlobalRegExpPrototype) {
+      %IncrementUseCounter(kRegExpPrototypeToString);
+      return '/(?:)/';
+    }
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        'RegExp.prototype.toString', this);
+  }
+  var result = '/' + REGEXP_SOURCE(this) + '/';
+  if (REGEXP_GLOBAL(this)) result += 'g';
+  if (REGEXP_IGNORE_CASE(this)) result += 'i';
+  if (REGEXP_MULTILINE(this)) result += 'm';
+  if (REGEXP_UNICODE(this)) result += 'u';
+  if (REGEXP_STICKY(this)) result += 'y';
+  return result;
+}
+
+
+// ES6 21.2.5.11.
+function RegExpSplit(string, limit) {
+  // TODO(yangguo): allow non-regexp receivers.
+  if (!IS_REGEXP(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        "RegExp.prototype.@@split", this);
+  }
+  var separator = this;
+  var subject = TO_STRING(string);
+
+  limit = (IS_UNDEFINED(limit)) ? kMaxUint32 : TO_UINT32(limit);
+  var length = subject.length;
+
+  if (limit === 0) return [];
+
+  if (length === 0) {
+    if (DoRegExpExec(separator, subject, 0, 0) !== null) return [];
+    return [subject];
+  }
+
+  var currentIndex = 0;
+  var startIndex = 0;
+  var startMatch = 0;
+  var result = new InternalArray();
+
+  outer_loop:
+  while (true) {
+    if (startIndex === length) {
+      result[result.length] = %_SubString(subject, currentIndex, length);
+      break;
+    }
+
+    var matchInfo = DoRegExpExec(separator, subject, startIndex);
+    if (matchInfo === null || length === (startMatch = matchInfo[CAPTURE0])) {
+      result[result.length] = %_SubString(subject, currentIndex, length);
+      break;
+    }
+    var endIndex = matchInfo[CAPTURE1];
+
+    // We ignore a zero-length match at the currentIndex.
+    if (startIndex === endIndex && endIndex === currentIndex) {
+      startIndex++;
+      continue;
+    }
+
+    result[result.length] = %_SubString(subject, currentIndex, startMatch);
+
+    if (result.length === limit) break;
+
+    var matchinfo_len = NUMBER_OF_CAPTURES(matchInfo) + REGEXP_FIRST_CAPTURE;
+    for (var i = REGEXP_FIRST_CAPTURE + 2; i < matchinfo_len; ) {
+      var start = matchInfo[i++];
+      var end = matchInfo[i++];
+      if (end != -1) {
+        result[result.length] = %_SubString(subject, start, end);
+      } else {
+        result[result.length] = UNDEFINED;
+      }
+      if (result.length === limit) break outer_loop;
+    }
+
+    startIndex = currentIndex = endIndex;
+  }
+
+  var array_result = [];
+  %MoveArrayContents(result, array_result);
+  return array_result;
+}
+
+
+// ES6 21.2.5.6.
+function RegExpMatch(string) {
+  // TODO(yangguo): allow non-regexp receivers.
+  if (!IS_REGEXP(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        "RegExp.prototype.@@match", this);
+  }
+  var subject = TO_STRING(string);
+
+  if (!REGEXP_GLOBAL(this)) return RegExpExecNoTests(this, subject, 0);
+  this.lastIndex = 0;
+  var result = %StringMatch(subject, this, RegExpLastMatchInfo);
+  return result;
+}
+
+
+// ES6 21.2.5.9.
+function RegExpSearch(string) {
+  // TODO(yangguo): allow non-regexp receivers.
+  if (!IS_REGEXP(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        "RegExp.prototype.@@search", this);
+  }
+  var match = DoRegExpExec(this, TO_STRING(string), 0);
+  if (match) return match[CAPTURE0];
+  return -1;
+}
+
+
+// Getters for the static properties lastMatch, lastParen, leftContext, and
+// rightContext of the RegExp constructor.  The properties are computed based
+// on the captures array of the last successful match and the subject string
+// of the last successful match.
+function RegExpGetLastMatch() {
+  var regExpSubject = LAST_SUBJECT(RegExpLastMatchInfo);
+  return %_SubString(regExpSubject,
+                     RegExpLastMatchInfo[CAPTURE0],
+                     RegExpLastMatchInfo[CAPTURE1]);
+}
+
+
+function RegExpGetLastParen() {
+  var length = NUMBER_OF_CAPTURES(RegExpLastMatchInfo);
+  if (length <= 2) return '';  // There were no captures.
+  // We match the SpiderMonkey behavior: return the substring defined by the
+  // last pair (after the first pair) of elements of the capture array even if
+  // it is empty.
+  var regExpSubject = LAST_SUBJECT(RegExpLastMatchInfo);
+  var start = RegExpLastMatchInfo[CAPTURE(length - 2)];
+  var end = RegExpLastMatchInfo[CAPTURE(length - 1)];
+  if (start != -1 && end != -1) {
+    return %_SubString(regExpSubject, start, end);
+  }
+  return "";
+}
+
+
+function RegExpGetLeftContext() {
+  var start_index;
+  var subject;
+  start_index = RegExpLastMatchInfo[CAPTURE0];
+  subject = LAST_SUBJECT(RegExpLastMatchInfo);
+  return %_SubString(subject, 0, start_index);
+}
+
+
+function RegExpGetRightContext() {
+  var start_index;
+  var subject;
+  start_index = RegExpLastMatchInfo[CAPTURE1];
+  subject = LAST_SUBJECT(RegExpLastMatchInfo);
+  return %_SubString(subject, start_index, subject.length);
+}
+
+
+// The properties $1..$9 are the first nine capturing substrings of the last
+// successful match, or ''.  The function RegExpMakeCaptureGetter will be
+// called with indices from 1 to 9.
+function RegExpMakeCaptureGetter(n) {
+  return function foo() {
+    var index = n * 2;
+    if (index >= NUMBER_OF_CAPTURES(RegExpLastMatchInfo)) return '';
+    var matchStart = RegExpLastMatchInfo[CAPTURE(index)];
+    var matchEnd = RegExpLastMatchInfo[CAPTURE(index + 1)];
+    if (matchStart == -1 || matchEnd == -1) return '';
+    return %_SubString(LAST_SUBJECT(RegExpLastMatchInfo), matchStart, matchEnd);
+  };
+}
+
+
+// ES6 21.2.5.4.
+function RegExpGetGlobal() {
+  if (!IS_REGEXP(this)) {
+    // TODO(littledan): Remove this RegExp compat workaround
+    if (this === GlobalRegExpPrototype) {
+      return UNDEFINED;
+    }
+    throw MakeTypeError(kRegExpNonRegExp, "RegExp.prototype.global");
+  }
+  return !!REGEXP_GLOBAL(this);
+}
+%FunctionSetName(RegExpGetGlobal, "RegExp.prototype.global");
+%SetNativeFlag(RegExpGetGlobal);
+
+
+// ES6 21.2.5.5.
+function RegExpGetIgnoreCase() {
+  if (!IS_REGEXP(this)) {
+    // TODO(littledan): Remove this RegExp compat workaround
+    if (this === GlobalRegExpPrototype) {
+      return UNDEFINED;
+    }
+    throw MakeTypeError(kRegExpNonRegExp, "RegExp.prototype.ignoreCase");
+  }
+  return !!REGEXP_IGNORE_CASE(this);
+}
+%FunctionSetName(RegExpGetIgnoreCase, "RegExp.prototype.ignoreCase");
+%SetNativeFlag(RegExpGetIgnoreCase);
+
+
+// ES6 21.2.5.7.
+function RegExpGetMultiline() {
+  if (!IS_REGEXP(this)) {
+    // TODO(littledan): Remove this RegExp compat workaround
+    if (this === GlobalRegExpPrototype) {
+      return UNDEFINED;
+    }
+    throw MakeTypeError(kRegExpNonRegExp, "RegExp.prototype.multiline");
+  }
+  return !!REGEXP_MULTILINE(this);
+}
+%FunctionSetName(RegExpGetMultiline, "RegExp.prototype.multiline");
+%SetNativeFlag(RegExpGetMultiline);
+
+
+// ES6 21.2.5.10.
+function RegExpGetSource() {
+  if (!IS_REGEXP(this)) {
+    // TODO(littledan): Remove this RegExp compat workaround
+    if (this === GlobalRegExpPrototype) {
+      return UNDEFINED;
+    }
+    throw MakeTypeError(kRegExpNonRegExp, "RegExp.prototype.source");
+  }
+  return REGEXP_SOURCE(this);
+}
+%FunctionSetName(RegExpGetSource, "RegExp.prototype.source");
+%SetNativeFlag(RegExpGetSource);
+
+// -------------------------------------------------------------------
+
+%FunctionSetInstanceClassName(GlobalRegExp, 'RegExp');
+GlobalRegExpPrototype = new GlobalObject();
+%FunctionSetPrototype(GlobalRegExp, GlobalRegExpPrototype);
+%AddNamedProperty(
+    GlobalRegExp.prototype, 'constructor', GlobalRegExp, DONT_ENUM);
+%SetCode(GlobalRegExp, RegExpConstructor);
+
+utils.InstallFunctions(GlobalRegExp.prototype, DONT_ENUM, [
+  "exec", RegExpExecJS,
+  "test", RegExpTest,
+  "toString", RegExpToString,
+  "compile", RegExpCompileJS,
+  matchSymbol, RegExpMatch,
+  searchSymbol, RegExpSearch,
+  splitSymbol, RegExpSplit,
+]);
+
+utils.InstallGetter(GlobalRegExp.prototype, 'global', RegExpGetGlobal);
+utils.InstallGetter(GlobalRegExp.prototype, 'ignoreCase', RegExpGetIgnoreCase);
+utils.InstallGetter(GlobalRegExp.prototype, 'multiline', RegExpGetMultiline);
+utils.InstallGetter(GlobalRegExp.prototype, 'source', RegExpGetSource);
+
+// The length of compile is 1 in SpiderMonkey.
+%FunctionSetLength(GlobalRegExp.prototype.compile, 1);
+
+// The properties `input` and `$_` are aliases for each other.  When this
+// value is set the value it is set to is coerced to a string.
+// Getter and setter for the input.
+var RegExpGetInput = function() {
+  var regExpInput = LAST_INPUT(RegExpLastMatchInfo);
+  return IS_UNDEFINED(regExpInput) ? "" : regExpInput;
+};
+var RegExpSetInput = function(string) {
+  LAST_INPUT(RegExpLastMatchInfo) = TO_STRING(string);
+};
+
+%OptimizeObjectForAddingMultipleProperties(GlobalRegExp, 22);
+utils.InstallGetterSetter(GlobalRegExp, 'input', RegExpGetInput, RegExpSetInput,
+                          DONT_DELETE);
+utils.InstallGetterSetter(GlobalRegExp, '$_', RegExpGetInput, RegExpSetInput,
+                          DONT_ENUM | DONT_DELETE);
+
+
+var NoOpSetter = function(ignored) {};
+
+
+// Static properties set by a successful match.
+utils.InstallGetterSetter(GlobalRegExp, 'lastMatch', RegExpGetLastMatch,
+                          NoOpSetter, DONT_DELETE);
+utils.InstallGetterSetter(GlobalRegExp, '$&', RegExpGetLastMatch, NoOpSetter,
+                          DONT_ENUM | DONT_DELETE);
+utils.InstallGetterSetter(GlobalRegExp, 'lastParen', RegExpGetLastParen,
+                          NoOpSetter, DONT_DELETE);
+utils.InstallGetterSetter(GlobalRegExp, '$+', RegExpGetLastParen, NoOpSetter,
+                          DONT_ENUM | DONT_DELETE);
+utils.InstallGetterSetter(GlobalRegExp, 'leftContext', RegExpGetLeftContext,
+                          NoOpSetter, DONT_DELETE);
+utils.InstallGetterSetter(GlobalRegExp, '$`', RegExpGetLeftContext, NoOpSetter,
+                          DONT_ENUM | DONT_DELETE);
+utils.InstallGetterSetter(GlobalRegExp, 'rightContext', RegExpGetRightContext,
+                          NoOpSetter, DONT_DELETE);
+utils.InstallGetterSetter(GlobalRegExp, "$'", RegExpGetRightContext, NoOpSetter,
+                          DONT_ENUM | DONT_DELETE);
+
+for (var i = 1; i < 10; ++i) {
+  utils.InstallGetterSetter(GlobalRegExp, '$' + i, RegExpMakeCaptureGetter(i),
+                            NoOpSetter, DONT_DELETE);
+}
+%ToFastProperties(GlobalRegExp);
+
+// -------------------------------------------------------------------
+// Exports
+
+utils.Export(function(to) {
+  to.RegExpExec = DoRegExpExec;
+  to.RegExpExecNoTests = RegExpExecNoTests;
+  to.RegExpLastMatchInfo = RegExpLastMatchInfo;
+  to.RegExpTest = RegExpTest;
+});
+
+})
diff --git a/src/js/runtime.js b/src/js/runtime.js
new file mode 100644
index 0000000..301d75a
--- /dev/null
+++ b/src/js/runtime.js
@@ -0,0 +1,191 @@
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This files contains runtime support implemented in JavaScript.
+
+// CAUTION: Some of the functions specified in this file are called
+// directly from compiled code. These are the functions with names in
+// ALL CAPS. The compiled code passes the first argument in 'this'.
+
+
+// The following declarations are shared with other native JS files.
+// They are all declared at this one spot to avoid redeclaration errors.
+
+(function(global, utils) {
+
+%CheckIsBootstrapping();
+
+var FLAG_harmony_species;
+var GlobalArray = global.Array;
+var GlobalBoolean = global.Boolean;
+var GlobalString = global.String;
+var MakeRangeError;
+var MakeTypeError;
+var speciesSymbol;
+
+utils.Import(function(from) {
+  MakeRangeError = from.MakeRangeError;
+  MakeTypeError = from.MakeTypeError;
+  speciesSymbol = from.species_symbol;
+});
+
+utils.ImportFromExperimental(function(from) {
+  FLAG_harmony_species = from.FLAG_harmony_species;
+});
+
+// ----------------------------------------------------------------------------
+
+/* -----------------------------
+   - - -   H e l p e r s   - - -
+   -----------------------------
+*/
+
+function CONCAT_ITERABLE_TO_ARRAY(iterable) {
+  return %concat_iterable_to_array(this, iterable);
+};
+
+
+/* -------------------------------------
+   - - -   C o n v e r s i o n s   - - -
+   -------------------------------------
+*/
+
+// ES5, section 9.12
+function SameValue(x, y) {
+  if (typeof x != typeof y) return false;
+  if (IS_NUMBER(x)) {
+    if (NUMBER_IS_NAN(x) && NUMBER_IS_NAN(y)) return true;
+    // x is +0 and y is -0 or vice versa.
+    if (x === 0 && y === 0 && %_IsMinusZero(x) != %_IsMinusZero(y)) {
+      return false;
+    }
+  }
+  if (IS_SIMD_VALUE(x)) return %SimdSameValue(x, y);
+  return x === y;
+}
+
+
+// ES6, section 7.2.4
+function SameValueZero(x, y) {
+  if (typeof x != typeof y) return false;
+  if (IS_NUMBER(x)) {
+    if (NUMBER_IS_NAN(x) && NUMBER_IS_NAN(y)) return true;
+  }
+  if (IS_SIMD_VALUE(x)) return %SimdSameValueZero(x, y);
+  return x === y;
+}
+
+
+function ConcatIterableToArray(target, iterable) {
+   var index = target.length;
+   for (var element of iterable) {
+     AddIndexedProperty(target, index++, element);
+   }
+   return target;
+}
+
+
+/* ---------------------------------
+   - - -   U t i l i t i e s   - - -
+   ---------------------------------
+*/
+
+
+// This function should be called rather than %AddElement in contexts where the
+// argument might not be less than 2**32-1. ES2015 ToLength semantics mean that
+// this is a concern at basically all callsites.
+function AddIndexedProperty(obj, index, value) {
+  if (index === TO_UINT32(index) && index !== kMaxUint32) {
+    %AddElement(obj, index, value);
+  } else {
+    %AddNamedProperty(obj, TO_STRING(index), value, NONE);
+  }
+}
+%SetForceInlineFlag(AddIndexedProperty);
+
+
+function ToPositiveInteger(x, rangeErrorIndex) {
+  var i = TO_INTEGER_MAP_MINUS_ZERO(x);
+  if (i < 0) throw MakeRangeError(rangeErrorIndex);
+  return i;
+}
+
+
+function MaxSimple(a, b) {
+  return a > b ? a : b;
+}
+
+
+function MinSimple(a, b) {
+  return a > b ? b : a;
+}
+
+
+%SetForceInlineFlag(MaxSimple);
+%SetForceInlineFlag(MinSimple);
+
+
+// ES2015 7.3.20
+// For the fallback with --harmony-species off, there are two possible choices:
+//  - "conservative": return defaultConstructor
+//  - "not conservative": return object.constructor
+// This fallback path is only needed in the transition to ES2015, and the
+// choice is made simply to preserve the previous behavior so that we don't
+// have a three-step upgrade: old behavior, unspecified intermediate behavior,
+// and ES2015.
+// In some cases, we were "conservative" (e.g., ArrayBuffer, RegExp), and in
+// other cases we were "not conservative (e.g., TypedArray, Promise).
+function SpeciesConstructor(object, defaultConstructor, conservative) {
+  if (FLAG_harmony_species) {
+    var constructor = object.constructor;
+    if (IS_UNDEFINED(constructor)) {
+      return defaultConstructor;
+    }
+    if (!IS_RECEIVER(constructor)) {
+      throw MakeTypeError(kConstructorNotReceiver);
+    }
+    var species = constructor[speciesSymbol];
+    if (IS_NULL_OR_UNDEFINED(species)) {
+      return defaultConstructor;
+    }
+    if (%IsConstructor(species)) {
+      return species;
+    }
+    throw MakeTypeError(kSpeciesNotConstructor);
+  } else {
+    return conservative ? defaultConstructor : object.constructor;
+  }
+}
+
+//----------------------------------------------------------------------------
+
+// NOTE: Setting the prototype for Array must take place as early as
+// possible due to code generation for array literals.  When
+// generating code for a array literal a boilerplate array is created
+// that is cloned when running the code.  It is essential that the
+// boilerplate gets the right prototype.
+%FunctionSetPrototype(GlobalArray, new GlobalArray(0));
+
+// ----------------------------------------------------------------------------
+// Exports
+
+utils.Export(function(to) {
+  to.AddIndexedProperty = AddIndexedProperty;
+  to.MaxSimple = MaxSimple;
+  to.MinSimple = MinSimple;
+  to.SameValue = SameValue;
+  to.SameValueZero = SameValueZero;
+  to.ToPositiveInteger = ToPositiveInteger;
+  to.SpeciesConstructor = SpeciesConstructor;
+});
+
+%InstallToContext([
+  "concat_iterable_to_array_builtin", CONCAT_ITERABLE_TO_ARRAY,
+]);
+
+%InstallToContext([
+  "concat_iterable_to_array", ConcatIterableToArray,
+]);
+
+})
diff --git a/src/js/spread.js b/src/js/spread.js
new file mode 100644
index 0000000..235c91a
--- /dev/null
+++ b/src/js/spread.js
@@ -0,0 +1,56 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function(global, utils) {
+
+'use strict';
+
+// -------------------------------------------------------------------
+// Imports
+var InternalArray = utils.InternalArray;
+var MakeTypeError;
+
+utils.Import(function(from) {
+  MakeTypeError = from.MakeTypeError;
+});
+
+// -------------------------------------------------------------------
+
+function SpreadArguments() {
+  var count = %_ArgumentsLength();
+  var args = new InternalArray();
+
+  for (var i = 0; i < count; ++i) {
+    var array = %_Arguments(i);
+    var length = array.length;
+    for (var j = 0; j < length; ++j) {
+      args.push(array[j]);
+    }
+  }
+
+  return args;
+}
+
+
+function SpreadIterable(collection) {
+  if (IS_NULL_OR_UNDEFINED(collection)) {
+    throw MakeTypeError(kNotIterable, collection);
+  }
+
+  var args = new InternalArray();
+  for (var value of collection) {
+    args.push(value);
+  }
+  return args;
+}
+
+// ----------------------------------------------------------------------------
+// Exports
+
+%InstallToContext([
+  "spread_arguments", SpreadArguments,
+  "spread_iterable", SpreadIterable,
+]);
+
+})
diff --git a/src/js/string-iterator.js b/src/js/string-iterator.js
new file mode 100644
index 0000000..3c331dd
--- /dev/null
+++ b/src/js/string-iterator.js
@@ -0,0 +1,102 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function(global, utils) {
+
+"use strict";
+
+%CheckIsBootstrapping();
+
+// -------------------------------------------------------------------
+// Imports
+
+var GlobalString = global.String;
+var IteratorPrototype = utils.ImportNow("IteratorPrototype");
+var iteratorSymbol = utils.ImportNow("iterator_symbol");
+var MakeTypeError;
+var stringIteratorIteratedStringSymbol =
+    utils.ImportNow("string_iterator_iterated_string_symbol");
+var stringIteratorNextIndexSymbol =
+    utils.ImportNow("string_iterator_next_index_symbol");
+var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
+
+utils.Import(function(from) {
+  MakeTypeError = from.MakeTypeError;
+});
+
+// -------------------------------------------------------------------
+
+function StringIterator() {}
+
+
+// 21.1.5.1 CreateStringIterator Abstract Operation
+function CreateStringIterator(string) {
+  var s = TO_STRING(string);
+  var iterator = new StringIterator;
+  SET_PRIVATE(iterator, stringIteratorIteratedStringSymbol, s);
+  SET_PRIVATE(iterator, stringIteratorNextIndexSymbol, 0);
+  return iterator;
+}
+
+
+// ES6 section 21.1.5.2.1 %StringIteratorPrototype%.next ( )
+function StringIteratorNext() {
+  var iterator = this;
+  var value = UNDEFINED;
+  var done = true;
+
+  if (!IS_RECEIVER(iterator) ||
+      !HAS_DEFINED_PRIVATE(iterator, stringIteratorNextIndexSymbol)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        'String Iterator.prototype.next');
+  }
+
+  var s = GET_PRIVATE(iterator, stringIteratorIteratedStringSymbol);
+  if (!IS_UNDEFINED(s)) {
+    var position = GET_PRIVATE(iterator, stringIteratorNextIndexSymbol);
+    var length = TO_UINT32(s.length);
+    if (position >= length) {
+      SET_PRIVATE(iterator, stringIteratorIteratedStringSymbol, UNDEFINED);
+    } else {
+      var first = %_StringCharCodeAt(s, position);
+      value = %_StringCharFromCode(first);
+      done = false;
+      position++;
+
+      if (first >= 0xD800 && first <= 0xDBFF && position < length) {
+        var second = %_StringCharCodeAt(s, position);
+        if (second >= 0xDC00 && second <= 0xDFFF) {
+          value += %_StringCharFromCode(second);
+          position++;
+        }
+      }
+
+      SET_PRIVATE(iterator, stringIteratorNextIndexSymbol, position);
+    }
+  }
+  return %_CreateIterResultObject(value, done);
+}
+
+
+// 21.1.3.27 String.prototype [ @@iterator ]( )
+function StringPrototypeIterator() {
+  return CreateStringIterator(this);
+}
+
+//-------------------------------------------------------------------
+
+%FunctionSetPrototype(StringIterator, {__proto__: IteratorPrototype});
+%FunctionSetInstanceClassName(StringIterator, 'String Iterator');
+
+utils.InstallFunctions(StringIterator.prototype, DONT_ENUM, [
+  'next', StringIteratorNext
+]);
+%AddNamedProperty(StringIterator.prototype, toStringTagSymbol,
+                  "String Iterator", READ_ONLY | DONT_ENUM);
+
+utils.SetFunctionName(StringPrototypeIterator, iteratorSymbol);
+%AddNamedProperty(GlobalString.prototype, iteratorSymbol,
+                  StringPrototypeIterator, DONT_ENUM);
+
+})
diff --git a/src/js/string.js b/src/js/string.js
new file mode 100644
index 0000000..b220038
--- /dev/null
+++ b/src/js/string.js
@@ -0,0 +1,1112 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function(global, utils) {
+
+%CheckIsBootstrapping();
+
+// -------------------------------------------------------------------
+// Imports
+
+var ArrayIndexOf;
+var ArrayJoin;
+var GlobalRegExp = global.RegExp;
+var GlobalString = global.String;
+var InternalArray = utils.InternalArray;
+var InternalPackedArray = utils.InternalPackedArray;
+var MakeRangeError;
+var MakeTypeError;
+var MathMax;
+var MathMin;
+var matchSymbol = utils.ImportNow("match_symbol");
+var RegExpExec;
+var RegExpExecNoTests;
+var RegExpLastMatchInfo;
+var searchSymbol = utils.ImportNow("search_symbol");
+var splitSymbol = utils.ImportNow("split_symbol");
+
+utils.Import(function(from) {
+  ArrayIndexOf = from.ArrayIndexOf;
+  ArrayJoin = from.ArrayJoin;
+  MakeRangeError = from.MakeRangeError;
+  MakeTypeError = from.MakeTypeError;
+  MathMax = from.MathMax;
+  MathMin = from.MathMin;
+  RegExpExec = from.RegExpExec;
+  RegExpExecNoTests = from.RegExpExecNoTests;
+  RegExpLastMatchInfo = from.RegExpLastMatchInfo;
+});
+
+//-------------------------------------------------------------------
+
+// ECMA-262 section 15.5.4.2
+function StringToString() {
+  if (!IS_STRING(this) && !IS_STRING_WRAPPER(this)) {
+    throw MakeTypeError(kNotGeneric, 'String.prototype.toString');
+  }
+  return %_ValueOf(this);
+}
+
+
+// ECMA-262 section 15.5.4.3
+function StringValueOf() {
+  if (!IS_STRING(this) && !IS_STRING_WRAPPER(this)) {
+    throw MakeTypeError(kNotGeneric, 'String.prototype.valueOf');
+  }
+  return %_ValueOf(this);
+}
+
+
+// ECMA-262, section 15.5.4.4
+function StringCharAtJS(pos) {
+  CHECK_OBJECT_COERCIBLE(this, "String.prototype.charAt");
+
+  var result = %_StringCharAt(this, pos);
+  if (%_IsSmi(result)) {
+    result = %_StringCharAt(TO_STRING(this), TO_INTEGER(pos));
+  }
+  return result;
+}
+
+
+// ECMA-262 section 15.5.4.5
+function StringCharCodeAtJS(pos) {
+  CHECK_OBJECT_COERCIBLE(this, "String.prototype.charCodeAt");
+
+  var result = %_StringCharCodeAt(this, pos);
+  if (!%_IsSmi(result)) {
+    result = %_StringCharCodeAt(TO_STRING(this), TO_INTEGER(pos));
+  }
+  return result;
+}
+
+
+// ECMA-262, section 15.5.4.6
+function StringConcat(other /* and more */) {  // length == 1
+  CHECK_OBJECT_COERCIBLE(this, "String.prototype.concat");
+  var len = %_ArgumentsLength();
+  var this_as_string = TO_STRING(this);
+  if (len === 1) {
+    return this_as_string + TO_STRING(other);
+  }
+  var parts = new InternalArray(len + 1);
+  parts[0] = this_as_string;
+  for (var i = 0; i < len; i++) {
+    var part = %_Arguments(i);
+    parts[i + 1] = TO_STRING(part);
+  }
+  return %StringBuilderConcat(parts, len + 1, "");
+}
+
+
+// ECMA-262 section 15.5.4.7
+function StringIndexOfJS(pattern /* position */) {  // length == 1
+  CHECK_OBJECT_COERCIBLE(this, "String.prototype.indexOf");
+
+  var subject = TO_STRING(this);
+  pattern = TO_STRING(pattern);
+  var index = 0;
+  if (%_ArgumentsLength() > 1) {
+    index = %_Arguments(1);  // position
+    index = TO_INTEGER(index);
+    if (index < 0) index = 0;
+    if (index > subject.length) index = subject.length;
+  }
+  return %StringIndexOf(subject, pattern, index);
+}
+
+
+// ECMA-262 section 15.5.4.8
+function StringLastIndexOfJS(pat /* position */) {  // length == 1
+  CHECK_OBJECT_COERCIBLE(this, "String.prototype.lastIndexOf");
+
+  var sub = TO_STRING(this);
+  var subLength = sub.length;
+  var pat = TO_STRING(pat);
+  var patLength = pat.length;
+  var index = subLength - patLength;
+  if (%_ArgumentsLength() > 1) {
+    var position = TO_NUMBER(%_Arguments(1));
+    if (!NUMBER_IS_NAN(position)) {
+      position = TO_INTEGER(position);
+      if (position < 0) {
+        position = 0;
+      }
+      if (position + patLength < subLength) {
+        index = position;
+      }
+    }
+  }
+  if (index < 0) {
+    return -1;
+  }
+  return %StringLastIndexOf(sub, pat, index);
+}
+
+
+// ECMA-262 section 15.5.4.9
+//
+// This function is implementation specific.  For now, we do not
+// do anything locale specific.
+function StringLocaleCompareJS(other) {
+  CHECK_OBJECT_COERCIBLE(this, "String.prototype.localeCompare");
+
+  return %StringLocaleCompare(TO_STRING(this), TO_STRING(other));
+}
+
+
+// ES6 21.1.3.11.
+function StringMatchJS(pattern) {
+  CHECK_OBJECT_COERCIBLE(this, "String.prototype.match");
+
+  if (!IS_NULL_OR_UNDEFINED(pattern)) {
+    var matcher = pattern[matchSymbol];
+    if (!IS_UNDEFINED(matcher)) {
+      return %_Call(matcher, pattern, this);
+    }
+  }
+
+  var subject = TO_STRING(this);
+
+  // Non-regexp argument.
+  var regexp = new GlobalRegExp(pattern);
+  return RegExpExecNoTests(regexp, subject, 0);
+}
+
+
+// ECMA-262 v6, section 21.1.3.12
+//
+// For now we do nothing, as proper normalization requires big tables.
+// If Intl is enabled, then i18n.js will override it and provide the the
+// proper functionality.
+function StringNormalizeJS() {
+  CHECK_OBJECT_COERCIBLE(this, "String.prototype.normalize");
+  var s = TO_STRING(this);
+
+  var formArg = %_Arguments(0);
+  var form = IS_UNDEFINED(formArg) ? 'NFC' : TO_STRING(formArg);
+
+  var NORMALIZATION_FORMS = ['NFC', 'NFD', 'NFKC', 'NFKD'];
+  var normalizationForm = %_Call(ArrayIndexOf, NORMALIZATION_FORMS, form);
+  if (normalizationForm === -1) {
+    throw MakeRangeError(kNormalizationForm,
+                         %_Call(ArrayJoin, NORMALIZATION_FORMS, ', '));
+  }
+
+  return s;
+}
+
+
+// This has the same size as the RegExpLastMatchInfo array, and can be used
+// for functions that expect that structure to be returned.  It is used when
+// the needle is a string rather than a regexp.  In this case we can't update
+// lastMatchArray without erroneously affecting the properties on the global
+// RegExp object.
+var reusableMatchInfo = [2, "", "", -1, -1];
+
+
+// ECMA-262, section 15.5.4.11
+function StringReplace(search, replace) {
+  CHECK_OBJECT_COERCIBLE(this, "String.prototype.replace");
+
+  var subject = TO_STRING(this);
+
+  // Decision tree for dispatch
+  // .. regexp search
+  // .... string replace
+  // ...... non-global search
+  // ........ empty string replace
+  // ........ non-empty string replace (with $-expansion)
+  // ...... global search
+  // ........ no need to circumvent last match info override
+  // ........ need to circument last match info override
+  // .... function replace
+  // ...... global search
+  // ...... non-global search
+  // .. string search
+  // .... special case that replaces with one single character
+  // ...... function replace
+  // ...... string replace (with $-expansion)
+
+  if (IS_REGEXP(search)) {
+    if (!IS_CALLABLE(replace)) {
+      replace = TO_STRING(replace);
+
+      if (!REGEXP_GLOBAL(search)) {
+        // Non-global regexp search, string replace.
+        var match = RegExpExec(search, subject, 0);
+        if (match == null) {
+          search.lastIndex = 0
+          return subject;
+        }
+        if (replace.length == 0) {
+          return %_SubString(subject, 0, match[CAPTURE0]) +
+                 %_SubString(subject, match[CAPTURE1], subject.length)
+        }
+        return ExpandReplacement(replace, subject, RegExpLastMatchInfo,
+                                 %_SubString(subject, 0, match[CAPTURE0])) +
+               %_SubString(subject, match[CAPTURE1], subject.length);
+      }
+
+      // Global regexp search, string replace.
+      search.lastIndex = 0;
+      return %StringReplaceGlobalRegExpWithString(
+          subject, search, replace, RegExpLastMatchInfo);
+    }
+
+    if (REGEXP_GLOBAL(search)) {
+      // Global regexp search, function replace.
+      return StringReplaceGlobalRegExpWithFunction(subject, search, replace);
+    }
+    // Non-global regexp search, function replace.
+    return StringReplaceNonGlobalRegExpWithFunction(subject, search, replace);
+  }
+
+  search = TO_STRING(search);
+
+  if (search.length == 1 &&
+      subject.length > 0xFF &&
+      IS_STRING(replace) &&
+      %StringIndexOf(replace, '$', 0) < 0) {
+    // Searching by traversing a cons string tree and replace with cons of
+    // slices works only when the replaced string is a single character, being
+    // replaced by a simple string and only pays off for long strings.
+    return %StringReplaceOneCharWithString(subject, search, replace);
+  }
+  var start = %StringIndexOf(subject, search, 0);
+  if (start < 0) return subject;
+  var end = start + search.length;
+
+  var result = %_SubString(subject, 0, start);
+
+  // Compute the string to replace with.
+  if (IS_CALLABLE(replace)) {
+    result += replace(search, start, subject);
+  } else {
+    reusableMatchInfo[CAPTURE0] = start;
+    reusableMatchInfo[CAPTURE1] = end;
+    result = ExpandReplacement(TO_STRING(replace),
+                               subject,
+                               reusableMatchInfo,
+                               result);
+  }
+
+  return result + %_SubString(subject, end, subject.length);
+}
+
+
+// Expand the $-expressions in the string and return a new string with
+// the result.
+function ExpandReplacement(string, subject, matchInfo, result) {
+  var length = string.length;
+  var next = %StringIndexOf(string, '$', 0);
+  if (next < 0) {
+    if (length > 0) result += string;
+    return result;
+  }
+
+  if (next > 0) result += %_SubString(string, 0, next);
+
+  while (true) {
+    var expansion = '$';
+    var position = next + 1;
+    if (position < length) {
+      var peek = %_StringCharCodeAt(string, position);
+      if (peek == 36) {         // $$
+        ++position;
+        result += '$';
+      } else if (peek == 38) {  // $& - match
+        ++position;
+        result +=
+          %_SubString(subject, matchInfo[CAPTURE0], matchInfo[CAPTURE1]);
+      } else if (peek == 96) {  // $` - prefix
+        ++position;
+        result += %_SubString(subject, 0, matchInfo[CAPTURE0]);
+      } else if (peek == 39) {  // $' - suffix
+        ++position;
+        result += %_SubString(subject, matchInfo[CAPTURE1], subject.length);
+      } else if (peek >= 48 && peek <= 57) {
+        // Valid indices are $1 .. $9, $01 .. $09 and $10 .. $99
+        var scaled_index = (peek - 48) << 1;
+        var advance = 1;
+        var number_of_captures = NUMBER_OF_CAPTURES(matchInfo);
+        if (position + 1 < string.length) {
+          var next = %_StringCharCodeAt(string, position + 1);
+          if (next >= 48 && next <= 57) {
+            var new_scaled_index = scaled_index * 10 + ((next - 48) << 1);
+            if (new_scaled_index < number_of_captures) {
+              scaled_index = new_scaled_index;
+              advance = 2;
+            }
+          }
+        }
+        if (scaled_index != 0 && scaled_index < number_of_captures) {
+          var start = matchInfo[CAPTURE(scaled_index)];
+          if (start >= 0) {
+            result +=
+              %_SubString(subject, start, matchInfo[CAPTURE(scaled_index + 1)]);
+          }
+          position += advance;
+        } else {
+          result += '$';
+        }
+      } else {
+        result += '$';
+      }
+    } else {
+      result += '$';
+    }
+
+    // Go the the next $ in the string.
+    next = %StringIndexOf(string, '$', position);
+
+    // Return if there are no more $ characters in the string. If we
+    // haven't reached the end, we need to append the suffix.
+    if (next < 0) {
+      if (position < length) {
+        result += %_SubString(string, position, length);
+      }
+      return result;
+    }
+
+    // Append substring between the previous and the next $ character.
+    if (next > position) {
+      result += %_SubString(string, position, next);
+    }
+  }
+  return result;
+}
+
+
+// Compute the string of a given regular expression capture.
+function CaptureString(string, lastCaptureInfo, index) {
+  // Scale the index.
+  var scaled = index << 1;
+  // Compute start and end.
+  var start = lastCaptureInfo[CAPTURE(scaled)];
+  // If start isn't valid, return undefined.
+  if (start < 0) return;
+  var end = lastCaptureInfo[CAPTURE(scaled + 1)];
+  return %_SubString(string, start, end);
+}
+
+
+// TODO(lrn): This array will survive indefinitely if replace is never
+// called again. However, it will be empty, since the contents are cleared
+// in the finally block.
+var reusableReplaceArray = new InternalArray(4);
+
+// Helper function for replacing regular expressions with the result of a
+// function application in String.prototype.replace.
+function StringReplaceGlobalRegExpWithFunction(subject, regexp, replace) {
+  var resultArray = reusableReplaceArray;
+  if (resultArray) {
+    reusableReplaceArray = null;
+  } else {
+    // Inside a nested replace (replace called from the replacement function
+    // of another replace) or we have failed to set the reusable array
+    // back due to an exception in a replacement function. Create a new
+    // array to use in the future, or until the original is written back.
+    resultArray = new InternalArray(16);
+  }
+  var res = %RegExpExecMultiple(regexp,
+                                subject,
+                                RegExpLastMatchInfo,
+                                resultArray);
+  regexp.lastIndex = 0;
+  if (IS_NULL(res)) {
+    // No matches at all.
+    reusableReplaceArray = resultArray;
+    return subject;
+  }
+  var len = res.length;
+  if (NUMBER_OF_CAPTURES(RegExpLastMatchInfo) == 2) {
+    // If the number of captures is two then there are no explicit captures in
+    // the regexp, just the implicit capture that captures the whole match.  In
+    // this case we can simplify quite a bit and end up with something faster.
+    // The builder will consist of some integers that indicate slices of the
+    // input string and some replacements that were returned from the replace
+    // function.
+    var match_start = 0;
+    for (var i = 0; i < len; i++) {
+      var elem = res[i];
+      if (%_IsSmi(elem)) {
+        // Integers represent slices of the original string.
+        if (elem > 0) {
+          match_start = (elem >> 11) + (elem & 0x7ff);
+        } else {
+          match_start = res[++i] - elem;
+        }
+      } else {
+        var func_result = replace(elem, match_start, subject);
+        // Overwrite the i'th element in the results with the string we got
+        // back from the callback function.
+        res[i] = TO_STRING(func_result);
+        match_start += elem.length;
+      }
+    }
+  } else {
+    for (var i = 0; i < len; i++) {
+      var elem = res[i];
+      if (!%_IsSmi(elem)) {
+        // elem must be an Array.
+        // Use the apply argument as backing for global RegExp properties.
+        var func_result = %Apply(replace, UNDEFINED, elem, 0, elem.length);
+        // Overwrite the i'th element in the results with the string we got
+        // back from the callback function.
+        res[i] = TO_STRING(func_result);
+      }
+    }
+  }
+  var result = %StringBuilderConcat(res, len, subject);
+  resultArray.length = 0;
+  reusableReplaceArray = resultArray;
+  return result;
+}
+
+
+function StringReplaceNonGlobalRegExpWithFunction(subject, regexp, replace) {
+  var matchInfo = RegExpExec(regexp, subject, 0);
+  if (IS_NULL(matchInfo)) {
+    regexp.lastIndex = 0;
+    return subject;
+  }
+  var index = matchInfo[CAPTURE0];
+  var result = %_SubString(subject, 0, index);
+  var endOfMatch = matchInfo[CAPTURE1];
+  // Compute the parameter list consisting of the match, captures, index,
+  // and subject for the replace function invocation.
+  // The number of captures plus one for the match.
+  var m = NUMBER_OF_CAPTURES(matchInfo) >> 1;
+  var replacement;
+  if (m == 1) {
+    // No captures, only the match, which is always valid.
+    var s = %_SubString(subject, index, endOfMatch);
+    // Don't call directly to avoid exposing the built-in global object.
+    replacement = replace(s, index, subject);
+  } else {
+    var parameters = new InternalArray(m + 2);
+    for (var j = 0; j < m; j++) {
+      parameters[j] = CaptureString(subject, matchInfo, j);
+    }
+    parameters[j] = index;
+    parameters[j + 1] = subject;
+
+    replacement = %Apply(replace, UNDEFINED, parameters, 0, j + 2);
+  }
+
+  result += replacement;  // The add method converts to string if necessary.
+  // Can't use matchInfo any more from here, since the function could
+  // overwrite it.
+  return result + %_SubString(subject, endOfMatch, subject.length);
+}
+
+
+// ES6 21.1.3.15.
+function StringSearch(pattern) {
+  CHECK_OBJECT_COERCIBLE(this, "String.prototype.search");
+
+  if (!IS_NULL_OR_UNDEFINED(pattern)) {
+    var searcher = pattern[searchSymbol];
+    if (!IS_UNDEFINED(searcher)) {
+      return %_Call(searcher, pattern, this);
+    }
+  }
+
+  var subject = TO_STRING(this);
+  var regexp = new GlobalRegExp(pattern);
+  return %_Call(regexp[searchSymbol], regexp, subject);
+}
+
+
+// ECMA-262 section 15.5.4.13
+function StringSlice(start, end) {
+  CHECK_OBJECT_COERCIBLE(this, "String.prototype.slice");
+
+  var s = TO_STRING(this);
+  var s_len = s.length;
+  var start_i = TO_INTEGER(start);
+  var end_i = s_len;
+  if (!IS_UNDEFINED(end)) {
+    end_i = TO_INTEGER(end);
+  }
+
+  if (start_i < 0) {
+    start_i += s_len;
+    if (start_i < 0) {
+      start_i = 0;
+    }
+  } else {
+    if (start_i > s_len) {
+      return '';
+    }
+  }
+
+  if (end_i < 0) {
+    end_i += s_len;
+    if (end_i < 0) {
+      return '';
+    }
+  } else {
+    if (end_i > s_len) {
+      end_i = s_len;
+    }
+  }
+
+  if (end_i <= start_i) {
+    return '';
+  }
+
+  return %_SubString(s, start_i, end_i);
+}
+
+
+// ES6 21.1.3.17.
+function StringSplitJS(separator, limit) {
+  CHECK_OBJECT_COERCIBLE(this, "String.prototype.split");
+
+  if (!IS_NULL_OR_UNDEFINED(separator)) {
+    var splitter = separator[splitSymbol];
+    if (!IS_UNDEFINED(splitter)) {
+      return %_Call(splitter, separator, this, limit);
+    }
+  }
+
+  var subject = TO_STRING(this);
+  limit = (IS_UNDEFINED(limit)) ? kMaxUint32 : TO_UINT32(limit);
+
+  var length = subject.length;
+  var separator_string = TO_STRING(separator);
+
+  if (limit === 0) return [];
+
+  // ECMA-262 says that if separator is undefined, the result should
+  // be an array of size 1 containing the entire string.
+  if (IS_UNDEFINED(separator)) return [subject];
+
+  var separator_length = separator_string.length;
+
+  // If the separator string is empty then return the elements in the subject.
+  if (separator_length === 0) return %StringToArray(subject, limit);
+
+  return %StringSplit(subject, separator_string, limit);
+}
+
+
+// ECMA-262 section 15.5.4.15
+function StringSubstring(start, end) {
+  CHECK_OBJECT_COERCIBLE(this, "String.prototype.subString");
+
+  var s = TO_STRING(this);
+  var s_len = s.length;
+
+  var start_i = TO_INTEGER(start);
+  if (start_i < 0) {
+    start_i = 0;
+  } else if (start_i > s_len) {
+    start_i = s_len;
+  }
+
+  var end_i = s_len;
+  if (!IS_UNDEFINED(end)) {
+    end_i = TO_INTEGER(end);
+    if (end_i > s_len) {
+      end_i = s_len;
+    } else {
+      if (end_i < 0) end_i = 0;
+      if (start_i > end_i) {
+        var tmp = end_i;
+        end_i = start_i;
+        start_i = tmp;
+      }
+    }
+  }
+
+  return %_SubString(s, start_i, end_i);
+}
+
+
+// ES6 draft, revision 26 (2014-07-18), section B.2.3.1
+function StringSubstr(start, n) {
+  CHECK_OBJECT_COERCIBLE(this, "String.prototype.substr");
+
+  var s = TO_STRING(this);
+  var len;
+
+  // Correct n: If not given, set to string length; if explicitly
+  // set to undefined, zero, or negative, returns empty string.
+  if (IS_UNDEFINED(n)) {
+    len = s.length;
+  } else {
+    len = TO_INTEGER(n);
+    if (len <= 0) return '';
+  }
+
+  // Correct start: If not given (or undefined), set to zero; otherwise
+  // convert to integer and handle negative case.
+  if (IS_UNDEFINED(start)) {
+    start = 0;
+  } else {
+    start = TO_INTEGER(start);
+    // If positive, and greater than or equal to the string length,
+    // return empty string.
+    if (start >= s.length) return '';
+    // If negative and absolute value is larger than the string length,
+    // use zero.
+    if (start < 0) {
+      start += s.length;
+      if (start < 0) start = 0;
+    }
+  }
+
+  var end = start + len;
+  if (end > s.length) end = s.length;
+
+  return %_SubString(s, start, end);
+}
+
+
+// ECMA-262, 15.5.4.16
+function StringToLowerCaseJS() {
+  CHECK_OBJECT_COERCIBLE(this, "String.prototype.toLowerCase");
+
+  return %StringToLowerCase(TO_STRING(this));
+}
+
+
+// ECMA-262, 15.5.4.17
+function StringToLocaleLowerCase() {
+  CHECK_OBJECT_COERCIBLE(this, "String.prototype.toLocaleLowerCase");
+
+  return %StringToLowerCase(TO_STRING(this));
+}
+
+
+// ECMA-262, 15.5.4.18
+function StringToUpperCaseJS() {
+  CHECK_OBJECT_COERCIBLE(this, "String.prototype.toUpperCase");
+
+  return %StringToUpperCase(TO_STRING(this));
+}
+
+
+// ECMA-262, 15.5.4.19
+function StringToLocaleUpperCase() {
+  CHECK_OBJECT_COERCIBLE(this, "String.prototype.toLocaleUpperCase");
+
+  return %StringToUpperCase(TO_STRING(this));
+}
+
+// ES5, 15.5.4.20
+function StringTrimJS() {
+  CHECK_OBJECT_COERCIBLE(this, "String.prototype.trim");
+
+  return %StringTrim(TO_STRING(this), true, true);
+}
+
+function StringTrimLeft() {
+  CHECK_OBJECT_COERCIBLE(this, "String.prototype.trimLeft");
+
+  return %StringTrim(TO_STRING(this), true, false);
+}
+
+function StringTrimRight() {
+  CHECK_OBJECT_COERCIBLE(this, "String.prototype.trimRight");
+
+  return %StringTrim(TO_STRING(this), false, true);
+}
+
+
+// ECMA-262, section 15.5.3.2
+function StringFromCharCode(code) {
+  var n = %_ArgumentsLength();
+  if (n == 1) return %_StringCharFromCode(code & 0xffff);
+
+  var one_byte = %NewString(n, NEW_ONE_BYTE_STRING);
+  var i;
+  for (i = 0; i < n; i++) {
+    code = %_Arguments(i) & 0xffff;
+    if (code > 0xff) break;
+    %_OneByteSeqStringSetChar(i, code, one_byte);
+  }
+  if (i == n) return one_byte;
+  one_byte = %TruncateString(one_byte, i);
+
+  var two_byte = %NewString(n - i, NEW_TWO_BYTE_STRING);
+  %_TwoByteSeqStringSetChar(0, code, two_byte);
+  i++;
+  for (var j = 1; i < n; i++, j++) {
+    code = %_Arguments(i) & 0xffff;
+    %_TwoByteSeqStringSetChar(j, code, two_byte);
+  }
+  return one_byte + two_byte;
+}
+
+
+// ES6 draft, revision 26 (2014-07-18), section B.2.3.2.1
+function HtmlEscape(str) {
+  return %_Call(StringReplace, TO_STRING(str), /"/g, "&quot;");
+}
+
+
+// ES6 draft, revision 26 (2014-07-18), section B.2.3.2
+function StringAnchor(name) {
+  CHECK_OBJECT_COERCIBLE(this, "String.prototype.anchor");
+  return "<a name=\"" + HtmlEscape(name) + "\">" + TO_STRING(this) +
+         "</a>";
+}
+
+
+// ES6 draft, revision 26 (2014-07-18), section B.2.3.3
+function StringBig() {
+  CHECK_OBJECT_COERCIBLE(this, "String.prototype.big");
+  return "<big>" + TO_STRING(this) + "</big>";
+}
+
+
+// ES6 draft, revision 26 (2014-07-18), section B.2.3.4
+function StringBlink() {
+  CHECK_OBJECT_COERCIBLE(this, "String.prototype.blink");
+  return "<blink>" + TO_STRING(this) + "</blink>";
+}
+
+
+// ES6 draft, revision 26 (2014-07-18), section B.2.3.5
+function StringBold() {
+  CHECK_OBJECT_COERCIBLE(this, "String.prototype.bold");
+  return "<b>" + TO_STRING(this) + "</b>";
+}
+
+
+// ES6 draft, revision 26 (2014-07-18), section B.2.3.6
+function StringFixed() {
+  CHECK_OBJECT_COERCIBLE(this, "String.prototype.fixed");
+  return "<tt>" + TO_STRING(this) + "</tt>";
+}
+
+
+// ES6 draft, revision 26 (2014-07-18), section B.2.3.7
+function StringFontcolor(color) {
+  CHECK_OBJECT_COERCIBLE(this, "String.prototype.fontcolor");
+  return "<font color=\"" + HtmlEscape(color) + "\">" + TO_STRING(this) +
+         "</font>";
+}
+
+
+// ES6 draft, revision 26 (2014-07-18), section B.2.3.8
+function StringFontsize(size) {
+  CHECK_OBJECT_COERCIBLE(this, "String.prototype.fontsize");
+  return "<font size=\"" + HtmlEscape(size) + "\">" + TO_STRING(this) +
+         "</font>";
+}
+
+
+// ES6 draft, revision 26 (2014-07-18), section B.2.3.9
+function StringItalics() {
+  CHECK_OBJECT_COERCIBLE(this, "String.prototype.italics");
+  return "<i>" + TO_STRING(this) + "</i>";
+}
+
+
+// ES6 draft, revision 26 (2014-07-18), section B.2.3.10
+function StringLink(s) {
+  CHECK_OBJECT_COERCIBLE(this, "String.prototype.link");
+  return "<a href=\"" + HtmlEscape(s) + "\">" + TO_STRING(this) + "</a>";
+}
+
+
+// ES6 draft, revision 26 (2014-07-18), section B.2.3.11
+function StringSmall() {
+  CHECK_OBJECT_COERCIBLE(this, "String.prototype.small");
+  return "<small>" + TO_STRING(this) + "</small>";
+}
+
+
+// ES6 draft, revision 26 (2014-07-18), section B.2.3.12
+function StringStrike() {
+  CHECK_OBJECT_COERCIBLE(this, "String.prototype.strike");
+  return "<strike>" + TO_STRING(this) + "</strike>";
+}
+
+
+// ES6 draft, revision 26 (2014-07-18), section B.2.3.13
+function StringSub() {
+  CHECK_OBJECT_COERCIBLE(this, "String.prototype.sub");
+  return "<sub>" + TO_STRING(this) + "</sub>";
+}
+
+
+// ES6 draft, revision 26 (2014-07-18), section B.2.3.14
+function StringSup() {
+  CHECK_OBJECT_COERCIBLE(this, "String.prototype.sup");
+  return "<sup>" + TO_STRING(this) + "</sup>";
+}
+
+// ES6, section 21.1.3.13
+function StringRepeat(count) {
+  CHECK_OBJECT_COERCIBLE(this, "String.prototype.repeat");
+
+  var s = TO_STRING(this);
+  var n = TO_INTEGER(count);
+
+  if (n < 0 || n === INFINITY) throw MakeRangeError(kInvalidCountValue);
+
+  // Early return to allow an arbitrarily-large repeat of the empty string.
+  if (s.length === 0) return "";
+
+  // The maximum string length is stored in a smi, so a longer repeat
+  // must result in a range error.
+  if (n > %_MaxSmi()) throw MakeRangeError(kInvalidCountValue);
+
+  var r = "";
+  while (true) {
+    if (n & 1) r += s;
+    n >>= 1;
+    if (n === 0) return r;
+    s += s;
+  }
+}
+
+
+// ES6 draft 04-05-14, section 21.1.3.18
+function StringStartsWith(searchString /* position */) {  // length == 1
+  CHECK_OBJECT_COERCIBLE(this, "String.prototype.startsWith");
+
+  var s = TO_STRING(this);
+
+  if (IS_REGEXP(searchString)) {
+    throw MakeTypeError(kFirstArgumentNotRegExp, "String.prototype.startsWith");
+  }
+
+  var ss = TO_STRING(searchString);
+  var pos = 0;
+  if (%_ArgumentsLength() > 1) {
+    var arg = %_Arguments(1);  // position
+    if (!IS_UNDEFINED(arg)) {
+      pos = TO_INTEGER(arg);
+    }
+  }
+
+  var s_len = s.length;
+  var start = MathMin(MathMax(pos, 0), s_len);
+  var ss_len = ss.length;
+  if (ss_len + start > s_len) {
+    return false;
+  }
+
+  return %_SubString(s, start, start + ss_len) === ss;
+}
+
+
+// ES6 draft 04-05-14, section 21.1.3.7
+function StringEndsWith(searchString /* position */) {  // length == 1
+  CHECK_OBJECT_COERCIBLE(this, "String.prototype.endsWith");
+
+  var s = TO_STRING(this);
+
+  if (IS_REGEXP(searchString)) {
+    throw MakeTypeError(kFirstArgumentNotRegExp, "String.prototype.endsWith");
+  }
+
+  var ss = TO_STRING(searchString);
+  var s_len = s.length;
+  var pos = s_len;
+  if (%_ArgumentsLength() > 1) {
+    var arg = %_Arguments(1);  // position
+    if (!IS_UNDEFINED(arg)) {
+      pos = TO_INTEGER(arg);
+    }
+  }
+
+  var end = MathMin(MathMax(pos, 0), s_len);
+  var ss_len = ss.length;
+  var start = end - ss_len;
+  if (start < 0) {
+    return false;
+  }
+
+  return %_SubString(s, start, start + ss_len) === ss;
+}
+
+
+// ES6 draft 04-05-14, section 21.1.3.6
+function StringIncludes(searchString /* position */) {  // length == 1
+  CHECK_OBJECT_COERCIBLE(this, "String.prototype.includes");
+
+  var string = TO_STRING(this);
+
+  if (IS_REGEXP(searchString)) {
+    throw MakeTypeError(kFirstArgumentNotRegExp, "String.prototype.includes");
+  }
+
+  searchString = TO_STRING(searchString);
+  var pos = 0;
+  if (%_ArgumentsLength() > 1) {
+    pos = %_Arguments(1);  // position
+    pos = TO_INTEGER(pos);
+  }
+
+  var stringLength = string.length;
+  if (pos < 0) pos = 0;
+  if (pos > stringLength) pos = stringLength;
+  var searchStringLength = searchString.length;
+
+  if (searchStringLength + pos > stringLength) {
+    return false;
+  }
+
+  return %StringIndexOf(string, searchString, pos) !== -1;
+}
+
+
+// ES6 Draft 05-22-2014, section 21.1.3.3
+function StringCodePointAt(pos) {
+  CHECK_OBJECT_COERCIBLE(this, "String.prototype.codePointAt");
+
+  var string = TO_STRING(this);
+  var size = string.length;
+  pos = TO_INTEGER(pos);
+  if (pos < 0 || pos >= size) {
+    return UNDEFINED;
+  }
+  var first = %_StringCharCodeAt(string, pos);
+  if (first < 0xD800 || first > 0xDBFF || pos + 1 == size) {
+    return first;
+  }
+  var second = %_StringCharCodeAt(string, pos + 1);
+  if (second < 0xDC00 || second > 0xDFFF) {
+    return first;
+  }
+  return (first - 0xD800) * 0x400 + second + 0x2400;
+}
+
+
+// ES6 Draft 05-22-2014, section 21.1.2.2
+function StringFromCodePoint(_) {  // length = 1
+  var code;
+  var length = %_ArgumentsLength();
+  var index;
+  var result = "";
+  for (index = 0; index < length; index++) {
+    code = %_Arguments(index);
+    if (!%_IsSmi(code)) {
+      code = TO_NUMBER(code);
+    }
+    if (code < 0 || code > 0x10FFFF || code !== TO_INTEGER(code)) {
+      throw MakeRangeError(kInvalidCodePoint, code);
+    }
+    if (code <= 0xFFFF) {
+      result += %_StringCharFromCode(code);
+    } else {
+      code -= 0x10000;
+      result += %_StringCharFromCode((code >>> 10) & 0x3FF | 0xD800);
+      result += %_StringCharFromCode(code & 0x3FF | 0xDC00);
+    }
+  }
+  return result;
+}
+
+
+// -------------------------------------------------------------------
+// String methods related to templates
+
+// ES6 Draft 03-17-2015, section 21.1.2.4
+function StringRaw(callSite) {
+  // TODO(caitp): Use rest parameters when implemented
+  var numberOfSubstitutions = %_ArgumentsLength();
+  var cooked = TO_OBJECT(callSite);
+  var raw = TO_OBJECT(cooked.raw);
+  var literalSegments = TO_LENGTH(raw.length);
+  if (literalSegments <= 0) return "";
+
+  var result = TO_STRING(raw[0]);
+
+  for (var i = 1; i < literalSegments; ++i) {
+    if (i < numberOfSubstitutions) {
+      result += TO_STRING(%_Arguments(i));
+    }
+    result += TO_STRING(raw[i]);
+  }
+
+  return result;
+}
+
+// -------------------------------------------------------------------
+
+// Set the String function and constructor.
+%FunctionSetPrototype(GlobalString, new GlobalString());
+
+// Set up the constructor property on the String prototype object.
+%AddNamedProperty(
+    GlobalString.prototype, "constructor", GlobalString, DONT_ENUM);
+
+// Set up the non-enumerable functions on the String object.
+utils.InstallFunctions(GlobalString, DONT_ENUM, [
+  "fromCharCode", StringFromCharCode,
+  "fromCodePoint", StringFromCodePoint,
+  "raw", StringRaw
+]);
+
+// Set up the non-enumerable functions on the String prototype object.
+utils.InstallFunctions(GlobalString.prototype, DONT_ENUM, [
+  "valueOf", StringValueOf,
+  "toString", StringToString,
+  "charAt", StringCharAtJS,
+  "charCodeAt", StringCharCodeAtJS,
+  "codePointAt", StringCodePointAt,
+  "concat", StringConcat,
+  "endsWith", StringEndsWith,
+  "includes", StringIncludes,
+  "indexOf", StringIndexOfJS,
+  "lastIndexOf", StringLastIndexOfJS,
+  "localeCompare", StringLocaleCompareJS,
+  "match", StringMatchJS,
+  "normalize", StringNormalizeJS,
+  "repeat", StringRepeat,
+  "replace", StringReplace,
+  "search", StringSearch,
+  "slice", StringSlice,
+  "split", StringSplitJS,
+  "substring", StringSubstring,
+  "substr", StringSubstr,
+  "startsWith", StringStartsWith,
+  "toLowerCase", StringToLowerCaseJS,
+  "toLocaleLowerCase", StringToLocaleLowerCase,
+  "toUpperCase", StringToUpperCaseJS,
+  "toLocaleUpperCase", StringToLocaleUpperCase,
+  "trim", StringTrimJS,
+  "trimLeft", StringTrimLeft,
+  "trimRight", StringTrimRight,
+
+  "link", StringLink,
+  "anchor", StringAnchor,
+  "fontcolor", StringFontcolor,
+  "fontsize", StringFontsize,
+  "big", StringBig,
+  "blink", StringBlink,
+  "bold", StringBold,
+  "fixed", StringFixed,
+  "italics", StringItalics,
+  "small", StringSmall,
+  "strike", StringStrike,
+  "sub", StringSub,
+  "sup", StringSup
+]);
+
+// -------------------------------------------------------------------
+// Exports
+
+utils.Export(function(to) {
+  to.StringCharAt = StringCharAtJS;
+  to.StringIndexOf = StringIndexOfJS;
+  to.StringLastIndexOf = StringLastIndexOfJS;
+  to.StringMatch = StringMatchJS;
+  to.StringReplace = StringReplace;
+  to.StringSlice = StringSlice;
+  to.StringSplit = StringSplitJS;
+  to.StringSubstr = StringSubstr;
+  to.StringSubstring = StringSubstring;
+});
+
+})
diff --git a/src/js/symbol.js b/src/js/symbol.js
new file mode 100644
index 0000000..5be6e01
--- /dev/null
+++ b/src/js/symbol.js
@@ -0,0 +1,135 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function(global, utils) {
+
+"use strict";
+
+%CheckIsBootstrapping();
+
+// -------------------------------------------------------------------
+// Imports
+
+var GlobalObject = global.Object;
+var GlobalSymbol = global.Symbol;
+var hasInstanceSymbol = utils.ImportNow("has_instance_symbol");
+var isConcatSpreadableSymbol =
+    utils.ImportNow("is_concat_spreadable_symbol");
+var iteratorSymbol = utils.ImportNow("iterator_symbol");
+var MakeTypeError;
+var toPrimitiveSymbol = utils.ImportNow("to_primitive_symbol");
+var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
+var unscopablesSymbol = utils.ImportNow("unscopables_symbol");
+
+utils.Import(function(from) {
+  MakeTypeError = from.MakeTypeError;
+});
+
+// -------------------------------------------------------------------
+
+// 19.4.3.4 Symbol.prototype [ @@toPrimitive ] ( hint )
+function SymbolToPrimitive(hint) {
+  if (!(IS_SYMBOL(this) || IS_SYMBOL_WRAPPER(this))) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        "Symbol.prototype [ @@toPrimitive ]", this);
+  }
+  return %_ValueOf(this);
+}
+
+
+function SymbolToString() {
+  if (!(IS_SYMBOL(this) || IS_SYMBOL_WRAPPER(this))) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        "Symbol.prototype.toString", this);
+  }
+  return %SymbolDescriptiveString(%_ValueOf(this));
+}
+
+
+function SymbolValueOf() {
+  if (!(IS_SYMBOL(this) || IS_SYMBOL_WRAPPER(this))) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        "Symbol.prototype.valueOf", this);
+  }
+  return %_ValueOf(this);
+}
+
+
+function SymbolFor(key) {
+  key = TO_STRING(key);
+  var registry = %SymbolRegistry();
+  if (IS_UNDEFINED(registry.for[key])) {
+    var symbol = %CreateSymbol(key);
+    registry.for[key] = symbol;
+    registry.keyFor[symbol] = key;
+  }
+  return registry.for[key];
+}
+
+
+function SymbolKeyFor(symbol) {
+  if (!IS_SYMBOL(symbol)) throw MakeTypeError(kSymbolKeyFor, symbol);
+  return %SymbolRegistry().keyFor[symbol];
+}
+
+
+// ES6 19.1.2.8
+function ObjectGetOwnPropertySymbols(obj) {
+  obj = TO_OBJECT(obj);
+
+  return %GetOwnPropertyKeys(obj, PROPERTY_FILTER_SKIP_STRINGS);
+}
+
+// -------------------------------------------------------------------
+
+%FunctionSetPrototype(GlobalSymbol, new GlobalObject());
+
+utils.InstallConstants(GlobalSymbol, [
+  // TODO(rossberg): expose when implemented.
+  // "hasInstance", hasInstanceSymbol,
+  // "isConcatSpreadable", isConcatSpreadableSymbol,
+  "iterator", iteratorSymbol,
+  // TODO(yangguo): expose when implemented.
+  // "match", matchSymbol,
+  // "replace", replaceSymbol,
+  // "search", searchSymbol,
+  // "split, splitSymbol,
+  "toPrimitive", toPrimitiveSymbol,
+  // TODO(dslomov, caitp): Currently defined in harmony-tostring.js ---
+  // Move here when shipping
+  // "toStringTag", toStringTagSymbol,
+  "unscopables", unscopablesSymbol,
+]);
+
+utils.InstallFunctions(GlobalSymbol, DONT_ENUM, [
+  "for", SymbolFor,
+  "keyFor", SymbolKeyFor
+]);
+
+%AddNamedProperty(
+    GlobalSymbol.prototype, "constructor", GlobalSymbol, DONT_ENUM);
+%AddNamedProperty(
+    GlobalSymbol.prototype, toStringTagSymbol, "Symbol", DONT_ENUM | READ_ONLY);
+
+utils.InstallFunctions(GlobalSymbol.prototype, DONT_ENUM | READ_ONLY, [
+  toPrimitiveSymbol, SymbolToPrimitive
+]);
+
+utils.InstallFunctions(GlobalSymbol.prototype, DONT_ENUM, [
+  "toString", SymbolToString,
+  "valueOf", SymbolValueOf
+]);
+
+utils.InstallFunctions(GlobalObject, DONT_ENUM, [
+  "getOwnPropertySymbols", ObjectGetOwnPropertySymbols
+]);
+
+// -------------------------------------------------------------------
+// Exports
+
+utils.Export(function(to) {
+  to.SymbolToString = SymbolToString;
+})
+
+})
diff --git a/src/js/templates.js b/src/js/templates.js
new file mode 100644
index 0000000..7236d5c
--- /dev/null
+++ b/src/js/templates.js
@@ -0,0 +1,84 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Called from a desugaring in the parser.
+
+(function(global, utils) {
+
+"use strict";
+
+%CheckIsBootstrapping();
+
+// -------------------------------------------------------------------
+// Imports
+
+var GlobalMap = global.Map;
+var InternalArray = utils.InternalArray;
+
+// -------------------------------------------------------------------
+
+var callSiteCache = new GlobalMap;
+var mapGetFn = GlobalMap.prototype.get;
+var mapSetFn = GlobalMap.prototype.set;
+
+
+function SameCallSiteElements(rawStrings, other) {
+  var length = rawStrings.length;
+  var other = other.raw;
+
+  if (length !== other.length) return false;
+
+  for (var i = 0; i < length; ++i) {
+    if (rawStrings[i] !== other[i]) return false;
+  }
+
+  return true;
+}
+
+
+function GetCachedCallSite(siteObj, hash) {
+  var obj = %_Call(mapGetFn, callSiteCache, hash);
+
+  if (IS_UNDEFINED(obj)) return;
+
+  var length = obj.length;
+  for (var i = 0; i < length; ++i) {
+    if (SameCallSiteElements(siteObj, obj[i])) return obj[i];
+  }
+}
+
+
+function SetCachedCallSite(siteObj, hash) {
+  var obj = %_Call(mapGetFn, callSiteCache, hash);
+  var array;
+
+  if (IS_UNDEFINED(obj)) {
+    array = new InternalArray(1);
+    array[0] = siteObj;
+    %_Call(mapSetFn, callSiteCache, hash, array);
+  } else {
+    obj.push(siteObj);
+  }
+
+  return siteObj;
+}
+
+
+function GetTemplateCallSite(siteObj, rawStrings, hash) {
+  var cached = GetCachedCallSite(rawStrings, hash);
+
+  if (!IS_UNDEFINED(cached)) return cached;
+
+  %AddNamedProperty(siteObj, "raw", %object_freeze(rawStrings),
+      READ_ONLY | DONT_ENUM | DONT_DELETE);
+
+  return SetCachedCallSite(%object_freeze(siteObj), hash);
+}
+
+// ----------------------------------------------------------------------------
+// Exports
+
+%InstallToContext(["get_template_call_site", GetTemplateCallSite]);
+
+})
diff --git a/src/js/typedarray.js b/src/js/typedarray.js
new file mode 100644
index 0000000..fd668a5
--- /dev/null
+++ b/src/js/typedarray.js
@@ -0,0 +1,980 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function(global, utils) {
+
+"use strict";
+
+%CheckIsBootstrapping();
+
+// -------------------------------------------------------------------
+// Imports
+
+var ArrayFrom;
+var ArrayToString;
+var ArrayValues;
+var GlobalArray = global.Array;
+var GlobalArrayBuffer = global.ArrayBuffer;
+var GlobalDataView = global.DataView;
+var GlobalObject = global.Object;
+var InternalArray = utils.InternalArray;
+var InnerArrayCopyWithin;
+var InnerArrayEvery;
+var InnerArrayFill;
+var InnerArrayFilter;
+var InnerArrayFind;
+var InnerArrayFindIndex;
+var InnerArrayForEach;
+var InnerArrayIncludes;
+var InnerArrayIndexOf;
+var InnerArrayJoin;
+var InnerArrayLastIndexOf;
+var InnerArrayReduce;
+var InnerArrayReduceRight;
+var InnerArraySome;
+var InnerArraySort;
+var InnerArrayToLocaleString;
+var InternalArray = utils.InternalArray;
+var IsNaN;
+var MakeRangeError;
+var MakeTypeError;
+var MaxSimple;
+var MinSimple;
+var PackedArrayReverse;
+var SpeciesConstructor;
+var ToPositiveInteger;
+var iteratorSymbol = utils.ImportNow("iterator_symbol");
+var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
+
+macro TYPED_ARRAYS(FUNCTION)
+// arrayIds below should be synchronized with Runtime_TypedArrayInitialize.
+FUNCTION(1, Uint8Array, 1)
+FUNCTION(2, Int8Array, 1)
+FUNCTION(3, Uint16Array, 2)
+FUNCTION(4, Int16Array, 2)
+FUNCTION(5, Uint32Array, 4)
+FUNCTION(6, Int32Array, 4)
+FUNCTION(7, Float32Array, 4)
+FUNCTION(8, Float64Array, 8)
+FUNCTION(9, Uint8ClampedArray, 1)
+endmacro
+
+macro DECLARE_GLOBALS(INDEX, NAME, SIZE)
+var GlobalNAME = global.NAME;
+endmacro
+
+TYPED_ARRAYS(DECLARE_GLOBALS)
+
+utils.Import(function(from) {
+  ArrayFrom = from.ArrayFrom;
+  ArrayToString = from.ArrayToString;
+  ArrayValues = from.ArrayValues;
+  InnerArrayCopyWithin = from.InnerArrayCopyWithin;
+  InnerArrayEvery = from.InnerArrayEvery;
+  InnerArrayFill = from.InnerArrayFill;
+  InnerArrayFilter = from.InnerArrayFilter;
+  InnerArrayFind = from.InnerArrayFind;
+  InnerArrayFindIndex = from.InnerArrayFindIndex;
+  InnerArrayForEach = from.InnerArrayForEach;
+  InnerArrayIncludes = from.InnerArrayIncludes;
+  InnerArrayIndexOf = from.InnerArrayIndexOf;
+  InnerArrayJoin = from.InnerArrayJoin;
+  InnerArrayLastIndexOf = from.InnerArrayLastIndexOf;
+  InnerArrayReduce = from.InnerArrayReduce;
+  InnerArrayReduceRight = from.InnerArrayReduceRight;
+  InnerArraySome = from.InnerArraySome;
+  InnerArraySort = from.InnerArraySort;
+  InnerArrayToLocaleString = from.InnerArrayToLocaleString;
+  IsNaN = from.IsNaN;
+  MakeRangeError = from.MakeRangeError;
+  MakeTypeError = from.MakeTypeError;
+  MaxSimple = from.MaxSimple;
+  MinSimple = from.MinSimple;
+  PackedArrayReverse = from.PackedArrayReverse;
+  SpeciesConstructor = from.SpeciesConstructor;
+  ToPositiveInteger = from.ToPositiveInteger;
+});
+
+// --------------- Typed Arrays ---------------------
+
+function TypedArrayDefaultConstructor(typedArray) {
+  switch (%_ClassOf(typedArray)) {
+macro TYPED_ARRAY_CONSTRUCTOR_CASE(ARRAY_ID, NAME, ELEMENT_SIZE)
+    case "NAME":
+      return GlobalNAME;
+endmacro
+TYPED_ARRAYS(TYPED_ARRAY_CONSTRUCTOR_CASE)
+  }
+  // The TypeError should not be generated since all callers should
+  // have already called ValidateTypedArray.
+  throw MakeTypeError(kIncompatibleMethodReceiver,
+                      "TypedArrayDefaultConstructor", this);
+}
+
+function TypedArrayCreate(constructor, arg0, arg1, arg2) {
+  if (IS_UNDEFINED(arg1)) {
+    var newTypedArray = new constructor(arg0);
+  } else {
+    var newTypedArray = new constructor(arg0, arg1, arg2);
+  }
+  if (!%_IsTypedArray(newTypedArray)) throw MakeTypeError(kNotTypedArray);
+  // TODO(littledan): Check for being detached, here and elsewhere
+  // All callers where the first argument is a Number have no additional
+  // arguments.
+  if (IS_NUMBER(arg0) && %_TypedArrayGetLength(newTypedArray) < arg0) {
+    throw MakeTypeError(kTypedArrayTooShort);
+  }
+  return newTypedArray;
+}
+
+function TypedArraySpeciesCreate(exemplar, arg0, arg1, arg2, conservative) {
+  var defaultConstructor = TypedArrayDefaultConstructor(exemplar);
+  var constructor = SpeciesConstructor(exemplar, defaultConstructor,
+                                       conservative);
+  return TypedArrayCreate(constructor, arg0, arg1, arg2);
+}
+
+macro TYPED_ARRAY_CONSTRUCTOR(ARRAY_ID, NAME, ELEMENT_SIZE)
+function NAMEConstructByArrayBuffer(obj, buffer, byteOffset, length) {
+  if (!IS_UNDEFINED(byteOffset)) {
+    byteOffset = ToPositiveInteger(byteOffset, kInvalidTypedArrayLength);
+  }
+  if (!IS_UNDEFINED(length)) {
+    length = ToPositiveInteger(length, kInvalidTypedArrayLength);
+  }
+
+  var bufferByteLength = %_ArrayBufferGetByteLength(buffer);
+  var offset;
+  if (IS_UNDEFINED(byteOffset)) {
+    offset = 0;
+  } else {
+    offset = byteOffset;
+
+    if (offset % ELEMENT_SIZE !== 0) {
+      throw MakeRangeError(kInvalidTypedArrayAlignment,
+                           "start offset", "NAME", ELEMENT_SIZE);
+    }
+    if (offset > bufferByteLength) {
+      throw MakeRangeError(kInvalidTypedArrayOffset);
+    }
+  }
+
+  var newByteLength;
+  var newLength;
+  if (IS_UNDEFINED(length)) {
+    if (bufferByteLength % ELEMENT_SIZE !== 0) {
+      throw MakeRangeError(kInvalidTypedArrayAlignment,
+                           "byte length", "NAME", ELEMENT_SIZE);
+    }
+    newByteLength = bufferByteLength - offset;
+    newLength = newByteLength / ELEMENT_SIZE;
+  } else {
+    var newLength = length;
+    newByteLength = newLength * ELEMENT_SIZE;
+  }
+  if ((offset + newByteLength > bufferByteLength)
+      || (newLength > %_MaxSmi())) {
+    throw MakeRangeError(kInvalidTypedArrayLength);
+  }
+  %_TypedArrayInitialize(obj, ARRAY_ID, buffer, offset, newByteLength, true);
+}
+
+function NAMEConstructByLength(obj, length) {
+  var l = IS_UNDEFINED(length) ?
+    0 : ToPositiveInteger(length, kInvalidTypedArrayLength);
+  if (l > %_MaxSmi()) {
+    throw MakeRangeError(kInvalidTypedArrayLength);
+  }
+  var byteLength = l * ELEMENT_SIZE;
+  if (byteLength > %_TypedArrayMaxSizeInHeap()) {
+    var buffer = new GlobalArrayBuffer(byteLength);
+    %_TypedArrayInitialize(obj, ARRAY_ID, buffer, 0, byteLength, true);
+  } else {
+    %_TypedArrayInitialize(obj, ARRAY_ID, null, 0, byteLength, true);
+  }
+}
+
+function NAMEConstructByArrayLike(obj, arrayLike) {
+  var length = arrayLike.length;
+  var l = ToPositiveInteger(length, kInvalidTypedArrayLength);
+
+  if (l > %_MaxSmi()) {
+    throw MakeRangeError(kInvalidTypedArrayLength);
+  }
+  var initialized = false;
+  var byteLength = l * ELEMENT_SIZE;
+  if (byteLength <= %_TypedArrayMaxSizeInHeap()) {
+    %_TypedArrayInitialize(obj, ARRAY_ID, null, 0, byteLength, false);
+  } else {
+    initialized =
+        %TypedArrayInitializeFromArrayLike(obj, ARRAY_ID, arrayLike, l);
+  }
+  if (!initialized) {
+    for (var i = 0; i < l; i++) {
+      // It is crucial that we let any execptions from arrayLike[i]
+      // propagate outside the function.
+      obj[i] = arrayLike[i];
+    }
+  }
+}
+
+function NAMEConstructByIterable(obj, iterable, iteratorFn) {
+  var list = new InternalArray();
+  // Reading the Symbol.iterator property of iterable twice would be
+  // observable with getters, so instead, we call the function which
+  // was already looked up, and wrap it in another iterable. The
+  // __proto__ of the new iterable is set to null to avoid any chance
+  // of modifications to Object.prototype being observable here.
+  var iterator = %_Call(iteratorFn, iterable);
+  var newIterable = {
+    __proto__: null
+  };
+  // TODO(littledan): Computed properties don't work yet in nosnap.
+  // Rephrase when they do.
+  newIterable[iteratorSymbol] = function() { return iterator; }
+  for (var value of newIterable) {
+    list.push(value);
+  }
+  NAMEConstructByArrayLike(obj, list);
+}
+
+function NAMEConstructor(arg1, arg2, arg3) {
+  if (!IS_UNDEFINED(new.target)) {
+    if (IS_ARRAYBUFFER(arg1) || IS_SHAREDARRAYBUFFER(arg1)) {
+      NAMEConstructByArrayBuffer(this, arg1, arg2, arg3);
+    } else if (IS_NUMBER(arg1) || IS_STRING(arg1) ||
+               IS_BOOLEAN(arg1) || IS_UNDEFINED(arg1)) {
+      NAMEConstructByLength(this, arg1);
+    } else {
+      // TODO(littledan): If arg1 is a TypedArray, follow the constructor
+      // path in ES2015 22.2.4.3, and call SpeciesConstructor, in a
+      // path that seems to be an optimized version of what's below, but
+      // in an observably different way.
+      var iteratorFn = arg1[iteratorSymbol];
+      if (IS_UNDEFINED(iteratorFn) || iteratorFn === ArrayValues) {
+        NAMEConstructByArrayLike(this, arg1);
+      } else {
+        NAMEConstructByIterable(this, arg1, iteratorFn);
+      }
+    }
+  } else {
+    throw MakeTypeError(kConstructorNotFunction, "NAME")
+  }
+}
+
+// TODO(littledan): Remove this performance workaround BUG(chromium:579905)
+function NAME_GetLength() {
+  if (!(%_ClassOf(this) === 'NAME')) {
+    throw MakeTypeError(kIncompatibleMethodReceiver, "NAME.length", this);
+  }
+  return %_TypedArrayGetLength(this);
+}
+
+function NAMESubArray(begin, end) {
+  var beginInt = TO_INTEGER(begin);
+  if (!IS_UNDEFINED(end)) {
+    var endInt = TO_INTEGER(end);
+    var srcLength = %_TypedArrayGetLength(this);
+  } else {
+    var srcLength = %_TypedArrayGetLength(this);
+    var endInt = srcLength;
+  }
+
+  if (beginInt < 0) {
+    beginInt = MaxSimple(0, srcLength + beginInt);
+  } else {
+    beginInt = MinSimple(beginInt, srcLength);
+  }
+
+  if (endInt < 0) {
+    endInt = MaxSimple(0, srcLength + endInt);
+  } else {
+    endInt = MinSimple(endInt, srcLength);
+  }
+
+  if (endInt < beginInt) {
+    endInt = beginInt;
+  }
+
+  var newLength = endInt - beginInt;
+  var beginByteOffset =
+      %_ArrayBufferViewGetByteOffset(this) + beginInt * ELEMENT_SIZE;
+  return TypedArraySpeciesCreate(this, %TypedArrayGetBuffer(this),
+                                 beginByteOffset, newLength, true);
+}
+endmacro
+
+TYPED_ARRAYS(TYPED_ARRAY_CONSTRUCTOR)
+
+function TypedArraySubArray(begin, end) {
+  switch (%_ClassOf(this)) {
+macro TYPED_ARRAY_SUBARRAY_CASE(ARRAY_ID, NAME, ELEMENT_SIZE)
+    case "NAME":
+      return %_Call(NAMESubArray, this, begin, end);
+endmacro
+TYPED_ARRAYS(TYPED_ARRAY_SUBARRAY_CASE)
+  }
+  throw MakeTypeError(kIncompatibleMethodReceiver,
+                      "get TypedArray.prototype.subarray", this);
+}
+%SetForceInlineFlag(TypedArraySubArray);
+
+function TypedArrayGetBuffer() {
+  if (!%_IsTypedArray(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        "get TypedArray.prototype.buffer", this);
+  }
+  return %TypedArrayGetBuffer(this);
+}
+%SetForceInlineFlag(TypedArrayGetBuffer);
+
+function TypedArrayGetByteLength() {
+  if (!%_IsTypedArray(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        "get TypedArray.prototype.byteLength", this);
+  }
+  return %_ArrayBufferViewGetByteLength(this);
+}
+%SetForceInlineFlag(TypedArrayGetByteLength);
+
+function TypedArrayGetByteOffset() {
+  if (!%_IsTypedArray(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        "get TypedArray.prototype.byteOffset", this);
+  }
+  return %_ArrayBufferViewGetByteOffset(this);
+}
+%SetForceInlineFlag(TypedArrayGetByteOffset);
+
+function TypedArrayGetLength() {
+  if (!%_IsTypedArray(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        "get TypedArray.prototype.length", this);
+  }
+  return %_TypedArrayGetLength(this);
+}
+%SetForceInlineFlag(TypedArrayGetLength);
+
+
+
+function TypedArraySetFromArrayLike(target, source, sourceLength, offset) {
+  if (offset > 0) {
+    for (var i = 0; i < sourceLength; i++) {
+      target[offset + i] = source[i];
+    }
+  }
+  else {
+    for (var i = 0; i < sourceLength; i++) {
+      target[i] = source[i];
+    }
+  }
+}
+
+function TypedArraySetFromOverlappingTypedArray(target, source, offset) {
+  var sourceElementSize = source.BYTES_PER_ELEMENT;
+  var targetElementSize = target.BYTES_PER_ELEMENT;
+  var sourceLength = source.length;
+
+  // Copy left part.
+  function CopyLeftPart() {
+    // First un-mutated byte after the next write
+    var targetPtr = target.byteOffset + (offset + 1) * targetElementSize;
+    // Next read at sourcePtr. We do not care for memory changing before
+    // sourcePtr - we have already copied it.
+    var sourcePtr = source.byteOffset;
+    for (var leftIndex = 0;
+         leftIndex < sourceLength && targetPtr <= sourcePtr;
+         leftIndex++) {
+      target[offset + leftIndex] = source[leftIndex];
+      targetPtr += targetElementSize;
+      sourcePtr += sourceElementSize;
+    }
+    return leftIndex;
+  }
+  var leftIndex = CopyLeftPart();
+
+  // Copy rigth part;
+  function CopyRightPart() {
+    // First unmutated byte before the next write
+    var targetPtr =
+      target.byteOffset + (offset + sourceLength - 1) * targetElementSize;
+    // Next read before sourcePtr. We do not care for memory changing after
+    // sourcePtr - we have already copied it.
+    var sourcePtr =
+      source.byteOffset + sourceLength * sourceElementSize;
+    for(var rightIndex = sourceLength - 1;
+        rightIndex >= leftIndex && targetPtr >= sourcePtr;
+        rightIndex--) {
+      target[offset + rightIndex] = source[rightIndex];
+      targetPtr -= targetElementSize;
+      sourcePtr -= sourceElementSize;
+    }
+    return rightIndex;
+  }
+  var rightIndex = CopyRightPart();
+
+  var temp = new GlobalArray(rightIndex + 1 - leftIndex);
+  for (var i = leftIndex; i <= rightIndex; i++) {
+    temp[i - leftIndex] = source[i];
+  }
+  for (i = leftIndex; i <= rightIndex; i++) {
+    target[offset + i] = temp[i - leftIndex];
+  }
+}
+
+function TypedArraySet(obj, offset) {
+  var intOffset = IS_UNDEFINED(offset) ? 0 : TO_INTEGER(offset);
+  if (intOffset < 0) throw MakeTypeError(kTypedArraySetNegativeOffset);
+
+  if (intOffset > %_MaxSmi()) {
+    throw MakeRangeError(kTypedArraySetSourceTooLarge);
+  }
+  switch (%TypedArraySetFastCases(this, obj, intOffset)) {
+    // These numbers should be synchronized with runtime.cc.
+    case 0: // TYPED_ARRAY_SET_TYPED_ARRAY_SAME_TYPE
+      return;
+    case 1: // TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING
+      TypedArraySetFromOverlappingTypedArray(this, obj, intOffset);
+      return;
+    case 2: // TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING
+      TypedArraySetFromArrayLike(this, obj, obj.length, intOffset);
+      return;
+    case 3: // TYPED_ARRAY_SET_NON_TYPED_ARRAY
+      var l = obj.length;
+      if (IS_UNDEFINED(l)) {
+        if (IS_NUMBER(obj)) {
+            // For number as a first argument, throw TypeError
+            // instead of silently ignoring the call, so that
+            // the user knows (s)he did something wrong.
+            // (Consistent with Firefox and Blink/WebKit)
+            throw MakeTypeError(kInvalidArgument);
+        }
+        return;
+      }
+      l = TO_LENGTH(l);
+      if (intOffset + l > this.length) {
+        throw MakeRangeError(kTypedArraySetSourceTooLarge);
+      }
+      TypedArraySetFromArrayLike(this, obj, l, intOffset);
+      return;
+  }
+}
+
+function TypedArrayGetToStringTag() {
+  if (!%_IsTypedArray(this)) return;
+  var name = %_ClassOf(this);
+  if (IS_UNDEFINED(name)) return;
+  return name;
+}
+
+
+function TypedArrayCopyWithin(target, start, end) {
+  if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
+
+  var length = %_TypedArrayGetLength(this);
+
+  // TODO(littledan): Replace with a memcpy for better performance
+  return InnerArrayCopyWithin(target, start, end, this, length);
+}
+%FunctionSetLength(TypedArrayCopyWithin, 2);
+
+
+// ES6 draft 05-05-15, section 22.2.3.7
+function TypedArrayEvery(f, receiver) {
+  if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
+
+  var length = %_TypedArrayGetLength(this);
+
+  return InnerArrayEvery(f, receiver, this, length);
+}
+%FunctionSetLength(TypedArrayEvery, 1);
+
+
+// ES6 draft 08-24-14, section 22.2.3.12
+function TypedArrayForEach(f, receiver) {
+  if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
+
+  var length = %_TypedArrayGetLength(this);
+
+  InnerArrayForEach(f, receiver, this, length);
+}
+%FunctionSetLength(TypedArrayForEach, 1);
+
+
+// ES6 draft 04-05-14 section 22.2.3.8
+function TypedArrayFill(value, start, end) {
+  if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
+
+  var length = %_TypedArrayGetLength(this);
+
+  return InnerArrayFill(value, start, end, this, length);
+}
+%FunctionSetLength(TypedArrayFill, 1);
+
+
+// ES6 draft 07-15-13, section 22.2.3.9
+function TypedArrayFilter(f, thisArg) {
+  if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
+
+  var length = %_TypedArrayGetLength(this);
+  if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f);
+  var result = new InternalArray();
+  InnerArrayFilter(f, thisArg, this, length, result);
+  var captured = result.length;
+  var output = TypedArraySpeciesCreate(this, captured);
+  for (var i = 0; i < captured; i++) {
+    output[i] = result[i];
+  }
+  return output;
+}
+%FunctionSetLength(TypedArrayFilter, 1);
+
+
+// ES6 draft 07-15-13, section 22.2.3.10
+function TypedArrayFind(predicate, thisArg) {
+  if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
+
+  var length = %_TypedArrayGetLength(this);
+
+  return InnerArrayFind(predicate, thisArg, this, length);
+}
+%FunctionSetLength(TypedArrayFind, 1);
+
+
+// ES6 draft 07-15-13, section 22.2.3.11
+function TypedArrayFindIndex(predicate, thisArg) {
+  if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
+
+  var length = %_TypedArrayGetLength(this);
+
+  return InnerArrayFindIndex(predicate, thisArg, this, length);
+}
+%FunctionSetLength(TypedArrayFindIndex, 1);
+
+
+// ES6 draft 05-18-15, section 22.2.3.21
+function TypedArrayReverse() {
+  if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
+
+  var length = %_TypedArrayGetLength(this);
+
+  return PackedArrayReverse(this, length);
+}
+
+
+function TypedArrayComparefn(x, y) {
+  if (IsNaN(x) && IsNaN(y)) {
+    return IsNaN(y) ? 0 : 1;
+  }
+  if (IsNaN(x)) {
+    return 1;
+  }
+  if (x === 0 && x === y) {
+    if (%_IsMinusZero(x)) {
+      if (!%_IsMinusZero(y)) {
+        return -1;
+      }
+    } else if (%_IsMinusZero(y)) {
+      return 1;
+    }
+  }
+  return x - y;
+}
+
+
+// ES6 draft 05-18-15, section 22.2.3.25
+function TypedArraySort(comparefn) {
+  if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
+
+  var length = %_TypedArrayGetLength(this);
+
+  if (IS_UNDEFINED(comparefn)) {
+    comparefn = TypedArrayComparefn;
+  }
+
+  return InnerArraySort(this, length, comparefn);
+}
+
+
+// ES6 section 22.2.3.13
+function TypedArrayIndexOf(element, index) {
+  if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
+
+  var length = %_TypedArrayGetLength(this);
+  return InnerArrayIndexOf(this, element, index, length);
+}
+%FunctionSetLength(TypedArrayIndexOf, 1);
+
+
+// ES6 section 22.2.3.16
+function TypedArrayLastIndexOf(element, index) {
+  if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
+
+  var length = %_TypedArrayGetLength(this);
+
+  return InnerArrayLastIndexOf(this, element, index, length,
+                        %_ArgumentsLength());
+}
+%FunctionSetLength(TypedArrayLastIndexOf, 1);
+
+
+// ES6 draft 07-15-13, section 22.2.3.18
+function TypedArrayMap(f, thisArg) {
+  if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
+
+  var length = %_TypedArrayGetLength(this);
+  var result = TypedArraySpeciesCreate(this, length);
+  if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f);
+  for (var i = 0; i < length; i++) {
+    var element = this[i];
+    result[i] = %_Call(f, thisArg, element, i, this);
+  }
+  return result;
+}
+%FunctionSetLength(TypedArrayMap, 1);
+
+
+// ES6 draft 05-05-15, section 22.2.3.24
+function TypedArraySome(f, receiver) {
+  if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
+
+  var length = %_TypedArrayGetLength(this);
+
+  return InnerArraySome(f, receiver, this, length);
+}
+%FunctionSetLength(TypedArraySome, 1);
+
+
+// ES6 section 22.2.3.27
+function TypedArrayToLocaleString() {
+  if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
+
+  var length = %_TypedArrayGetLength(this);
+
+  return InnerArrayToLocaleString(this, length);
+}
+
+
+// ES6 section 22.2.3.28
+function TypedArrayToString() {
+  return %_Call(ArrayToString, this);
+}
+
+
+// ES6 section 22.2.3.14
+function TypedArrayJoin(separator) {
+  if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
+
+  var length = %_TypedArrayGetLength(this);
+
+  return InnerArrayJoin(separator, this, length);
+}
+
+
+// ES6 draft 07-15-13, section 22.2.3.19
+function TypedArrayReduce(callback, current) {
+  if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
+
+  var length = %_TypedArrayGetLength(this);
+  return InnerArrayReduce(callback, current, this, length,
+                          %_ArgumentsLength());
+}
+%FunctionSetLength(TypedArrayReduce, 1);
+
+
+// ES6 draft 07-15-13, section 22.2.3.19
+function TypedArrayReduceRight(callback, current) {
+  if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
+
+  var length = %_TypedArrayGetLength(this);
+  return InnerArrayReduceRight(callback, current, this, length,
+                               %_ArgumentsLength());
+}
+%FunctionSetLength(TypedArrayReduceRight, 1);
+
+
+function TypedArraySlice(start, end) {
+  if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
+  var len = %_TypedArrayGetLength(this);
+
+  var relativeStart = TO_INTEGER(start);
+
+  var k;
+  if (relativeStart < 0) {
+    k = MaxSimple(len + relativeStart, 0);
+  } else {
+    k = MinSimple(relativeStart, len);
+  }
+
+  var relativeEnd;
+  if (IS_UNDEFINED(end)) {
+    relativeEnd = len;
+  } else {
+    relativeEnd = TO_INTEGER(end);
+  }
+
+  var final;
+  if (relativeEnd < 0) {
+    final = MaxSimple(len + relativeEnd, 0);
+  } else {
+    final = MinSimple(relativeEnd, len);
+  }
+
+  var count = MaxSimple(final - k, 0);
+  var array = TypedArraySpeciesCreate(this, count);
+  // The code below is the 'then' branch; the 'else' branch species
+  // a memcpy. Because V8 doesn't canonicalize NaN, the difference is
+  // unobservable.
+  var n = 0;
+  while (k < final) {
+    var kValue = this[k];
+    array[n] = kValue;
+    k++;
+    n++;
+  }
+  return array;
+}
+
+
+// ES2016 draft, section 22.2.3.14
+function TypedArrayIncludes(searchElement, fromIndex) {
+  if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
+
+  var length = %_TypedArrayGetLength(this);
+
+  return InnerArrayIncludes(searchElement, fromIndex, this, length);
+}
+%FunctionSetLength(TypedArrayIncludes, 1);
+
+
+// ES6 draft 08-24-14, section 22.2.2.2
+function TypedArrayOf() {
+  var length = %_ArgumentsLength();
+  var array = TypedArrayCreate(this, length);
+  for (var i = 0; i < length; i++) {
+    array[i] = %_Arguments(i);
+  }
+  return array;
+}
+
+
+function TypedArrayFrom(source, mapfn, thisArg) {
+  // TODO(littledan): Investigate if there is a receiver which could be
+  // faster to accumulate on than Array, e.g., a TypedVector.
+  // TODO(littledan): Rewrite this code to ensure that things happen
+  // in the right order, e.g., the constructor needs to be called before
+  // the mapping function on array-likes.
+  var array = %_Call(ArrayFrom, GlobalArray, source, mapfn, thisArg);
+  return TypedArrayCreate(this, array);
+}
+%FunctionSetLength(TypedArrayFrom, 1);
+
+function TypedArray() {
+  if (IS_UNDEFINED(new.target)) {
+    throw MakeTypeError(kConstructorNonCallable, "TypedArray");
+  }
+  if (new.target === TypedArray) {
+    throw MakeTypeError(kConstructAbstractClass, "TypedArray");
+  }
+}
+
+// -------------------------------------------------------------------
+
+%FunctionSetPrototype(TypedArray, new GlobalObject());
+%AddNamedProperty(TypedArray.prototype,
+                  "constructor", TypedArray, DONT_ENUM);
+utils.InstallFunctions(TypedArray, DONT_ENUM | DONT_DELETE | READ_ONLY, [
+  "from", TypedArrayFrom,
+  "of", TypedArrayOf
+]);
+utils.InstallGetter(TypedArray.prototype, "buffer", TypedArrayGetBuffer);
+utils.InstallGetter(TypedArray.prototype, "byteOffset", TypedArrayGetByteOffset,
+                    DONT_ENUM | DONT_DELETE);
+utils.InstallGetter(TypedArray.prototype, "byteLength",
+                    TypedArrayGetByteLength, DONT_ENUM | DONT_DELETE);
+utils.InstallGetter(TypedArray.prototype, "length", TypedArrayGetLength,
+                    DONT_ENUM | DONT_DELETE);
+utils.InstallGetter(TypedArray.prototype, toStringTagSymbol,
+                    TypedArrayGetToStringTag);
+utils.InstallFunctions(TypedArray.prototype, DONT_ENUM, [
+  "subarray", TypedArraySubArray,
+  "set", TypedArraySet,
+  "copyWithin", TypedArrayCopyWithin,
+  "every", TypedArrayEvery,
+  "fill", TypedArrayFill,
+  "filter", TypedArrayFilter,
+  "find", TypedArrayFind,
+  "findIndex", TypedArrayFindIndex,
+  "includes", TypedArrayIncludes,
+  "indexOf", TypedArrayIndexOf,
+  "join", TypedArrayJoin,
+  "lastIndexOf", TypedArrayLastIndexOf,
+  "forEach", TypedArrayForEach,
+  "map", TypedArrayMap,
+  "reduce", TypedArrayReduce,
+  "reduceRight", TypedArrayReduceRight,
+  "reverse", TypedArrayReverse,
+  "slice", TypedArraySlice,
+  "some", TypedArraySome,
+  "sort", TypedArraySort,
+  "toString", TypedArrayToString,
+  "toLocaleString", TypedArrayToLocaleString
+]);
+
+
+macro SETUP_TYPED_ARRAY(ARRAY_ID, NAME, ELEMENT_SIZE)
+  %SetCode(GlobalNAME, NAMEConstructor);
+  %FunctionSetPrototype(GlobalNAME, new GlobalObject());
+  %InternalSetPrototype(GlobalNAME, TypedArray);
+  %InternalSetPrototype(GlobalNAME.prototype, TypedArray.prototype);
+
+  %AddNamedProperty(GlobalNAME, "BYTES_PER_ELEMENT", ELEMENT_SIZE,
+                    READ_ONLY | DONT_ENUM | DONT_DELETE);
+
+  %AddNamedProperty(GlobalNAME.prototype,
+                    "constructor", global.NAME, DONT_ENUM);
+  %AddNamedProperty(GlobalNAME.prototype,
+                    "BYTES_PER_ELEMENT", ELEMENT_SIZE,
+                    READ_ONLY | DONT_ENUM | DONT_DELETE);
+  // TODO(littledan): Remove this performance workaround BUG(chromium:579905)
+  utils.InstallGetter(GlobalNAME.prototype, "length", NAME_GetLength,
+                      DONT_ENUM | DONT_DELETE);
+endmacro
+
+TYPED_ARRAYS(SETUP_TYPED_ARRAY)
+
+// --------------------------- DataView -----------------------------
+
+function DataViewConstructor(buffer, byteOffset, byteLength) { // length = 3
+  if (IS_UNDEFINED(new.target)) {
+    throw MakeTypeError(kConstructorNotFunction, "DataView");
+  }
+
+  // TODO(binji): support SharedArrayBuffers?
+  if (!IS_ARRAYBUFFER(buffer)) throw MakeTypeError(kDataViewNotArrayBuffer);
+  if (!IS_UNDEFINED(byteOffset)) {
+    byteOffset = ToPositiveInteger(byteOffset, kInvalidDataViewOffset);
+  }
+  if (!IS_UNDEFINED(byteLength)) {
+    byteLength = TO_INTEGER(byteLength);
+  }
+
+  var bufferByteLength = %_ArrayBufferGetByteLength(buffer);
+
+  var offset = IS_UNDEFINED(byteOffset) ?  0 : byteOffset;
+  if (offset > bufferByteLength) throw MakeRangeError(kInvalidDataViewOffset);
+
+  var length = IS_UNDEFINED(byteLength)
+      ? bufferByteLength - offset
+      : byteLength;
+  if (length < 0 || offset + length > bufferByteLength) {
+    throw new MakeRangeError(kInvalidDataViewLength);
+  }
+  var result = %NewObject(GlobalDataView, new.target);
+  %_DataViewInitialize(result, buffer, offset, length);
+  return result;
+}
+
+function DataViewGetBufferJS() {
+  if (!IS_DATAVIEW(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver, 'DataView.buffer', this);
+  }
+  return %DataViewGetBuffer(this);
+}
+
+function DataViewGetByteOffset() {
+  if (!IS_DATAVIEW(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        'DataView.byteOffset', this);
+  }
+  return %_ArrayBufferViewGetByteOffset(this);
+}
+
+function DataViewGetByteLength() {
+  if (!IS_DATAVIEW(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        'DataView.byteLength', this);
+  }
+  return %_ArrayBufferViewGetByteLength(this);
+}
+
+macro DATA_VIEW_TYPES(FUNCTION)
+  FUNCTION(Int8)
+  FUNCTION(Uint8)
+  FUNCTION(Int16)
+  FUNCTION(Uint16)
+  FUNCTION(Int32)
+  FUNCTION(Uint32)
+  FUNCTION(Float32)
+  FUNCTION(Float64)
+endmacro
+
+
+macro DATA_VIEW_GETTER_SETTER(TYPENAME)
+function DataViewGetTYPENAMEJS(offset, little_endian) {
+  if (!IS_DATAVIEW(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        'DataView.getTYPENAME', this);
+  }
+  if (%_ArgumentsLength() < 1) throw MakeTypeError(kInvalidArgument);
+  offset = ToPositiveInteger(offset, kInvalidDataViewAccessorOffset);
+  return %DataViewGetTYPENAME(this, offset, !!little_endian);
+}
+
+function DataViewSetTYPENAMEJS(offset, value, little_endian) {
+  if (!IS_DATAVIEW(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        'DataView.setTYPENAME', this);
+  }
+  if (%_ArgumentsLength() < 2) throw MakeTypeError(kInvalidArgument);
+  offset = ToPositiveInteger(offset, kInvalidDataViewAccessorOffset);
+  %DataViewSetTYPENAME(this, offset, TO_NUMBER(value), !!little_endian);
+}
+endmacro
+
+DATA_VIEW_TYPES(DATA_VIEW_GETTER_SETTER)
+
+// Setup the DataView constructor.
+%SetCode(GlobalDataView, DataViewConstructor);
+%FunctionSetPrototype(GlobalDataView, new GlobalObject);
+
+// Set up constructor property on the DataView prototype.
+%AddNamedProperty(GlobalDataView.prototype, "constructor", GlobalDataView,
+                  DONT_ENUM);
+%AddNamedProperty(GlobalDataView.prototype, toStringTagSymbol, "DataView",
+                  READ_ONLY|DONT_ENUM);
+
+utils.InstallGetter(GlobalDataView.prototype, "buffer", DataViewGetBufferJS);
+utils.InstallGetter(GlobalDataView.prototype, "byteOffset",
+                    DataViewGetByteOffset);
+utils.InstallGetter(GlobalDataView.prototype, "byteLength",
+                    DataViewGetByteLength);
+
+utils.InstallFunctions(GlobalDataView.prototype, DONT_ENUM, [
+  "getInt8", DataViewGetInt8JS,
+  "setInt8", DataViewSetInt8JS,
+
+  "getUint8", DataViewGetUint8JS,
+  "setUint8", DataViewSetUint8JS,
+
+  "getInt16", DataViewGetInt16JS,
+  "setInt16", DataViewSetInt16JS,
+
+  "getUint16", DataViewGetUint16JS,
+  "setUint16", DataViewSetUint16JS,
+
+  "getInt32", DataViewGetInt32JS,
+  "setInt32", DataViewSetInt32JS,
+
+  "getUint32", DataViewGetUint32JS,
+  "setUint32", DataViewSetUint32JS,
+
+  "getFloat32", DataViewGetFloat32JS,
+  "setFloat32", DataViewSetFloat32JS,
+
+  "getFloat64", DataViewGetFloat64JS,
+  "setFloat64", DataViewSetFloat64JS
+]);
+
+})
diff --git a/src/js/uri.js b/src/js/uri.js
new file mode 100644
index 0000000..712d7e6
--- /dev/null
+++ b/src/js/uri.js
@@ -0,0 +1,380 @@
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file contains support for URI manipulations written in
+// JavaScript.
+
+(function(global, utils) {
+
+"use strict";
+
+%CheckIsBootstrapping();
+
+//- ------------------------------------------------------------------
+// Imports
+
+var GlobalObject = global.Object;
+var GlobalArray = global.Array;
+var InternalArray = utils.InternalArray;
+var MakeURIError;
+
+utils.Import(function(from) {
+  MakeURIError = from.MakeURIError;
+});
+
+
+// -------------------------------------------------------------------
+// Define internal helper functions.
+
+function HexValueOf(code) {
+  // 0-9
+  if (code >= 48 && code <= 57) return code - 48;
+  // A-F
+  if (code >= 65 && code <= 70) return code - 55;
+  // a-f
+  if (code >= 97 && code <= 102) return code - 87;
+
+  return -1;
+}
+
+// Does the char code correspond to an alpha-numeric char.
+function isAlphaNumeric(cc) {
+  // a - z
+  if (97 <= cc && cc <= 122) return true;
+  // A - Z
+  if (65 <= cc && cc <= 90) return true;
+  // 0 - 9
+  if (48 <= cc && cc <= 57) return true;
+
+  return false;
+}
+
+// Lazily initialized.
+var hexCharCodeArray = 0;
+
+function URIAddEncodedOctetToBuffer(octet, result, index) {
+  result[index++] = 37; // Char code of '%'.
+  result[index++] = hexCharCodeArray[octet >> 4];
+  result[index++] = hexCharCodeArray[octet & 0x0F];
+  return index;
+}
+
+function URIEncodeOctets(octets, result, index) {
+  if (hexCharCodeArray === 0) {
+    hexCharCodeArray = [48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
+                        65, 66, 67, 68, 69, 70];
+  }
+  index = URIAddEncodedOctetToBuffer(octets[0], result, index);
+  if (octets[1]) index = URIAddEncodedOctetToBuffer(octets[1], result, index);
+  if (octets[2]) index = URIAddEncodedOctetToBuffer(octets[2], result, index);
+  if (octets[3]) index = URIAddEncodedOctetToBuffer(octets[3], result, index);
+  return index;
+}
+
+function URIEncodeSingle(cc, result, index) {
+  var x = (cc >> 12) & 0xF;
+  var y = (cc >> 6) & 63;
+  var z = cc & 63;
+  var octets = new GlobalArray(3);
+  if (cc <= 0x007F) {
+    octets[0] = cc;
+  } else if (cc <= 0x07FF) {
+    octets[0] = y + 192;
+    octets[1] = z + 128;
+  } else {
+    octets[0] = x + 224;
+    octets[1] = y + 128;
+    octets[2] = z + 128;
+  }
+  return URIEncodeOctets(octets, result, index);
+}
+
+function URIEncodePair(cc1 , cc2, result, index) {
+  var u = ((cc1 >> 6) & 0xF) + 1;
+  var w = (cc1 >> 2) & 0xF;
+  var x = cc1 & 3;
+  var y = (cc2 >> 6) & 0xF;
+  var z = cc2 & 63;
+  var octets = new GlobalArray(4);
+  octets[0] = (u >> 2) + 240;
+  octets[1] = (((u & 3) << 4) | w) + 128;
+  octets[2] = ((x << 4) | y) + 128;
+  octets[3] = z + 128;
+  return URIEncodeOctets(octets, result, index);
+}
+
+function URIHexCharsToCharCode(highChar, lowChar) {
+  var highCode = HexValueOf(highChar);
+  var lowCode = HexValueOf(lowChar);
+  if (highCode == -1 || lowCode == -1) throw MakeURIError();
+  return (highCode << 4) | lowCode;
+}
+
+// Callers must ensure that |result| is a sufficiently long sequential
+// two-byte string!
+function URIDecodeOctets(octets, result, index) {
+  var value;
+  var o0 = octets[0];
+  if (o0 < 0x80) {
+    value = o0;
+  } else if (o0 < 0xc2) {
+    throw MakeURIError();
+  } else {
+    var o1 = octets[1];
+    if (o0 < 0xe0) {
+      var a = o0 & 0x1f;
+      if ((o1 < 0x80) || (o1 > 0xbf)) throw MakeURIError();
+      var b = o1 & 0x3f;
+      value = (a << 6) + b;
+      if (value < 0x80 || value > 0x7ff) throw MakeURIError();
+    } else {
+      var o2 = octets[2];
+      if (o0 < 0xf0) {
+        var a = o0 & 0x0f;
+        if ((o1 < 0x80) || (o1 > 0xbf)) throw MakeURIError();
+        var b = o1 & 0x3f;
+        if ((o2 < 0x80) || (o2 > 0xbf)) throw MakeURIError();
+        var c = o2 & 0x3f;
+        value = (a << 12) + (b << 6) + c;
+        if ((value < 0x800) || (value > 0xffff)) throw MakeURIError();
+      } else {
+        var o3 = octets[3];
+        if (o0 < 0xf8) {
+          var a = (o0 & 0x07);
+          if ((o1 < 0x80) || (o1 > 0xbf)) throw MakeURIError();
+          var b = (o1 & 0x3f);
+          if ((o2 < 0x80) || (o2 > 0xbf)) {
+            throw MakeURIError();
+          }
+          var c = (o2 & 0x3f);
+          if ((o3 < 0x80) || (o3 > 0xbf)) throw MakeURIError();
+          var d = (o3 & 0x3f);
+          value = (a << 18) + (b << 12) + (c << 6) + d;
+          if ((value < 0x10000) || (value > 0x10ffff)) throw MakeURIError();
+        } else {
+          throw MakeURIError();
+        }
+      }
+    }
+  }
+  if (0xD800 <= value && value <= 0xDFFF) throw MakeURIError();
+  if (value < 0x10000) {
+    %_TwoByteSeqStringSetChar(index++, value, result);
+  } else {
+    %_TwoByteSeqStringSetChar(index++, (value >> 10) + 0xd7c0, result);
+    %_TwoByteSeqStringSetChar(index++, (value & 0x3ff) + 0xdc00, result);
+  }
+  return index;
+}
+
+// ECMA-262, section 15.1.3
+function Encode(uri, unescape) {
+  uri = TO_STRING(uri);
+  var uriLength = uri.length;
+  var array = new InternalArray(uriLength);
+  var index = 0;
+  for (var k = 0; k < uriLength; k++) {
+    var cc1 = %_StringCharCodeAt(uri, k);
+    if (unescape(cc1)) {
+      array[index++] = cc1;
+    } else {
+      if (cc1 >= 0xDC00 && cc1 <= 0xDFFF) throw MakeURIError();
+      if (cc1 < 0xD800 || cc1 > 0xDBFF) {
+        index = URIEncodeSingle(cc1, array, index);
+      } else {
+        k++;
+        if (k == uriLength) throw MakeURIError();
+        var cc2 = %_StringCharCodeAt(uri, k);
+        if (cc2 < 0xDC00 || cc2 > 0xDFFF) throw MakeURIError();
+        index = URIEncodePair(cc1, cc2, array, index);
+      }
+    }
+  }
+
+  var result = %NewString(array.length, NEW_ONE_BYTE_STRING);
+  for (var i = 0; i < array.length; i++) {
+    %_OneByteSeqStringSetChar(i, array[i], result);
+  }
+  return result;
+}
+
+// ECMA-262, section 15.1.3
+function Decode(uri, reserved) {
+  uri = TO_STRING(uri);
+  var uriLength = uri.length;
+  var one_byte = %NewString(uriLength, NEW_ONE_BYTE_STRING);
+  var index = 0;
+  var k = 0;
+
+  // Optimistically assume one-byte string.
+  for ( ; k < uriLength; k++) {
+    var code = %_StringCharCodeAt(uri, k);
+    if (code == 37) {  // '%'
+      if (k + 2 >= uriLength) throw MakeURIError();
+      var cc = URIHexCharsToCharCode(%_StringCharCodeAt(uri, k+1),
+                                     %_StringCharCodeAt(uri, k+2));
+      if (cc >> 7) break;  // Assumption wrong, two-byte string.
+      if (reserved(cc)) {
+        %_OneByteSeqStringSetChar(index++, 37, one_byte);  // '%'.
+        %_OneByteSeqStringSetChar(index++, %_StringCharCodeAt(uri, k+1),
+                                  one_byte);
+        %_OneByteSeqStringSetChar(index++, %_StringCharCodeAt(uri, k+2),
+                                  one_byte);
+      } else {
+        %_OneByteSeqStringSetChar(index++, cc, one_byte);
+      }
+      k += 2;
+    } else {
+      if (code > 0x7f) break;  // Assumption wrong, two-byte string.
+      %_OneByteSeqStringSetChar(index++, code, one_byte);
+    }
+  }
+
+  one_byte = %TruncateString(one_byte, index);
+  if (k == uriLength) return one_byte;
+
+  // Write into two byte string.
+  var two_byte = %NewString(uriLength - k, NEW_TWO_BYTE_STRING);
+  index = 0;
+
+  for ( ; k < uriLength; k++) {
+    var code = %_StringCharCodeAt(uri, k);
+    if (code == 37) {  // '%'
+      if (k + 2 >= uriLength) throw MakeURIError();
+      var cc = URIHexCharsToCharCode(%_StringCharCodeAt(uri, ++k),
+                                     %_StringCharCodeAt(uri, ++k));
+      if (cc >> 7) {
+        var n = 0;
+        while (((cc << ++n) & 0x80) != 0) { }
+        if (n == 1 || n > 4) throw MakeURIError();
+        var octets = new GlobalArray(n);
+        octets[0] = cc;
+        if (k + 3 * (n - 1) >= uriLength) throw MakeURIError();
+        for (var i = 1; i < n; i++) {
+          if (uri[++k] != '%') throw MakeURIError();
+          octets[i] = URIHexCharsToCharCode(%_StringCharCodeAt(uri, ++k),
+                                            %_StringCharCodeAt(uri, ++k));
+        }
+        index = URIDecodeOctets(octets, two_byte, index);
+      } else  if (reserved(cc)) {
+        %_TwoByteSeqStringSetChar(index++, 37, two_byte);  // '%'.
+        %_TwoByteSeqStringSetChar(index++, %_StringCharCodeAt(uri, k - 1),
+                                  two_byte);
+        %_TwoByteSeqStringSetChar(index++, %_StringCharCodeAt(uri, k),
+                                  two_byte);
+      } else {
+        %_TwoByteSeqStringSetChar(index++, cc, two_byte);
+      }
+    } else {
+      %_TwoByteSeqStringSetChar(index++, code, two_byte);
+    }
+  }
+
+  two_byte = %TruncateString(two_byte, index);
+  return one_byte + two_byte;
+}
+
+// -------------------------------------------------------------------
+// Define exported functions.
+
+// ECMA-262 - B.2.1.
+function URIEscapeJS(s) {
+  return %URIEscape(s);
+}
+
+// ECMA-262 - B.2.2.
+function URIUnescapeJS(s) {
+  return %URIUnescape(s);
+}
+
+// ECMA-262 - 15.1.3.1.
+function URIDecode(uri) {
+  var reservedPredicate = function(cc) {
+    // #$
+    if (35 <= cc && cc <= 36) return true;
+    // &
+    if (cc == 38) return true;
+    // +,
+    if (43 <= cc && cc <= 44) return true;
+    // /
+    if (cc == 47) return true;
+    // :;
+    if (58 <= cc && cc <= 59) return true;
+    // =
+    if (cc == 61) return true;
+    // ?@
+    if (63 <= cc && cc <= 64) return true;
+
+    return false;
+  };
+  return Decode(uri, reservedPredicate);
+}
+
+// ECMA-262 - 15.1.3.2.
+function URIDecodeComponent(component) {
+  var reservedPredicate = function(cc) { return false; };
+  return Decode(component, reservedPredicate);
+}
+
+// ECMA-262 - 15.1.3.3.
+function URIEncode(uri) {
+  var unescapePredicate = function(cc) {
+    if (isAlphaNumeric(cc)) return true;
+    // !
+    if (cc == 33) return true;
+    // #$
+    if (35 <= cc && cc <= 36) return true;
+    // &'()*+,-./
+    if (38 <= cc && cc <= 47) return true;
+    // :;
+    if (58 <= cc && cc <= 59) return true;
+    // =
+    if (cc == 61) return true;
+    // ?@
+    if (63 <= cc && cc <= 64) return true;
+    // _
+    if (cc == 95) return true;
+    // ~
+    if (cc == 126) return true;
+
+    return false;
+  };
+  return Encode(uri, unescapePredicate);
+}
+
+// ECMA-262 - 15.1.3.4
+function URIEncodeComponent(component) {
+  var unescapePredicate = function(cc) {
+    if (isAlphaNumeric(cc)) return true;
+    // !
+    if (cc == 33) return true;
+    // '()*
+    if (39 <= cc && cc <= 42) return true;
+    // -.
+    if (45 <= cc && cc <= 46) return true;
+    // _
+    if (cc == 95) return true;
+    // ~
+    if (cc == 126) return true;
+
+    return false;
+  };
+  return Encode(component, unescapePredicate);
+}
+
+// -------------------------------------------------------------------
+// Install exported functions.
+
+// Set up non-enumerable URI functions on the global object and set
+// their names.
+utils.InstallFunctions(global, DONT_ENUM, [
+  "escape", URIEscapeJS,
+  "unescape", URIUnescapeJS,
+  "decodeURI", URIDecode,
+  "decodeURIComponent", URIDecodeComponent,
+  "encodeURI", URIEncode,
+  "encodeURIComponent", URIEncodeComponent
+]);
+
+})
diff --git a/src/js/v8natives.js b/src/js/v8natives.js
new file mode 100644
index 0000000..26447da
--- /dev/null
+++ b/src/js/v8natives.js
@@ -0,0 +1,1190 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function(global, utils) {
+
+%CheckIsBootstrapping();
+
+// ----------------------------------------------------------------------------
+// Imports
+
+var GlobalArray = global.Array;
+var GlobalBoolean = global.Boolean;
+var GlobalNumber = global.Number;
+var GlobalObject = global.Object;
+var InternalArray = utils.InternalArray;
+var iteratorSymbol = utils.ImportNow("iterator_symbol");
+var MakeRangeError;
+var MakeSyntaxError;
+var MakeTypeError;
+var MathAbs;
+var NaN = %GetRootNaN();
+var ObjectToString = utils.ImportNow("object_to_string");
+var ObserveBeginPerformSplice;
+var ObserveEndPerformSplice;
+var ObserveEnqueueSpliceRecord;
+var SameValue = utils.ImportNow("SameValue");
+var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
+
+utils.Import(function(from) {
+  MakeRangeError = from.MakeRangeError;
+  MakeSyntaxError = from.MakeSyntaxError;
+  MakeTypeError = from.MakeTypeError;
+  MathAbs = from.MathAbs;
+  ObserveBeginPerformSplice = from.ObserveBeginPerformSplice;
+  ObserveEndPerformSplice = from.ObserveEndPerformSplice;
+  ObserveEnqueueSpliceRecord = from.ObserveEnqueueSpliceRecord;
+});
+
+// ----------------------------------------------------------------------------
+
+
+// ES6 18.2.3 isNaN(number)
+function GlobalIsNaN(number) {
+  number = TO_NUMBER(number);
+  return NUMBER_IS_NAN(number);
+}
+
+
+// ES6 18.2.2 isFinite(number)
+function GlobalIsFinite(number) {
+  number = TO_NUMBER(number);
+  return NUMBER_IS_FINITE(number);
+}
+
+
+// ES6 18.2.5 parseInt(string, radix)
+function GlobalParseInt(string, radix) {
+  if (IS_UNDEFINED(radix) || radix === 10 || radix === 0) {
+    // Some people use parseInt instead of Math.floor.  This
+    // optimization makes parseInt on a Smi 12 times faster (60ns
+    // vs 800ns).  The following optimization makes parseInt on a
+    // non-Smi number 9 times faster (230ns vs 2070ns).  Together
+    // they make parseInt on a string 1.4% slower (274ns vs 270ns).
+    if (%_IsSmi(string)) return string;
+    if (IS_NUMBER(string) &&
+        ((0.01 < string && string < 1e9) ||
+            (-1e9 < string && string < -0.01))) {
+      // Truncate number.
+      return string | 0;
+    }
+    string = TO_STRING(string);
+    radix = radix | 0;
+  } else {
+    // The spec says ToString should be evaluated before ToInt32.
+    string = TO_STRING(string);
+    radix = TO_INT32(radix);
+    if (!(radix == 0 || (2 <= radix && radix <= 36))) {
+      return NaN;
+    }
+  }
+
+  if (%_HasCachedArrayIndex(string) &&
+      (radix == 0 || radix == 10)) {
+    return %_GetCachedArrayIndex(string);
+  }
+  return %StringParseInt(string, radix);
+}
+
+
+// ES6 18.2.4 parseFloat(string)
+function GlobalParseFloat(string) {
+  // 1. Let inputString be ? ToString(string).
+  string = TO_STRING(string);
+  if (%_HasCachedArrayIndex(string)) return %_GetCachedArrayIndex(string);
+  return %StringParseFloat(string);
+}
+
+
+// ----------------------------------------------------------------------------
+
+// Set up global object.
+var attributes = DONT_ENUM | DONT_DELETE | READ_ONLY;
+
+utils.InstallConstants(global, [
+  // ES6 18.1.1
+  "Infinity", INFINITY,
+  // ES6 18.1.2
+  "NaN", NaN,
+  // ES6 18.1.3
+  "undefined", UNDEFINED,
+]);
+
+// Set up non-enumerable function on the global object.
+utils.InstallFunctions(global, DONT_ENUM, [
+  "isNaN", GlobalIsNaN,
+  "isFinite", GlobalIsFinite,
+  "parseInt", GlobalParseInt,
+  "parseFloat", GlobalParseFloat,
+]);
+
+
+// ----------------------------------------------------------------------------
+// Object
+
+// ES6 19.1.3.5 Object.prototype.toLocaleString([reserved1 [,reserved2]])
+function ObjectToLocaleString() {
+  CHECK_OBJECT_COERCIBLE(this, "Object.prototype.toLocaleString");
+  return this.toString();
+}
+
+
+// ES6 19.1.3.7 Object.prototype.valueOf()
+function ObjectValueOf() {
+  return TO_OBJECT(this);
+}
+
+
+// ES6 7.3.11
+function ObjectHasOwnProperty(value) {
+  var name = TO_NAME(value);
+  var object = TO_OBJECT(this);
+  return %HasOwnProperty(object, name);
+}
+
+
+// ES6 19.1.3.3 Object.prototype.isPrototypeOf(V)
+function ObjectIsPrototypeOf(V) {
+  if (!IS_RECEIVER(V)) return false;
+  var O = TO_OBJECT(this);
+  return %HasInPrototypeChain(V, O);
+}
+
+
+// ES6 19.1.3.4
+function ObjectPropertyIsEnumerable(V) {
+  var P = TO_NAME(V);
+  return %PropertyIsEnumerable(TO_OBJECT(this), P);
+}
+
+
+// Extensions for providing property getters and setters.
+function ObjectDefineGetter(name, fun) {
+  var receiver = this;
+  if (IS_NULL(receiver) || IS_UNDEFINED(receiver)) {
+    receiver = %GlobalProxy(ObjectDefineGetter);
+  }
+  if (!IS_CALLABLE(fun)) {
+    throw MakeTypeError(kObjectGetterExpectingFunction);
+  }
+  var desc = new PropertyDescriptor();
+  desc.setGet(fun);
+  desc.setEnumerable(true);
+  desc.setConfigurable(true);
+  DefineOwnProperty(TO_OBJECT(receiver), TO_NAME(name), desc, false);
+}
+
+
+function ObjectLookupGetter(name) {
+  var receiver = this;
+  if (IS_NULL(receiver) || IS_UNDEFINED(receiver)) {
+    receiver = %GlobalProxy(ObjectLookupGetter);
+  }
+  return %LookupAccessor(TO_OBJECT(receiver), TO_NAME(name), GETTER);
+}
+
+
+function ObjectDefineSetter(name, fun) {
+  var receiver = this;
+  if (IS_NULL(receiver) || IS_UNDEFINED(receiver)) {
+    receiver = %GlobalProxy(ObjectDefineSetter);
+  }
+  if (!IS_CALLABLE(fun)) {
+    throw MakeTypeError(kObjectSetterExpectingFunction);
+  }
+  var desc = new PropertyDescriptor();
+  desc.setSet(fun);
+  desc.setEnumerable(true);
+  desc.setConfigurable(true);
+  DefineOwnProperty(TO_OBJECT(receiver), TO_NAME(name), desc, false);
+}
+
+
+function ObjectLookupSetter(name) {
+  var receiver = this;
+  if (IS_NULL(receiver) || IS_UNDEFINED(receiver)) {
+    receiver = %GlobalProxy(ObjectLookupSetter);
+  }
+  return %LookupAccessor(TO_OBJECT(receiver), TO_NAME(name), SETTER);
+}
+
+
+// ES6 6.2.4.1
+function IsAccessorDescriptor(desc) {
+  if (IS_UNDEFINED(desc)) return false;
+  return desc.hasGetter() || desc.hasSetter();
+}
+
+
+// ES6 6.2.4.2
+function IsDataDescriptor(desc) {
+  if (IS_UNDEFINED(desc)) return false;
+  return desc.hasValue() || desc.hasWritable();
+}
+
+
+// ES6 6.2.4.3
+function IsGenericDescriptor(desc) {
+  if (IS_UNDEFINED(desc)) return false;
+  return !(IsAccessorDescriptor(desc) || IsDataDescriptor(desc));
+}
+
+
+function IsInconsistentDescriptor(desc) {
+  return IsAccessorDescriptor(desc) && IsDataDescriptor(desc);
+}
+
+
+// Harmony Proxies
+function FromGenericPropertyDescriptor(desc) {
+  if (IS_UNDEFINED(desc)) return desc;
+  var obj = new GlobalObject();
+
+  if (desc.hasValue()) {
+    %AddNamedProperty(obj, "value", desc.getValue(), NONE);
+  }
+  if (desc.hasWritable()) {
+    %AddNamedProperty(obj, "writable", desc.isWritable(), NONE);
+  }
+  if (desc.hasGetter()) {
+    %AddNamedProperty(obj, "get", desc.getGet(), NONE);
+  }
+  if (desc.hasSetter()) {
+    %AddNamedProperty(obj, "set", desc.getSet(), NONE);
+  }
+  if (desc.hasEnumerable()) {
+    %AddNamedProperty(obj, "enumerable", desc.isEnumerable(), NONE);
+  }
+  if (desc.hasConfigurable()) {
+    %AddNamedProperty(obj, "configurable", desc.isConfigurable(), NONE);
+  }
+  return obj;
+}
+
+
+// ES6 6.2.4.5
+function ToPropertyDescriptor(obj) {
+  if (!IS_RECEIVER(obj)) throw MakeTypeError(kPropertyDescObject, obj);
+
+  var desc = new PropertyDescriptor();
+
+  if ("enumerable" in obj) {
+    desc.setEnumerable(TO_BOOLEAN(obj.enumerable));
+  }
+
+  if ("configurable" in obj) {
+    desc.setConfigurable(TO_BOOLEAN(obj.configurable));
+  }
+
+  if ("value" in obj) {
+    desc.setValue(obj.value);
+  }
+
+  if ("writable" in obj) {
+    desc.setWritable(TO_BOOLEAN(obj.writable));
+  }
+
+  if ("get" in obj) {
+    var get = obj.get;
+    if (!IS_UNDEFINED(get) && !IS_CALLABLE(get)) {
+      throw MakeTypeError(kObjectGetterCallable, get);
+    }
+    desc.setGet(get);
+  }
+
+  if ("set" in obj) {
+    var set = obj.set;
+    if (!IS_UNDEFINED(set) && !IS_CALLABLE(set)) {
+      throw MakeTypeError(kObjectSetterCallable, set);
+    }
+    desc.setSet(set);
+  }
+
+  if (IsInconsistentDescriptor(desc)) {
+    throw MakeTypeError(kValueAndAccessor, obj);
+  }
+  return desc;
+}
+
+// TODO(cbruni): remove once callers have been removed
+function ToCompletePropertyDescriptor(obj) {
+  var desc = ToPropertyDescriptor(obj);
+  if (IsGenericDescriptor(desc) || IsDataDescriptor(desc)) {
+    if (!desc.hasValue()) desc.setValue(UNDEFINED);
+    if (!desc.hasWritable()) desc.setWritable(false);
+  } else {
+    // Is accessor descriptor.
+    if (!desc.hasGetter()) desc.setGet(UNDEFINED);
+    if (!desc.hasSetter()) desc.setSet(UNDEFINED);
+  }
+  if (!desc.hasEnumerable()) desc.setEnumerable(false);
+  if (!desc.hasConfigurable()) desc.setConfigurable(false);
+  return desc;
+}
+
+
+function PropertyDescriptor() {
+  // Initialize here so they are all in-object and have the same map.
+  // Default values from ES5 8.6.1.
+  this.value_ = UNDEFINED;
+  this.hasValue_ = false;
+  this.writable_ = false;
+  this.hasWritable_ = false;
+  this.enumerable_ = false;
+  this.hasEnumerable_ = false;
+  this.configurable_ = false;
+  this.hasConfigurable_ = false;
+  this.get_ = UNDEFINED;
+  this.hasGetter_ = false;
+  this.set_ = UNDEFINED;
+  this.hasSetter_ = false;
+}
+
+utils.SetUpLockedPrototype(PropertyDescriptor, [
+  "value_",
+  "hasValue_",
+  "writable_",
+  "hasWritable_",
+  "enumerable_",
+  "hasEnumerable_",
+  "configurable_",
+  "hasConfigurable_",
+  "get_",
+  "hasGetter_",
+  "set_",
+  "hasSetter_"
+], [
+  "toString", function PropertyDescriptor_ToString() {
+    return "[object PropertyDescriptor]";
+  },
+  "setValue", function PropertyDescriptor_SetValue(value) {
+    this.value_ = value;
+    this.hasValue_ = true;
+  },
+  "getValue", function PropertyDescriptor_GetValue() {
+    return this.value_;
+  },
+  "hasValue", function PropertyDescriptor_HasValue() {
+    return this.hasValue_;
+  },
+  "setEnumerable", function PropertyDescriptor_SetEnumerable(enumerable) {
+    this.enumerable_ = enumerable;
+      this.hasEnumerable_ = true;
+  },
+  "isEnumerable", function PropertyDescriptor_IsEnumerable() {
+    return this.enumerable_;
+  },
+  "hasEnumerable", function PropertyDescriptor_HasEnumerable() {
+    return this.hasEnumerable_;
+  },
+  "setWritable", function PropertyDescriptor_SetWritable(writable) {
+    this.writable_ = writable;
+    this.hasWritable_ = true;
+  },
+  "isWritable", function PropertyDescriptor_IsWritable() {
+    return this.writable_;
+  },
+  "hasWritable", function PropertyDescriptor_HasWritable() {
+    return this.hasWritable_;
+  },
+  "setConfigurable",
+  function PropertyDescriptor_SetConfigurable(configurable) {
+    this.configurable_ = configurable;
+    this.hasConfigurable_ = true;
+  },
+  "hasConfigurable", function PropertyDescriptor_HasConfigurable() {
+    return this.hasConfigurable_;
+  },
+  "isConfigurable", function PropertyDescriptor_IsConfigurable() {
+    return this.configurable_;
+  },
+  "setGet", function PropertyDescriptor_SetGetter(get) {
+    this.get_ = get;
+    this.hasGetter_ = true;
+  },
+  "getGet", function PropertyDescriptor_GetGetter() {
+    return this.get_;
+  },
+  "hasGetter", function PropertyDescriptor_HasGetter() {
+    return this.hasGetter_;
+  },
+  "setSet", function PropertyDescriptor_SetSetter(set) {
+    this.set_ = set;
+    this.hasSetter_ = true;
+  },
+  "getSet", function PropertyDescriptor_GetSetter() {
+    return this.set_;
+  },
+  "hasSetter", function PropertyDescriptor_HasSetter() {
+    return this.hasSetter_;
+  }
+]);
+
+
+// Converts an array returned from Runtime_GetOwnProperty to an actual
+// property descriptor. For a description of the array layout please
+// see the runtime.cc file.
+function ConvertDescriptorArrayToDescriptor(desc_array) {
+  if (IS_UNDEFINED(desc_array)) {
+    return UNDEFINED;
+  }
+
+  var desc = new PropertyDescriptor();
+  // This is an accessor.
+  if (desc_array[IS_ACCESSOR_INDEX]) {
+    desc.setGet(desc_array[GETTER_INDEX]);
+    desc.setSet(desc_array[SETTER_INDEX]);
+  } else {
+    desc.setValue(desc_array[VALUE_INDEX]);
+    desc.setWritable(desc_array[WRITABLE_INDEX]);
+  }
+  desc.setEnumerable(desc_array[ENUMERABLE_INDEX]);
+  desc.setConfigurable(desc_array[CONFIGURABLE_INDEX]);
+
+  return desc;
+}
+
+
+// For Harmony proxies.
+function GetTrap(handler, name, defaultTrap) {
+  var trap = handler[name];
+  if (IS_UNDEFINED(trap)) {
+    if (IS_UNDEFINED(defaultTrap)) {
+      throw MakeTypeError(kIllegalInvocation);
+    }
+    trap = defaultTrap;
+  } else if (!IS_CALLABLE(trap)) {
+    throw MakeTypeError(kIllegalInvocation);
+  }
+  return trap;
+}
+
+
+function CallTrap1(handler, name, defaultTrap, x) {
+  return %_Call(GetTrap(handler, name, defaultTrap), handler, x);
+}
+
+
+function CallTrap2(handler, name, defaultTrap, x, y) {
+  return %_Call(GetTrap(handler, name, defaultTrap), handler, x, y);
+}
+
+
+// ES5 section 8.12.1.
+// TODO(jkummerow): Deprecated. Migrate all callers to
+// ObjectGetOwnPropertyDescriptor and delete this.
+function GetOwnPropertyJS(obj, v) {
+  var p = TO_NAME(v);
+  if (IS_PROXY(obj)) {
+    // TODO(rossberg): adjust once there is a story for symbols vs proxies.
+    if (IS_SYMBOL(v)) return UNDEFINED;
+
+    var handler = %JSProxyGetHandler(obj);
+    var descriptor = CallTrap1(
+                         handler, "getOwnPropertyDescriptor", UNDEFINED, p);
+    if (IS_UNDEFINED(descriptor)) return descriptor;
+    var desc = ToCompletePropertyDescriptor(descriptor);
+    if (!desc.isConfigurable()) {
+      throw MakeTypeError(kIllegalInvocation);
+    }
+    return desc;
+  }
+
+  // GetOwnProperty returns an array indexed by the constants
+  // defined in macros.py.
+  // If p is not a property on obj undefined is returned.
+  var props = %GetOwnProperty_Legacy(TO_OBJECT(obj), p);
+
+  return ConvertDescriptorArrayToDescriptor(props);
+}
+
+
+// ES6 7.3.9
+function GetMethod(obj, p) {
+  var func = obj[p];
+  if (IS_NULL_OR_UNDEFINED(func)) return UNDEFINED;
+  if (IS_CALLABLE(func)) return func;
+  throw MakeTypeError(kCalledNonCallable, typeof func);
+}
+
+
+// Harmony proxies.
+function DefineProxyProperty(obj, p, attributes, should_throw) {
+  // TODO(rossberg): adjust once there is a story for symbols vs proxies.
+  if (IS_SYMBOL(p)) return false;
+
+  var handler = %JSProxyGetHandler(obj);
+  var result = CallTrap2(handler, "defineProperty", UNDEFINED, p, attributes);
+  if (!result) {
+    if (should_throw) {
+      throw MakeTypeError(kIllegalInvocation);
+    } else {
+      return false;
+    }
+  }
+  return true;
+}
+
+
+// ES6 9.1.6 [[DefineOwnProperty]](P, Desc)
+function DefineObjectProperty(obj, p, desc, should_throw) {
+  var current_array = %GetOwnProperty_Legacy(obj, TO_NAME(p));
+  var current = ConvertDescriptorArrayToDescriptor(current_array);
+  var extensible = %object_is_extensible(obj);
+
+  if (IS_UNDEFINED(current) && !extensible) {
+    if (should_throw) {
+      throw MakeTypeError(kDefineDisallowed, p);
+    } else {
+      return false;
+    }
+  }
+
+  if (!IS_UNDEFINED(current)) {
+    if ((IsGenericDescriptor(desc) ||
+         IsDataDescriptor(desc) == IsDataDescriptor(current)) &&
+        (!desc.hasEnumerable() ||
+         SameValue(desc.isEnumerable(), current.isEnumerable())) &&
+        (!desc.hasConfigurable() ||
+         SameValue(desc.isConfigurable(), current.isConfigurable())) &&
+        (!desc.hasWritable() ||
+         SameValue(desc.isWritable(), current.isWritable())) &&
+        (!desc.hasValue() ||
+         SameValue(desc.getValue(), current.getValue())) &&
+        (!desc.hasGetter() ||
+         SameValue(desc.getGet(), current.getGet())) &&
+        (!desc.hasSetter() ||
+         SameValue(desc.getSet(), current.getSet()))) {
+      return true;
+    }
+    if (!current.isConfigurable()) {
+      // Step 7
+      if (desc.isConfigurable() ||
+          (desc.hasEnumerable() &&
+           desc.isEnumerable() != current.isEnumerable())) {
+        if (should_throw) {
+          throw MakeTypeError(kRedefineDisallowed, p);
+        } else {
+          return false;
+        }
+      }
+      // Step 8
+      if (!IsGenericDescriptor(desc)) {
+        // Step 9a
+        if (IsDataDescriptor(current) != IsDataDescriptor(desc)) {
+          if (should_throw) {
+            throw MakeTypeError(kRedefineDisallowed, p);
+          } else {
+            return false;
+          }
+        }
+        // Step 10a
+        if (IsDataDescriptor(current) && IsDataDescriptor(desc)) {
+          var currentIsWritable = current.isWritable();
+          if (currentIsWritable != desc.isWritable()) {
+            if (!currentIsWritable || IS_STRONG(obj)) {
+              if (should_throw) {
+                throw currentIsWritable
+                    ? MakeTypeError(kStrongRedefineDisallowed, obj, p)
+                    : MakeTypeError(kRedefineDisallowed, p);
+              } else {
+                return false;
+              }
+            }
+          }
+          if (!currentIsWritable && desc.hasValue() &&
+              !SameValue(desc.getValue(), current.getValue())) {
+            if (should_throw) {
+              throw MakeTypeError(kRedefineDisallowed, p);
+            } else {
+              return false;
+            }
+          }
+        }
+        // Step 11
+        if (IsAccessorDescriptor(desc) && IsAccessorDescriptor(current)) {
+          if (desc.hasSetter() &&
+              !SameValue(desc.getSet(), current.getSet())) {
+            if (should_throw) {
+              throw MakeTypeError(kRedefineDisallowed, p);
+            } else {
+              return false;
+            }
+          }
+          if (desc.hasGetter() && !SameValue(desc.getGet(),current.getGet())) {
+            if (should_throw) {
+              throw MakeTypeError(kRedefineDisallowed, p);
+            } else {
+              return false;
+            }
+          }
+        }
+      }
+    }
+  }
+
+  // Send flags - enumerable and configurable are common - writable is
+  // only send to the data descriptor.
+  // Take special care if enumerable and configurable is not defined on
+  // desc (we need to preserve the existing values from current).
+  var flag = NONE;
+  if (desc.hasEnumerable()) {
+    flag |= desc.isEnumerable() ? 0 : DONT_ENUM;
+  } else if (!IS_UNDEFINED(current)) {
+    flag |= current.isEnumerable() ? 0 : DONT_ENUM;
+  } else {
+    flag |= DONT_ENUM;
+  }
+
+  if (desc.hasConfigurable()) {
+    flag |= desc.isConfigurable() ? 0 : DONT_DELETE;
+  } else if (!IS_UNDEFINED(current)) {
+    flag |= current.isConfigurable() ? 0 : DONT_DELETE;
+  } else
+    flag |= DONT_DELETE;
+
+  if (IsDataDescriptor(desc) ||
+      (IsGenericDescriptor(desc) &&
+       (IS_UNDEFINED(current) || IsDataDescriptor(current)))) {
+    // There are 3 cases that lead here:
+    // Step 4a - defining a new data property.
+    // Steps 9b & 12 - replacing an existing accessor property with a data
+    //                 property.
+    // Step 12 - updating an existing data property with a data or generic
+    //           descriptor.
+
+    if (desc.hasWritable()) {
+      flag |= desc.isWritable() ? 0 : READ_ONLY;
+    } else if (!IS_UNDEFINED(current)) {
+      flag |= current.isWritable() ? 0 : READ_ONLY;
+    } else {
+      flag |= READ_ONLY;
+    }
+
+    var value = UNDEFINED;  // Default value is undefined.
+    if (desc.hasValue()) {
+      value = desc.getValue();
+    } else if (!IS_UNDEFINED(current) && IsDataDescriptor(current)) {
+      value = current.getValue();
+    }
+
+    %DefineDataPropertyUnchecked(obj, p, value, flag);
+  } else {
+    // There are 3 cases that lead here:
+    // Step 4b - defining a new accessor property.
+    // Steps 9c & 12 - replacing an existing data property with an accessor
+    //                 property.
+    // Step 12 - updating an existing accessor property with an accessor
+    //           descriptor.
+    var getter = null;
+    if (desc.hasGetter()) {
+      getter = desc.getGet();
+    } else if (IsAccessorDescriptor(current) && current.hasGetter()) {
+      getter = current.getGet();
+    }
+    var setter = null;
+    if (desc.hasSetter()) {
+      setter = desc.getSet();
+    } else if (IsAccessorDescriptor(current) && current.hasSetter()) {
+      setter = current.getSet();
+    }
+    %DefineAccessorPropertyUnchecked(obj, p, getter, setter, flag);
+  }
+  return true;
+}
+
+
+// ES5 section 15.4.5.1.
+function DefineArrayProperty(obj, p, desc, should_throw) {
+  // Step 3 - Special handling for array index.
+  if (!IS_SYMBOL(p)) {
+    var index = TO_UINT32(p);
+    var emit_splice = false;
+    if (TO_STRING(index) == p && index != 4294967295) {
+      var length = obj.length;
+      if (index >= length && %IsObserved(obj)) {
+        emit_splice = true;
+        ObserveBeginPerformSplice(obj);
+      }
+
+      var length_desc = GetOwnPropertyJS(obj, "length");
+      if ((index >= length && !length_desc.isWritable()) ||
+          !DefineObjectProperty(obj, p, desc, true)) {
+        if (emit_splice)
+          ObserveEndPerformSplice(obj);
+        if (should_throw) {
+          throw MakeTypeError(kDefineDisallowed, p);
+        } else {
+          return false;
+        }
+      }
+      if (index >= length) {
+        obj.length = index + 1;
+      }
+      if (emit_splice) {
+        ObserveEndPerformSplice(obj);
+        ObserveEnqueueSpliceRecord(obj, length, [], index + 1 - length);
+      }
+      return true;
+    }
+  }
+
+  // Step 5 - Fallback to default implementation.
+  return DefineObjectProperty(obj, p, desc, should_throw);
+}
+
+
+// ES5 section 8.12.9, ES5 section 15.4.5.1 and Harmony proxies.
+function DefineOwnProperty(obj, p, desc, should_throw) {
+  if (IS_PROXY(obj)) {
+    // TODO(rossberg): adjust once there is a story for symbols vs proxies.
+    if (IS_SYMBOL(p)) return false;
+
+    var attributes = FromGenericPropertyDescriptor(desc);
+    return DefineProxyProperty(obj, p, attributes, should_throw);
+  } else if (IS_ARRAY(obj)) {
+    return DefineArrayProperty(obj, p, desc, should_throw);
+  } else {
+    return DefineObjectProperty(obj, p, desc, should_throw);
+  }
+}
+
+
+// ES6 section 19.1.2.9
+function ObjectGetPrototypeOf(obj) {
+  return %_GetPrototype(TO_OBJECT(obj));
+}
+
+// ES6 section 19.1.2.18.
+function ObjectSetPrototypeOf(obj, proto) {
+  CHECK_OBJECT_COERCIBLE(obj, "Object.setPrototypeOf");
+
+  if (proto !== null && !IS_RECEIVER(proto)) {
+    throw MakeTypeError(kProtoObjectOrNull, proto);
+  }
+
+  if (IS_RECEIVER(obj)) {
+    %SetPrototype(obj, proto);
+  }
+
+  return obj;
+}
+
+
+// ES6 section 19.1.2.6
+function ObjectGetOwnPropertyDescriptor(obj, p) {
+  return %GetOwnProperty(obj, p);
+}
+
+
+// ES5 section 15.2.3.4.
+function ObjectGetOwnPropertyNames(obj) {
+  obj = TO_OBJECT(obj);
+  return %GetOwnPropertyKeys(obj, PROPERTY_FILTER_SKIP_SYMBOLS);
+}
+
+
+// ES5 section 15.2.3.6.
+function ObjectDefineProperty(obj, p, attributes) {
+  // The new pure-C++ implementation doesn't support O.o.
+  // TODO(jkummerow): Implement missing features and remove fallback path.
+  if (%IsObserved(obj)) {
+    if (!IS_RECEIVER(obj)) {
+      throw MakeTypeError(kCalledOnNonObject, "Object.defineProperty");
+    }
+    var name = TO_NAME(p);
+    var desc = ToPropertyDescriptor(attributes);
+    DefineOwnProperty(obj, name, desc, true);
+    return obj;
+  }
+  return %ObjectDefineProperty(obj, p, attributes);
+}
+
+
+function GetOwnEnumerablePropertyNames(object) {
+  return %GetOwnPropertyKeys(object, PROPERTY_FILTER_ONLY_ENUMERABLE);
+}
+
+
+// ES5 section 15.2.3.7.
+function ObjectDefineProperties(obj, properties) {
+  // The new pure-C++ implementation doesn't support O.o.
+  // TODO(jkummerow): Implement missing features and remove fallback path.
+  if (%IsObserved(obj)) {
+    if (!IS_RECEIVER(obj)) {
+      throw MakeTypeError(kCalledOnNonObject, "Object.defineProperties");
+    }
+    var props = TO_OBJECT(properties);
+    var names = GetOwnEnumerablePropertyNames(props);
+    var descriptors = new InternalArray();
+    for (var i = 0; i < names.length; i++) {
+      descriptors.push(ToPropertyDescriptor(props[names[i]]));
+    }
+    for (var i = 0; i < names.length; i++) {
+      DefineOwnProperty(obj, names[i], descriptors[i], true);
+    }
+    return obj;
+  }
+  return %ObjectDefineProperties(obj, properties);
+}
+
+
+// ES6 B.2.2.1.1
+function ObjectGetProto() {
+  return %_GetPrototype(TO_OBJECT(this));
+}
+
+
+// ES6 B.2.2.1.2
+function ObjectSetProto(proto) {
+  CHECK_OBJECT_COERCIBLE(this, "Object.prototype.__proto__");
+
+  if ((IS_RECEIVER(proto) || IS_NULL(proto)) && IS_RECEIVER(this)) {
+    %SetPrototype(this, proto);
+  }
+}
+
+
+// ES6 19.1.1.1
+function ObjectConstructor(x) {
+  if (GlobalObject != new.target && !IS_UNDEFINED(new.target)) {
+    return this;
+  }
+  if (IS_NULL(x) || IS_UNDEFINED(x)) return {};
+  return TO_OBJECT(x);
+}
+
+
+// ----------------------------------------------------------------------------
+// Object
+
+%SetNativeFlag(GlobalObject);
+%SetCode(GlobalObject, ObjectConstructor);
+
+%AddNamedProperty(GlobalObject.prototype, "constructor", GlobalObject,
+                  DONT_ENUM);
+
+// Set up non-enumerable functions on the Object.prototype object.
+utils.InstallFunctions(GlobalObject.prototype, DONT_ENUM, [
+  "toString", ObjectToString,
+  "toLocaleString", ObjectToLocaleString,
+  "valueOf", ObjectValueOf,
+  "hasOwnProperty", ObjectHasOwnProperty,
+  "isPrototypeOf", ObjectIsPrototypeOf,
+  "propertyIsEnumerable", ObjectPropertyIsEnumerable,
+  "__defineGetter__", ObjectDefineGetter,
+  "__lookupGetter__", ObjectLookupGetter,
+  "__defineSetter__", ObjectDefineSetter,
+  "__lookupSetter__", ObjectLookupSetter
+]);
+utils.InstallGetterSetter(GlobalObject.prototype, "__proto__", ObjectGetProto,
+                    ObjectSetProto);
+
+// Set up non-enumerable functions in the Object object.
+utils.InstallFunctions(GlobalObject, DONT_ENUM, [
+  // assign is added in bootstrapper.cc.
+  // keys is added in bootstrapper.cc.
+  "defineProperty", ObjectDefineProperty,
+  "defineProperties", ObjectDefineProperties,
+  "getPrototypeOf", ObjectGetPrototypeOf,
+  "setPrototypeOf", ObjectSetPrototypeOf,
+  "getOwnPropertyDescriptor", ObjectGetOwnPropertyDescriptor,
+  "getOwnPropertyNames", ObjectGetOwnPropertyNames,
+  // getOwnPropertySymbols is added in symbol.js.
+  "is", SameValue,  // ECMA-262, Edition 6, section 19.1.2.10
+  // deliverChangeRecords, getNotifier, observe and unobserve are added
+  // in object-observe.js.
+]);
+
+
+// ----------------------------------------------------------------------------
+// Boolean
+
+function BooleanConstructor(x) {
+  // TODO(bmeurer): Move this to toplevel.
+  "use strict";
+  if (!IS_UNDEFINED(new.target)) {
+    %_SetValueOf(this, TO_BOOLEAN(x));
+  } else {
+    return TO_BOOLEAN(x);
+  }
+}
+
+
+function BooleanToString() {
+  // NOTE: Both Boolean objects and values can enter here as
+  // 'this'. This is not as dictated by ECMA-262.
+  var b = this;
+  if (!IS_BOOLEAN(b)) {
+    if (!IS_BOOLEAN_WRAPPER(b)) {
+      throw MakeTypeError(kNotGeneric, 'Boolean.prototype.toString');
+    }
+    b = %_ValueOf(b);
+  }
+  return b ? 'true' : 'false';
+}
+
+
+function BooleanValueOf() {
+  // NOTE: Both Boolean objects and values can enter here as
+  // 'this'. This is not as dictated by ECMA-262.
+  if (!IS_BOOLEAN(this) && !IS_BOOLEAN_WRAPPER(this)) {
+    throw MakeTypeError(kNotGeneric, 'Boolean.prototype.valueOf');
+  }
+  return %_ValueOf(this);
+}
+
+
+// ----------------------------------------------------------------------------
+
+%SetCode(GlobalBoolean, BooleanConstructor);
+%FunctionSetPrototype(GlobalBoolean, new GlobalBoolean(false));
+%AddNamedProperty(GlobalBoolean.prototype, "constructor", GlobalBoolean,
+                  DONT_ENUM);
+
+utils.InstallFunctions(GlobalBoolean.prototype, DONT_ENUM, [
+  "toString", BooleanToString,
+  "valueOf", BooleanValueOf
+]);
+
+
+// ----------------------------------------------------------------------------
+// Number
+
+// ES6 Number.prototype.toString([ radix ])
+function NumberToStringJS(radix) {
+  // NOTE: Both Number objects and values can enter here as
+  // 'this'. This is not as dictated by ECMA-262.
+  var number = this;
+  if (!IS_NUMBER(this)) {
+    if (!IS_NUMBER_WRAPPER(this)) {
+      throw MakeTypeError(kNotGeneric, 'Number.prototype.toString');
+    }
+    // Get the value of this number in case it's an object.
+    number = %_ValueOf(this);
+  }
+  // Fast case: Convert number in radix 10.
+  if (IS_UNDEFINED(radix) || radix === 10) {
+    return %_NumberToString(number);
+  }
+
+  // Convert the radix to an integer and check the range.
+  radix = TO_INTEGER(radix);
+  if (radix < 2 || radix > 36) throw MakeRangeError(kToRadixFormatRange);
+  // Convert the number to a string in the given radix.
+  return %NumberToRadixString(number, radix);
+}
+
+
+// ES6 20.1.3.4 Number.prototype.toLocaleString([reserved1 [, reserved2]])
+function NumberToLocaleString() {
+  return %_Call(NumberToStringJS, this);
+}
+
+
+// ES6 20.1.3.7 Number.prototype.valueOf()
+function NumberValueOf() {
+  // NOTE: Both Number objects and values can enter here as
+  // 'this'. This is not as dictated by ECMA-262.
+  if (!IS_NUMBER(this) && !IS_NUMBER_WRAPPER(this)) {
+    throw MakeTypeError(kNotGeneric, 'Number.prototype.valueOf');
+  }
+  return %_ValueOf(this);
+}
+
+
+// ES6 20.1.3.3 Number.prototype.toFixed(fractionDigits)
+function NumberToFixedJS(fractionDigits) {
+  var x = this;
+  if (!IS_NUMBER(this)) {
+    if (!IS_NUMBER_WRAPPER(this)) {
+      throw MakeTypeError(kIncompatibleMethodReceiver,
+                          "Number.prototype.toFixed", this);
+    }
+    // Get the value of this number in case it's an object.
+    x = %_ValueOf(this);
+  }
+  var f = TO_INTEGER(fractionDigits);
+
+  if (f < 0 || f > 20) {
+    throw MakeRangeError(kNumberFormatRange, "toFixed() digits");
+  }
+
+  if (NUMBER_IS_NAN(x)) return "NaN";
+  if (x == INFINITY) return "Infinity";
+  if (x == -INFINITY) return "-Infinity";
+
+  return %NumberToFixed(x, f);
+}
+
+
+// ES6 20.1.3.2 Number.prototype.toExponential(fractionDigits)
+function NumberToExponentialJS(fractionDigits) {
+  var x = this;
+  if (!IS_NUMBER(this)) {
+    if (!IS_NUMBER_WRAPPER(this)) {
+      throw MakeTypeError(kIncompatibleMethodReceiver,
+                          "Number.prototype.toExponential", this);
+    }
+    // Get the value of this number in case it's an object.
+    x = %_ValueOf(this);
+  }
+  var f = IS_UNDEFINED(fractionDigits) ? UNDEFINED : TO_INTEGER(fractionDigits);
+
+  if (NUMBER_IS_NAN(x)) return "NaN";
+  if (x == INFINITY) return "Infinity";
+  if (x == -INFINITY) return "-Infinity";
+
+  if (IS_UNDEFINED(f)) {
+    f = -1;  // Signal for runtime function that f is not defined.
+  } else if (f < 0 || f > 20) {
+    throw MakeRangeError(kNumberFormatRange, "toExponential()");
+  }
+  return %NumberToExponential(x, f);
+}
+
+
+// ES6 20.1.3.5 Number.prototype.toPrecision(precision)
+function NumberToPrecisionJS(precision) {
+  var x = this;
+  if (!IS_NUMBER(this)) {
+    if (!IS_NUMBER_WRAPPER(this)) {
+      throw MakeTypeError(kIncompatibleMethodReceiver,
+                          "Number.prototype.toPrecision", this);
+    }
+    // Get the value of this number in case it's an object.
+    x = %_ValueOf(this);
+  }
+  if (IS_UNDEFINED(precision)) return TO_STRING(x);
+  var p = TO_INTEGER(precision);
+
+  if (NUMBER_IS_NAN(x)) return "NaN";
+  if (x == INFINITY) return "Infinity";
+  if (x == -INFINITY) return "-Infinity";
+
+  if (p < 1 || p > 21) {
+    throw MakeRangeError(kToPrecisionFormatRange);
+  }
+  return %NumberToPrecision(x, p);
+}
+
+
+// Harmony isFinite.
+function NumberIsFinite(number) {
+  return IS_NUMBER(number) && NUMBER_IS_FINITE(number);
+}
+
+
+// Harmony isInteger
+function NumberIsInteger(number) {
+  return NumberIsFinite(number) && TO_INTEGER(number) == number;
+}
+
+
+// Harmony isNaN.
+function NumberIsNaN(number) {
+  return IS_NUMBER(number) && NUMBER_IS_NAN(number);
+}
+
+
+// Harmony isSafeInteger
+function NumberIsSafeInteger(number) {
+  if (NumberIsFinite(number)) {
+    var integral = TO_INTEGER(number);
+    if (integral == number) {
+      return MathAbs(integral) <= kMaxSafeInteger;
+    }
+  }
+  return false;
+}
+
+
+// ----------------------------------------------------------------------------
+
+%FunctionSetPrototype(GlobalNumber, new GlobalNumber(0));
+
+%OptimizeObjectForAddingMultipleProperties(GlobalNumber.prototype, 8);
+// Set up the constructor property on the Number prototype object.
+%AddNamedProperty(GlobalNumber.prototype, "constructor", GlobalNumber,
+                  DONT_ENUM);
+
+utils.InstallConstants(GlobalNumber, [
+  // ECMA-262 section 15.7.3.1.
+  "MAX_VALUE", 1.7976931348623157e+308,
+  // ECMA-262 section 15.7.3.2.
+  "MIN_VALUE", 5e-324,
+  // ECMA-262 section 15.7.3.3.
+  "NaN", NaN,
+  // ECMA-262 section 15.7.3.4.
+  "NEGATIVE_INFINITY", -INFINITY,
+  // ECMA-262 section 15.7.3.5.
+  "POSITIVE_INFINITY", INFINITY,
+
+  // --- Harmony constants (no spec refs until settled.)
+
+  "MAX_SAFE_INTEGER", %_MathPow(2, 53) - 1,
+  "MIN_SAFE_INTEGER", -%_MathPow(2, 53) + 1,
+  "EPSILON", %_MathPow(2, -52)
+]);
+
+// Set up non-enumerable functions on the Number prototype object.
+utils.InstallFunctions(GlobalNumber.prototype, DONT_ENUM, [
+  "toString", NumberToStringJS,
+  "toLocaleString", NumberToLocaleString,
+  "valueOf", NumberValueOf,
+  "toFixed", NumberToFixedJS,
+  "toExponential", NumberToExponentialJS,
+  "toPrecision", NumberToPrecisionJS
+]);
+
+// Harmony Number constructor additions
+utils.InstallFunctions(GlobalNumber, DONT_ENUM, [
+  "isFinite", NumberIsFinite,
+  "isInteger", NumberIsInteger,
+  "isNaN", NumberIsNaN,
+  "isSafeInteger", NumberIsSafeInteger,
+  "parseInt", GlobalParseInt,
+  "parseFloat", GlobalParseFloat
+]);
+
+%SetForceInlineFlag(NumberIsNaN);
+
+
+// ----------------------------------------------------------------------------
+// Iterator related spec functions.
+
+// ES6 7.4.1 GetIterator(obj, method)
+function GetIterator(obj, method) {
+  if (IS_UNDEFINED(method)) {
+    method = obj[iteratorSymbol];
+  }
+  if (!IS_CALLABLE(method)) {
+    throw MakeTypeError(kNotIterable, obj);
+  }
+  var iterator = %_Call(method, obj);
+  if (!IS_RECEIVER(iterator)) {
+    throw MakeTypeError(kNotAnIterator, iterator);
+  }
+  return iterator;
+}
+
+// ----------------------------------------------------------------------------
+// Exports
+
+utils.Export(function(to) {
+  to.GetIterator = GetIterator;
+  to.GetMethod = GetMethod;
+  to.IsFinite = GlobalIsFinite;
+  to.IsNaN = GlobalIsNaN;
+  to.NumberIsNaN = NumberIsNaN;
+  to.ObjectDefineProperties = ObjectDefineProperties;
+  to.ObjectDefineProperty = ObjectDefineProperty;
+  to.ObjectHasOwnProperty = ObjectHasOwnProperty;
+});
+
+%InstallToContext([
+  "object_value_of", ObjectValueOf,
+]);
+
+})
diff --git a/src/js/weak-collection.js b/src/js/weak-collection.js
new file mode 100644
index 0000000..308b9ed
--- /dev/null
+++ b/src/js/weak-collection.js
@@ -0,0 +1,190 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function(global, utils) {
+
+"use strict";
+
+%CheckIsBootstrapping();
+
+// -------------------------------------------------------------------
+// Imports
+
+var GetExistingHash;
+var GetHash;
+var GlobalObject = global.Object;
+var GlobalWeakMap = global.WeakMap;
+var GlobalWeakSet = global.WeakSet;
+var MakeTypeError;
+var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
+
+utils.Import(function(from) {
+  GetExistingHash = from.GetExistingHash;
+  GetHash = from.GetHash;
+  MakeTypeError = from.MakeTypeError;
+});
+
+// -------------------------------------------------------------------
+// Harmony WeakMap
+
+function WeakMapConstructor(iterable) {
+  if (IS_UNDEFINED(new.target)) {
+    throw MakeTypeError(kConstructorNotFunction, "WeakMap");
+  }
+
+  %WeakCollectionInitialize(this);
+
+  if (!IS_NULL_OR_UNDEFINED(iterable)) {
+    var adder = this.set;
+    if (!IS_CALLABLE(adder)) {
+      throw MakeTypeError(kPropertyNotFunction, adder, 'set', this);
+    }
+    for (var nextItem of iterable) {
+      if (!IS_RECEIVER(nextItem)) {
+        throw MakeTypeError(kIteratorValueNotAnObject, nextItem);
+      }
+      %_Call(adder, this, nextItem[0], nextItem[1]);
+    }
+  }
+}
+
+
+function WeakMapGet(key) {
+  if (!IS_WEAKMAP(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        'WeakMap.prototype.get', this);
+  }
+  if (!IS_RECEIVER(key)) return UNDEFINED;
+  var hash = GetExistingHash(key);
+  if (IS_UNDEFINED(hash)) return UNDEFINED;
+  return %WeakCollectionGet(this, key, hash);
+}
+
+
+function WeakMapSet(key, value) {
+  if (!IS_WEAKMAP(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        'WeakMap.prototype.set', this);
+  }
+  if (!IS_RECEIVER(key)) throw MakeTypeError(kInvalidWeakMapKey);
+  return %WeakCollectionSet(this, key, value, GetHash(key));
+}
+
+
+function WeakMapHas(key) {
+  if (!IS_WEAKMAP(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        'WeakMap.prototype.has', this);
+  }
+  if (!IS_RECEIVER(key)) return false;
+  var hash = GetExistingHash(key);
+  if (IS_UNDEFINED(hash)) return false;
+  return %WeakCollectionHas(this, key, hash);
+}
+
+
+function WeakMapDelete(key) {
+  if (!IS_WEAKMAP(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        'WeakMap.prototype.delete', this);
+  }
+  if (!IS_RECEIVER(key)) return false;
+  var hash = GetExistingHash(key);
+  if (IS_UNDEFINED(hash)) return false;
+  return %WeakCollectionDelete(this, key, hash);
+}
+
+
+// -------------------------------------------------------------------
+
+%SetCode(GlobalWeakMap, WeakMapConstructor);
+%FunctionSetLength(GlobalWeakMap, 0);
+%FunctionSetPrototype(GlobalWeakMap, new GlobalObject());
+%AddNamedProperty(GlobalWeakMap.prototype, "constructor", GlobalWeakMap,
+                  DONT_ENUM);
+%AddNamedProperty(GlobalWeakMap.prototype, toStringTagSymbol, "WeakMap",
+                  DONT_ENUM | READ_ONLY);
+
+// Set up the non-enumerable functions on the WeakMap prototype object.
+utils.InstallFunctions(GlobalWeakMap.prototype, DONT_ENUM, [
+  "get", WeakMapGet,
+  "set", WeakMapSet,
+  "has", WeakMapHas,
+  "delete", WeakMapDelete
+]);
+
+// -------------------------------------------------------------------
+// Harmony WeakSet
+
+function WeakSetConstructor(iterable) {
+  if (IS_UNDEFINED(new.target)) {
+    throw MakeTypeError(kConstructorNotFunction, "WeakSet");
+  }
+
+  %WeakCollectionInitialize(this);
+
+  if (!IS_NULL_OR_UNDEFINED(iterable)) {
+    var adder = this.add;
+    if (!IS_CALLABLE(adder)) {
+      throw MakeTypeError(kPropertyNotFunction, adder, 'add', this);
+    }
+    for (var value of iterable) {
+      %_Call(adder, this, value);
+    }
+  }
+}
+
+
+function WeakSetAdd(value) {
+  if (!IS_WEAKSET(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        'WeakSet.prototype.add', this);
+  }
+  if (!IS_RECEIVER(value)) throw MakeTypeError(kInvalidWeakSetValue);
+  return %WeakCollectionSet(this, value, true, GetHash(value));
+}
+
+
+function WeakSetHas(value) {
+  if (!IS_WEAKSET(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        'WeakSet.prototype.has', this);
+  }
+  if (!IS_RECEIVER(value)) return false;
+  var hash = GetExistingHash(value);
+  if (IS_UNDEFINED(hash)) return false;
+  return %WeakCollectionHas(this, value, hash);
+}
+
+
+function WeakSetDelete(value) {
+  if (!IS_WEAKSET(this)) {
+    throw MakeTypeError(kIncompatibleMethodReceiver,
+                        'WeakSet.prototype.delete', this);
+  }
+  if (!IS_RECEIVER(value)) return false;
+  var hash = GetExistingHash(value);
+  if (IS_UNDEFINED(hash)) return false;
+  return %WeakCollectionDelete(this, value, hash);
+}
+
+
+// -------------------------------------------------------------------
+
+%SetCode(GlobalWeakSet, WeakSetConstructor);
+%FunctionSetLength(GlobalWeakSet, 0);
+%FunctionSetPrototype(GlobalWeakSet, new GlobalObject());
+%AddNamedProperty(GlobalWeakSet.prototype, "constructor", GlobalWeakSet,
+                 DONT_ENUM);
+%AddNamedProperty(GlobalWeakSet.prototype, toStringTagSymbol, "WeakSet",
+                  DONT_ENUM | READ_ONLY);
+
+// Set up the non-enumerable functions on the WeakSet prototype object.
+utils.InstallFunctions(GlobalWeakSet.prototype, DONT_ENUM, [
+  "add", WeakSetAdd,
+  "has", WeakSetHas,
+  "delete", WeakSetDelete
+]);
+
+})
