"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.URIUnescaped = exports.URIMark = exports.DecimalDigit = exports.URIAlpha = exports.URIReserved = undefined; exports.SplitMatch = SplitMatch; exports.RequireObjectCoercible = RequireObjectCoercible; exports.AbstractRelationalComparison = AbstractRelationalComparison; exports.AbstractEqualityComparison = AbstractEqualityComparison; exports.StrictEqualityComparison = StrictEqualityComparison; exports.StrictEqualityComparisonPartial = StrictEqualityComparisonPartial; exports.SameValueZero = SameValueZero; exports.SameValueZeroPartial = SameValueZeroPartial; exports.SameValue = SameValue; exports.SameValuePartial = SameValuePartial; exports.SameValueNonNumber = SameValueNonNumber; exports.SamePropertyKey = SamePropertyKey; exports.Add = Add; exports.InstanceofOperator = InstanceofOperator; exports.OrdinaryHasInstance = OrdinaryHasInstance; exports.Type = Type; exports.SymbolDescriptiveString = SymbolDescriptiveString; exports.UpdateEmpty = UpdateEmpty; var _errors = require("../errors.js"); var _index = require("../values/index.js"); var _call = require("./call.js"); var _is = require("./is.js"); var _completions = require("../completions.js"); var _get = require("./get.js"); var _has = require("./has.js"); var _singletons = require("../singletons.js"); var _invariant = require("../invariant.js"); var _invariant2 = _interopRequireDefault(_invariant); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var URIReserved = exports.URIReserved = ";/?:@&=+$,"; /** * 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 URIAlpha = exports.URIAlpha = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; var DecimalDigit = exports.DecimalDigit = "0123456789"; var URIMark = exports.URIMark = "-_.!~*'()"; var URIUnescaped = exports.URIUnescaped = URIAlpha + DecimalDigit + URIMark; // ECMA262 21.1.3.17.1 function SplitMatch(realm, S, q, R) { // 1. Assert: Type(R) is String. (0, _invariant2.default)(typeof R === "string", "expected a string"); // 2. Let r be the number of code units in R. var r = R.length; // 3. Let s be the number of code units in S. var s = S.length; // 4. If q+r > s, return false. if (q + r > s) return false; // 5. If there exists an integer i between 0 (inclusive) and r (exclusive) such that the code unit at index // q+i of S is different from the code unit at index i of R, return false. for (var i = 0; i < r; i++) { if (S[q + i] !== R[i]) { return false; } } // 6. Return q+r. return q + r; } // ECMA262 7.2.1 function RequireObjectCoercible(realm, arg, argLoc) { if (arg instanceof _index.AbstractValue && (arg.mightBeNull() || arg.mightBeUndefined())) { if (argLoc) { var error = new _errors.CompilerDiagnostic("member expression object is unknown", argLoc, "PP0012", "FatalError"); realm.handleError(error); throw new _errors.FatalError(); } arg.throwIfNotConcrete(); } if (arg instanceof _index.NullValue || arg instanceof _index.UndefinedValue) { throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError, "null or undefined"); } else { return arg; } } // ECMA262 7.2.12 Abstract Relational Comparison function AbstractRelationalComparison(realm, x, y, LeftFirst) { var px = void 0, py = void 0; // 1. If the LeftFirst flag is true, then if (LeftFirst) { // a. Let px be ? ToPrimitive(x, hint Number). px = _singletons.To.ToPrimitive(realm, x, "number"); // b. Let py be ? ToPrimitive(y, hint Number). py = _singletons.To.ToPrimitive(realm, y, "number"); } else { // 2. Else the order of evaluation needs to be reversed to preserve left to right evaluation // a. Let py be ? ToPrimitive(y, hint Number). py = _singletons.To.ToPrimitive(realm, y, "number"); // b. Let px be ? ToPrimitive(x, hint Number). px = _singletons.To.ToPrimitive(realm, x, "number"); } // 3. If both px and py are Strings, then if (px instanceof _index.StringValue && py instanceof _index.StringValue) { // a. If py is a prefix of px, return false. (A String value p is a prefix of String value q if q can be the result of concatenating p and some other String r. Note that any String is a prefix of itself, because r may be the empty String.) if (px.value.startsWith(py.value)) return realm.intrinsics.false; // b. If px is a prefix of py, return true. if (py.value.startsWith(px.value)) return realm.intrinsics.true; // c. Let k be the smallest nonnegative integer such that the code unit at index k within px is different from the code unit at index k within py. (There must be such a k, for neither String is a prefix of the other.) var k = 0; while (px.value.charCodeAt(k) === py.value.charCodeAt(k)) { k += 1; } // d. Let m be the integer that is the code unit value at index k within px. var m = px.value.charCodeAt(k); // e. Let n be the integer that is the code unit value at index k within py. var n = py.value.charCodeAt(k); // f. If m < n, return true. Otherwise, return false. return m < n ? realm.intrinsics.true : realm.intrinsics.false; } else { // 4. Else, // a. Let nx be ? ToNumber(px). Because px and py are primitive values evaluation order is not important. var nx = _singletons.To.ToNumber(realm, px); // b. Let ny be ? ToNumber(py). var ny = _singletons.To.ToNumber(realm, py); // c. If nx is NaN, return undefined. if (isNaN(nx)) return realm.intrinsics.undefined; // d. If ny is NaN, return undefined. if (isNaN(ny)) return realm.intrinsics.undefined; // e. If nx and ny are the same Number value, return false. if (Object.is(nx, ny)) { return realm.intrinsics.false; } // f. If nx is +0 and ny is -0, return false. if (Object.is(nx, +0) && Object.is(ny, -0)) { return realm.intrinsics.false; } // g. If nx is -0 and ny is +0, return false. if (Object.is(nx, -0) && Object.is(ny, +0)) { return realm.intrinsics.false; } // h. If nx is +∞, return false. // i. If ny is +∞, return true. // j. If ny is -∞, return false. // k. If nx is -∞, return true. // i. If the mathematical value of nx is less than the mathematical value of ny —note that these // mathematical values are both finite and not both zero—return true. Otherwise, return false. if (nx < ny) { return realm.intrinsics.true; } else { return realm.intrinsics.false; } } } // ECMA262 7.2.13 function AbstractEqualityComparison(realm, x, y) { // 1. If Type(x) is the same as Type(y), then if (x.getType() === y.getType()) { // a. Return the result of performing Strict Equality Comparison x === y. return StrictEqualityComparison(realm, x, y); } // 2. If x is null and y is undefined, return true. if (x instanceof _index.NullValue && y instanceof _index.UndefinedValue) { return true; } // 3. If x is undefined and y is null, return true. if (x instanceof _index.UndefinedValue && y instanceof _index.NullValue) { return true; } // 4. If Type(x) is Number and Type(y) is String, return the result of the comparison x == ToNumber(y). if (x instanceof _index.NumberValue && y instanceof _index.StringValue) { return AbstractEqualityComparison(realm, x, new _index.NumberValue(realm, _singletons.To.ToNumber(realm, y))); } // 5. If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y. if (x instanceof _index.StringValue && y instanceof _index.NumberValue) { return AbstractEqualityComparison(realm, new _index.NumberValue(realm, _singletons.To.ToNumber(realm, x)), y); } // 6. If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y. if (x instanceof _index.BooleanValue) { return AbstractEqualityComparison(realm, new _index.NumberValue(realm, _singletons.To.ToNumber(realm, x)), y); } // 7. If Type(y) is Boolean, return the result of the comparison x == ToNumber(y). if (y instanceof _index.BooleanValue) { return AbstractEqualityComparison(realm, x, new _index.NumberValue(realm, _singletons.To.ToNumber(realm, y))); } // 8. If Type(x) is either String, Number, or Symbol and Type(y) is Object, return the result of the comparison x == ToPrimitive(y). if ((x instanceof _index.StringValue || x instanceof _index.NumberValue || x instanceof _index.SymbolValue) && y instanceof _index.ObjectValue) { return AbstractEqualityComparison(realm, x, _singletons.To.ToPrimitive(realm, y)); } // 9. If Type(x) is Object and Type(y) is either String, Number, or Symbol, return the result of the comparison ToPrimitive(x) == y. if (x instanceof _index.ObjectValue && (y instanceof _index.StringValue || y instanceof _index.NumberValue || y instanceof _index.SymbolValue)) { return AbstractEqualityComparison(realm, _singletons.To.ToPrimitive(realm, x), y); } // 10. Return false. return false; } // ECMA262 7.2.14 Strict Equality Comparison function StrictEqualityComparison(realm, x, y) { // 1. If Type(x) is different from Type(y), return false. if (x.getType() !== y.getType()) { return false; } // 2. If Type(x) is Number, then if (x instanceof _index.NumberValue && y instanceof _index.NumberValue) { // a. If x is NaN, return false. if (isNaN(x.value)) return false; // b. If y is NaN, return false. if (isNaN(y.value)) return false; // c. If x is the same Number value as y, return true. // d. If x is +0 and y is -0, return true. (handled by c) // e. If x is -0 and y is +0, return true. (handled by c) if (x.value === y.value) return true; // f. Return false. return false; } // 3. Return SameValueNonNumber(x, y). return SameValueNonNumber(realm, x, y); } function StrictEqualityComparisonPartial(realm, x, y) { return StrictEqualityComparison(realm, x.throwIfNotConcrete(), y.throwIfNotConcrete()); } // ECMA262 7.2.10 function SameValueZero(realm, x, y) { // 1. If Type(x) is different from Type(y), return false. if (x.getType() !== y.getType()) { return false; } // 2. If Type(x) is Number, then if (x instanceof _index.NumberValue) { (0, _invariant2.default)(y instanceof _index.NumberValue); // a. If x is NaN and y is NaN, return true. if (isNaN(x.value) && isNaN(y.value)) return true; // b. If x is +0 and y is -0, return true. if (Object.is(x.value, +0) && Object.is(y.value, -0)) return true; // c. If x is -0 and y is +0, return true. if (Object.is(x.value, -0) && Object.is(y.value, +0)) return true; // d. If x is the same Number value as y, return true. if (x.value === y.value) return true; // e. Return false. return false; } // 3. Return SameValueNonNumber(x, y). return SameValueNonNumber(realm, x, y); } function SameValueZeroPartial(realm, x, y) { return SameValueZero(realm, x.throwIfNotConcrete(), y.throwIfNotConcrete()); } // ECMA262 7.2.9 function SameValue(realm, x, y) { // 1. If Type(x) is different from Type(y), return false. if (x.getType() !== y.getType()) return false; // 2. If Type(x) is Number, then if (x instanceof _index.NumberValue && y instanceof _index.NumberValue) { // a. If x is NaN and y is NaN, return true. if (isNaN(x.value) && isNaN(y.value)) return true; // b. If x is +0 and y is -0, return false. if (Object.is(x.value, +0) && Object.is(y.value, -0)) return false; // c. If x is -0 and y is +0, return false. if (Object.is(x.value, -0) && Object.is(y.value, +0)) return false; // d. If x is the same Number value as y, return true. if (x.value === y.value) return true; // e. Return false. return false; } // 3. Return SameValueNonNumber(x, y). return SameValueNonNumber(realm, x, y); } function SameValuePartial(realm, x, y) { return SameValue(realm, x.throwIfNotConcrete(), y.throwIfNotConcrete()); } // ECMA262 7.2.11 function SameValueNonNumber(realm, x, y) { // 1. Assert: Type(x) is not Number. (0, _invariant2.default)(!(x instanceof _index.NumberValue), "numbers not allowed"); // 2. Assert: Type(x) is the same as Type(y). (0, _invariant2.default)(x.getType() === y.getType(), "must be same type"); // 3. If Type(x) is Undefined, return true. if (x instanceof _index.UndefinedValue) return true; // 4. If Type(x) is Null, return true. if (x instanceof _index.NullValue) return true; // 5. If Type(x) is String, then if (x instanceof _index.StringValue && y instanceof _index.StringValue) { // a. If x and y are exactly the same sequence of code units (same length and same code units at corresponding indices), return true; otherwise, return false. return x.value === y.value; } // 6. If Type(x) is Boolean, then if (x instanceof _index.BooleanValue && y instanceof _index.BooleanValue) { // a. If x and y are both true or both false, return true; otherwise, return false. return x.value === y.value; } // 7. If Type(x) is Symbol, then if (x instanceof _index.SymbolValue) { // a. If x and y are both the same Symbol value, return true; otherwise, return false. return x === y; } // 8. Return true if x and y are the same Object value. Otherwise, return false. return x === y; } // Checks if two property keys are identical. function SamePropertyKey(realm, x, y) { if (typeof x === "string" && typeof y === "string") { return x === y; } if (x instanceof _index.StringValue && y instanceof _index.StringValue) { return x.value === y.value; } if (x instanceof _index.SymbolValue && y instanceof _index.SymbolValue) { return x === y; } return false; } // ECMA262 12.8.5 Applying the Additive Operators to Numbers function Add(realm, a, b) { var subtract = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; // If either operand is NaN, the result is NaN. if (isNaN(a) || isNaN(b)) { return realm.intrinsics.NaN; } // The sum of two infinities of opposite sign is NaN. // The sum of two infinities of the same sign is the infinity of that sign. // The sum of an infinity and a finite value is equal to the infinite operand. // The sum of two negative zeroes is -0. The sum of two positive zeroes, or of two zeroes of opposite sign, is +0. // The sum of a zero and a nonzero finite value is equal to the nonzero operand. // The sum of two nonzero finite values of the same magnitude and opposite sign is +0. var anum = a; var bnum = b; // The - operator performs subtraction when applied to two operands of numeric type, // producing the difference of its operands; the left operand is the minuend and the right // operand is the subtrahend. Given numeric operands a and b, it is always the case that // a-b produces the same result as a+(-b). if (subtract) { bnum = -bnum; } return new _index.NumberValue(realm, anum + bnum); } // ECMA262 12.10.4 function InstanceofOperator(realm, O, C) { // 1. If Type(C) is not Object, throw a TypeError exception. if (!C.mightBeObject()) { throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError, "Expecting a function in instanceof check"); } // 2. Let instOfHandler be ? GetMethod(C, @@hasInstance). var instOfHandler = (0, _get.GetMethod)(realm, C, realm.intrinsics.SymbolHasInstance); // 3. If instOfHandler is not undefined, then if (!(instOfHandler instanceof _index.UndefinedValue)) { // a. Return ToBoolean(? Call(instOfHandler, C, « O »)). return _singletons.To.ToBooleanPartial(realm, (0, _call.Call)(realm, instOfHandler, C, [O])); } // 4. If IsCallable(C) is false, throw a TypeError exception. if ((0, _is.IsCallable)(realm, C) === false) { throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError, "Expecting a function in instanceof check"); } // 5. Return ? OrdinaryHasInstance(C, O). return OrdinaryHasInstance(realm, C, O); } // ECMA262 7.3.19 function OrdinaryHasInstance(realm, C, O) { // 1. If IsCallable(C) is false, return false. if ((0, _is.IsCallable)(realm, C) === false) return false; (0, _invariant2.default)(C instanceof _index.ObjectValue); // 2. If C has a [[BoundTargetFunction]] internal slot, then if (C instanceof _index.BoundFunctionValue) { // a. Let BC be the value of C's [[BoundTargetFunction]] internal slot. var BC = C.$BoundTargetFunction; // b. Return ? InstanceofOperator(O, BC). return InstanceofOperator(realm, O, BC); } // 3. If Type(O) is not Object, return false. O = O.throwIfNotConcrete(); if (!(O instanceof _index.ObjectValue)) return false; // 4. Let P be ? Get(C, "prototype"). var P = (0, _get.Get)(realm, C, "prototype").throwIfNotConcrete(); // 5. If Type(P) is not Object, throw a TypeError exception. if (!(P instanceof _index.ObjectValue)) { throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError, "Type(P) is not Object"); } // 6. Repeat while (true) { // a. Let O be ? O.[[GetPrototypeOf]](). O = O.$GetPrototypeOf(); // b. If O is null, return false. if (O instanceof _index.NullValue) return false; // c. If SameValue(P, O) is true, return true. if (SameValue(realm, P, O) === true) return true; } return false; } // function Type(realm, val) { if (val instanceof _index.UndefinedValue) { return "Undefined"; } else if (val instanceof _index.NullValue) { return "Null"; } else if ((0, _has.HasCompatibleType)(val, _index.BooleanValue)) { return "Boolean"; } else if ((0, _has.HasCompatibleType)(val, _index.StringValue)) { return "String"; } else if ((0, _has.HasCompatibleType)(val, _index.SymbolValue)) { return "Symbol"; } else if ((0, _has.HasCompatibleType)(val, _index.NumberValue)) { return "Number"; } else if (!val.mightNotBeObject()) { return "Object"; } else { (0, _invariant2.default)(val instanceof _index.AbstractValue); _index.AbstractValue.reportIntrospectionError(val); throw new _errors.FatalError(); } } // ECMA262 19.4.3.2.1 function SymbolDescriptiveString(realm, sym) { // 1. Assert: Type(sym) is Symbol. (0, _invariant2.default)(sym instanceof _index.SymbolValue, "expected symbol"); // 2. Let desc be sym's [[Description]] value. var desc = sym.$Description; // 3. If desc is undefined, let desc be the empty string. if (!desc) desc = "";else desc = desc.throwIfNotConcreteString().value; // 4. Assert: Type(desc) is String. (0, _invariant2.default)(typeof desc === "string", "expected string"); // 5. Return the result of concatenating the strings "Symbol(", desc, and ")". return "Symbol(" + desc + ")"; } // ECMA262 6.2.2.5 function UpdateEmpty(realm, completionRecord, value) { // 1. Assert: If completionRecord.[[Type]] is either return or throw, then completionRecord.[[Value]] is not empty. if (completionRecord instanceof _completions.ReturnCompletion || completionRecord instanceof _completions.ThrowCompletion) { (0, _invariant2.default)(completionRecord.value, "expected completion record to have a value"); } // 2. If completionRecord.[[Value]] is not empty, return Completion(completionRecord). if (completionRecord instanceof _index.EmptyValue) return value; if (completionRecord instanceof _index.Value || completionRecord.value && !(completionRecord.value instanceof _index.EmptyValue)) return completionRecord; // 3. Return Completion{[[Type]]: completionRecord.[[Type]], [[Value]]: value, [[Target]]: completionRecord.[[Target]] }.' completionRecord.value = value; return completionRecord; } //# sourceMappingURL=abstract.js.map