Files
2023-08-01 13:49:46 +02:00

884 lines
35 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"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