summaryrefslogtreecommitdiffstats
path: root/js/src/jsiter.cpp
diff options
context:
space:
mode:
authorjanekptacijarabaci <janekptacijarabaci@seznam.cz>2018-03-30 09:44:21 +0200
committerjanekptacijarabaci <janekptacijarabaci@seznam.cz>2018-03-30 09:44:21 +0200
commita1a007a4856fa50d6d811c2268f881e3666f4c67 (patch)
tree24b082c1bfb5777f1770c82a534bf765160bc1b8 /js/src/jsiter.cpp
parenteddd0de2ae80e176011f41a5400e81522d53f4f3 (diff)
parent59bf4204a84f7638d3f89a29bc7c04e5dc401369 (diff)
downloadUXP-a1a007a4856fa50d6d811c2268f881e3666f4c67.tar
UXP-a1a007a4856fa50d6d811c2268f881e3666f4c67.tar.gz
UXP-a1a007a4856fa50d6d811c2268f881e3666f4c67.tar.lz
UXP-a1a007a4856fa50d6d811c2268f881e3666f4c67.tar.xz
UXP-a1a007a4856fa50d6d811c2268f881e3666f4c67.zip
Merge branch 'master' of https://github.com/MoonchildProductions/UXP into html_input_datetime_1
Diffstat (limited to 'js/src/jsiter.cpp')
-rw-r--r--js/src/jsiter.cpp52
1 files changed, 52 insertions, 0 deletions
diff --git a/js/src/jsiter.cpp b/js/src/jsiter.cpp
index 63c81e6af..c1ae5dc15 100644
--- a/js/src/jsiter.cpp
+++ b/js/src/jsiter.cpp
@@ -12,6 +12,7 @@
#include "mozilla/Maybe.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/PodOperations.h"
+#include "mozilla/Unused.h"
#include "jsarray.h"
#include "jsatom.h"
@@ -1229,6 +1230,7 @@ js::CloseIterator(JSContext* cx, HandleObject obj)
}
return LegacyGeneratorObject::close(cx, obj);
}
+
return true;
}
@@ -1246,6 +1248,56 @@ js::UnwindIteratorForException(JSContext* cx, HandleObject obj)
return true;
}
+bool
+js::IteratorCloseForException(JSContext* cx, HandleObject obj)
+{
+ MOZ_ASSERT(cx->isExceptionPending());
+
+ bool isClosingGenerator = cx->isClosingGenerator();
+ JS::AutoSaveExceptionState savedExc(cx);
+
+ // Implements IteratorClose (ES 7.4.6) for exception unwinding. See
+ // also the bytecode generated by BytecodeEmitter::emitIteratorClose.
+
+ // Step 3.
+ //
+ // Get the "return" method.
+ RootedValue returnMethod(cx);
+ if (!GetProperty(cx, obj, obj, cx->names().return_, &returnMethod))
+ return false;
+
+ // Step 4.
+ //
+ // Do nothing if "return" is null or undefined. Throw a TypeError if the
+ // method is not IsCallable.
+ if (returnMethod.isNullOrUndefined())
+ return true;
+ if (!IsCallable(returnMethod))
+ return ReportIsNotFunction(cx, returnMethod);
+
+ // Step 5, 6, 8.
+ //
+ // Call "return" if it is not null or undefined.
+ RootedValue rval(cx);
+ bool ok = Call(cx, returnMethod, obj, &rval);
+ if (isClosingGenerator) {
+ // Closing an iterator is implemented as an exception, but in spec
+ // terms it is a Completion value with [[Type]] return. In this case
+ // we *do* care if the call threw and if it returned an object.
+ if (!ok)
+ return false;
+ if (!rval.isObject())
+ return ThrowCheckIsObject(cx, CheckIsObjectKind::IteratorReturn);
+ } else {
+ // We don't care if the call threw or that it returned an Object, as
+ // Step 6 says if IteratorClose is being called during a throw, the
+ // original throw has primacy.
+ savedExc.restore();
+ }
+
+ return true;
+}
+
void
js::UnwindIteratorForUncatchableException(JSContext* cx, JSObject* obj)
{