prepack
Version:
Execute a JS bundle, serialize global state and side effects to a snapshot that can be quickly restored.
187 lines (153 loc) • 7.32 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = function (realm, obj) {
// ECMA262 20.1.3
obj.$NumberData = realm.intrinsics.zero;
// ECMA262 20.1.3.2
obj.defineNativeMethod("toExponential", 1, (context, [fractionDigits]) => {
// 1. Let x be ? thisNumberValue(this value).
let x = _singletons.To.thisNumberValue(realm, context).value;
// 2. Let f be ? ToInteger(fractionDigits).
fractionDigits = fractionDigits.throwIfNotConcrete();
let f = _singletons.To.ToInteger(realm, fractionDigits);
// 3. Assert: f is 0, when fractionDigits is undefined.
(0, _invariant2.default)(f === 0 || !(fractionDigits instanceof _index.UndefinedValue));
// 4. If x is NaN, return the String "NaN".
if (isNaN(x)) return new _index.StringValue(realm, "NaN");
// 5. Let s be the empty String.
let s = "";
// 6. If x < 0, then
if (x < 0) {
// 6a. Let s be "-".
s = "-";
// 6b. Let x be -x.
x = -x;
}
// 7. If x = +∞, then
if (x === +Infinity) {
// 7a. Return the concatenation of the Strings s and "Infinity".
return new _index.StringValue(realm, s + "Infinity");
}
// 8. If f < 0 or f > 20, throw a RangeError exception. However, an implementation is permitted to extend the behaviour of toExponential for values of f less than 0 or greater than 20. In this case toExponential would not necessarily throw RangeError for such values.
if (f < 0 || f > 20) {
throw realm.createErrorThrowCompletion(realm.intrinsics.RangeError, "f < 0 || f > 20");
}
let positiveResultString = x.toExponential(fractionDigits instanceof _index.UndefinedValue ? undefined : f);
return new _index.StringValue(realm, s + positiveResultString);
});
// ECMA262 20.1.3.3
obj.defineNativeMethod("toFixed", 1, (context, [fractionDigits]) => {
// 1. Let f be ToInteger(fractionDigits). (If fractionDigits is undefined, this step produces the value 0).
let f = _singletons.To.ToInteger(realm, fractionDigits);
// 2. If f < 0 or f > 20, throw a RangeError exception.
if (f < 0 || f > 20) {
throw realm.createErrorThrowCompletion(realm.intrinsics.RangeError, "f < 0 || f > 20");
}
// 3. Let x be this Number value.
let x = _singletons.To.thisNumberValue(realm, context).value;
// 4. If x is NaN, return the String "NaN".
if (isNaN(x)) return new _index.StringValue(realm, "NaN");
return new _index.StringValue(realm, x.toFixed(f));
});
let toLocaleStringSrc = "(A).toLocaleString()";
let toLocaleString = (0, _builder2.default)(toLocaleStringSrc);
// ECMA262 20.1.3.4
obj.defineNativeMethod("toLocaleString", 0, context => {
let x = _singletons.To.thisNumberValue(realm, context);
if (realm.useAbstractInterpretation) {
// The locale is environment-dependent and may also be time-dependent
// so do this at runtime and at this point in time
return _index.AbstractValue.createTemporalFromTemplate(realm, toLocaleString, _index.StringValue, [x]);
} else {
return new _index.StringValue(realm, x.toLocaleString());
}
});
// ECMA262 20.1.3.5
obj.defineNativeMethod("toPrecision", 1, (context, [precision]) => {
// 1. Let x be ? thisNumberValue(this value).
// 2. If precision is undefined, return ! ToString(x).
let num = _singletons.To.thisNumberValue(realm, context);
if (precision instanceof _index.UndefinedValue) {
return new _index.StringValue(realm, _singletons.To.ToString(realm, num));
}
// 3. Let p be ? ToInteger(precision).
let p = _singletons.To.ToInteger(realm, precision.throwIfNotConcrete());
// 4. If x is NaN, return the String "NaN".
let x = num.value;
if (isNaN(x)) {
return new _index.StringValue(realm, "NaN");
}
// 5. Let s be the empty String.
let s = "";
// 6. If x < 0, then
if (x < 0) {
// a. Let s be code unit 0x002D (HYPHEN-MINUS).
s = "-";
// b. Let x be -x.
x = -x;
}
// 7. If x = +∞, then
if (x === +Infinity) {
// a. Return the String that is the concatenation of s and "Infinity".
return new _index.StringValue(realm, s + "Infinity");
}
// 8. If p < 1 or p > 21, throw a RangeError exception.
// However, an implementation is permitted to extend the behaviour of
// toPrecision for values of p less than 1 or greater than 21.
// In this case toPrecision would not necessarily throw RangeError for such
// values.
if (p < 1 || p > 21) {
// for simplicity, throw the error
throw realm.createErrorThrowCompletion(realm.intrinsics.RangeError, "p should be in between 1 and 21 inclusive");
}
return new _index.StringValue(realm, s + x.toPrecision(p));
});
const tsTemplateSrc = "(A).toString()";
const tsTemplate = (0, _builder2.default)(tsTemplateSrc);
// ECMA262 20.1.3.6
obj.defineNativeMethod("toString", 1, (context, [radix]) => {
if (radix instanceof _index.UndefinedValue) {
const target = context instanceof _index.ObjectValue ? context.$NumberData : context;
if (target instanceof _index.AbstractValue && (target.getType() === _index.NumberValue || target.getType() === _index.IntegralValue)) {
return _index.AbstractValue.createFromTemplate(realm, tsTemplate, _index.StringValue, [target], tsTemplateSrc);
}
}
// 1. Let x be ? thisNumberValue(this value).
let x = _singletons.To.thisNumberValue(realm, context);
// 2. If radix is not present, let radixNumber be 10.
// 3. Else if radix is undefined, let radixNumber be 10.
let radixNumber;
if (!radix || radix instanceof _index.UndefinedValue) {
radixNumber = 10;
} else {
// 4. Else let radixNumber be ? ToInteger(radix).
radixNumber = _singletons.To.ToInteger(realm, radix.throwIfNotConcrete());
}
// 5. If radixNumber < 2 or radixNumber > 36, throw a RangeError exception.
if (radixNumber < 2 || radixNumber > 36) {
throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError);
}
// 6. If radixNumber = 10, return ! ToString(x).
if (radixNumber === 10) return new _index.StringValue(realm, _singletons.To.ToString(realm, x));
// 7. Return the String representation of this Number value using the radix specified by radixNumber.
// Letters a-z are used for digits with values 10 through 35. The precise algorithm is
// implementation-dependent, however the algorithm should be a generalization of that specified in
// 7.1.12.1.
return new _index.StringValue(realm, x.value.toString(radixNumber));
});
// ECMA262 20.1.3.7
obj.defineNativeMethod("valueOf", 0, context => {
// 1. Return ? thisNumberValue(this value).
return _singletons.To.thisNumberValue(realm, context);
});
};
var _index = require("../../values/index.js");
var _singletons = require("../../singletons.js");
var _invariant = require("../../invariant.js");
var _invariant2 = _interopRequireDefault(_invariant);
var _builder = require("../../utils/builder.js");
var _builder2 = _interopRequireDefault(_builder);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
//# sourceMappingURL=NumberPrototype.js.map