// 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 GlobalFunction = global.Function;
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 StringIndexOf;
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;
  StringIndexOf = from.StringIndexOf;
});

// ----------------------------------------------------------------------------


// 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);
}


// ES6 18.2.1 eval(x)
function GlobalEval(x) {
  if (!IS_STRING(x)) return x;

  var global_proxy = %GlobalProxy(GlobalEval);

  var f = %CompileString(x, false);
  if (!IS_FUNCTION(f)) return f;

  return %_Call(f, global_proxy);
}


// ----------------------------------------------------------------------------

// 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,
  "eval", GlobalEval
]);


// ----------------------------------------------------------------------------
// 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_SPEC_OBJECT(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);
}


function ObjectKeys(obj) {
  obj = TO_OBJECT(obj);
  var filter = PROPERTY_FILTER_ONLY_ENUMERABLE | PROPERTY_FILTER_SKIP_SYMBOLS;
  return %GetOwnPropertyKeys(obj, filter);
}


// 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_SPEC_OBJECT(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 (%_IsJSProxy(obj)) {
    // TODO(rossberg): adjust once there is a story for symbols vs proxies.
    if (IS_SYMBOL(v)) return UNDEFINED;

    var handler = %GetHandler(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 = %GetHandler(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 = %IsExtensible(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 (%_IsJSProxy(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_SPEC_OBJECT(proto)) {
    throw MakeTypeError(kProtoObjectOrNull, proto);
  }

  if (IS_SPEC_OBJECT(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.5.
function ObjectCreate(proto, properties) {
  if (!IS_SPEC_OBJECT(proto) && proto !== null) {
    throw MakeTypeError(kProtoObjectOrNull, proto);
  }
  var obj = {};
  %InternalSetPrototype(obj, proto);
  if (!IS_UNDEFINED(properties)) ObjectDefineProperties(obj, properties);
  return obj;
}


// 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_SPEC_OBJECT(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_SPEC_OBJECT(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 19.1.2.17
function ObjectSealJS(obj) {
  if (!IS_SPEC_OBJECT(obj)) return obj;
  return %ObjectSeal(obj);
}


// ES6 19.1.2.5
function ObjectFreezeJS(obj) {
  if (!IS_SPEC_OBJECT(obj)) return obj;
  return %ObjectFreeze(obj);
}


// ES6 19.1.2.15
function ObjectPreventExtension(obj) {
  if (!IS_SPEC_OBJECT(obj)) return obj;
  return %PreventExtensions(obj);
}


// ES6 19.1.2.13
function ObjectIsSealed(obj) {
  if (!IS_SPEC_OBJECT(obj)) return true;
  return %ObjectIsSealed(obj);
}


// ES6 19.1.2.12
function ObjectIsFrozen(obj) {
  if (!IS_SPEC_OBJECT(obj)) return true;
  return %ObjectIsFrozen(obj);
}


// ES6 19.1.2.11
function ObjectIsExtensible(obj) {
  if (!IS_SPEC_OBJECT(obj)) return false;
  return %IsExtensible(obj);
}


// 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_SPEC_OBJECT(proto) || IS_NULL(proto)) && IS_SPEC_OBJECT(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", ObjectKeys,
  "create", ObjectCreate,
  "defineProperty", ObjectDefineProperty,
  "defineProperties", ObjectDefineProperties,
  "freeze", ObjectFreezeJS,
  "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
  "isExtensible", ObjectIsExtensible,
  "isFrozen", ObjectIsFrozen,
  "isSealed", ObjectIsSealed,
  "preventExtensions", ObjectPreventExtension,
  "seal", ObjectSealJS
  // 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

function NumberConstructor(x) {
  // TODO(bmeurer): Move this to toplevel.
  "use strict";
  var value = %_ArgumentsLength() == 0 ? 0 : TO_NUMBER(x);
  if (IS_UNDEFINED(new.target)) return value;

  var result = %NewObject(GlobalNumber, new.target);
  %_SetValueOf(result, value);
  return result;
}


// 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;
}


// ----------------------------------------------------------------------------

%SetCode(GlobalNumber, NumberConstructor);
%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);


// ----------------------------------------------------------------------------
// Function

function NativeCodeFunctionSourceString(func) {
  var name = %FunctionGetName(func);
  if (name) {
    // Mimic what KJS does.
    return 'function ' + name + '() { [native code] }';
  }

  return 'function () { [native code] }';
}

function FunctionSourceString(func) {
  if (!IS_FUNCTION(func)) {
    throw MakeTypeError(kNotGeneric, 'Function.prototype.toString');
  }

  if (%FunctionHidesSource(func)) {
    return NativeCodeFunctionSourceString(func);
  }

  var classSource = %ClassGetSourceCode(func);
  if (IS_STRING(classSource)) {
    return classSource;
  }

  var source = %FunctionGetSourceCode(func);
  if (!IS_STRING(source)) {
    return NativeCodeFunctionSourceString(func);
  }

  if (%FunctionIsArrow(func)) {
    return source;
  }

  var name = %FunctionNameShouldPrintAsAnonymous(func)
      ? 'anonymous'
      : %FunctionGetName(func);

  var isGenerator = %FunctionIsGenerator(func);
  var head = %FunctionIsConciseMethod(func)
      ? (isGenerator ? '*' : '')
      : (isGenerator ? 'function* ' : 'function ');
  return head + name + source;
}


function FunctionToString() {
  return FunctionSourceString(this);
}


// ES5 15.3.4.5
// ES6 9.2.3.2 Function.prototype.bind(thisArg , ...args)
// TODO(cbruni): check again and remove FunctionProxies section further down
function FunctionBind(this_arg) { // Length is 1.
  if (!IS_CALLABLE(this)) throw MakeTypeError(kFunctionBind);

  var boundFunction = function () {
    // Poison .arguments and .caller, but is otherwise not detectable.
    "use strict";
    // This function must not use any object literals (Object, Array, RegExp),
    // since the literals-array is being used to store the bound data.
    if (!IS_UNDEFINED(new.target)) {
      return %NewObjectFromBound(boundFunction);
    }
    var bindings = %BoundFunctionGetBindings(boundFunction);

    var argc = %_ArgumentsLength();
    if (argc == 0) {
      return %Apply(bindings[0], bindings[1], bindings, 2, bindings.length - 2);
    }
    if (bindings.length === 2) {
      return %Apply(bindings[0], bindings[1], arguments, 0, argc);
    }
    var bound_argc = bindings.length - 2;
    var argv = new InternalArray(bound_argc + argc);
    for (var i = 0; i < bound_argc; i++) {
      argv[i] = bindings[i + 2];
    }
    for (var j = 0; j < argc; j++) {
      argv[i++] = %_Arguments(j);
    }
    return %Apply(bindings[0], bindings[1], argv, 0, bound_argc + argc);
  };

  var new_length = 0;
  var old_length = this.length;
  // FunctionProxies might provide a non-UInt32 value. If so, ignore it.
  if ((typeof old_length === "number") &&
      ((old_length >>> 0) === old_length)) {
    var argc = %_ArgumentsLength();
    if (argc > 0) argc--;  // Don't count the thisArg as parameter.
    new_length = old_length - argc;
    if (new_length < 0) new_length = 0;
  }
  // This runtime function finds any remaining arguments on the stack,
  // so we don't pass the arguments object.
  var result = %FunctionBindArguments(boundFunction, this,
                                      this_arg, new_length);

  var name = this.name;
  var bound_name = IS_STRING(name) ? name : "";
  %DefineDataPropertyUnchecked(result, "name", "bound " + bound_name,
                               DONT_ENUM | READ_ONLY);

  // We already have caller and arguments properties on functions,
  // which are non-configurable. It therefore makes no sence to
  // try to redefine these as defined by the spec. The spec says
  // that bind should make these throw a TypeError if get or set
  // is called and make them non-enumerable and non-configurable.
  // To be consistent with our normal functions we leave this as it is.
  // TODO(lrn): Do set these to be thrower.
  return result;
}


function NewFunctionString(args, function_token) {
  var n = args.length;
  var p = '';
  if (n > 1) {
    p = TO_STRING(args[0]);
    for (var i = 1; i < n - 1; i++) {
      p += ',' + TO_STRING(args[i]);
    }
    // If the formal parameters string include ) - an illegal
    // character - it may make the combined function expression
    // compile. We avoid this problem by checking for this early on.
    if (%_Call(StringIndexOf, p, ')') != -1) {
      throw MakeSyntaxError(kParenthesisInArgString);
    }
    // If the formal parameters include an unbalanced block comment, the
    // function must be rejected. Since JavaScript does not allow nested
    // comments we can include a trailing block comment to catch this.
    p += '\n/' + '**/';
  }
  var body = (n > 0) ? TO_STRING(args[n - 1]) : '';
  return '(' + function_token + '(' + p + ') {\n' + body + '\n})';
}


function FunctionConstructor(arg1) {  // length == 1
  var source = NewFunctionString(arguments, 'function');
  var global_proxy = %GlobalProxy(FunctionConstructor);
  // Compile the string in the constructor and not a helper so that errors
  // appear to come from here.
  var func = %_Call(%CompileString(source, true), global_proxy);
  // Set name-should-print-as-anonymous flag on the ShareFunctionInfo and
  // ensure that |func| uses correct initial map from |new.target| if
  // it's available.
  return %CompleteFunctionConstruction(func, GlobalFunction, new.target);
}


// ----------------------------------------------------------------------------

%SetCode(GlobalFunction, FunctionConstructor);
%AddNamedProperty(GlobalFunction.prototype, "constructor", GlobalFunction,
                  DONT_ENUM);

utils.InstallFunctions(GlobalFunction.prototype, DONT_ENUM, [
  "bind", FunctionBind,
  "toString", FunctionToString
]);

// ----------------------------------------------------------------------------
// 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_SPEC_OBJECT(iterator)) {
    throw MakeTypeError(kNotAnIterator, iterator);
  }
  return iterator;
}

// ----------------------------------------------------------------------------
// Exports

utils.Export(function(to) {
  to.FunctionSourceString = FunctionSourceString;
  to.GetIterator = GetIterator;
  to.GetMethod = GetMethod;
  to.IsFinite = GlobalIsFinite;
  to.IsNaN = GlobalIsNaN;
  to.NewFunctionString = NewFunctionString;
  to.NumberIsNaN = NumberIsNaN;
  to.ObjectDefineProperties = ObjectDefineProperties;
  to.ObjectDefineProperty = ObjectDefineProperty;
  to.ObjectFreeze = ObjectFreezeJS;
  to.ObjectHasOwnProperty = ObjectHasOwnProperty;
  to.ObjectIsFrozen = ObjectIsFrozen;
  to.ObjectIsSealed = ObjectIsSealed;
  to.ObjectKeys = ObjectKeys;
});

%InstallToContext([
  "global_eval_fun", GlobalEval,
  "object_value_of", ObjectValueOf,
]);

})
