Title: [204438] trunk/Source/_javascript_Core
Revision
204438
Author
[email protected]
Date
2016-08-12 19:02:04 -0700 (Fri, 12 Aug 2016)

Log Message

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):

Modified Paths

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);
 }
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to