Ignore:
Timestamp:
Mar 5, 2015, 6:57:17 AM (10 years ago)
Author:
Yusuke Suzuki
Message:

Upgrade ES6 Iterator interfaces
https://bugs.webkit.org/show_bug.cgi?id=141351

Reviewed by Filip Pizlo.

This patch upgrades the exising ES6 iterator to align the latest spec.
In the latest spec,

  1. Iterator.next returns object that implements IteratorResult interface { value: value, done, boolean }.
  2. Iterator.return is introduced. When the iteration is terminated by the abrupt completion,

it is called to close iterator state.

  1. Iterator.next of Array is moved from an iterator object to %ArrayIteratorPrototype%.

To upgrade it, we changes the bytecode that represents for-of loops.
And to embody the efficient iteration with an iterator object,
we implemented %ArrayIteratorPrototype%.next in JavaScript and
it is located in builtins/ArrayIterator.prototype.js.
Implementing it in JavaScript encourages inlining and
utilizes escape analysis for an iterator result object in DFG JIT.
And we dropped the intrinsic version of %ArrayIteratorPrototype%.next.

And we introduced IteratorOperations that is defined in the spec.
It aligns the iteration in the runtime to the latest spec.
Currently, Promise.all and Promise.race uses an iterable object.
However, Promise.all and Promise.race implementation is also based on the old spec.
Subsequent patches will upgrade it.

  • CMakeLists.txt:
  • DerivedSources.make:
  • JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
  • JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • builtins/ArrayIterator.prototype.js: Copied from Source/JavaScriptCore/runtime/ArrayIteratorPrototype.h.

(next):

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::emitReturn):
(JSC::BytecodeGenerator::emitThrowTypeError):
(JSC::BytecodeGenerator::emitEnumeration):
(JSC::BytecodeGenerator::emitIsObject):
(JSC::BytecodeGenerator::emitIsUndefined):

  • bytecompiler/BytecodeGenerator.h:
  • jit/ThunkGenerators.cpp:

(JSC::arrayIteratorNextThunkGenerator): Deleted.
(JSC::arrayIteratorNextKeyThunkGenerator): Deleted.
(JSC::arrayIteratorNextValueThunkGenerator): Deleted.

  • jit/ThunkGenerators.h:
  • runtime/ArgumentsIteratorPrototype.cpp:

(JSC::ArgumentsIteratorPrototype::finishCreation):
(JSC::argumentsIteratorPrototypeFuncNext):

  • runtime/ArrayIteratorPrototype.cpp:

(JSC::ArrayIteratorPrototype::finishCreation):
(JSC::ArrayIteratorPrototype::getOwnPropertySlot):
(JSC::arrayIteratorProtoFuncIterator):
(JSC::arrayIteratorPrototypeIterate): Deleted.

  • runtime/ArrayIteratorPrototype.h:
  • runtime/CommonIdentifiers.h:
  • runtime/Intrinsic.h:
  • runtime/IteratorOperations.cpp: Added.

(JSC::iteratorNext):
(JSC::iteratorValue):
(JSC::iteratorComplete):
(JSC::iteratorStep):
(JSC::iteratorClose):
(JSC::createIterResultObject):

  • runtime/IteratorOperations.h: Copied from Source/JavaScriptCore/runtime/ArrayIteratorPrototype.cpp.
  • runtime/JSArrayIterator.cpp:

(JSC::JSArrayIterator::finishCreation):
(JSC::JSArrayIterator::visitChildren): Deleted.
(JSC::createIteratorResult): Deleted.
(JSC::arrayIteratorNext): Deleted.
(JSC::arrayIteratorNextKey): Deleted.
(JSC::arrayIteratorNextValue): Deleted.
(JSC::arrayIteratorNextGeneric): Deleted.

  • runtime/JSArrayIterator.h:

(JSC::JSArrayIterator::JSArrayIterator):
(JSC::JSArrayIterator::iterationKind): Deleted.
(JSC::JSArrayIterator::iteratedObject): Deleted.
(JSC::JSArrayIterator::nextIndex): Deleted.
(JSC::JSArrayIterator::setNextIndex): Deleted.
(JSC::JSArrayIterator::finish): Deleted.
(JSC::JSArrayIterator::offsetOfIterationKind): Deleted.
(JSC::JSArrayIterator::offsetOfIteratedObject): Deleted.
(JSC::JSArrayIterator::offsetOfNextIndex): Deleted.

  • runtime/JSGlobalObject.cpp:

(JSC::JSGlobalObject::init):

  • runtime/JSPromiseConstructor.cpp:

(JSC::performPromiseRaceLoop):
(JSC::JSPromiseConstructorFuncRace):
(JSC::performPromiseAll):
(JSC::JSPromiseConstructorFuncAll):

  • runtime/MapIteratorPrototype.cpp:

(JSC::MapIteratorPrototype::finishCreation):
(JSC::MapIteratorPrototypeFuncNext):

  • runtime/SetIteratorPrototype.cpp:

(JSC::SetIteratorPrototype::finishCreation):
(JSC::SetIteratorPrototypeFuncNext):

  • runtime/VM.cpp:

(JSC::thunkGeneratorForIntrinsic):

  • tests/stress/array-iterators-next-with-call.js: Added.

(increment):
(for):

  • tests/stress/array-iterators-next.js: Added.

Revive the older Array iterator tests that manually call 'next' method.

  • tests/stress/custom-iterators.js: Added.

(iter.next):
(iter.Symbol.iterator):
(iter.return):
(iter.get next):
(iter.get return):
(iteratorInterfaceErrorTest.iter.next):
(iteratorInterfaceErrorTest.iter.Symbol.iterator):
(iteratorInterfaceErrorTest.iter.return):
(iteratorInterfaceErrorTest):
(iteratorInterfaceErrorTestReturn.iter.next):
(iteratorInterfaceErrorTestReturn.iter.Symbol.iterator):
(iteratorInterfaceErrorTestReturn.iter.return):
(iteratorInterfaceErrorTestReturn):
(iteratorInterfaceBreakTestReturn.iter.next):
(iteratorInterfaceBreakTestReturn.iter.Symbol.iterator):
(iteratorInterfaceBreakTestReturn.iter.return):
(iteratorInterfaceBreakTestReturn):

This tests the behavior of custom iterators.
'next' and 'return' of iterator work with for-of.

  • tests/stress/iterators-shape.js: Added.

(iteratorShape):
(sameNextMethods):
(set var):

This tests the shape of iterators; iterators of Array have 'next' method in %ArrayIteratorPrototype%.

  • tests/stress/map-iterators-next.js: Added.

(set var):
(.get if):
(otherKey):

  • tests/stress/set-iterators-next.js: Added.

(otherKey):

File:
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/builtins/ArrayIterator.prototype.js

    r181075 r181077  
    11/*
    2  * Copyright (C) 2013 Apple, Inc. All rights reserved.
     2 * Copyright (C) 2015 Yusuke Suzuki <[email protected]>.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2121 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    2222 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
     23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2424 */
    2525
    26 #ifndef ArrayIteratorPrototype_h
    27 #define ArrayIteratorPrototype_h
     26function next() {
     27    "use strict";
    2828
    29 #include "JSObject.h"
     29    if (this == null)
     30        throw new @TypeError("%ArrayIteratorPrototype%.next requires that |this| not be null or undefined");
    3031
    31 namespace JSC {
     32    var itemKind = this.@arrayIterationKind;
     33    if (itemKind === undefined)
     34        throw new @TypeError("%ArrayIteratorPrototype%.next requires that |this| be Array Iterator Instance");
    3235
    33 class ArrayIteratorPrototype : public JSNonFinalObject {
    34 public:
    35     typedef JSNonFinalObject Base;
     36    var done = true;
     37    var value = undefined;
    3638
    37     static ArrayIteratorPrototype* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
    38     {
    39         ArrayIteratorPrototype* prototype = new (NotNull, allocateCell<ArrayIteratorPrototype>(vm.heap)) ArrayIteratorPrototype(vm, structure);
    40         prototype->finishCreation(vm, globalObject);
    41         return prototype;
     39    var array = this.@iteratedObject;
     40    if (array !== undefined) {
     41        var index = this.@arrayIteratorNextIndex;
     42        var length = array.length >>> 0;
     43        if (index >= length) {
     44            this.@iteratedObject = undefined;
     45        } else {
     46            this.@arrayIteratorNextIndex = index + 1;
     47            done = false;
     48            if (itemKind === @arrayIterationKindKey) {
     49                value = index;
     50            } else if (itemKind === @arrayIterationKindValue) {
     51                value = array[index];
     52            } else {
     53                value = [ index, array[index] ];
     54            }
     55        }
    4256    }
    4357
    44     DECLARE_INFO;
    45 
    46     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
    47     {
    48         return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
    49     }
    50 
    51 private:
    52     ArrayIteratorPrototype(VM& vm, Structure* structure)
    53         : Base(vm, structure)
    54     {
    55     }
    56     void finishCreation(VM&, JSGlobalObject*);
    57 };
    58 
     58    return {
     59        done: done,
     60        value: value
     61    };
    5962}
    60 
    61 #endif // !defined(ArrayIteratorPrototype_h)
Note: See TracChangeset for help on using the changeset viewer.