Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (204437 => 204438)
--- trunk/Source/_javascript_Core/ChangeLog 2016-08-13 00:56:48 UTC (rev 204437)
+++ trunk/Source/_javascript_Core/ChangeLog 2016-08-13 02:02:04 UTC (rev 204438)
@@ -1,3 +1,28 @@
+2016-08-12 Ryosuke Niwa <[email protected]>
+
+ Add a helper class for enumerating elements in an iterable object
+ https://bugs.webkit.org/show_bug.cgi?id=160800
+
+ Reviewed by Benjamin Poulain.
+
+ Added iteratorForIterable which provides an abstraction for iterating over an iterable object,
+ and deployed it in the constructors of Set, WeakSet, Map, and WeakMap.
+
+ Also added a helper function iteratorForIterable, which retrieves the iterator out of an iterable object.
+
+ * runtime/IteratorOperations.cpp:
+ (JSC::iteratorForIterable): Added.
+ * runtime/IteratorOperations.h:
+ (JSC::forEachInIterable): Added.
+ * runtime/MapConstructor.cpp:
+ (JSC::constructMap):
+ * runtime/SetConstructor.cpp:
+ (JSC::constructSet):
+ * runtime/WeakMapConstructor.cpp:
+ (JSC::constructWeakMap):
+ * runtime/WeakSetConstructor.cpp:
+ (JSC::constructWeakSet):
+
2016-08-12 Joseph Pecoraro <[email protected]>
Remove unused includes of RefCountedLeakCounter.h
Modified: trunk/Source/_javascript_Core/runtime/IteratorOperations.cpp (204437 => 204438)
--- trunk/Source/_javascript_Core/runtime/IteratorOperations.cpp 2016-08-13 00:56:48 UTC (rev 204437)
+++ trunk/Source/_javascript_Core/runtime/IteratorOperations.cpp 2016-08-13 02:02:04 UTC (rev 204438)
@@ -153,4 +153,30 @@
return resultObject;
}
+JSValue iteratorForIterable(ExecState* state, JSValue iterable)
+{
+ JSValue iteratorFunction = iterable.get(state, state->propertyNames().iteratorSymbol);
+ if (state->hadException())
+ return JSValue();
+
+ CallData iteratorFunctionCallData;
+ CallType iteratorFunctionCallType = getCallData(iteratorFunction, iteratorFunctionCallData);
+ if (iteratorFunctionCallType == CallType::None) {
+ throwTypeError(state);
+ return JSValue();
+ }
+
+ ArgList iteratorFunctionArguments;
+ JSValue iterator = call(state, iteratorFunction, iteratorFunctionCallType, iteratorFunctionCallData, iterable, iteratorFunctionArguments);
+ if (state->hadException())
+ return JSValue();
+
+ if (!iterator.isObject()) {
+ throwTypeError(state);
+ return JSValue();
+ }
+
+ return iterator;
+}
+
} // namespace JSC
Modified: trunk/Source/_javascript_Core/runtime/IteratorOperations.h (204437 => 204438)
--- trunk/Source/_javascript_Core/runtime/IteratorOperations.h 2016-08-13 00:56:48 UTC (rev 204437)
+++ trunk/Source/_javascript_Core/runtime/IteratorOperations.h 2016-08-13 02:02:04 UTC (rev 204438)
@@ -41,6 +41,32 @@
Structure* createIteratorResultObjectStructure(VM&, JSGlobalObject&);
+JSValue iteratorForIterable(ExecState*, JSValue iterable);
+
+template <typename CallBackType>
+void forEachInIterable(ExecState* state, JSValue iterable, const CallBackType& callback)
+{
+ auto& vm = state->vm();
+ JSValue iterator = iteratorForIterable(state, iterable);
+ if (vm.exception())
+ return;
+ while (true) {
+ JSValue next = iteratorStep(state, iterator);
+ if (next.isFalse() || vm.exception())
+ return;
+
+ JSValue nextValue = iteratorValue(state, next);
+ if (vm.exception())
+ return;
+
+ callback(vm, state, nextValue);
+ if (vm.exception()) {
+ iteratorClose(state, iterator);
+ return;
+ }
+ }
}
+}
+
#endif // !defined(IteratorOperations_h)
Modified: trunk/Source/_javascript_Core/runtime/MapConstructor.cpp (204437 => 204438)
--- trunk/Source/_javascript_Core/runtime/MapConstructor.cpp 2016-08-13 00:56:48 UTC (rev 204437)
+++ trunk/Source/_javascript_Core/runtime/MapConstructor.cpp 2016-08-13 02:02:04 UTC (rev 204438)
@@ -73,63 +73,26 @@
if (adderFunctionCallType == CallType::None)
return JSValue::encode(throwTypeError(exec));
- JSValue iteratorFunction = iterable.get(exec, exec->propertyNames().iteratorSymbol);
- if (exec->hadException())
- return JSValue::encode(jsUndefined());
-
- CallData iteratorFunctionCallData;
- CallType iteratorFunctionCallType = getCallData(iteratorFunction, iteratorFunctionCallData);
- if (iteratorFunctionCallType == CallType::None)
- return JSValue::encode(throwTypeError(exec));
-
- ArgList iteratorFunctionArguments;
- JSValue iterator = call(exec, iteratorFunction, iteratorFunctionCallType, iteratorFunctionCallData, iterable, iteratorFunctionArguments);
- if (exec->hadException())
- return JSValue::encode(jsUndefined());
-
- if (!iterator.isObject())
- return JSValue::encode(throwTypeError(exec));
-
- while (true) {
- JSValue next = iteratorStep(exec, iterator);
- if (exec->hadException())
- return JSValue::encode(jsUndefined());
-
- if (next.isFalse())
- return JSValue::encode(map);
-
- JSValue nextItem = iteratorValue(exec, next);
- if (exec->hadException())
- return JSValue::encode(jsUndefined());
-
+ forEachInIterable(exec, iterable, [&](VM& vm, ExecState* exec, JSValue nextItem) {
if (!nextItem.isObject()) {
throwTypeError(exec);
- iteratorClose(exec, iterator);
- return JSValue::encode(jsUndefined());
+ return;
}
JSValue key = nextItem.get(exec, static_cast<unsigned>(0));
- if (exec->hadException()) {
- iteratorClose(exec, iterator);
- return JSValue::encode(jsUndefined());
- }
+ if (vm.exception())
+ return;
JSValue value = nextItem.get(exec, static_cast<unsigned>(1));
- if (exec->hadException()) {
- iteratorClose(exec, iterator);
- return JSValue::encode(jsUndefined());
- }
+ if (vm.exception())
+ return;
MarkedArgumentBuffer arguments;
arguments.append(key);
arguments.append(value);
call(exec, adderFunction, adderFunctionCallType, adderFunctionCallData, map, arguments);
- if (exec->hadException()) {
- iteratorClose(exec, iterator);
- return JSValue::encode(jsUndefined());
- }
- }
- RELEASE_ASSERT_NOT_REACHED();
+ });
+
return JSValue::encode(map);
}
Modified: trunk/Source/_javascript_Core/runtime/SetConstructor.cpp (204437 => 204438)
--- trunk/Source/_javascript_Core/runtime/SetConstructor.cpp 2016-08-13 00:56:48 UTC (rev 204437)
+++ trunk/Source/_javascript_Core/runtime/SetConstructor.cpp 2016-08-13 02:02:04 UTC (rev 204438)
@@ -74,44 +74,12 @@
if (adderFunctionCallType == CallType::None)
return JSValue::encode(throwTypeError(exec));
- JSValue iteratorFunction = iterable.get(exec, exec->propertyNames().iteratorSymbol);
- if (exec->hadException())
- return JSValue::encode(jsUndefined());
-
- CallData iteratorFunctionCallData;
- CallType iteratorFunctionCallType = getCallData(iteratorFunction, iteratorFunctionCallData);
- if (iteratorFunctionCallType == CallType::None)
- return JSValue::encode(throwTypeError(exec));
-
- ArgList iteratorFunctionArguments;
- JSValue iterator = call(exec, iteratorFunction, iteratorFunctionCallType, iteratorFunctionCallData, iterable, iteratorFunctionArguments);
- if (exec->hadException())
- return JSValue::encode(jsUndefined());
-
- if (!iterator.isObject())
- return JSValue::encode(throwTypeError(exec));
-
- while (true) {
- JSValue next = iteratorStep(exec, iterator);
- if (exec->hadException())
- return JSValue::encode(jsUndefined());
-
- if (next.isFalse())
- return JSValue::encode(set);
-
- JSValue nextValue = iteratorValue(exec, next);
- if (exec->hadException())
- return JSValue::encode(jsUndefined());
-
+ forEachInIterable(exec, iterable, [&](VM&, ExecState* exec, JSValue nextValue) {
MarkedArgumentBuffer arguments;
arguments.append(nextValue);
call(exec, adderFunction, adderFunctionCallType, adderFunctionCallData, set, arguments);
- if (exec->hadException()) {
- iteratorClose(exec, iterator);
- return JSValue::encode(jsUndefined());
- }
- }
- RELEASE_ASSERT_NOT_REACHED();
+ });
+
return JSValue::encode(set);
}
Modified: trunk/Source/_javascript_Core/runtime/WeakMapConstructor.cpp (204437 => 204438)
--- trunk/Source/_javascript_Core/runtime/WeakMapConstructor.cpp 2016-08-13 00:56:48 UTC (rev 204437)
+++ trunk/Source/_javascript_Core/runtime/WeakMapConstructor.cpp 2016-08-13 02:02:04 UTC (rev 204438)
@@ -71,63 +71,26 @@
if (adderFunctionCallType == CallType::None)
return JSValue::encode(throwTypeError(exec));
- JSValue iteratorFunction = iterable.get(exec, exec->propertyNames().iteratorSymbol);
- if (exec->hadException())
- return JSValue::encode(jsUndefined());
-
- CallData iteratorFunctionCallData;
- CallType iteratorFunctionCallType = getCallData(iteratorFunction, iteratorFunctionCallData);
- if (iteratorFunctionCallType == CallType::None)
- return JSValue::encode(throwTypeError(exec));
-
- ArgList iteratorFunctionArguments;
- JSValue iterator = call(exec, iteratorFunction, iteratorFunctionCallType, iteratorFunctionCallData, iterable, iteratorFunctionArguments);
- if (exec->hadException())
- return JSValue::encode(jsUndefined());
-
- if (!iterator.isObject())
- return JSValue::encode(throwTypeError(exec));
-
- while (true) {
- JSValue next = iteratorStep(exec, iterator);
- if (exec->hadException())
- return JSValue::encode(jsUndefined());
-
- if (next.isFalse())
- return JSValue::encode(weakMap);
-
- JSValue nextItem = iteratorValue(exec, next);
- if (exec->hadException())
- return JSValue::encode(jsUndefined());
-
+ forEachInIterable(exec, iterable, [&](VM& vm, ExecState* exec, JSValue nextItem) {
if (!nextItem.isObject()) {
throwTypeError(exec);
- iteratorClose(exec, iterator);
- return JSValue::encode(jsUndefined());
+ return;
}
JSValue key = nextItem.get(exec, static_cast<unsigned>(0));
- if (exec->hadException()) {
- iteratorClose(exec, iterator);
- return JSValue::encode(jsUndefined());
- }
+ if (vm.exception())
+ return;
JSValue value = nextItem.get(exec, static_cast<unsigned>(1));
- if (exec->hadException()) {
- iteratorClose(exec, iterator);
- return JSValue::encode(jsUndefined());
- }
+ if (vm.exception())
+ return;
MarkedArgumentBuffer arguments;
arguments.append(key);
arguments.append(value);
call(exec, adderFunction, adderFunctionCallType, adderFunctionCallData, weakMap, arguments);
- if (exec->hadException()) {
- iteratorClose(exec, iterator);
- return JSValue::encode(jsUndefined());
- }
- }
- RELEASE_ASSERT_NOT_REACHED();
+ });
+
return JSValue::encode(weakMap);
}
Modified: trunk/Source/_javascript_Core/runtime/WeakSetConstructor.cpp (204437 => 204438)
--- trunk/Source/_javascript_Core/runtime/WeakSetConstructor.cpp 2016-08-13 00:56:48 UTC (rev 204437)
+++ trunk/Source/_javascript_Core/runtime/WeakSetConstructor.cpp 2016-08-13 02:02:04 UTC (rev 204438)
@@ -71,44 +71,12 @@
if (adderFunctionCallType == CallType::None)
return JSValue::encode(throwTypeError(exec));
- JSValue iteratorFunction = iterable.get(exec, exec->propertyNames().iteratorSymbol);
- if (exec->hadException())
- return JSValue::encode(jsUndefined());
-
- CallData iteratorFunctionCallData;
- CallType iteratorFunctionCallType = getCallData(iteratorFunction, iteratorFunctionCallData);
- if (iteratorFunctionCallType == CallType::None)
- return JSValue::encode(throwTypeError(exec));
-
- ArgList iteratorFunctionArguments;
- JSValue iterator = call(exec, iteratorFunction, iteratorFunctionCallType, iteratorFunctionCallData, iterable, iteratorFunctionArguments);
- if (exec->hadException())
- return JSValue::encode(jsUndefined());
-
- if (!iterator.isObject())
- return JSValue::encode(throwTypeError(exec));
-
- while (true) {
- JSValue next = iteratorStep(exec, iterator);
- if (exec->hadException())
- return JSValue::encode(jsUndefined());
-
- if (next.isFalse())
- return JSValue::encode(weakSet);
-
- JSValue nextValue = iteratorValue(exec, next);
- if (exec->hadException())
- return JSValue::encode(jsUndefined());
-
+ forEachInIterable(exec, iterable, [&](VM&, ExecState* exec, JSValue nextValue) {
MarkedArgumentBuffer arguments;
arguments.append(nextValue);
call(exec, adderFunction, adderFunctionCallType, adderFunctionCallData, weakSet, arguments);
- if (exec->hadException()) {
- iteratorClose(exec, iterator);
- return JSValue::encode(jsUndefined());
- }
- }
- RELEASE_ASSERT_NOT_REACHED();
+ });
+
return JSValue::encode(weakSet);
}