mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-05 07:18:39 +09:00
parent
97197f29bf
commit
5f3e5dc3fb
13 changed files with 704 additions and 203 deletions
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue