Changeset 181077 in webkit
- Timestamp:
- Mar 5, 2015 6:57:17 AM (9 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 7 added
- 22 edited
- 2 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/CMakeLists.txt
r180691 r181077 439 439 runtime/ErrorPrototype.cpp 440 440 runtime/ExceptionFuzz.cpp 441 runtime/ExceptionHelpers.cpp 441 runtime/ExceptionHelpers.cpp 442 442 runtime/Executable.cpp 443 443 runtime/FunctionConstructor.cpp … … 451 451 runtime/IntendedStructureChain.cpp 452 452 runtime/InternalFunction.cpp 453 runtime/IteratorOperations.cpp 453 454 runtime/JSAPIValueWrapper.cpp 454 455 runtime/JSLexicalEnvironment.cpp … … 580 581 set(JavaScriptCore_LUT_FILES 581 582 runtime/ArrayConstructor.cpp 583 runtime/ArrayIteratorPrototype.cpp 582 584 runtime/ArrayPrototype.cpp 583 585 runtime/BooleanPrototype.cpp -
trunk/Source/JavaScriptCore/ChangeLog
r181064 r181077 1 2015-03-05 Yusuke Suzuki <utatane.tea@gmail.com> 2 3 Upgrade ES6 Iterator interfaces 4 https://bugs.webkit.org/show_bug.cgi?id=141351 5 6 Reviewed by Filip Pizlo. 7 8 This patch upgrades the exising ES6 iterator to align the latest spec. 9 In the latest spec, 10 1. `Iterator.next` returns object that implements IteratorResult interface { value: value, done, boolean }. 11 2. `Iterator.return` is introduced. When the iteration is terminated by the abrupt completion, 12 it is called to close iterator state. 13 3. Iterator.next of Array is moved from an iterator object to `%ArrayIteratorPrototype%`. 14 15 To upgrade it, we changes the bytecode that represents for-of loops. 16 And to embody the efficient iteration with an iterator object, 17 we implemented %ArrayIteratorPrototype%.next in JavaScript and 18 it is located in builtins/ArrayIterator.prototype.js. 19 Implementing it in JavaScript encourages inlining and 20 utilizes escape analysis for an iterator result object in DFG JIT. 21 And we dropped the intrinsic version of %ArrayIteratorPrototype%.next. 22 23 And we introduced IteratorOperations that is defined in the spec. 24 It aligns the iteration in the runtime to the latest spec. 25 Currently, Promise.all and Promise.race uses an iterable object. 26 However, Promise.all and Promise.race implementation is also based on the old spec. 27 Subsequent patches will upgrade it. 28 29 * CMakeLists.txt: 30 * DerivedSources.make: 31 * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: 32 * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: 33 * JavaScriptCore.xcodeproj/project.pbxproj: 34 * builtins/ArrayIterator.prototype.js: Copied from Source/JavaScriptCore/runtime/ArrayIteratorPrototype.h. 35 (next): 36 * bytecompiler/BytecodeGenerator.cpp: 37 (JSC::BytecodeGenerator::emitReturn): 38 (JSC::BytecodeGenerator::emitThrowTypeError): 39 (JSC::BytecodeGenerator::emitEnumeration): 40 (JSC::BytecodeGenerator::emitIsObject): 41 (JSC::BytecodeGenerator::emitIsUndefined): 42 * bytecompiler/BytecodeGenerator.h: 43 * jit/ThunkGenerators.cpp: 44 (JSC::arrayIteratorNextThunkGenerator): Deleted. 45 (JSC::arrayIteratorNextKeyThunkGenerator): Deleted. 46 (JSC::arrayIteratorNextValueThunkGenerator): Deleted. 47 * jit/ThunkGenerators.h: 48 * runtime/ArgumentsIteratorPrototype.cpp: 49 (JSC::ArgumentsIteratorPrototype::finishCreation): 50 (JSC::argumentsIteratorPrototypeFuncNext): 51 * runtime/ArrayIteratorPrototype.cpp: 52 (JSC::ArrayIteratorPrototype::finishCreation): 53 (JSC::ArrayIteratorPrototype::getOwnPropertySlot): 54 (JSC::arrayIteratorProtoFuncIterator): 55 (JSC::arrayIteratorPrototypeIterate): Deleted. 56 * runtime/ArrayIteratorPrototype.h: 57 * runtime/CommonIdentifiers.h: 58 * runtime/Intrinsic.h: 59 * runtime/IteratorOperations.cpp: Added. 60 (JSC::iteratorNext): 61 (JSC::iteratorValue): 62 (JSC::iteratorComplete): 63 (JSC::iteratorStep): 64 (JSC::iteratorClose): 65 (JSC::createIterResultObject): 66 * runtime/IteratorOperations.h: Copied from Source/JavaScriptCore/runtime/ArrayIteratorPrototype.cpp. 67 * runtime/JSArrayIterator.cpp: 68 (JSC::JSArrayIterator::finishCreation): 69 (JSC::JSArrayIterator::visitChildren): Deleted. 70 (JSC::createIteratorResult): Deleted. 71 (JSC::arrayIteratorNext): Deleted. 72 (JSC::arrayIteratorNextKey): Deleted. 73 (JSC::arrayIteratorNextValue): Deleted. 74 (JSC::arrayIteratorNextGeneric): Deleted. 75 * runtime/JSArrayIterator.h: 76 (JSC::JSArrayIterator::JSArrayIterator): 77 (JSC::JSArrayIterator::iterationKind): Deleted. 78 (JSC::JSArrayIterator::iteratedObject): Deleted. 79 (JSC::JSArrayIterator::nextIndex): Deleted. 80 (JSC::JSArrayIterator::setNextIndex): Deleted. 81 (JSC::JSArrayIterator::finish): Deleted. 82 (JSC::JSArrayIterator::offsetOfIterationKind): Deleted. 83 (JSC::JSArrayIterator::offsetOfIteratedObject): Deleted. 84 (JSC::JSArrayIterator::offsetOfNextIndex): Deleted. 85 * runtime/JSGlobalObject.cpp: 86 (JSC::JSGlobalObject::init): 87 * runtime/JSPromiseConstructor.cpp: 88 (JSC::performPromiseRaceLoop): 89 (JSC::JSPromiseConstructorFuncRace): 90 (JSC::performPromiseAll): 91 (JSC::JSPromiseConstructorFuncAll): 92 * runtime/MapIteratorPrototype.cpp: 93 (JSC::MapIteratorPrototype::finishCreation): 94 (JSC::MapIteratorPrototypeFuncNext): 95 * runtime/SetIteratorPrototype.cpp: 96 (JSC::SetIteratorPrototype::finishCreation): 97 (JSC::SetIteratorPrototypeFuncNext): 98 * runtime/VM.cpp: 99 (JSC::thunkGeneratorForIntrinsic): 100 * tests/stress/array-iterators-next-with-call.js: Added. 101 (increment): 102 (for): 103 * tests/stress/array-iterators-next.js: Added. 104 105 Revive the older Array iterator tests that manually call 'next' method. 106 107 * tests/stress/custom-iterators.js: Added. 108 (iter.next): 109 (iter.Symbol.iterator): 110 (iter.return): 111 (iter.get next): 112 (iter.get return): 113 (iteratorInterfaceErrorTest.iter.next): 114 (iteratorInterfaceErrorTest.iter.Symbol.iterator): 115 (iteratorInterfaceErrorTest.iter.return): 116 (iteratorInterfaceErrorTest): 117 (iteratorInterfaceErrorTestReturn.iter.next): 118 (iteratorInterfaceErrorTestReturn.iter.Symbol.iterator): 119 (iteratorInterfaceErrorTestReturn.iter.return): 120 (iteratorInterfaceErrorTestReturn): 121 (iteratorInterfaceBreakTestReturn.iter.next): 122 (iteratorInterfaceBreakTestReturn.iter.Symbol.iterator): 123 (iteratorInterfaceBreakTestReturn.iter.return): 124 (iteratorInterfaceBreakTestReturn): 125 126 This tests the behavior of custom iterators. 127 'next' and 'return' of iterator work with for-of. 128 129 * tests/stress/iterators-shape.js: Added. 130 (iteratorShape): 131 (sameNextMethods): 132 (set var): 133 134 This tests the shape of iterators; iterators of Array have 'next' method in %ArrayIteratorPrototype%. 135 136 * tests/stress/map-iterators-next.js: Added. 137 (set var): 138 (.get if): 139 (otherKey): 140 * tests/stress/set-iterators-next.js: Added. 141 (otherKey): 142 1 143 2015-03-04 Yusuke Suzuki <utatane.tea@gmail.com> 2 144 -
trunk/Source/JavaScriptCore/DerivedSources.make
r179429 r181077 37 37 all : \ 38 38 ArrayConstructor.lut.h \ 39 ArrayIteratorPrototype.lut.h \ 39 40 ArrayPrototype.lut.h \ 40 41 BooleanPrototype.lut.h \ -
trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj
r180691 r181077 719 719 <ClCompile Include="..\runtime\IntendedStructureChain.cpp" /> 720 720 <ClCompile Include="..\runtime\InternalFunction.cpp" /> 721 <ClCompile Include="..\runtime\IteratorOperations.cpp" /> 721 722 <ClCompile Include="..\runtime\JSAPIValueWrapper.cpp" /> 722 723 <ClCompile Include="..\runtime\JSLexicalEnvironment.cpp" /> … … 855 856 <ItemGroup> 856 857 <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\ArrayConstructor.lut.h" /> 858 <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\ArrayIteratorPrototype.lut.h" /> 857 859 <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\ArrayPrototype.lut.h" /> 858 860 <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\BooleanPrototype.lut.h" /> … … 1493 1495 <ClInclude Include="..\runtime\InternalFunction.h" /> 1494 1496 <ClInclude Include="..\runtime\Intrinsic.h" /> 1497 <ClInclude Include="..\runtime\IteratorOperations.h" /> 1495 1498 <ClInclude Include="..\runtime\JSAPIValueWrapper.h" /> 1496 1499 <ClInclude Include="..\runtime\JSLexicalEnvironment.h" /> -
trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters
r180570 r181077 631 631 <Filter>runtime</Filter> 632 632 </ClCompile> 633 <ClCompile Include="..\runtime\IteratorOperations.cpp"> 634 <Filter>runtime</Filter> 635 </ClCompile> 633 636 <ClCompile Include="..\runtime\JSLexicalEnvironment.cpp"> 634 637 <Filter>runtime</Filter> … … 2662 2665 <Filter>runtime</Filter> 2663 2666 </ClInclude> 2667 <ClInclude Include="..\runtime\IteratorOperations.h"> 2668 <Filter>runtime</Filter> 2669 </ClInclude> 2664 2670 <ClInclude Include="..\runtime\JSLexicalEnvironment.h"> 2665 2671 <Filter>runtime</Filter> … … 3063 3069 </ClInclude> 3064 3070 <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\StringConstructor.lut.h"> 3071 <Filter>Derived Sources</Filter> 3072 </ClInclude> 3073 <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\ArrayIteratorPrototype.lut.h"> 3065 3074 <Filter>Derived Sources</Filter> 3066 3075 </ClInclude> -
trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r181010 r181077 945 945 65FB5117184EEE7000C12B70 /* ProtoCallFrame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65FB5116184EE9BC00C12B70 /* ProtoCallFrame.cpp */; }; 946 946 6AD2CB4D19B9140100065719 /* DebuggerEvalEnabler.h in Headers */ = {isa = PBXBuildFile; fileRef = 6AD2CB4C19B9140100065719 /* DebuggerEvalEnabler.h */; settings = {ATTRIBUTES = (Private, ); }; }; 947 70113D4B1A8DB093003848C4 /* IteratorOperations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 70113D491A8DB093003848C4 /* IteratorOperations.cpp */; }; 948 70113D4C1A8DB093003848C4 /* IteratorOperations.h in Headers */ = {isa = PBXBuildFile; fileRef = 70113D4A1A8DB093003848C4 /* IteratorOperations.h */; settings = {ATTRIBUTES = (Private, ); }; }; 947 949 705B41AB1A6E501E00716757 /* Symbol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 705B41A31A6E501E00716757 /* Symbol.cpp */; }; 948 950 705B41AC1A6E501E00716757 /* Symbol.h in Headers */ = {isa = PBXBuildFile; fileRef = 705B41A41A6E501E00716757 /* Symbol.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 2627 2629 65FB5116184EE9BC00C12B70 /* ProtoCallFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProtoCallFrame.cpp; sourceTree = "<group>"; }; 2628 2630 6AD2CB4C19B9140100065719 /* DebuggerEvalEnabler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebuggerEvalEnabler.h; sourceTree = "<group>"; }; 2631 70113D491A8DB093003848C4 /* IteratorOperations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IteratorOperations.cpp; sourceTree = "<group>"; }; 2632 70113D4A1A8DB093003848C4 /* IteratorOperations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IteratorOperations.h; sourceTree = "<group>"; }; 2629 2633 704FD35305697E6D003DBED9 /* BooleanObject.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = BooleanObject.h; sourceTree = "<group>"; tabWidth = 8; }; 2630 2634 705B41A31A6E501E00716757 /* Symbol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Symbol.cpp; sourceTree = "<group>"; }; … … 4339 4343 BC11667A0E199C05008066DD /* InternalFunction.h */, 4340 4344 86BF642A148DB2B5004DE36A /* Intrinsic.h */, 4345 70113D491A8DB093003848C4 /* IteratorOperations.cpp */, 4346 70113D4A1A8DB093003848C4 /* IteratorOperations.h */, 4341 4347 A76140CB182982CB00750624 /* JSArgumentsIterator.cpp */, 4342 4348 A76140CC182982CB00750624 /* JSArgumentsIterator.h */, … … 5888 5894 1429D77C0ED20D7300B89619 /* Interpreter.h in Headers */, 5889 5895 860BD801148EA6F200112B2F /* Intrinsic.h in Headers */, 5896 70113D4C1A8DB093003848C4 /* IteratorOperations.h in Headers */, 5890 5897 BC18C4130E16F5CD00B34460 /* JavaScript.h in Headers */, 5891 5898 0F2B9CF519D0BAC100B1D1B5 /* FTLExitPropertyValue.h in Headers */, … … 7094 7101 147F39CF107EC37600427A48 /* InternalFunction.cpp in Sources */, 7095 7102 1429D7D40ED2128200B89619 /* Interpreter.cpp in Sources */, 7103 70113D4B1A8DB093003848C4 /* IteratorOperations.cpp in Sources */, 7096 7104 A503FA19188E0FB000110F14 /* JavaScriptCallFrame.cpp in Sources */, 7097 7105 1429D92F0ED22D7000B89619 /* JIT.cpp in Sources */, -
trunk/Source/JavaScriptCore/builtins/ArrayIterator.prototype.js
r181075 r181077 1 1 /* 2 * Copyright (C) 201 3 Apple, Inc. All rights reserved.2 * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 21 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 22 * (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. 24 24 */ 25 25 26 #ifndef ArrayIteratorPrototype_h 27 #define ArrayIteratorPrototype_h 26 function next() { 27 "use strict"; 28 28 29 #include "JSObject.h" 29 if (this == null) 30 throw new @TypeError("%ArrayIteratorPrototype%.next requires that |this| not be null or undefined"); 30 31 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"); 32 35 33 class ArrayIteratorPrototype : public JSNonFinalObject { 34 public: 35 typedef JSNonFinalObject Base; 36 var done = true; 37 var value = undefined; 36 38 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 } 42 56 } 43 57 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 }; 59 62 } 60 61 #endif // !defined(ArrayIteratorPrototype_h) -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
r180875 r181077 1906 1906 if (isConstructor() && src->index() != m_thisRegister.index()) { 1907 1907 RefPtr<Label> isObjectLabel = newLabel(); 1908 RefPtr<RegisterID> isObjectRegister = newTemporary(); 1909 1910 emitOpcode(op_is_object); 1911 instructions().append(isObjectRegister->index()); 1912 instructions().append(src->index()); 1913 1914 size_t begin = instructions().size(); 1915 emitOpcode(op_jtrue); 1916 instructions().append(isObjectRegister->index()); 1917 instructions().append(isObjectLabel->bind(begin, instructions().size())); 1908 1909 emitJumpIfTrue(emitIsObject(newTemporary(), src), isObjectLabel.get()); 1918 1910 1919 1911 emitUnaryNoDstOp(op_ret, &m_thisRegister); … … 2353 2345 } 2354 2346 2347 void BytecodeGenerator::emitThrowTypeError(const String& message) 2348 { 2349 emitOpcode(op_throw_static_error); 2350 instructions().append(addConstantValue(addStringConstant(Identifier(m_vm, message)))->index()); 2351 instructions().append(false); 2352 } 2353 2355 2354 void BytecodeGenerator::emitPushFunctionNameScope(RegisterID* dst, const Identifier& property, RegisterID* value, unsigned attributes) 2356 2355 { … … 2552 2551 RefPtr<RegisterID> iterator = emitGetById(newTemporary(), subject.get(), propertyNames().iteratorPrivateName); 2553 2552 { 2554 CallArguments args(*this, 0);2553 CallArguments args(*this, nullptr); 2555 2554 emitMove(args.thisRegister(), subject.get()); 2556 2555 emitCall(iterator.get(), iterator.get(), NoExpectedFunction, args, node->divot(), node->divotStart(), node->divotEnd()); 2557 2556 } 2558 RefPtr<RegisterID> iteratorNext = emitGetById(newTemporary(), iterator.get(), propertyNames().iteratorNextPrivateName);2559 2557 RefPtr<RegisterID> value = newTemporary(); 2560 2558 emitLoad(value.get(), jsUndefined()); … … 2563 2561 2564 2562 RefPtr<Label> loopStart = newLabel(); 2563 RefPtr<Label> iteratorDone = newLabel(); 2565 2564 emitLabel(loopStart.get()); 2566 2565 emitLoopHint(); 2566 2567 RefPtr<Label> tryStartLabel = newLabel(); 2568 emitLabel(tryStartLabel.get()); 2569 TryData* tryData = pushTry(tryStartLabel.get()); 2567 2570 callBack(*this, value.get()); 2571 RefPtr<Label> catchHere = emitLabel(newLabel().get()); 2572 2568 2573 emitLabel(scope->continueTarget()); 2569 CallArguments nextArguments(*this, 0, 1); 2570 emitMove(nextArguments.thisRegister(), iterator.get()); 2571 emitMove(nextArguments.argumentRegister(0), value.get()); 2572 emitCall(value.get(), iteratorNext.get(), NoExpectedFunction, nextArguments, node->divot(), node->divotStart(), node->divotEnd()); 2573 RefPtr<RegisterID> result = newTemporary(); 2574 emitJumpIfFalse(emitEqualityOp(op_stricteq, result.get(), value.get(), emitLoad(0, JSValue(vm()->iterationTerminator.get()))), loopStart.get()); 2574 { 2575 RefPtr<RegisterID> next = emitGetById(newTemporary(), iterator.get(), propertyNames().next); 2576 CallArguments nextArguments(*this, nullptr); 2577 emitMove(nextArguments.thisRegister(), iterator.get()); 2578 emitCall(value.get(), next.get(), NoExpectedFunction, nextArguments, node->divot(), node->divotStart(), node->divotEnd()); 2579 } 2580 { 2581 RefPtr<Label> typeIsObject = newLabel(); 2582 emitJumpIfTrue(emitIsObject(newTemporary(), value.get()), typeIsObject.get()); 2583 emitThrowTypeError(ASCIILiteral("Iterator result interface is not an object.")); 2584 emitLabel(typeIsObject.get()); 2585 } 2586 emitJumpIfTrue(emitGetById(newTemporary(), value.get(), propertyNames().done), iteratorDone.get()); 2587 emitGetById(value.get(), value.get(), propertyNames().value); 2588 emitJump(loopStart.get()); 2589 2590 // IteratorClose sequence for throw-ed control flow. 2591 { 2592 RefPtr<RegisterID> exceptionRegister = popTryAndEmitCatch(tryData, newTemporary(), catchHere.get()); 2593 RefPtr<Label> rethrow = newLabel(); 2594 2595 RefPtr<RegisterID> returnMethod = emitGetById(newTemporary(), iterator.get(), propertyNames().returnKeyword); 2596 emitJumpIfTrue(emitIsUndefined(newTemporary(), returnMethod.get()), rethrow.get()); 2597 2598 RefPtr<Label> returnCallTryStart = newLabel(); 2599 emitLabel(returnCallTryStart.get()); 2600 TryData* returnCallTryData = pushTry(returnCallTryStart.get()); 2601 2602 CallArguments returnArguments(*this, nullptr); 2603 emitMove(returnArguments.thisRegister(), iterator.get()); 2604 emitCall(value.get(), returnMethod.get(), NoExpectedFunction, returnArguments, node->divot(), node->divotStart(), node->divotEnd()); 2605 2606 RefPtr<Label> returnCallCatchHere = emitLabel(newLabel().get()); 2607 emitJump(rethrow.get()); 2608 2609 popTryAndEmitCatch(returnCallTryData, newTemporary(), returnCallCatchHere.get()); 2610 emitLabel(rethrow.get()); 2611 emitThrow(exceptionRegister.get()); 2612 } 2613 2614 // IteratorClose sequence for break-ed control flow. 2575 2615 emitLabel(scope->breakTarget()); 2616 { 2617 RefPtr<RegisterID> returnMethod = emitGetById(newTemporary(), iterator.get(), propertyNames().returnKeyword); 2618 emitJumpIfTrue(emitIsUndefined(newTemporary(), returnMethod.get()), iteratorDone.get()); 2619 2620 CallArguments returnArguments(*this, nullptr); 2621 emitMove(returnArguments.thisRegister(), iterator.get()); 2622 emitCall(value.get(), returnMethod.get(), NoExpectedFunction, returnArguments, node->divot(), node->divotStart(), node->divotEnd()); 2623 emitJumpIfTrue(emitIsObject(newTemporary(), value.get()), iteratorDone.get()); 2624 emitThrowTypeError(ASCIILiteral("Iterator result interface is not an object.")); 2625 } 2626 2627 emitLabel(iteratorDone.get()); 2576 2628 } 2577 2629 … … 2647 2699 instructions().append(dst->index()); 2648 2700 instructions().append(index->index()); 2701 return dst; 2702 } 2703 2704 2705 RegisterID* BytecodeGenerator::emitIsObject(RegisterID* dst, RegisterID* src) 2706 { 2707 emitOpcode(op_is_object); 2708 instructions().append(dst->index()); 2709 instructions().append(src->index()); 2710 return dst; 2711 } 2712 2713 RegisterID* BytecodeGenerator::emitIsUndefined(RegisterID* dst, RegisterID* src) 2714 { 2715 emitOpcode(op_is_undefined); 2716 instructions().append(dst->index()); 2717 instructions().append(src->index()); 2649 2718 return dst; 2650 2719 } -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
r180875 r181077 530 530 RegisterID* emitToIndexString(RegisterID* dst, RegisterID* index); 531 531 532 RegisterID* emitIsObject(RegisterID* dst, RegisterID* src); 533 RegisterID* emitIsUndefined(RegisterID* dst, RegisterID* src); 534 532 535 void emitReadOnlyExceptionIfNeeded(); 533 536 … … 544 547 545 548 void emitThrowReferenceError(const String& message); 549 void emitThrowTypeError(const String& message); 546 550 547 551 void emitPushFunctionNameScope(RegisterID* dst, const Identifier& property, RegisterID* value, unsigned attributes); -
trunk/Source/JavaScriptCore/jit/ThunkGenerators.cpp
r179478 r181077 1045 1045 } 1046 1046 1047 static MacroAssemblerCodeRef arrayIteratorNextThunkGenerator(VM* vm, ArrayIterationKind kind)1048 {1049 typedef SpecializedThunkJIT::TrustedImm32 TrustedImm32;1050 typedef SpecializedThunkJIT::TrustedImmPtr TrustedImmPtr;1051 typedef SpecializedThunkJIT::Address Address;1052 typedef SpecializedThunkJIT::BaseIndex BaseIndex;1053 typedef SpecializedThunkJIT::Jump Jump;1054 1055 SpecializedThunkJIT jit(vm);1056 // Make sure we're being called on an array iterator, and load m_iteratedObject, and m_nextIndex into regT0 and regT1 respectively1057 jit.loadArgumentWithSpecificClass(JSArrayIterator::info(), SpecializedThunkJIT::ThisArgument, SpecializedThunkJIT::regT4, SpecializedThunkJIT::regT1);1058 1059 // Early exit if we don't have a thunk for this form of iteration1060 jit.appendFailure(jit.branch32(SpecializedThunkJIT::AboveOrEqual, Address(SpecializedThunkJIT::regT4, JSArrayIterator::offsetOfIterationKind()), TrustedImm32(ArrayIterateKeyValue)));1061 1062 jit.loadPtr(Address(SpecializedThunkJIT::regT4, JSArrayIterator::offsetOfIteratedObject()), SpecializedThunkJIT::regT0);1063 1064 jit.load32(Address(SpecializedThunkJIT::regT4, JSArrayIterator::offsetOfNextIndex()), SpecializedThunkJIT::regT1);1065 1066 // Pull out the butterfly from iteratedObject1067 jit.load8(Address(SpecializedThunkJIT::regT0, JSCell::indexingTypeOffset()), SpecializedThunkJIT::regT3);1068 jit.loadPtr(Address(SpecializedThunkJIT::regT0, JSObject::butterflyOffset()), SpecializedThunkJIT::regT2);1069 Jump nullButterfly = jit.branchTestPtr(SpecializedThunkJIT::Zero, SpecializedThunkJIT::regT2);1070 1071 Jump notDone = jit.branch32(SpecializedThunkJIT::Below, SpecializedThunkJIT::regT1, Address(SpecializedThunkJIT::regT2, Butterfly::offsetOfPublicLength()));1072 1073 nullButterfly.link(&jit);1074 1075 // Return the termination signal to indicate that we've finished1076 jit.move(TrustedImmPtr(vm->iterationTerminator.get()), SpecializedThunkJIT::regT0);1077 jit.returnJSCell(SpecializedThunkJIT::regT0);1078 1079 notDone.link(&jit);1080 1081 if (kind == ArrayIterateKey) {1082 jit.add32(TrustedImm32(1), Address(SpecializedThunkJIT::regT4, JSArrayIterator::offsetOfNextIndex()));1083 jit.returnInt32(SpecializedThunkJIT::regT1);1084 return jit.finalize(vm->jitStubs->ctiNativeTailCall(vm), "array-iterator-next-key");1085 1086 }1087 ASSERT(kind == ArrayIterateValue);1088 1089 // Okay, now we're returning a value so make sure we're inside the vector size1090 jit.appendFailure(jit.branch32(SpecializedThunkJIT::AboveOrEqual, SpecializedThunkJIT::regT1, Address(SpecializedThunkJIT::regT2, Butterfly::offsetOfVectorLength())));1091 1092 // So now we perform inline loads for int32, value/undecided, and double storage1093 Jump undecidedStorage = jit.branch32(SpecializedThunkJIT::Equal, SpecializedThunkJIT::regT3, TrustedImm32(ArrayWithUndecided));1094 Jump notContiguousStorage = jit.branch32(SpecializedThunkJIT::NotEqual, SpecializedThunkJIT::regT3, TrustedImm32(ArrayWithContiguous));1095 1096 undecidedStorage.link(&jit);1097 1098 jit.loadPtr(Address(SpecializedThunkJIT::regT0, JSObject::butterflyOffset()), SpecializedThunkJIT::regT2);1099 1100 #if USE(JSVALUE64)1101 jit.load64(BaseIndex(SpecializedThunkJIT::regT2, SpecializedThunkJIT::regT1, SpecializedThunkJIT::TimesEight), SpecializedThunkJIT::regT0);1102 Jump notHole = jit.branchTest64(SpecializedThunkJIT::NonZero, SpecializedThunkJIT::regT0);1103 jit.move(JSInterfaceJIT::TrustedImm64(ValueUndefined), JSInterfaceJIT::regT0);1104 notHole.link(&jit);1105 jit.addPtr(TrustedImm32(1), Address(SpecializedThunkJIT::regT4, JSArrayIterator::offsetOfNextIndex()));1106 jit.returnJSValue(SpecializedThunkJIT::regT0);1107 #else1108 jit.load32(BaseIndex(SpecializedThunkJIT::regT2, SpecializedThunkJIT::regT1, SpecializedThunkJIT::TimesEight, JSValue::offsetOfTag()), SpecializedThunkJIT::regT3);1109 Jump notHole = jit.branch32(SpecializedThunkJIT::NotEqual, SpecializedThunkJIT::regT3, TrustedImm32(JSValue::EmptyValueTag));1110 jit.move(JSInterfaceJIT::TrustedImm32(JSValue::UndefinedTag), JSInterfaceJIT::regT1);1111 jit.move(JSInterfaceJIT::TrustedImm32(0), JSInterfaceJIT::regT0);1112 jit.add32(TrustedImm32(1), Address(SpecializedThunkJIT::regT4, JSArrayIterator::offsetOfNextIndex()));1113 jit.returnJSValue(SpecializedThunkJIT::regT0, JSInterfaceJIT::regT1);1114 notHole.link(&jit);1115 jit.load32(BaseIndex(SpecializedThunkJIT::regT2, SpecializedThunkJIT::regT1, SpecializedThunkJIT::TimesEight, JSValue::offsetOfPayload()), SpecializedThunkJIT::regT0);1116 jit.add32(TrustedImm32(1), Address(SpecializedThunkJIT::regT4, JSArrayIterator::offsetOfNextIndex()));1117 jit.move(SpecializedThunkJIT::regT3, SpecializedThunkJIT::regT1);1118 jit.returnJSValue(SpecializedThunkJIT::regT0, SpecializedThunkJIT::regT1);1119 #endif1120 notContiguousStorage.link(&jit);1121 1122 Jump notInt32Storage = jit.branch32(SpecializedThunkJIT::NotEqual, SpecializedThunkJIT::regT3, TrustedImm32(ArrayWithInt32));1123 jit.loadPtr(Address(SpecializedThunkJIT::regT0, JSObject::butterflyOffset()), SpecializedThunkJIT::regT2);1124 jit.load32(BaseIndex(SpecializedThunkJIT::regT2, SpecializedThunkJIT::regT1, SpecializedThunkJIT::TimesEight, JSValue::offsetOfPayload()), SpecializedThunkJIT::regT0);1125 jit.add32(TrustedImm32(1), Address(SpecializedThunkJIT::regT4, JSArrayIterator::offsetOfNextIndex()));1126 jit.returnInt32(SpecializedThunkJIT::regT0);1127 notInt32Storage.link(&jit);1128 1129 jit.appendFailure(jit.branch32(SpecializedThunkJIT::NotEqual, SpecializedThunkJIT::regT3, TrustedImm32(ArrayWithDouble)));1130 jit.loadPtr(Address(SpecializedThunkJIT::regT0, JSObject::butterflyOffset()), SpecializedThunkJIT::regT2);1131 jit.loadDouble(BaseIndex(SpecializedThunkJIT::regT2, SpecializedThunkJIT::regT1, SpecializedThunkJIT::TimesEight), SpecializedThunkJIT::fpRegT0);1132 jit.add32(TrustedImm32(1), Address(SpecializedThunkJIT::regT4, JSArrayIterator::offsetOfNextIndex()));1133 jit.returnDouble(SpecializedThunkJIT::fpRegT0);1134 1135 return jit.finalize(vm->jitStubs->ctiNativeTailCall(vm), "array-iterator-next-value");1136 }1137 1138 MacroAssemblerCodeRef arrayIteratorNextKeyThunkGenerator(VM* vm)1139 {1140 return arrayIteratorNextThunkGenerator(vm, ArrayIterateKey);1141 }1142 1143 MacroAssemblerCodeRef arrayIteratorNextValueThunkGenerator(VM* vm)1144 {1145 return arrayIteratorNextThunkGenerator(vm, ArrayIterateValue);1146 }1147 1148 1047 } 1149 1048 -
trunk/Source/JavaScriptCore/jit/ThunkGenerators.h
r179478 r181077 131 131 MacroAssemblerCodeRef powThunkGenerator(VM*); 132 132 MacroAssemblerCodeRef imulThunkGenerator(VM*); 133 MacroAssemblerCodeRef arrayIteratorNextKeyThunkGenerator(VM*);134 MacroAssemblerCodeRef arrayIteratorNextValueThunkGenerator(VM*);135 133 136 134 } -
trunk/Source/JavaScriptCore/runtime/ArgumentsIteratorPrototype.cpp
r171824 r181077 27 27 #include "ArgumentsIteratorPrototype.h" 28 28 29 #include "IteratorOperations.h" 29 30 #include "JSArgumentsIterator.h" 30 31 #include "JSCInlines.h" … … 44 45 45 46 JSC_NATIVE_FUNCTION(vm.propertyNames->iteratorPrivateName, argumentsIteratorPrototypeFuncIterator, DontEnum, 0); 46 JSC_NATIVE_FUNCTION(vm.propertyNames-> iteratorNextPrivateName, argumentsIteratorPrototypeFuncNext, DontEnum, 0);47 JSC_NATIVE_FUNCTION(vm.propertyNames->next, argumentsIteratorPrototypeFuncNext, DontEnum, 0); 47 48 } 48 49 … … 56 57 JSValue result; 57 58 if (jsCast<JSArgumentsIterator*>(callFrame->thisValue())->next(callFrame, result)) 58 return JSValue::encode( result);59 return JSValue::encode(c allFrame->vm().iterationTerminator.get());59 return JSValue::encode(createIterResultObject(callFrame, result, false)); 60 return JSValue::encode(createIterResultObject(callFrame, jsUndefined(), true)); 60 61 } 61 62 -
trunk/Source/JavaScriptCore/runtime/ArrayIteratorPrototype.cpp
r171824 r181077 21 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 22 * (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. 24 24 */ 25 25 … … 27 27 #include "ArrayIteratorPrototype.h" 28 28 29 namespace JSC { 30 31 static EncodedJSValue JSC_HOST_CALL arrayIteratorProtoFuncIterator(ExecState*); 32 33 } 34 35 #include "ArrayIteratorPrototype.lut.h" 36 37 #include "IteratorOperations.h" 29 38 #include "JSArrayIterator.h" 39 #include "JSCInlines.h" 30 40 #include "JSCJSValueInlines.h" 31 41 #include "JSCellInlines.h" … … 36 46 namespace JSC { 37 47 38 const ClassInfo ArrayIteratorPrototype::s_info = { "Array Iterator", &Base::s_info, 0, CREATE_METHOD_TABLE(ArrayIteratorPrototype) };39 48 40 static EncodedJSValue JSC_HOST_CALL arrayIteratorPrototypeIterate(ExecState*); 49 const ClassInfo ArrayIteratorPrototype::s_info = { "Array Iterator", &Base::s_info, &arrayIteratorPrototypeTable, CREATE_METHOD_TABLE(ArrayIteratorPrototype) }; 50 51 /* Source for ArrayIteratorPrototype.lut.h 52 @begin arrayIteratorPrototypeTable 53 next arrayIteratorProtoFuncNext DontEnum|Function 0 54 @end 55 */ 41 56 42 57 void ArrayIteratorPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject) … … 45 60 ASSERT(inherits(info())); 46 61 vm.prototypeMap.addPrototype(this); 47 48 JSC_NATIVE_FUNCTION(vm.propertyNames->iteratorPrivateName, arrayIteratorPrototypeIterate, DontEnum, 0); 62 JSC_NATIVE_FUNCTION(vm.propertyNames->iteratorPrivateName, arrayIteratorProtoFuncIterator, DontEnum, 0); 49 63 } 50 64 51 EncodedJSValue JSC_HOST_CALL arrayIteratorPrototypeIterate(CallFrame* callFrame)65 bool ArrayIteratorPrototype::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot) 52 66 { 53 return JSValue::encode(callFrame->thisValue());67 return getStaticFunctionSlot<Base>(exec, arrayIteratorPrototypeTable, jsCast<ArrayIteratorPrototype*>(object), propertyName, slot); 54 68 } 55 69 70 // ------------------------------ Array Functions ---------------------------- 71 72 EncodedJSValue JSC_HOST_CALL arrayIteratorProtoFuncIterator(ExecState* exec) 73 { 74 return JSValue::encode(exec->thisValue()); 56 75 } 76 77 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/ArrayIteratorPrototype.h
r156791 r181077 49 49 } 50 50 51 protected: 52 static const unsigned StructureFlags = OverridesGetOwnPropertySlot | Base::StructureFlags; 53 51 54 private: 52 55 ArrayIteratorPrototype(VM& vm, Structure* structure) … … 54 57 { 55 58 } 59 56 60 void finishCreation(VM&, JSGlobalObject*); 61 static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&); 57 62 }; 58 63 -
trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h
r180370 r181077 236 236 #define JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_PROPERTY_NAME(macro) \ 237 237 JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL(macro) \ 238 macro(iteratorNext) \ 238 macro(iteratedObject) \ 239 macro(arrayIteratorNextIndex) \ 240 macro(arrayIterationKind) \ 241 macro(arrayIterationKindKey) \ 242 macro(arrayIterationKindValue) \ 243 macro(arrayIterationKindKeyValue) \ 239 244 macro(resolve) \ 240 245 macro(reject) \ -
trunk/Source/JavaScriptCore/runtime/Intrinsic.h
r171096 r181077 53 53 IMulIntrinsic, 54 54 FRoundIntrinsic, 55 ArrayIteratorNextValueIntrinsic, 56 ArrayIteratorNextKeyIntrinsic, 57 ArrayIteratorNextGenericIntrinsic, 58 55 59 56 // Debugging intrinsics. These are meant to be used as testing hacks within 60 57 // jsc.cpp and should never be exposed to users. -
trunk/Source/JavaScriptCore/runtime/IteratorOperations.h
r181075 r181077 1 1 /* 2 * Copyright (C) 201 3 Apple, Inc. All rights reserved.2 * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 21 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 22 * (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. 24 24 */ 25 25 26 #i nclude "config.h"27 # include "ArrayIteratorPrototype.h"26 #ifndef IteratorOperations_h 27 #define IteratorOperations_h 28 28 29 #include "JSArrayIterator.h" 30 #include "JSCJSValueInlines.h" 31 #include "JSCellInlines.h" 32 #include "JSGlobalObject.h" 33 #include "ObjectConstructor.h" 34 #include "StructureInlines.h" 29 #include "JSCJSValue.h" 30 #include "JSObject.h" 35 31 36 32 namespace JSC { 37 33 38 const ClassInfo ArrayIteratorPrototype::s_info = { "Array Iterator", &Base::s_info, 0, CREATE_METHOD_TABLE(ArrayIteratorPrototype) }; 34 JSValue iteratorNext(ExecState*, JSValue iterator, JSValue); 35 JSValue iteratorNext(ExecState*, JSValue iterator); 36 JSValue iteratorValue(ExecState*, JSValue iterResult); 37 bool iteratorComplete(ExecState*, JSValue iterResult); 38 JSValue iteratorStep(ExecState*, JSValue iterator); 39 void iteratorClose(ExecState*, JSValue iterator); 40 JSObject* createIterResultObject(ExecState*, JSValue, bool done); 39 41 40 static EncodedJSValue JSC_HOST_CALL arrayIteratorPrototypeIterate(ExecState*);41 42 void ArrayIteratorPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject)43 {44 Base::finishCreation(vm);45 ASSERT(inherits(info()));46 vm.prototypeMap.addPrototype(this);47 48 JSC_NATIVE_FUNCTION(vm.propertyNames->iteratorPrivateName, arrayIteratorPrototypeIterate, DontEnum, 0);49 42 } 50 43 51 EncodedJSValue JSC_HOST_CALL arrayIteratorPrototypeIterate(CallFrame* callFrame) 52 { 53 return JSValue::encode(callFrame->thisValue()); 54 } 55 56 } 44 #endif // !defined(IteratorOperations_h) -
trunk/Source/JavaScriptCore/runtime/JSArrayIterator.cpp
r173410 r181077 36 36 const ClassInfo JSArrayIterator::s_info = { "ArrayIterator", &Base::s_info, 0, CREATE_METHOD_TABLE(JSArrayIterator) }; 37 37 38 static EncodedJSValue JSC_HOST_CALL arrayIteratorNextKey(ExecState*); 39 static EncodedJSValue JSC_HOST_CALL arrayIteratorNextValue(ExecState*); 40 static EncodedJSValue JSC_HOST_CALL arrayIteratorNextGeneric(ExecState*); 41 42 void JSArrayIterator::finishCreation(VM& vm, JSGlobalObject* globalObject, ArrayIterationKind kind, JSObject* iteratedObject) 38 void JSArrayIterator::finishCreation(VM& vm, JSGlobalObject*, ArrayIterationKind kind, JSObject* iteratedObject) 43 39 { 44 40 Base::finishCreation(vm); 45 41 ASSERT(inherits(info())); 46 m_iterationKind = kind;47 m_iteratedObject.set(vm, this, iteratedObject);48 switch (kind) {49 case ArrayIterateKey:50 JSC_NATIVE_INTRINSIC_FUNCTION(vm.propertyNames->iteratorNextPrivateName, arrayIteratorNextKey, DontEnum, 0, ArrayIteratorNextKeyIntrinsic);51 break;52 case ArrayIterateValue:53 JSC_NATIVE_INTRINSIC_FUNCTION(vm.propertyNames->iteratorNextPrivateName, arrayIteratorNextValue, DontEnum, 0, ArrayIteratorNextValueIntrinsic);54 break;55 default:56 JSC_NATIVE_INTRINSIC_FUNCTION(vm.propertyNames->iteratorNextPrivateName, arrayIteratorNextGeneric, DontEnum, 0, ArrayIteratorNextGenericIntrinsic);57 break;58 }59 42 60 } 61 62 63 void JSArrayIterator::visitChildren(JSCell* cell, SlotVisitor& visitor) 64 { 65 JSArrayIterator* thisObject = jsCast<JSArrayIterator*>(cell); 66 ASSERT_GC_OBJECT_INHERITS(thisObject, info()); 67 Base::visitChildren(thisObject, visitor); 68 visitor.append(&thisObject->m_iteratedObject); 69 } 70 71 static EncodedJSValue createIteratorResult(CallFrame* callFrame, ArrayIterationKind kind, size_t index, JSValue result, bool done) 72 { 73 if (done) 74 return JSValue::encode(callFrame->vm().iterationTerminator.get()); 75 76 switch (kind & ~ArrayIterateSparseTag) { 77 case ArrayIterateKey: 78 return JSValue::encode(jsNumber(index)); 79 80 case ArrayIterateValue: 81 return JSValue::encode(result); 82 83 case ArrayIterateKeyValue: { 84 MarkedArgumentBuffer args; 85 args.append(jsNumber(index)); 86 args.append(result); 87 JSGlobalObject* globalObject = callFrame->callee()->globalObject(); 88 return JSValue::encode(constructArray(callFrame, 0, globalObject, args)); 89 90 } 91 default: 92 RELEASE_ASSERT_NOT_REACHED(); 93 } 94 return JSValue::encode(JSValue()); 95 } 96 97 static inline EncodedJSValue JSC_HOST_CALL arrayIteratorNext(CallFrame* callFrame) 98 { 99 JSArrayIterator* iterator = jsDynamicCast<JSArrayIterator*>(callFrame->thisValue()); 100 if (!iterator) { 101 ASSERT_NOT_REACHED(); 102 return JSValue::encode(throwTypeError(callFrame, ASCIILiteral("Cannot call ArrayIterator.next() on a non-ArrayIterator object"))); 103 } 104 JSObject* iteratedObject = iterator->iteratedObject(); 105 size_t index = iterator->nextIndex(); 106 ArrayIterationKind kind = iterator->iterationKind(); 107 JSValue jsLength = JSValue(iteratedObject).get(callFrame, callFrame->propertyNames().length); 108 if (callFrame->hadException()) 109 return JSValue::encode(jsNull()); 110 111 size_t length = jsLength.toUInt32(callFrame); 112 if (callFrame->hadException()) 113 return JSValue::encode(jsNull()); 114 115 if (index >= length) { 116 iterator->finish(); 117 return createIteratorResult(callFrame, kind, index, jsUndefined(), true); 118 } 119 if (JSValue result = iteratedObject->tryGetIndexQuickly(index)) { 120 iterator->setNextIndex(index + 1); 121 return createIteratorResult(callFrame, kind, index, result, false); 122 } 123 124 JSValue result = jsUndefined(); 125 PropertySlot slot(iteratedObject); 126 if (kind > ArrayIterateSparseTag) { 127 // We assume that the indexed property will be an own property so cache the getOwnProperty 128 // method locally 129 auto getOwnPropertySlotByIndex = iteratedObject->methodTable()->getOwnPropertySlotByIndex; 130 while (index < length) { 131 if (getOwnPropertySlotByIndex(iteratedObject, callFrame, index, slot)) { 132 result = slot.getValue(callFrame, index); 133 break; 134 } 135 if (iteratedObject->getPropertySlot(callFrame, index, slot)) { 136 result = slot.getValue(callFrame, index); 137 break; 138 } 139 index++; 140 } 141 } else if (iteratedObject->getPropertySlot(callFrame, index, slot)) 142 result = slot.getValue(callFrame, index); 143 144 if (index == length) 145 iterator->finish(); 146 else 147 iterator->setNextIndex(index + 1); 148 return createIteratorResult(callFrame, kind, index, jsUndefined(), index == length); 149 } 150 151 EncodedJSValue JSC_HOST_CALL arrayIteratorNextKey(CallFrame* callFrame) 152 { 153 return arrayIteratorNext(callFrame); 154 } 155 156 EncodedJSValue JSC_HOST_CALL arrayIteratorNextValue(CallFrame* callFrame) 157 { 158 return arrayIteratorNext(callFrame); 159 } 160 161 EncodedJSValue JSC_HOST_CALL arrayIteratorNextGeneric(CallFrame* callFrame) 162 { 163 return arrayIteratorNext(callFrame); 43 putDirect(vm, vm.propertyNames->iteratedObjectPrivateName, iteratedObject); 44 putDirect(vm, vm.propertyNames->arrayIteratorNextIndexPrivateName, jsNumber(0)); 45 putDirect(vm, vm.propertyNames->arrayIterationKindPrivateName, jsNumber(kind)); 164 46 } 165 47 -
trunk/Source/JavaScriptCore/runtime/JSArrayIterator.h
r171939 r181077 34 34 ArrayIterateKey, 35 35 ArrayIterateValue, 36 ArrayIterateKeyValue, 37 ArrayIterateSparseTag = 4, 38 ArrayIterateSparseKey, 39 ArrayIterateSparseValue, 40 ArrayIterateSparseKeyValue 36 ArrayIterateKeyValue 41 37 }; 42 38 … … 60 56 } 61 57 62 ArrayIterationKind iterationKind() const { return m_iterationKind; }63 JSObject* iteratedObject() const { return m_iteratedObject.get(); }64 size_t nextIndex() const { return m_nextIndex; }65 void setNextIndex(size_t nextIndex) { m_nextIndex = nextIndex; }66 void finish() { m_nextIndex = std::numeric_limits<uint32_t>::max(); }67 68 58 using JSNonFinalObject::arrayStorageOrNull; 69 static ptrdiff_t offsetOfIterationKind() { return OBJECT_OFFSETOF(JSArrayIterator, m_iterationKind); }70 static ptrdiff_t offsetOfIteratedObject() { return OBJECT_OFFSETOF(JSArrayIterator, m_iteratedObject); }71 static ptrdiff_t offsetOfNextIndex() { return OBJECT_OFFSETOF(JSArrayIterator, m_nextIndex); }72 73 59 private: 74 60 JSArrayIterator(VM& vm, Structure* structure) 75 61 : Base(vm, structure) 76 , m_nextIndex(0)77 62 { 78 63 } 79 64 80 65 void finishCreation(VM&, JSGlobalObject*, ArrayIterationKind, JSObject* iteratedObject); 81 static void visitChildren(JSCell*, SlotVisitor&);82 83 ArrayIterationKind m_iterationKind;84 WriteBarrier<JSObject> m_iteratedObject;85 uint32_t m_nextIndex;86 66 }; 87 67 -
trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
r181064 r181077 430 430 GlobalPropertyInfo(vm.propertyNames->floorPrivateName, privateFuncFloor, DontEnum | DontDelete | ReadOnly), 431 431 GlobalPropertyInfo(vm.propertyNames->isFinitePrivateName, privateFuncIsFinite, DontEnum | DontDelete | ReadOnly), 432 GlobalPropertyInfo(vm.propertyNames->arrayIterationKindKeyPrivateName, jsNumber(ArrayIterateKey), DontEnum | DontDelete | ReadOnly), 433 GlobalPropertyInfo(vm.propertyNames->arrayIterationKindValuePrivateName, jsNumber(ArrayIterateValue), DontEnum | DontDelete | ReadOnly), 434 GlobalPropertyInfo(vm.propertyNames->arrayIterationKindKeyValuePrivateName, jsNumber(ArrayIterateKeyValue), DontEnum | DontDelete | ReadOnly), 432 435 }; 433 436 addStaticGlobals(staticGlobals, WTF_ARRAY_LENGTH(staticGlobals)); -
trunk/Source/JavaScriptCore/runtime/JSPromiseConstructor.cpp
r173681 r181077 30 30 31 31 #include "Error.h" 32 #include "IteratorOperations.h" 32 33 #include "JSCJSValueInlines.h" 33 34 #include "JSCellInlines.h" … … 233 234 } 234 235 236 static void performPromiseRaceLoop(ExecState* exec, JSValue iterator, JSPromiseDeferred* deferred, JSValue C) 237 { 238 // 6. Repeat 239 do { 240 // i. Let 'next' be the result of calling IteratorStep(iterator). 241 JSValue next = iteratorStep(exec, iterator); 242 243 // ii. RejectIfAbrupt(next, deferred). 244 if (exec->hadException()) 245 return; 246 247 // iii. If 'next' is false, return deferred.[[Promise]]. 248 if (next.isFalse()) 249 return; 250 251 // iv. Let 'nextValue' be the result of calling IteratorValue(next). 252 // v. RejectIfAbrupt(nextValue, deferred). 253 JSValue nextValue = iteratorValue(exec, next); 254 if (exec->hadException()) 255 return; 256 257 // vi. Let 'nextPromise' be the result of calling Invoke(C, "resolve", (nextValue)). 258 JSValue resolveFunction = C.get(exec, exec->vm().propertyNames->resolve); 259 if (exec->hadException()) 260 return; 261 262 CallData resolveFunctionCallData; 263 CallType resolveFunctionCallType = getCallData(resolveFunction, resolveFunctionCallData); 264 if (resolveFunctionCallType == CallTypeNone) { 265 throwTypeError(exec); 266 return; 267 } 268 269 MarkedArgumentBuffer resolveFunctionArguments; 270 resolveFunctionArguments.append(nextValue); 271 JSValue nextPromise = call(exec, resolveFunction, resolveFunctionCallType, resolveFunctionCallData, C, resolveFunctionArguments); 272 273 // vii. RejectIfAbrupt(nextPromise, deferred). 274 if (exec->hadException()) 275 return; 276 277 // viii. Let 'result' be the result of calling Invoke(nextPromise, "then", (deferred.[[Resolve]], deferred.[[Reject]])). 278 JSValue thenFunction = nextPromise.get(exec, exec->vm().propertyNames->then); 279 if (exec->hadException()) 280 return; 281 282 CallData thenFunctionCallData; 283 CallType thenFunctionCallType = getCallData(thenFunction, thenFunctionCallData); 284 if (thenFunctionCallType == CallTypeNone) { 285 throwTypeError(exec); 286 return; 287 } 288 289 MarkedArgumentBuffer thenFunctionArguments; 290 thenFunctionArguments.append(deferred->resolve()); 291 thenFunctionArguments.append(deferred->reject()); 292 293 call(exec, thenFunction, thenFunctionCallType, thenFunctionCallData, nextPromise, thenFunctionArguments); 294 295 // ix. RejectIfAbrupt(result, deferred). 296 if (exec->hadException()) 297 return; 298 } while (true); 299 } 300 235 301 EncodedJSValue JSC_HOST_CALL JSPromiseConstructorFuncRace(ExecState* exec) 236 302 { … … 270 336 return JSValue::encode(abruptRejection(exec, deferred)); 271 337 272 // 6. Repeat 273 do { 274 // i. Let 'next' be the result of calling IteratorStep(iterator). 275 JSValue nextFunction = iterator.get(exec, exec->vm().propertyNames->iteratorNextPrivateName); 276 if (exec->hadException()) 277 return JSValue::encode(abruptRejection(exec, deferred)); 278 279 CallData nextFunctionCallData; 280 CallType nextFunctionCallType = getCallData(nextFunction, nextFunctionCallData); 281 if (nextFunctionCallType == CallTypeNone) { 282 throwTypeError(exec); 283 return JSValue::encode(abruptRejection(exec, deferred)); 284 } 285 286 MarkedArgumentBuffer nextFunctionArguments; 287 nextFunctionArguments.append(jsUndefined()); 288 JSValue next = call(exec, nextFunction, nextFunctionCallType, nextFunctionCallData, iterator, nextFunctionArguments); 289 290 // ii. RejectIfAbrupt(next, deferred). 291 if (exec->hadException()) 292 return JSValue::encode(abruptRejection(exec, deferred)); 293 294 // iii. If 'next' is false, return deferred.[[Promise]]. 295 // Note: We implement this as an iterationTerminator 296 if (next == vm.iterationTerminator.get()) 297 return JSValue::encode(deferred->promise()); 298 299 // iv. Let 'nextValue' be the result of calling IteratorValue(next). 300 // v. RejectIfAbrupt(nextValue, deferred). 301 // Note: 'next' is already the value, so there is nothing to do here. 302 303 // vi. Let 'nextPromise' be the result of calling Invoke(C, "resolve", (nextValue)). 304 JSValue resolveFunction = C.get(exec, vm.propertyNames->resolve); 305 if (exec->hadException()) 306 return JSValue::encode(abruptRejection(exec, deferred)); 307 308 CallData resolveFunctionCallData; 309 CallType resolveFunctionCallType = getCallData(resolveFunction, resolveFunctionCallData); 310 if (resolveFunctionCallType == CallTypeNone) { 311 throwTypeError(exec); 312 return JSValue::encode(abruptRejection(exec, deferred)); 313 } 314 315 MarkedArgumentBuffer resolveFunctionArguments; 316 resolveFunctionArguments.append(next); 317 JSValue nextPromise = call(exec, resolveFunction, resolveFunctionCallType, resolveFunctionCallData, C, resolveFunctionArguments); 318 319 // vii. RejectIfAbrupt(nextPromise, deferred). 320 if (exec->hadException()) 321 return JSValue::encode(abruptRejection(exec, deferred)); 322 323 // viii. Let 'result' be the result of calling Invoke(nextPromise, "then", (deferred.[[Resolve]], deferred.[[Reject]])). 324 JSValue thenFunction = nextPromise.get(exec, vm.propertyNames->then); 325 if (exec->hadException()) 326 return JSValue::encode(abruptRejection(exec, deferred)); 327 328 CallData thenFunctionCallData; 329 CallType thenFunctionCallType = getCallData(thenFunction, thenFunctionCallData); 330 if (thenFunctionCallType == CallTypeNone) { 331 throwTypeError(exec); 332 return JSValue::encode(abruptRejection(exec, deferred)); 333 } 334 335 MarkedArgumentBuffer thenFunctionArguments; 336 thenFunctionArguments.append(deferred->resolve()); 337 thenFunctionArguments.append(deferred->reject()); 338 339 call(exec, thenFunction, thenFunctionCallType, thenFunctionCallData, nextPromise, thenFunctionArguments); 340 341 // ix. RejectIfAbrupt(result, deferred). 342 if (exec->hadException()) 343 return JSValue::encode(abruptRejection(exec, deferred)); 344 } while (true); 345 } 346 347 EncodedJSValue JSC_HOST_CALL JSPromiseConstructorFuncAll(ExecState* exec) 348 { 349 // -- Promise.all(iterable) -- 350 351 JSValue iterable = exec->argument(0); 338 performPromiseRaceLoop(exec, iterator, deferred, C); 339 if (exec->hadException()) 340 iteratorClose(exec, iterator); 341 if (exec->hadException()) 342 return JSValue::encode(abruptRejection(exec, deferred)); 343 return JSValue::encode(deferred->promise()); 344 } 345 346 static JSValue performPromiseAll(ExecState* exec, JSValue iterator, JSValue C, JSPromiseDeferred* deferred) 347 { 348 JSObject* thisObject = asObject(C); 352 349 VM& vm = exec->vm(); 353 354 // 1. Let 'C' be the this value.355 JSValue C = exec->thisValue();356 357 // 2. Let 'deferred' be the result of calling GetDeferred(C).358 JSValue deferredValue = createJSPromiseDeferredFromConstructor(exec, C);359 360 // 3. ReturnIfAbrupt(deferred).361 if (exec->hadException())362 return JSValue::encode(jsUndefined());363 364 // NOTE: A non-abrupt completion of createJSPromiseDeferredFromConstructor implies that365 // C and deferredValue are objects.366 JSObject* thisObject = asObject(C);367 JSPromiseDeferred* deferred = jsCast<JSPromiseDeferred*>(deferredValue);368 369 // 4. Let 'iterator' be the result of calling GetIterator(iterable).370 JSValue iteratorFunction = iterable.get(exec, vm.propertyNames->iteratorPrivateName);371 if (exec->hadException())372 return JSValue::encode(abruptRejection(exec, deferred));373 374 CallData iteratorFunctionCallData;375 CallType iteratorFunctionCallType = getCallData(iteratorFunction, iteratorFunctionCallData);376 if (iteratorFunctionCallType == CallTypeNone) {377 throwTypeError(exec);378 return JSValue::encode(abruptRejection(exec, deferred));379 }380 381 ArgList iteratorFunctionArguments;382 JSValue iterator = call(exec, iteratorFunction, iteratorFunctionCallType, iteratorFunctionCallData, iterable, iteratorFunctionArguments);383 384 // 5. RejectIfAbrupt(iterator, deferred).385 if (exec->hadException())386 return JSValue::encode(abruptRejection(exec, deferred));387 350 388 351 // 6. Let 'values' be the result of calling ArrayCreate(0). 389 352 JSArray* values = constructEmptyArray(exec, nullptr, thisObject->globalObject()); 390 353 391 354 // 7. Let 'countdownHolder' be Record { [[Countdown]]: 0 }. 392 355 NumberObject* countdownHolder = constructNumber(exec, thisObject->globalObject(), JSValue(0)); 393 356 394 357 // 8. Let 'index' be 0. 395 358 unsigned index = 0; 396 359 397 360 // 9. Repeat. 398 361 do { 399 362 // i. Let 'next' be the result of calling IteratorStep(iterator). 400 JSValue nextFunction = iterator.get(exec, exec->vm().propertyNames->iteratorNextPrivateName); 401 if (exec->hadException()) 402 return JSValue::encode(abruptRejection(exec, deferred)); 403 404 CallData nextFunctionCallData; 405 CallType nextFunctionCallType = getCallData(nextFunction, nextFunctionCallData); 406 if (nextFunctionCallType == CallTypeNone) { 407 throwTypeError(exec); 408 return JSValue::encode(abruptRejection(exec, deferred)); 409 } 410 411 MarkedArgumentBuffer nextFunctionArguments; 412 nextFunctionArguments.append(jsUndefined()); 413 JSValue next = call(exec, nextFunction, nextFunctionCallType, nextFunctionCallData, iterator, nextFunctionArguments); 414 415 // ii. RejectIfAbrupt(next, deferred). 416 if (exec->hadException()) 417 return JSValue::encode(abruptRejection(exec, deferred)); 363 JSValue next = iteratorStep(exec, iterator); 364 if (exec->hadException()) 365 return jsUndefined(); 418 366 419 367 // iii. If 'next' is false, 420 // Note: We implement this as an iterationTerminator 421 if (next == vm.iterationTerminator.get()) { 368 if (next.isFalse()) { 422 369 // a. If 'index' is 0, 423 370 if (!index) { … … 429 376 // b. ReturnIfAbrupt(resolveResult). 430 377 if (exec->hadException()) 431 return JSValue::encode(jsUndefined());378 return jsUndefined(); 432 379 } 433 380 434 381 // b. Return deferred.[[Promise]]. 435 return JSValue::encode(deferred->promise());382 return deferred->promise(); 436 383 } 437 384 438 385 // iv. Let 'nextValue' be the result of calling IteratorValue(next). 439 386 // v. RejectIfAbrupt(nextValue, deferred). 440 // Note: 'next' is already the value, so there is nothing to do here. 387 JSValue nextValue = iteratorValue(exec, next); 388 if (exec->hadException()) 389 return jsUndefined(); 390 391 values->push(exec, jsUndefined()); 441 392 442 393 // vi. Let 'nextPromise' be the result of calling Invoke(C, "resolve", (nextValue)). 443 394 JSValue resolveFunction = C.get(exec, vm.propertyNames->resolve); 444 395 if (exec->hadException()) 445 return JSValue::encode(abruptRejection(exec, deferred));396 return jsUndefined(); 446 397 447 398 CallData resolveFunctionCallData; … … 449 400 if (resolveFunctionCallType == CallTypeNone) { 450 401 throwTypeError(exec); 451 return JSValue::encode(abruptRejection(exec, deferred));402 return jsUndefined(); 452 403 } 453 404 454 405 MarkedArgumentBuffer resolveFunctionArguments; 455 resolveFunctionArguments.append(next );406 resolveFunctionArguments.append(nextValue); 456 407 JSValue nextPromise = call(exec, resolveFunction, resolveFunctionCallType, resolveFunctionCallData, C, resolveFunctionArguments); 457 408 458 409 // vii. RejectIfAbrupt(nextPromise, deferred). 459 410 if (exec->hadException()) 460 return JSValue::encode(abruptRejection(exec, deferred));411 return jsUndefined(); 461 412 462 413 // viii. Let 'countdownFunction' be a new built-in function object as defined in Promise.all Countdown Functions. 463 414 JSFunction* countdownFunction = createPromiseAllCountdownFunction(vm, thisObject->globalObject()); 464 415 465 416 // ix. Set the [[Index]] internal slot of 'countdownFunction' to 'index'. 466 417 countdownFunction->putDirect(vm, vm.propertyNames->indexPrivateName, JSValue(index)); … … 478 429 JSValue thenFunction = nextPromise.get(exec, vm.propertyNames->then); 479 430 if (exec->hadException()) 480 return JSValue::encode(abruptRejection(exec, deferred));431 return jsUndefined(); 481 432 482 433 CallData thenFunctionCallData; … … 484 435 if (thenFunctionCallType == CallTypeNone) { 485 436 throwTypeError(exec); 486 return JSValue::encode(abruptRejection(exec, deferred));437 return jsUndefined(); 487 438 } 488 439 … … 495 446 // xiv. RejectIfAbrupt(result, deferred). 496 447 if (exec->hadException()) 497 return JSValue::encode(abruptRejection(exec, deferred));448 return jsUndefined(); 498 449 499 450 // xv. Set index to index + 1. … … 504 455 countdownHolder->setInternalValue(vm, JSValue(newCountdownValue)); 505 456 } while (true); 457 ASSERT_NOT_REACHED(); 458 return jsUndefined(); 459 } 460 461 EncodedJSValue JSC_HOST_CALL JSPromiseConstructorFuncAll(ExecState* exec) 462 { 463 // -- Promise.all(iterable) -- 464 465 JSValue iterable = exec->argument(0); 466 VM& vm = exec->vm(); 467 468 // 1. Let 'C' be the this value. 469 JSValue C = exec->thisValue(); 470 471 // 2. Let 'deferred' be the result of calling GetDeferred(C). 472 JSValue deferredValue = createJSPromiseDeferredFromConstructor(exec, C); 473 474 // 3. ReturnIfAbrupt(deferred). 475 if (exec->hadException()) 476 return JSValue::encode(jsUndefined()); 477 478 // NOTE: A non-abrupt completion of createJSPromiseDeferredFromConstructor implies that 479 // C and deferredValue are objects. 480 JSPromiseDeferred* deferred = jsCast<JSPromiseDeferred*>(deferredValue); 481 482 // 4. Let 'iterator' be the result of calling GetIterator(iterable). 483 JSValue iteratorFunction = iterable.get(exec, vm.propertyNames->iteratorPrivateName); 484 if (exec->hadException()) 485 return JSValue::encode(abruptRejection(exec, deferred)); 486 487 CallData iteratorFunctionCallData; 488 CallType iteratorFunctionCallType = getCallData(iteratorFunction, iteratorFunctionCallData); 489 if (iteratorFunctionCallType == CallTypeNone) { 490 throwTypeError(exec); 491 return JSValue::encode(abruptRejection(exec, deferred)); 492 } 493 494 ArgList iteratorFunctionArguments; 495 JSValue iterator = call(exec, iteratorFunction, iteratorFunctionCallType, iteratorFunctionCallData, iterable, iteratorFunctionArguments); 496 497 // 5. RejectIfAbrupt(iterator, deferred). 498 if (exec->hadException()) 499 return JSValue::encode(abruptRejection(exec, deferred)); 500 501 JSValue result = performPromiseAll(exec, iterator, C, deferred); 502 if (exec->hadException()) { 503 iteratorClose(exec, iterator); 504 if (exec->hadException()) 505 return JSValue::encode(abruptRejection(exec, deferred)); 506 } 507 return JSValue::encode(result); 506 508 } 507 509 -
trunk/Source/JavaScriptCore/runtime/MapIteratorPrototype.cpp
r173410 r181077 27 27 #include "MapIteratorPrototype.h" 28 28 29 #include "IteratorOperations.h" 29 30 #include "JSCJSValueInlines.h" 30 31 #include "JSCellInlines.h" … … 47 48 48 49 JSC_NATIVE_FUNCTION(vm.propertyNames->iteratorPrivateName, MapIteratorPrototypeFuncIterator, DontEnum, 0); 49 JSC_NATIVE_FUNCTION(vm.propertyNames-> iteratorNextPrivateName, MapIteratorPrototypeFuncNext, DontEnum, 0);50 JSC_NATIVE_FUNCTION(vm.propertyNames->next, MapIteratorPrototypeFuncNext, DontEnum, 0); 50 51 } 51 52 … … 60 61 if (!iterator) 61 62 return JSValue::encode(throwTypeError(callFrame, ASCIILiteral("Cannot call MapIterator.next() on a non-MapIterator object"))); 62 63 63 64 JSValue result; 64 65 if (iterator->next(callFrame, result)) 65 return JSValue::encode( result);66 return JSValue::encode(createIterResultObject(callFrame, result, false)); 66 67 iterator->finish(); 67 return JSValue::encode(c allFrame->vm().iterationTerminator.get());68 return JSValue::encode(createIterResultObject(callFrame, jsUndefined(), true)); 68 69 } 69 70 -
trunk/Source/JavaScriptCore/runtime/SetIteratorPrototype.cpp
r173410 r181077 27 27 #include "SetIteratorPrototype.h" 28 28 29 #include "IteratorOperations.h" 29 30 #include "JSCJSValueInlines.h" 30 31 #include "JSCellInlines.h" … … 47 48 48 49 JSC_NATIVE_FUNCTION(vm.propertyNames->iteratorPrivateName, SetIteratorPrototypeFuncIterator, DontEnum, 0); 49 JSC_NATIVE_FUNCTION(vm.propertyNames-> iteratorNextPrivateName, SetIteratorPrototypeFuncNext, DontEnum, 0);50 JSC_NATIVE_FUNCTION(vm.propertyNames->next, SetIteratorPrototypeFuncNext, DontEnum, 0); 50 51 } 51 52 … … 63 64 64 65 if (iterator->next(callFrame, result)) 65 return JSValue::encode( result);66 return JSValue::encode(createIterResultObject(callFrame, result, false)); 66 67 iterator->finish(); 67 return JSValue::encode(c allFrame->vm().iterationTerminator.get());68 return JSValue::encode(createIterResultObject(callFrame, jsUndefined(), true)); 68 69 } 69 70 70 71 71 } -
trunk/Source/JavaScriptCore/runtime/VM.cpp
r181010 r181077 400 400 case IMulIntrinsic: 401 401 return imulThunkGenerator; 402 case ArrayIteratorNextKeyIntrinsic:403 return arrayIteratorNextKeyThunkGenerator;404 case ArrayIteratorNextValueIntrinsic:405 return arrayIteratorNextValueThunkGenerator;406 402 default: 407 403 return 0;
Note: See TracChangeset
for help on using the changeset viewer.