"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ToImplementation = undefined; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ var _get = require("./get.js"); var _singletons = require("../singletons.js"); var _has = require("./has.js"); var _call = require("./call.js"); var _errors = require("../errors.js"); var _is = require("./is.js"); var _abstract = require("./abstract.js"); var _index = require("../values/index.js"); var _invariant = require("../invariant.js"); var _invariant2 = _interopRequireDefault(_invariant); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function modulo(x, y) { return x < 0 ? x % y + y : x % y; } var ToImplementation = exports.ToImplementation = function () { function ToImplementation() { _classCallCheck(this, ToImplementation); this.ElementConv = { Int8: this.ToInt8.bind(this), Int16: this.ToInt16.bind(this), Int32: this.ToInt32.bind(this), Uint8: this.ToUint8.bind(this), Uint16: this.ToUint16.bind(this), Uint32: this.ToUint32.bind(this), Uint8Clamped: this.ToUint8Clamp.bind(this) }; } _createClass(ToImplementation, [{ key: "ToInt32", // ECMA262 7.1.5 value: function ToInt32(realm, argument) { // 1. Let number be ? ToNumber(argument). var number = this.ToNumber(realm, argument); // 2. If number is NaN, +0, -0, +∞, or -∞, return +0. if (isNaN(number) || number === 0 || !isFinite(number)) return +0; // 3. Let int be the mathematical value that is the same sign as number and whose magnitude is floor(abs(number)). var int = number < 0 ? -Math.floor(Math.abs(number)) : Math.floor(Math.abs(number)); // 4. Let int16bit be int modulo 2^32. var int32bit = modulo(int, Math.pow(2, 32)); // 5. If int32bit ≥ 2^31, return int32bit - 2^32; otherwise return int32bit. return int32bit >= Math.pow(2, 31) ? int32bit - Math.pow(2, 32) : int32bit; } // ECMA262 7.1.6 }, { key: "ToUint32", value: function ToUint32(realm, argument) { // 1. Let number be ? ToNumber(argument). var number = this.ToNumber(realm, argument); // 2. If number is NaN, +0, -0, +∞, or -∞, return +0. if (isNaN(number) || number === 0 || !isFinite(number)) return +0; // 3. Let int be the mathematical value that is the same sign as number and whose magnitude is floor(abs(number)). var int = number < 0 ? -Math.floor(Math.abs(number)) : Math.floor(Math.abs(number)); // 4. Let int16bit be int modulo 2^32. var int32bit = modulo(int, Math.pow(2, 32)); // 5. Return int32bit. return int32bit; } // ECMA262 7.1.7 }, { key: "ToInt16", value: function ToInt16(realm, argument) { // 1. Let number be ? ToNumber(argument). var number = this.ToNumber(realm, argument); // 2. If number is NaN, +0, -0, +∞, or -∞, return +0. if (isNaN(number) || number === 0 || !isFinite(number)) return +0; // 3. Let int be the mathematical value that is the same sign as number and whose magnitude is floor(abs(number)). var int = number < 0 ? -Math.floor(Math.abs(number)) : Math.floor(Math.abs(number)); // 4. Let int16bit be int modulo 2^16. var int16bit = modulo(int, Math.pow(2, 16)); // 5. If int16bit ≥ 2^15, return int16bit - 2^16; otherwise return int16bit. return int16bit >= Math.pow(2, 15) ? int16bit - Math.pow(2, 16) : int16bit; } // ECMA262 7.1.8 }, { key: "ToUint16", value: function ToUint16(realm, argument) { // 1. Let number be ? ToNumber(argument). var number = this.ToNumber(realm, argument); // 2. If number is NaN, +0, -0, +∞, or -∞, return +0. if (isNaN(number) || number === 0 || !isFinite(number)) return +0; // 3. Let int be the mathematical value that is the same sign as number and whose magnitude is floor(abs(number)). var int = number < 0 ? -Math.floor(Math.abs(number)) : Math.floor(Math.abs(number)); // 4. Let int16bit be int modulo 2^16. var int16bit = modulo(int, Math.pow(2, 16)); // 5. Return int16bit. return int16bit; } // ECMA262 7.1.9 }, { key: "ToInt8", value: function ToInt8(realm, argument) { // 1. Let number be ? ToNumber(argument). var number = this.ToNumber(realm, argument); // 2. If number is NaN, +0, -0, +∞, or -∞, return +0. if (isNaN(number) || number === 0 || !isFinite(number)) return +0; // 3. Let int be the mathematical value that is the same sign as number and whose magnitude is floor(abs(number)). var int = number < 0 ? -Math.floor(Math.abs(number)) : Math.floor(Math.abs(number)); // 4. Let int8bit be int modulo 2^8. var int8bit = modulo(int, Math.pow(2, 8)); // 5. If int8bit ≥ 2^7, return int8bit - 2^8; otherwise return int8bit. return int8bit >= Math.pow(2, 7) ? int8bit - Math.pow(2, 8) : int8bit; } // ECMA262 7.1.10 }, { key: "ToUint8", value: function ToUint8(realm, argument) { // 1. Let number be ? ToNumber(argument). var number = this.ToNumber(realm, argument); // 2. If number is NaN, +0, -0, +∞, or -∞, return +0. if (isNaN(number) || number === 0 || !isFinite(number)) return +0; // 3. Let int be the mathematical value that is the same sign as number and whose magnitude is floor(abs(number)). var int = number < 0 ? -Math.floor(Math.abs(number)) : Math.floor(Math.abs(number)); // 4. Let int8bit be int modulo 2^8. var int8bit = modulo(int, Math.pow(2, 8)); // 5. Return int8bit. return int8bit; } // ECMA262 7.1.11 }, { key: "ToUint8Clamp", value: function ToUint8Clamp(realm, argument) { // 1. Let number be ? ToNumber(argument). var number = this.ToNumber(realm, argument); // 2. If number is NaN, return +0. if (isNaN(number)) return +0; // 3. If number ≤ 0, return +0. if (number <= 0) return +0; // 4. If number ≥ 255, return 255. if (number >= 255) return 255; // 5. Let f be floor(number). var f = Math.floor(number); // 6. If f + 0.5 < number, return f + 1. if (f + 0.5 < number) return f + 1; // 7. If number < f + 0.5, return f. if (number < f + 0.5) return f; // 8. If f is odd, return f + 1. if (f % 2 === 1) return f + 1; // 9. Return f. return f; } // ECMA262 19.3.3.1 }, { key: "thisBooleanValue", value: function thisBooleanValue(realm, value) { // 1. If Type(value) is Boolean, return value. if (value instanceof _index.BooleanValue) return value; // 2. If Type(value) is Object and value has a [[BooleanData]] internal slot, then if (value instanceof _index.ObjectValue && value.$BooleanData) { var booleanData = value.$BooleanData.throwIfNotConcreteBoolean(); // a. Assert: value's [[BooleanData]] internal slot is a Boolean value. (0, _invariant2.default)(booleanData instanceof _index.BooleanValue, "expected boolean data internal slot to be a boolean value"); // b. Return the value of value's [[BooleanData]] internal slot. return booleanData; } value.throwIfNotConcrete(); // 3. Throw a TypeError exception. throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError); } // ECMA262 20.1.3 }, { key: "thisNumberValue", value: function thisNumberValue(realm, value) { // 1. If Type(value) is Number, return value. if (value instanceof _index.NumberValue) return value; // 2. If Type(value) is Object and value has a [[NumberData]] internal slot, then if (value instanceof _index.ObjectValue && value.$NumberData) { var numberData = value.$NumberData.throwIfNotConcreteNumber(); // a. Assert: value's [[NumberData]] internal slot is a Number value. (0, _invariant2.default)(numberData instanceof _index.NumberValue, "expected number data internal slot to be a number value"); // b. Return the value of value's [[NumberData]] internal slot. return numberData; } value = value.throwIfNotConcrete(); // 3. Throw a TypeError exception. throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError); } // ECMA262 21.1.3 }, { key: "thisStringValue", value: function thisStringValue(realm, value) { // 1. If Type(value) is String, return value. if (value instanceof _index.StringValue) return value; // 2. If Type(value) is Object and value has a [[StringData]] internal slot, then if (value instanceof _index.ObjectValue && value.$StringData) { var stringData = value.$StringData.throwIfNotConcreteString(); // a. Assert: value's [[StringData]] internal slot is a String value. (0, _invariant2.default)(stringData instanceof _index.StringValue, "expected string data internal slot to be a string value"); // b. Return the value of value's [[StringData]] internal slot. return stringData; } value = value.throwIfNotConcrete(); // 3. Throw a TypeError exception. throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError); } // ECMA262 6.2.4.5 }, { key: "ToPropertyDescriptor", value: function ToPropertyDescriptor(realm, Obj) { Obj = Obj.throwIfNotConcrete(); // 1. If Type(Obj) is not Object, throw a TypeError exception. if (!(Obj instanceof _index.ObjectValue)) { throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError); } // 2. Let desc be a new Property Descriptor that initially has no fields. var desc = {}; // 3. Let hasEnumerable be ? HasProperty(Obj, "enumerable"). var hasEnumerable = (0, _has.HasProperty)(realm, Obj, "enumerable"); // 4. If hasEnumerable is true, then if (hasEnumerable === true) { // a. Let enum be ToBoolean(? Get(Obj, "enumerable")). var enu = this.ToBooleanPartial(realm, (0, _get.Get)(realm, Obj, "enumerable")); // b. Set the [[Enumerable]] field of desc to enum. desc.enumerable = enu === true; } // 5. Let hasConfigurable be ? HasProperty(Obj, "configurable"). var hasConfigurable = (0, _has.HasProperty)(realm, Obj, "configurable"); // 6. If hasConfigurable is true, then if (hasConfigurable === true) { // a. Let conf be ToBoolean(? Get(Obj, "configurable")). var conf = this.ToBooleanPartial(realm, (0, _get.Get)(realm, Obj, "configurable")); // b. Set the [[Configurable]] field of desc to conf. desc.configurable = conf === true; } // 7. Let hasValue be ? HasProperty(Obj, "value"). var hasValue = (0, _has.HasProperty)(realm, Obj, "value"); // 8. If hasValue is true, then if (hasValue === true) { // a. Let value be ? Get(Obj, "value"). var value = (0, _get.Get)(realm, Obj, "value"); // b. Set the [[Value]] field of desc to value. desc.value = value; } // 9. Let hasWritable be ? HasProperty(Obj, "writable"). var hasWritable = (0, _has.HasProperty)(realm, Obj, "writable"); // 10. If hasWritable is true, then if (hasWritable === true) { // a. Let writable be ToBoolean(? Get(Obj, "writable")). var writable = this.ToBooleanPartial(realm, (0, _get.Get)(realm, Obj, "writable")); // b. Set the [[Writable]] field of desc to writable. desc.writable = writable === true; } // 11. Let hasGet be ? HasProperty(Obj, "get"). var hasGet = (0, _has.HasProperty)(realm, Obj, "get"); // 12. If hasGet is true, then if (hasGet === true) { // a. Let getter be ? Get(Obj, "get"). var getter = (0, _get.Get)(realm, Obj, "get"); // b. If IsCallable(getter) is false and getter is not undefined, throw a TypeError exception. if ((0, _is.IsCallable)(realm, getter) === false && !getter.mightBeUndefined()) { throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError); } getter.throwIfNotConcrete(); // c. Set the [[Get]] field of desc to getter. desc.get = getter; } // 13. Let hasSet be ? HasProperty(Obj, "set"). var hasSet = (0, _has.HasProperty)(realm, Obj, "set"); // 14. If hasSet is true, then if (hasSet === true) { // a. Let setter be ? Get(Obj, "set"). var setter = (0, _get.Get)(realm, Obj, "set"); // b. If IsCallable(setter) is false and setter is not undefined, throw a TypeError exception. if ((0, _is.IsCallable)(realm, setter) === false && !setter.mightBeUndefined()) { throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError); } setter.throwIfNotConcrete(); // c. Set the [[Set]] field of desc to setter. desc.set = setter; } // 15. If either desc.[[Get]] or desc.[[Set]] is present, then if (desc.get || desc.set) { // a. If either desc.[[Value]] or desc.[[Writable]] is present, throw a TypeError exception. if ("value" in desc || "writable" in desc) { throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError); } } // 16. Return desc. return desc; } // ECMA262 7.1.13 }, { key: "ToObject", value: function ToObject(realm, arg) { if (arg instanceof _index.UndefinedValue) { throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError); } else if (arg instanceof _index.NullValue) { throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError); } else if (arg instanceof _index.BooleanValue) { var obj = new _index.ObjectValue(realm, realm.intrinsics.BooleanPrototype); obj.$BooleanData = arg; return obj; } else if (arg instanceof _index.NumberValue) { var _obj = new _index.ObjectValue(realm, realm.intrinsics.NumberPrototype); _obj.$NumberData = arg; return _obj; } else if (arg instanceof _index.StringValue) { var _obj2 = _singletons.Create.StringCreate(realm, arg, realm.intrinsics.StringPrototype); return _obj2; } else if (arg instanceof _index.SymbolValue) { var _obj3 = new _index.ObjectValue(realm, realm.intrinsics.SymbolPrototype); _obj3.$SymbolData = arg; return _obj3; } else if (arg instanceof _index.ObjectValue) { return arg; } (0, _invariant2.default)(false); } }, { key: "_WrapAbstractInObject", value: function _WrapAbstractInObject(realm, arg) { var obj = void 0; switch (arg.types.getType()) { case _index.NumberValue: obj = new _index.ObjectValue(realm, realm.intrinsics.NumberPrototype); obj.$NumberData = arg; break; case _index.StringValue: obj = new _index.ObjectValue(realm, realm.intrinsics.StringPrototype); obj.$StringData = arg; break; case _index.BooleanValue: obj = new _index.ObjectValue(realm, realm.intrinsics.BooleanPrototype); obj.$BooleanData = arg; break; case _index.SymbolValue: obj = new _index.ObjectValue(realm, realm.intrinsics.SymbolPrototype); obj.$SymbolData = arg; break; case _index.UndefinedValue: case _index.NullValue: throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError); default: obj = arg.throwIfNotConcreteObject(); break; } return obj; } }, { key: "ToObjectPartial", value: function ToObjectPartial(realm, arg) { if (arg instanceof _index.AbstractObjectValue) return arg; if (arg instanceof _index.AbstractValue) { return this._WrapAbstractInObject(realm, arg); } arg = arg.throwIfNotConcrete(); return this.ToObject(realm, arg); } // ECMA262 7.1.15 }, { key: "ToLength", value: function ToLength(realm, argument) { // Let len be ? ToInteger(argument). var len = this.ToInteger(realm, argument); // If len ≤ +0, return +0. if (len <= 0) return +0; // If len is +∞, return 2^53-1. if (len === +Infinity) return Math.pow(2, 53) - 1; // Return min(len, 2^53-1). return Math.min(len, Math.pow(2, 53) - 1); } // ECMA262 7.1.4 }, { key: "ToInteger", value: function ToInteger(realm, argument) { // 1. Let number be ? ToNumber(argument). var number = this.ToNumber(realm, argument); // 2. If number is NaN, return +0. if (isNaN(number)) return +0; // 3. If number is +0, -0, +∞, or -∞, return number. if (!isFinite(number) || number === 0) return number; // 4. Return the number value that is the same sign as number and whose magnitude is floor(abs(number)). return number < 0 ? -Math.floor(Math.abs(number)) : Math.floor(Math.abs(number)); } // ECMA262 7.1.17 }, { key: "ToIndex", value: function ToIndex(realm, value) { var index = void 0; // 1. If value is undefined, then if (value instanceof _index.UndefinedValue) { // a. Let index be 0. index = 0; } else { // 2. Else, // a. Let integerIndex be ? ToInteger(value). var integerIndex = this.ToInteger(realm, value); // b. If integerIndex < 0, throw a RangeError exception. if (integerIndex < 0) { throw realm.createErrorThrowCompletion(realm.intrinsics.RangeError, "integerIndex < 0"); } // c. Let index be ! ToLength(integerIndex). index = this.ToLength(realm, integerIndex); // d. If SameValueZero(integerIndex, index) is false, throw a RangeError exception. if ((0, _abstract.SameValueZero)(realm, new _index.NumberValue(realm, integerIndex), new _index.NumberValue(realm, index)) === false) { throw realm.createErrorThrowCompletion(realm.intrinsics.RangeError, "integerIndex < 0"); } } // 3. Return index. return index; } }, { key: "ToIndexPartial", value: function ToIndexPartial(realm, value) { return this.ToIndex(realm, typeof value === "number" ? value : value.throwIfNotConcrete()); } }, { key: "ToNumber", value: function ToNumber(realm, val) { var num = this.ToNumberOrAbstract(realm, val); if (typeof num !== "number") { _index.AbstractValue.reportIntrospectionError(num); throw new _errors.FatalError(); } return num; } // ECMA262 7.1.3 }, { key: "ToNumberOrAbstract", value: function ToNumberOrAbstract(realm, val) { if (typeof val === "number") { return val; } else if (val instanceof _index.AbstractValue) { return val; } else if (val instanceof _index.UndefinedValue) { return NaN; } else if (val instanceof _index.NullValue) { return +0; } else if (val instanceof _index.ObjectValue) { var prim = this.ToPrimitiveOrAbstract(realm, val, "number"); return this.ToNumberOrAbstract(realm, prim); } else if (val instanceof _index.BooleanValue) { if (val.value === true) { return 1; } else { // `val.value === false` return 0; } } else if (val instanceof _index.NumberValue) { return val.value; } else if (val instanceof _index.StringValue) { return Number(val.value); } else if (val instanceof _index.SymbolValue) { throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError); } else { (0, _invariant2.default)(false, "unexpected type of value"); } } }, { key: "IsToNumberPure", value: function IsToNumberPure(realm, val) { if (val instanceof _index.Value) { if (this.IsToPrimitivePure(realm, val)) { var type = val.getType(); return type !== _index.SymbolValue && type !== _index.PrimitiveValue && type !== _index.Value; } return false; } return true; } // ECMA262 7.1.1 }, { key: "ToPrimitive", value: function ToPrimitive(realm, input, hint) { return this.ToPrimitiveOrAbstract(realm, input, hint).throwIfNotConcretePrimitive(); } }, { key: "ToPrimitiveOrAbstract", value: function ToPrimitiveOrAbstract(realm, input, hint) { if (input instanceof _index.PrimitiveValue) { return input; } // When Type(input) is Object, the following steps are taken (0, _invariant2.default)(input instanceof _index.ObjectValue, "expected an object"); // 1. If PreferredType was not passed, let hint be "default". hint = hint || "default"; // Following two steps are redundant since we just pass string hints. // 2. Else if PreferredType is hint String, let hint be "string". // 3. Else PreferredType is hint Number, let hint be "number". // 4. Let exoticToPrim be ? GetMethod(input, @@toPrimitive). var exoticToPrim = (0, _get.GetMethod)(realm, input, realm.intrinsics.SymbolToPrimitive); // 5. If exoticToPrim is not undefined, then if (!(exoticToPrim instanceof _index.UndefinedValue)) { // a. Let result be ? Call(exoticToPrim, input, « hint »). var result = (0, _call.Call)(realm, exoticToPrim, input, [new _index.StringValue(realm, hint)]); // b. If Type(result) is not Object, return result. if (!(result instanceof _index.ObjectValue)) { (0, _invariant2.default)(result instanceof _index.PrimitiveValue); return result; } // c. Throw a TypeError exception. throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError); } // 6. If hint is "default", let hint be "number". if (hint === "default") hint = "number"; // 7. Return ? OrdinaryToPrimitive(input, hint). return this.OrdinaryToPrimitiveOrAbstract(realm, input, hint); } // Returns result type of ToPrimitive if it is pure (terminates, does not throw exception, does not read or write heap), otherwise undefined. }, { key: "GetToPrimitivePureResultType", value: function GetToPrimitivePureResultType(realm, input) { var type = input.getType(); if (input instanceof _index.PrimitiveValue) return type; if (input instanceof _index.AbstractValue && _index.Value.isTypeCompatibleWith(type, _index.PrimitiveValue)) return type; return undefined; } }, { key: "IsToPrimitivePure", value: function IsToPrimitivePure(realm, input) { return this.GetToPrimitivePureResultType(realm, input) !== undefined; } // ECMA262 7.1.1 }, { key: "OrdinaryToPrimitive", value: function OrdinaryToPrimitive(realm, input, hint) { return this.OrdinaryToPrimitiveOrAbstract(realm, input, hint).throwIfNotConcretePrimitive(); } }, { key: "OrdinaryToPrimitiveOrAbstract", value: function OrdinaryToPrimitiveOrAbstract(realm, input, hint) { var methodNames = void 0; // 1. Assert: Type(O) is Object. (0, _invariant2.default)(input instanceof _index.ObjectValue, "Expected object"); // 2. Assert: Type(hint) is String and its value is either "string" or "number". (0, _invariant2.default)(hint === "string" || hint === "number", "Expected string or number hint"); // 3. If hint is "string", then if (hint === "string") { // a. Let methodNames be « "toString", "valueOf" ». methodNames = ["toString", "valueOf"]; } else { // 4. Else, // a. Let methodNames be « "valueOf", "toString" ». methodNames = ["valueOf", "toString"]; } // 5. For each name in methodNames in List order, do var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = methodNames[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var name = _step.value; // a. Let method be ? Get(O, name). var method = (0, _get.Get)(realm, input, new _index.StringValue(realm, name)); // b. If IsCallable(method) is true, then if ((0, _is.IsCallable)(realm, method)) { // i. Let result be ? Call(method, O). var result = (0, _call.Call)(realm, method, input); var resultType = result.getType(); // ii. If Type(result) is not Object, return result. if (_index.Value.isTypeCompatibleWith(resultType, _index.PrimitiveValue)) { (0, _invariant2.default)(result instanceof _index.AbstractValue || result instanceof _index.PrimitiveValue); return result; } } } // 6. Throw a TypeError exception. } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError, "can't turn to primitive"); } // ECMA262 7.1.12 }, { key: "ToString", value: function ToString(realm, val) { if (typeof val === "string") { return val; } else if (val instanceof _index.StringValue) { return val.value; } else if (val instanceof _index.NumberValue) { return val.value + ""; } else if (val instanceof _index.UndefinedValue) { return "undefined"; } else if (val instanceof _index.NullValue) { return "null"; } else if (val instanceof _index.SymbolValue) { throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError); } else if (val instanceof _index.BooleanValue) { return val.value ? "true" : "false"; } else if (val instanceof _index.ObjectValue) { var primValue = this.ToPrimitive(realm, val, "string"); return this.ToString(realm, primValue); } else { throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError, "unknown value type, can't coerce to string"); } } }, { key: "ToStringPartial", value: function ToStringPartial(realm, val) { return this.ToString(realm, typeof val === "string" ? val : val.throwIfNotConcrete()); } }, { key: "ToStringValue", value: function ToStringValue(realm, val) { if (val.getType() === _index.StringValue) return val; var str = void 0; if (typeof val === "string") { str = val; } else if (val instanceof _index.NumberValue) { str = val.value + ""; } else if (val instanceof _index.UndefinedValue) { str = "undefined"; } else if (val instanceof _index.NullValue) { str = "null"; } else if (val instanceof _index.SymbolValue) { throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError); } else if (val instanceof _index.BooleanValue) { str = val.value ? "true" : "false"; } else if (val instanceof _index.ObjectValue) { var primValue = this.ToPrimitiveOrAbstract(realm, val, "string"); if (primValue.getType() === _index.StringValue) return primValue; str = this.ToStringPartial(realm, primValue); } else { throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError, "unknown value type, can't coerce to string"); } return new _index.StringValue(realm, str); } // ECMA262 7.1.2 }, { key: "ToBoolean", value: function ToBoolean(realm, val) { if (val instanceof _index.BooleanValue) { return val.value; } else if (val instanceof _index.UndefinedValue) { return false; } else if (val instanceof _index.NullValue) { return false; } else if (val instanceof _index.NumberValue) { return val.value !== 0 && !isNaN(val.value); } else if (val instanceof _index.StringValue) { return val.value.length > 0; } else if (val instanceof _index.ObjectValue) { return true; } else if (val instanceof _index.SymbolValue) { return true; } else { (0, _invariant2.default)(!(val instanceof _index.AbstractValue)); throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError, "unknown value type, can't coerce to a boolean"); } } }, { key: "ToBooleanPartial", value: function ToBooleanPartial(realm, val) { if (!val.mightNotBeObject()) return true; return this.ToBoolean(realm, val.throwIfNotConcrete()); } // ECMA262 7.1.14 }, { key: "ToPropertyKey", value: function ToPropertyKey(realm, arg) /* but not StringValue */{ // 1. Let key be ? ToPrimitive(argument, hint String). var key = this.ToPrimitive(realm, arg, "string"); // 2. If Type(key) is Symbol, then if (key instanceof _index.SymbolValue) { // a. Return key. return key; } // 3. Return ! ToString(key). return this.ToString(realm, key); } }, { key: "ToPropertyKeyPartial", value: function ToPropertyKeyPartial(realm, arg) /* but not StringValue */{ if (arg instanceof _index.ConcreteValue) return this.ToPropertyKey(realm, arg); if (arg.mightNotBeString() && arg.mightNotBeNumber()) arg.throwIfNotConcrete(); (0, _invariant2.default)(arg instanceof _index.AbstractValue); return arg; } // ECMA262 7.1.16 }, { key: "CanonicalNumericIndexString", value: function CanonicalNumericIndexString(realm, argument) { // 1. Assert: Type(argument) is String. (0, _invariant2.default)(argument instanceof _index.StringValue); // 2. If argument is "-0", return −0. if (argument.value === "-0") return -0; // 3. Let n be ToNumber(argument). var n = this.ToNumber(realm, argument); // 4. If SameValue(ToString(n), argument) is false, return undefined. if ((0, _abstract.SameValue)(realm, new _index.StringValue(realm, this.ToString(realm, new _index.NumberValue(realm, n))), argument) === false) return undefined; // 5. Return n. return n; } }]); return ToImplementation; }(); //# sourceMappingURL=to.js.map