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

545 lines
20 KiB
JavaScript

"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