Modified: trunk/Source/WebCore/bindings/js/JSDOMIterator.h (200677 => 200678)
--- trunk/Source/WebCore/bindings/js/JSDOMIterator.h 2016-05-11 07:14:31 UTC (rev 200677)
+++ trunk/Source/WebCore/bindings/js/JSDOMIterator.h 2016-05-11 07:50:49 UTC (rev 200678)
@@ -108,10 +108,16 @@
{
}
+ template<typename IteratorValue> typename std::enable_if<IteratorInspector<IteratorValue>::isMap, JSC::JSValue>::type
+ asJS(JSC::ExecState&, IteratorValue&);
+ template<typename IteratorValue> typename std::enable_if<IteratorInspector<IteratorValue>::isSet, JSC::JSValue>::type
+ asJS(JSC::ExecState&, IteratorValue&);
+
static void destroy(JSC::JSCell*);
- typename DOMWrapped::Iterator m_iterator;
+ Optional<typename DOMWrapped::Iterator> m_iterator;
IterationKind m_kind;
+ size_t m_index { 0 };
};
template<typename JSWrapper>
@@ -129,30 +135,31 @@
return JSC::JSValue::encode(JSDOMIterator<JSWrapper>::create(globalObject.vm(), getDOMStructure<JSDOMIterator<JSWrapper>>(globalObject.vm(), globalObject), *wrapper, kind));
}
-template<typename IteratorValue> typename std::enable_if<IteratorInspector<IteratorValue>::isMap, JSC::JSValue>::type
-toJS(JSC::ExecState& state, JSDOMGlobalObject* globalObject, IteratorValue& value, IterationKind kind)
+template<typename JSWrapper>
+template<typename IteratorValue> inline typename std::enable_if<IteratorInspector<IteratorValue>::isMap, JSC::JSValue>::type
+JSDOMIterator<JSWrapper>::asJS(JSC::ExecState& state, IteratorValue& value)
{
ASSERT(value);
- if (kind != IterationKind::KeyValue)
- return toJS(&state, globalObject, (kind == IterationKind::Key) ? value->key : value->value);
+ if (m_kind != IterationKind::KeyValue)
+ return toJS(&state, globalObject(), (m_kind == IterationKind::Key) ? value->key : value->value);
- return jsPair(state, globalObject, value->key, value->value);
+ return jsPair(state, globalObject(), value->key, value->value);
}
-template<typename IteratorValue> typename std::enable_if<IteratorInspector<IteratorValue>::isSet, JSC::JSValue>::type
-toJS(JSC::ExecState& state, JSDOMGlobalObject* globalObject, IteratorValue& value, IterationKind kind)
+template<typename JSWrapper>
+template<typename IteratorValue> inline typename std::enable_if<IteratorInspector<IteratorValue>::isSet, JSC::JSValue>::type
+JSDOMIterator<JSWrapper>::asJS(JSC::ExecState& state, IteratorValue& value)
{
ASSERT(value);
- JSC::JSValue result = toJS(&state, globalObject, *value);
- if (kind != IterationKind::KeyValue)
+ JSC::JSValue result = toJS(&state, globalObject(), *value);
+ if (m_kind != IterationKind::KeyValue)
return result;
- // FIXME: first pair value should be the index of result.
- return jsPair(state, globalObject, result, result);
+ return jsPair(state, globalObject(), JSC::jsNumber(m_index++), result);
}
template<typename IteratorValue> typename std::enable_if<IteratorInspector<IteratorValue>::isMap, void>::type
-appendForEachArguments(JSC::ExecState& state, JSDOMGlobalObject* globalObject, JSC::MarkedArgumentBuffer& arguments, IteratorValue& value)
+appendForEachArguments(JSC::ExecState& state, JSDOMGlobalObject* globalObject, JSC::MarkedArgumentBuffer& arguments, IteratorValue& value, size_t&)
{
ASSERT(value);
arguments.append(toJS(&state, globalObject, value->value));
@@ -160,12 +167,12 @@
}
template<typename IteratorValue> typename std::enable_if<IteratorInspector<IteratorValue>::isSet, void>::type
-appendForEachArguments(JSC::ExecState& state, JSDOMGlobalObject* globalObject, JSC::MarkedArgumentBuffer& arguments, IteratorValue& value)
+appendForEachArguments(JSC::ExecState& state, JSDOMGlobalObject* globalObject, JSC::MarkedArgumentBuffer& arguments, IteratorValue& value, size_t& index)
{
ASSERT(value);
JSC::JSValue argument = toJS(&state, globalObject, *value);
arguments.append(argument);
- arguments.append(argument);
+ arguments.append(JSC::jsNumber(index++));
}
template<typename JSWrapper>
@@ -180,10 +187,11 @@
if (callType == JSC::CallType::None)
return throwVMTypeError(&state);
+ size_t index = 0;
auto iterator = wrapper->wrapped().createIterator();
while (auto value = iterator.next()) {
JSC::MarkedArgumentBuffer arguments;
- appendForEachArguments(state, wrapper->globalObject(), arguments, value);
+ appendForEachArguments(state, wrapper->globalObject(), arguments, value, index);
arguments.append(wrapper);
JSC::call(&state, state.argument(0), callType, callData, wrapper, arguments);
if (state.hadException())
@@ -202,10 +210,13 @@
template<typename JSWrapper>
JSC::JSValue JSDOMIterator<JSWrapper>::next(JSC::ExecState& state)
{
- auto iteratorValue = m_iterator.next();
- if (!iteratorValue)
- return createIteratorResultObject(&state, JSC::jsUndefined(), true);
- return createIteratorResultObject(&state, toJS(state, globalObject(), iteratorValue, m_kind), false);
+ if (m_iterator) {
+ auto iteratorValue = m_iterator->next();
+ if (iteratorValue)
+ return createIteratorResultObject(&state, asJS(state, iteratorValue), false);
+ m_iterator = Nullopt;
+ }
+ return createIteratorResultObject(&state, JSC::jsUndefined(), true);
}
template<typename JSWrapper>