SSL Iterator.js
Interaktion und PortierbarkeitJAVA
/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
function IteratorIdentity() { returnthis;
}
/* ECMA262 7.2.7 */ function IteratorNext(iteratorRecord, value) { // Steps 1-2. var result =
ArgumentsLength() < 2
? callContentFunction(iteratorRecord.nextMethod, iteratorRecord.iterator)
: callContentFunction(
iteratorRecord.nextMethod,
iteratorRecord.iterator,
value
); // Step 3. if (!IsObject(result)) {
ThrowTypeError(JSMSG_OBJECT_REQUIRED, result);
} // Step 4. return result;
}
// https://tc39.es/ecma262/#sec-getiterator function GetIterator(obj, isAsync, method) { // Step 1. If hint is not present, set hint to sync. // Step 2. If method is not present, then if (!method) { // Step 2.a. If hint is async, then if (isAsync) { // Step 2.a.i. Set method to ? GetMethod(obj, @@asyncIterator).
method = GetMethod(obj, GetBuiltinSymbol("asyncIterator"));
// Step 2.a.ii. If method is undefined, then if (!method) { // Step 2.a.ii.1. Let syncMethod be ? GetMethod(obj, @@iterator). var syncMethod = GetMethod(obj, GetBuiltinSymbol("iterator"));
// Step 2.a.ii.2. Let syncIteratorRecord be ? GetIterator(obj, sync, syncMethod). var syncIteratorRecord = GetIterator(obj, false, syncMethod);
// Step 3. Let iterator be ? Call(method, obj). var iterator = callContentFunction(method, obj);
// Step 4. If Type(iterator) is not Object, throw a TypeError exception. if (!IsObject(iterator)) {
ThrowTypeError(JSMSG_NOT_ITERABLE, obj === null ? "null" : typeof obj);
}
// Step 5. Let nextMethod be ? GetV(iterator, "next"). var nextMethod = iterator.next;
// Step 6. Let iteratorRecord be the Record { [[Iterator]]: iterator, [[NextMethod]]: nextMethod, [[Done]]: false }. var iteratorRecord = {
__proto__: null,
iterator,
nextMethod,
done: false,
};
#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT /** * Explicit Resource Management Proposal * 27.1.2.1 %IteratorPrototype% [ @@dispose ] ( ) * https://arai-a.github.io/ecma262-compare/?pr=3000&id=sec-%25iteratorprototype%25-%40%40dispose
*/ function IteratorDispose() { // Step 1. Let O be the this value. var O = this;
// Step 2. Let return be ? GetMethod(O, "return"). var returnMethod = GetMethod(O, "return");
// Step 3. If return is not undefined, then if (returnMethod !== undefined) { // Step 3.a. Perform ? Call(return, O, « »).
callContentFunction(returnMethod, O);
}
// Lazy %Iterator.prototype% methods // // In order to match the semantics of the built-in generator objects used in // the proposal, we use a reserved slot on the IteratorHelper objects to store // a regular generator that is called from the %IteratorHelper.prototype% // methods. // // Each of the lazy methods is divided into a prelude and a body, with the // eager prelude steps being contained in the corresponding IteratorX method // and the lazy body steps inside the IteratorXGenerator generator functions. // // Each prelude method initializes and returns a new IteratorHelper object. // As part of this initialization process, the appropriate generator function // is called, followed by GeneratorNext being called on returned generator // instance in order to move it to its first yield point. This is done so that // if the `return` method is called on the IteratorHelper before `next` has been // called, we can catch them in the try and use the finally block to close the // underlying iterator.
// Step 3. if (!IsCallable(mapper)) {
ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, mapper));
}
// Step 4. (Inlined call to GetIteratorDirect.) var nextMethod = iterator.next;
// Steps 5-7. var result = NewIteratorHelper(); var generator = IteratorMapGenerator(iterator, nextMethod, mapper);
UnsafeSetReservedSlot(
result,
ITERATOR_HELPER_GENERATOR_SLOT,
generator
);
// Stop at the initial yield point.
callFunction(GeneratorNext, generator);
// Step 8. return result;
}
/** * Iterator.prototype.map ( mapper ) * * Abstract closure definition. * * https://tc39.es/proposal-iterator-helpers/#sec-iteratorprototype.map
*/ function* IteratorMapGenerator(iterator, nextMethod, mapper) { var isReturnCompletion = true; try { // Initial yield point to handle closing the iterator before the for-of // loop has been entered for the first time.
yield;
// Not a Return completion when execution continues normally after |yield|.
isReturnCompletion = false;
} finally { // Call IteratorClose on a Return completion. if (isReturnCompletion) {
IteratorClose(iterator);
}
}
// Step 5.a. var counter = 0;
// Step 5.b. for (var value of allowContentIterWithNext(iterator, nextMethod)) { // Steps 5.b.i-iii. (Implicit through for-of loop)
// Step 5.b.iv. var mapped = callContentFunction(mapper, undefined, value, counter);
// Step 3. if (!IsCallable(predicate)) {
ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, predicate));
}
// Step 4. (Inlined call to GetIteratorDirect.) var nextMethod = iterator.next;
// Steps 5-7. var result = NewIteratorHelper(); var generator = IteratorFilterGenerator(iterator, nextMethod, predicate);
UnsafeSetReservedSlot(
result,
ITERATOR_HELPER_GENERATOR_SLOT,
generator
);
// Stop at the initial yield point.
callFunction(GeneratorNext, generator);
// Step 8. return result;
}
/** * Iterator.prototype.filter ( predicate ) * * Abstract closure definition. * * https://tc39.es/proposal-iterator-helpers/#sec-iteratorprototype.filter
*/ function* IteratorFilterGenerator(iterator, nextMethod, predicate) { var isReturnCompletion = true; try { // Initial yield point to handle closing the iterator before the for-of // loop has been entered for the first time.
yield;
// Not a Return completion when execution continues normally after |yield|.
isReturnCompletion = false;
} finally { // Call IteratorClose on a Return completion. if (isReturnCompletion) {
IteratorClose(iterator);
}
}
// Step 5.a. var counter = 0;
// Step 5.b. for (var value of allowContentIterWithNext(iterator, nextMethod)) { // Steps 5.b.i-iii. (Implicit through for-of loop)
// Step 5.b.iv. var selected = callContentFunction(predicate, undefined, value, counter);
// Steps 3-6. var integerLimit = std_Math_trunc(limit); if (!(integerLimit >= 0)) {
ThrowRangeError(JSMSG_NEGATIVE_LIMIT);
}
// Step 7. (Inlined call to GetIteratorDirect.) var nextMethod = iterator.next;
// Steps 8-10. var result = NewIteratorHelper(); var generator = IteratorTakeGenerator(iterator, nextMethod, integerLimit);
UnsafeSetReservedSlot(
result,
ITERATOR_HELPER_GENERATOR_SLOT,
generator
);
// Stop at the initial yield point.
callFunction(GeneratorNext, generator);
// Step 11. return result;
}
/** * Iterator.prototype.take ( limit ) * * Abstract closure definition. * * https://tc39.es/proposal-iterator-helpers/#sec-iteratorprototype.take
*/ function* IteratorTakeGenerator(iterator, nextMethod, remaining) { var isReturnCompletion = true; try { // Initial yield point to handle closing the iterator before the for-of // loop has been entered for the first time.
yield;
// Not a Return completion when execution continues normally after |yield|.
isReturnCompletion = false;
} finally { // Call IteratorClose on a Return completion. if (isReturnCompletion) {
IteratorClose(iterator);
}
}
// Step 8.a. (Implicit)
// Step 8.b.i. (Reordered before for-of loop entry) if (remaining === 0) {
IteratorClose(iterator); return;
}
// Step 8.b. for (var value of allowContentIterWithNext(iterator, nextMethod)) { // Steps 8.b.iii-iv. (Implicit through for-of loop)
// Steps 3-6. var integerLimit = std_Math_trunc(limit); if (!(integerLimit >= 0)) {
ThrowRangeError(JSMSG_NEGATIVE_LIMIT);
}
// Step 7. (Inlined call to GetIteratorDirect.) var nextMethod = iterator.next;
// Steps 8-10. var result = NewIteratorHelper(); var generator = IteratorDropGenerator(iterator, nextMethod, integerLimit);
UnsafeSetReservedSlot(
result,
ITERATOR_HELPER_GENERATOR_SLOT,
generator
);
// Stop at the initial yield point.
callFunction(GeneratorNext, generator);
// Step 11. return result;
}
/** * Iterator.prototype.drop ( limit ) * * Abstract closure definition. * * https://tc39.es/proposal-iterator-helpers/#sec-iteratorprototype.drop
*/ function* IteratorDropGenerator(iterator, nextMethod, remaining) { var isReturnCompletion = true; try { // Initial yield point to handle closing the iterator before the for-of // loop has been entered for the first time.
yield;
// Not a Return completion when execution continues normally after |yield|.
isReturnCompletion = false;
} finally { // Call IteratorClose on a Return completion. if (isReturnCompletion) {
IteratorClose(iterator);
}
}
// Step 8.a. (Implicit)
// Steps 8.b-c. for (var value of allowContentIterWithNext(iterator, nextMethod)) { // Step 8.b.i. if (remaining-- <= 0) { // Steps 8.b.ii-iii. (Implicit through for-of loop) // Steps 8.c.i-ii. (Implicit through for-of loop)
// Step 8.c.iii.
yield value;
// Step 8.c.iv. (Implicit through for-of loop)
}
}
}
// Step 3. if (!IsCallable(mapper)) {
ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, mapper));
}
// Step 4. (Inlined call to GetIteratorDirect.) var nextMethod = iterator.next;
// Steps 5-7. var result = NewIteratorHelper(); var generator = IteratorFlatMapGenerator(iterator, nextMethod, mapper);
UnsafeSetReservedSlot(
result,
ITERATOR_HELPER_GENERATOR_SLOT,
generator
);
// Stop at the initial yield point.
callFunction(GeneratorNext, generator);
// Step 8. return result;
}
/** * Iterator.prototype.flatMap ( mapper ) * * https://tc39.es/proposal-iterator-helpers/#sec-iteratorprototype.flatmap
*/ function* IteratorFlatMapGenerator(iterator, nextMethod, mapper) { var isReturnCompletion = true; try { // Initial yield point to handle closing the iterator before the for-of // loop has been entered for the first time.
yield;
// Not a Return completion when execution continues normally after |yield|.
isReturnCompletion = false;
} finally { // Call IteratorClose on a Return completion. if (isReturnCompletion) {
IteratorClose(iterator);
}
}
// Step 5.a. var counter = 0;
// Step 5.b. for (var value of allowContentIterWithNext(iterator, nextMethod)) { // Steps 5.b.i-iii. (Implicit through for-of loop)
// Step 5.b.iv. var mapped = callContentFunction(mapper, undefined, value, counter);
// Step 5.b.v. (Implicit through for-of loop)
// Steps 5.b.vi. var innerIterator = GetIteratorFlattenable(mapped, /* rejectStrings= */ true); var innerIteratorNextMethod = innerIterator.next;
// Step 5.b.vii. (Implicit through for-of loop)
// Steps 5.b.viii-ix. for (var innerValue of allowContentIterWithNext(innerIterator, innerIteratorNextMethod)) { // Steps 5.b.ix.1-3 and 5.b.ix.4.a-b. (Implicit through for-of loop)
// Step 5.b.ix.4.c.
yield innerValue;
// Step 5.b.ix.4.d. (Implicit through for-of loop)
}
// Step 3. if (!IsCallable(reducer)) {
ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, reducer));
}
// Step 4. (Inlined call to GetIteratorDirect.) var nextMethod = iterator.next;
// Steps 5-6. var accumulator; var counter; if (ArgumentsLength() === 1) { // Steps 5.a-d. (Moved below.)
counter = -1;
} else { // Step 6.a.
accumulator = GetArgument(1);
// Step 6.b.
counter = 0;
}
// Step 7. for (var value of allowContentIterWithNext(iterator, nextMethod)) { if (counter < 0) { // Step 5. (Reordered steps to compute initial accumulator.)
// Step 5.c.
accumulator = value;
// Step 5.d.
counter = 1;
} else { // Steps 7.a-c and 7.e. (Implicit through for-of loop)
/**
* Iterator.range (start, end, step, inclusiveEnd, zero, one)
*
* https://tc39.es/proposal-iterator.range/#sec-create-numeric-range-iterator
*/
function* IteratorRangeGenerator(start, end, step, inclusiveEnd, zero, one) {
//TODO: Handle setting prototype for generators returned from Iterator.range
// Step 18. Let closure be a new Abstract Closure with no parameters that captures start, end, step, inclusiveEnd, zero, one and performs the following steps when called:
// Step 18.a: If end > start, let ifIncrease be true
// Step 18.b: Else let ifIncrease be false
var ifIncrease = end > start;
// Step 18.c: If step > zero, let ifStepIncrease be true
// Step 18.d: Else let ifStepIncrease be false
var ifStepIncrease = step > zero;
// Step 18.e: If ifIncrease is not ifStepIncrease, return undefined
if (ifIncrease !== ifStepIncrease) {
return undefined;
}
// Step 18.f: Let hitsEnd be false
var hitsEnd = false;
// Step 18.g: Let currentCount be zero
var currentCount = zero;
// Step 18.i: Iterate while hitsEnd is false
while (hitsEnd === false) {
// Step 18.i.i: Let currentYieldingValue be start + (step × currentCount)
var currentYieldingValue = start + (step * currentCount);
// Step 18.i.ii: If currentYieldingValue is end, set hitsEnd to true
if (currentYieldingValue === end) {
hitsEnd = true;
}
// Step 18.i.iii: Set currentCount to currentCount + one
currentCount = currentCount + one;
// Step 18.i.iv: If ifIncrease is true, then
if (ifIncrease === true) {
// Step 18.i.iv.1: If inclusiveEnd is true, then
if (inclusiveEnd === true) {
// Step 18.i.iv.1.a: If currentYieldingValue > end, return undefined
if (currentYieldingValue > end) {
return undefined;
}
} else {
// Step 18.i.iv.2.a: If currentYieldingValue ≥ end, return undefined
if (currentYieldingValue >= end) {
return undefined;
}
}
}
// Step 18.i.v: Else
else {
// Step 18.i.v.1: If inclusiveEnd is true, then
if (inclusiveEnd === true) {
// Step 18.i.v.1.a: If end > currentYieldingValue, return undefined
if (end > currentYieldingValue) {
return undefined;
}
} else {
// Step 18.i.v.2.a: If end ≥ currentYieldingValue, return undefined
if (end >= currentYieldingValue) {
return undefined;
}
}
}
/**
* Iterator.range ( start, end, optionOrStep, type )
*
* https://tc39.es/proposal-iterator.range/#sec-iterator.range
*/
function CreateNumericRangeIterator(start, end, optionOrStep, isNumberRange) {
// Step 1: If start is NaN, throw a RangeError exception.
if (isNumberRange && Number_isNaN(start)) {
ThrowRangeError(JSMSG_ITERATOR_RANGE_INVALID_START_RANGEERR);
}
// Step 2: If end is NaN, throw a RangeError exception.
if (isNumberRange && Number_isNaN(end)) {
ThrowRangeError(JSMSG_ITERATOR_RANGE_INVALID_END_RANGEERR);
}
// Step 3: If type is NUMBER-RANGE, then
if (isNumberRange) {
// Step 3.a. Assert: start is a Number.
assert(typeof start === 'number', "The 'start' argument must be a number");
// Step 3.b. If end is not a Number, throw a TypeError exception.
if (typeof end !== 'number') {
ThrowTypeError(JSMSG_ITERATOR_RANGE_INVALID_END);
}
// Step 3.c. Let zero be 0ℤ.
var zero = 0;
// Step 3.d. Let one be 1ℤ.
var one = 1;
// 4: Else,
} else {
// 4.a. Assert: start is a BigInt.
assert(typeof start === 'bigint', "The 'start' argument must be a bigint");
// 4.b. If end is not +∞ or -∞ and end is not a BigInt, throw a TypeError exception.
if (typeof end !== 'bigint' && !(Number_isFinite(end))) {
ThrowTypeError(JSMSG_ITERATOR_RANGE_INVALID_END);
}
// 4.c. Let zero be 0.
var zero = 0n;
// 4.d. Let one be 1.
var one = 1n;
}
// Step 5: If start is +∞ or -∞, throw a RangeError exception.
if (typeof start === 'number' && !Number_isFinite(start)) {
ThrowRangeError(JSMSG_ITERATOR_RANGE_START_INFINITY);
}
// Step 6: Let inclusiveEnd be false.
var inclusiveEnd = false;
// Step 7: If optionOrStep is undefined or null, then
// Step 7.a. Let step be undefined.
var step;
// Step 8: Else if optionOrStep is an Object, then
if (optionOrStep !== null && typeof optionOrStep === 'object') {
// Step 8.a. Let step be ? Get(optionOrStep, "step").
step = optionOrStep.step;
// Step 8.b. Set inclusiveEnd to ToBoolean(? Get(optionOrStep, "inclusive")).
// eslint-disable-next-line no-unused-vars
inclusiveEnd = ToBoolean(optionOrStep.inclusiveEnd);
}
// Step 9: Else if type is NUMBER-RANGE and optionOrStep is a Number, then
else if (isNumberRange && typeof optionOrStep === 'number') {
// Step 9.a. Let step be optionOrStep.
step = optionOrStep;
}
// Step 10: Else if type is BIGINT-RANGE and optionOrStep is a BigInt, then
// Step 10.a. Let step be optionOrStep.
else if (!isNumberRange && typeof optionOrStep === 'bigint') {
step = optionOrStep;
}
// Step 11: Else, throw a TypeError exception.
else if (optionOrStep !== undefined && optionOrStep !== null) {
ThrowTypeError(JSMSG_ITERATOR_RANGE_INVALID_STEP);
}
// Step 12: If step is undefined or null, then
if (step === undefined || step === null) {
// Step 12.a. If end > start, let step be one.
// Step 12.b. Else let step be -one.
step = end > start ? one : -one;
}
// Step 13: If step is NaN, throw a RangeError exception.
if (typeof step === "number" && Number_isNaN(step)) {
ThrowRangeError(JSMSG_ITERATOR_RANGE_STEP_NAN);
}
// Step 14: If type is NUMBER-RANGE and step is not a Number, throw a TypeError exception.
if (isNumberRange && typeof step !== 'number') {
ThrowTypeError(JSMSG_ITERATOR_RANGE_STEP_NOT_NUMBER);
}
// Step 15: Else if type is BIGINT-RANGE and step is not a BigInt, throw a TypeError exception
else if (!isNumberRange && typeof step !== 'bigint') {
ThrowTypeError(JSMSG_ITERATOR_RANGE_STEP_NOT_BIGINT);
}
// Step 16: If step is +∞ or -∞, throw a RangeError exception.
if (typeof step === 'number' && !Number_isFinite(step)) {
ThrowRangeError(JSMSG_ITERATOR_RANGE_STEP_NOT_FINITE);
}
// Step 17: If step is zero and start is not end, throw a RangeError exception.
if (step === zero && start !== end) {
ThrowRangeError(JSMSG_ITERATOR_RANGE_STEP_ZERO);
}
// Step 19: Return CreateIteratorFromClosure(closure, "%NumericRangeIteratorPrototype%", %NumericRangeIteratorPrototype%).
return IteratorRangeGenerator(start, end, step, inclusiveEnd, zero, one);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.