Bug 1772772 - Implement ReadableStream.from. r=saschanaz,spidermonkey-reviewers,webidl,mgaudet

Differential Revision: https://phabricator.services.mozilla.com/D148358
This commit is contained in:
Tom Schuster 2023-07-04 16:48:23 +00:00
Родитель 03f524f519
Коммит 918d6e00af
14 изменённых файлов: 488 добавлений и 449 удалений

Просмотреть файл

@ -16,6 +16,7 @@
#include "js/PropertyAndElement.h"
#include "js/TypeDecls.h"
#include "js/Value.h"
#include "js/Iterator.h"
#include "mozilla/AlreadyAddRefed.h"
#include "mozilla/Assertions.h"
#include "mozilla/Attributes.h"
@ -240,6 +241,218 @@ already_AddRefed<ReadableStream> ReadableStream::Constructor(
return readableStream.forget();
}
// https://streams.spec.whatwg.org/#readable-stream-from-iterable
class ReadableStreamFromAlgorithms final
: public UnderlyingSourceAlgorithmsWrapper {
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(
ReadableStreamFromAlgorithms, UnderlyingSourceAlgorithmsWrapper)
ReadableStreamFromAlgorithms(nsIGlobalObject* aGlobal,
JS::Handle<JSObject*> aIteratorRecord)
: mGlobal(aGlobal), mIteratorRecord(aIteratorRecord) {
mozilla::HoldJSObjects(this);
};
// Step 3. Let startAlgorithm be an algorithm that returns undefined.
// Note: Provided by UnderlyingSourceAlgorithmsWrapper::StartCallback.
// Step 4. Let pullAlgorithm be the following steps:
MOZ_CAN_RUN_SCRIPT already_AddRefed<Promise> PullCallbackImpl(
JSContext* aCx, ReadableStreamController& aController,
ErrorResult& aRv) override {
aRv.MightThrowJSException();
// Step 1. Let nextResult be IteratorNext(iteratorRecord).
JS::Rooted<JSObject*> iteratorRecord(aCx, mIteratorRecord);
JS::Rooted<JS::Value> nextResult(aCx);
if (!JS::IteratorNext(aCx, iteratorRecord, &nextResult)) {
// Step 2. If nextResult is an abrupt completion, return a promise
// rejected with nextResult.[[Value]].
aRv.StealExceptionFromJSContext(aCx);
return nullptr;
}
// Step 3. Let nextPromise be a promise resolved with nextResult.[[Value]].
RefPtr<Promise> nextPromise = Promise::CreateInfallible(mGlobal);
nextPromise->MaybeResolve(nextResult);
// Step 4. Return the result of reacting to nextPromise with the following
// fulfillment steps, given iterResult:
auto result = nextPromise->ThenWithCycleCollectedArgs(
[](JSContext* aCx, JS::Handle<JS::Value> aIterResult, ErrorResult& aRv,
const RefPtr<ReadableStreamDefaultController>& aController)
MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION -> already_AddRefed<Promise> {
aRv.MightThrowJSException();
// Step 4.1. If Type(iterResult) is not Object, throw a TypeError.
if (!aIterResult.isObject()) {
aRv.ThrowTypeError("next() returned a non-object value");
return nullptr;
}
// Step 4.2. Let done be ? IteratorComplete(iterResult).
JS::Rooted<JSObject*> iterResult(aCx, &aIterResult.toObject());
bool done = false;
if (!JS::IteratorComplete(aCx, iterResult, &done)) {
aRv.StealExceptionFromJSContext(aCx);
return nullptr;
}
// Step 4.3. If done is true:
if (done) {
// Step 4.3.1. Perform !
// ReadableStreamDefaultControllerClose(stream.[[controller]]).
ReadableStreamDefaultControllerClose(aCx, aController, aRv);
} else {
// Step 4.4. Otherwise:
// Step 4.4.1. Let value be ? IteratorValue(iterResult).
JS::Rooted<JS::Value> value(aCx);
if (!JS::IteratorValue(aCx, iterResult, &value)) {
aRv.StealExceptionFromJSContext(aCx);
return nullptr;
}
// Step 4.4.2. Perform !
// ReadableStreamDefaultControllerEnqueue(stream.[[controller]],
// value).
ReadableStreamDefaultControllerEnqueue(aCx, aController, value,
aRv);
}
return nullptr;
},
RefPtr(aController.AsDefault()));
if (result.isErr()) {
aRv.Throw(result.unwrapErr());
return nullptr;
}
return result.unwrap().forget();
};
// Step 5. Let cancelAlgorithm be the following steps, given reason:
MOZ_CAN_RUN_SCRIPT already_AddRefed<Promise> CancelCallbackImpl(
JSContext* aCx, const Optional<JS::Handle<JS::Value>>& aReason,
ErrorResult& aRv) override {
aRv.MightThrowJSException();
// Step 1. Let iterator be iteratorRecord.[[Iterator]].
JS::Rooted<JSObject*> iteratorRecord(aCx, mIteratorRecord);
JS::Rooted<JS::Value> iterator(aCx);
if (!JS::GetIteratorRecordIterator(aCx, iteratorRecord, &iterator)) {
aRv.StealExceptionFromJSContext(aCx);
return nullptr;
}
// Step 2. Let returnMethod be GetMethod(iterator, "return").
JS::Rooted<JS::Value> returnMethod(aCx);
if (!JS::GetReturnMethod(aCx, iterator, &returnMethod)) {
// Step 3. If returnMethod is an abrupt completion, return a promise
// rejected with returnMethod.[[Value]].
aRv.StealExceptionFromJSContext(aCx);
return nullptr;
}
// Step 4. If returnMethod.[[Value]] is undefined, return a promise resolved
// with undefined.
if (returnMethod.isUndefined()) {
return Promise::CreateResolvedWithUndefined(mGlobal, aRv);
}
// Step 5. Let returnResult be Call(returnMethod.[[Value]], iterator, «
// reason »).
JS::Rooted<JS::Value> returnResult(aCx);
if (!JS::Call(aCx, iterator, returnMethod,
JS::HandleValueArray(aReason.Value()), &returnResult)) {
// Step 6. If returnResult is an abrupt completion, return a promise
// rejected with returnResult.[[Value]].
aRv.StealExceptionFromJSContext(aCx);
return nullptr;
}
// Step 7. Let returnPromise be a promise resolved with
// returnResult.[[Value]].
RefPtr<Promise> returnPromise = Promise::CreateInfallible(mGlobal);
returnPromise->MaybeResolve(returnResult);
// Step 8. Return the result of reacting to returnPromise with the following
// fulfillment steps, given iterResult:
auto result = returnPromise->ThenWithCycleCollectedArgs(
[](JSContext* aCx, JS::Handle<JS::Value> aIterResult, ErrorResult& aRv)
MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION -> already_AddRefed<Promise> {
// Step 8.1. If Type(iterResult) is not Object, throw a TypeError.
if (!aIterResult.isObject()) {
aRv.ThrowTypeError("return() returned a non-object value");
return nullptr;
}
// Step 8.2. Return undefined.
return nullptr;
});
if (result.isErr()) {
aRv.Throw(result.unwrapErr());
return nullptr;
}
return result.unwrap().forget();
};
protected:
~ReadableStreamFromAlgorithms() override { mozilla::DropJSObjects(this); };
private:
// Virtually const, but are cycle collected
nsCOMPtr<nsIGlobalObject> mGlobal;
JS::Heap<JSObject*> mIteratorRecord;
};
NS_IMPL_CYCLE_COLLECTION_INHERITED_WITH_JS_MEMBERS(
ReadableStreamFromAlgorithms, UnderlyingSourceAlgorithmsWrapper, (mGlobal),
(mIteratorRecord))
NS_IMPL_ADDREF_INHERITED(ReadableStreamFromAlgorithms,
UnderlyingSourceAlgorithmsWrapper)
NS_IMPL_RELEASE_INHERITED(ReadableStreamFromAlgorithms,
UnderlyingSourceAlgorithmsWrapper)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ReadableStreamFromAlgorithms)
NS_INTERFACE_MAP_END_INHERITING(UnderlyingSourceAlgorithmsWrapper)
// https://streams.spec.whatwg.org/#readable-stream-from-iterable
static already_AddRefed<ReadableStream> MOZ_CAN_RUN_SCRIPT
ReadableStreamFromIterable(JSContext* aCx, nsIGlobalObject* aGlobal,
JS::Handle<JS::Value> aAsyncIterable,
ErrorResult& aRv) {
aRv.MightThrowJSException();
// Step 1. Let stream be undefined. (not required)
// Step 2. Let iteratorRecord be ? GetIterator(asyncIterable, async).
JS::Rooted<JSObject*> iteratorRecord(
aCx, JS::GetIteratorObject(aCx, aAsyncIterable, true));
if (!iteratorRecord) {
aRv.StealExceptionFromJSContext(aCx);
return nullptr;
}
// Steps 3-5. are in ReadableStreamFromAlgorithms.
auto algorithms =
MakeRefPtr<ReadableStreamFromAlgorithms>(aGlobal, iteratorRecord);
// Step 6. Set stream to ! CreateReadableStream(startAlgorithm, pullAlgorithm,
// cancelAlgorithm, 0).
// Step 7. Return stream.
return ReadableStream::CreateAbstract(aCx, aGlobal, algorithms,
mozilla::Some(0.0), nullptr, aRv);
}
/* static */
already_AddRefed<ReadableStream> ReadableStream::From(
const GlobalObject& aGlobal, JS::Handle<JS::Value> aAsyncIterable,
ErrorResult& aRv) {
// Step 1. Return ? ReadableStreamFromIterable(asyncIterable).
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
return ReadableStreamFromIterable(aGlobal.Context(), global, aAsyncIterable,
aRv);
}
// Dealing with const this ptr is a pain, so just re-implement.
// https://streams.spec.whatwg.org/#is-readable-stream-locked
bool ReadableStream::Locked() const {

Просмотреть файл

@ -199,6 +199,10 @@ class ReadableStream : public nsISupports, public nsWrapperCache {
const Optional<JS::Handle<JSObject*>>& aUnderlyingSource,
const QueuingStrategy& aStrategy, ErrorResult& aRv);
MOZ_CAN_RUN_SCRIPT static already_AddRefed<ReadableStream> From(
const GlobalObject& aGlobal, JS::Handle<JS::Value> asyncIterable,
ErrorResult& aRv);
bool Locked() const;
MOZ_CAN_RUN_SCRIPT already_AddRefed<Promise> Cancel(

Просмотреть файл

@ -151,7 +151,9 @@ already_AddRefed<Promise> UnderlyingSourceAlgorithmsWrapper::CancelCallback(
nsCOMPtr<nsIGlobalObject> global = xpc::CurrentNativeGlobal(aCx);
return PromisifyAlgorithm(
global,
[&](ErrorResult& aRv) { return CancelCallbackImpl(aCx, aReason, aRv); },
[&](ErrorResult& aRv) MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION {
return CancelCallbackImpl(aCx, aReason, aRv);
},
aRv);
}

Просмотреть файл

@ -153,7 +153,7 @@ class UnderlyingSourceAlgorithmsWrapper
return nullptr;
}
virtual already_AddRefed<Promise> CancelCallbackImpl(
MOZ_CAN_RUN_SCRIPT virtual already_AddRefed<Promise> CancelCallbackImpl(
JSContext* aCx, const Optional<JS::Handle<JS::Value>>& aReason,
ErrorResult& aRv) {
// cancelAlgorithm is optional, return null by default

Просмотреть файл

@ -12,6 +12,9 @@ interface ReadableStream {
[Throws]
constructor(optional object underlyingSource, optional QueuingStrategy strategy = {});
[Pref="dom.streams.from.enabled", Throws]
static ReadableStream from(any asyncIterable);
readonly attribute boolean locked;
[NewObject]

39
js/public/Iterator.h Normal file
Просмотреть файл

@ -0,0 +1,39 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef js_Iterator_h
#define js_Iterator_h
#include "js/TypeDecls.h"
namespace JS {
// https://tc39.es/ecma262/#sec-getiterator
// GetIterator
JSObject* GetIteratorObject(JSContext* cx, Handle<Value> obj, bool isAsync);
// https://tc39.es/ecma262/#sec-iteratornext
bool IteratorNext(JSContext* cx, Handle<JSObject*> iteratorRecord,
MutableHandle<Value> result);
// https://tc39.es/ecma262/#sec-iteratorcomplete
bool IteratorComplete(JSContext* cx, Handle<JSObject*> iterResult, bool* done);
// https://tc39.es/ecma262/#sec-iteratorvalue
bool IteratorValue(JSContext* cx, Handle<JSObject*> iterResult,
MutableHandle<Value> value);
// Implements iteratorRecord.[[Iterator]]
bool GetIteratorRecordIterator(JSContext* cx, Handle<JSObject*> iteratorRecord,
MutableHandle<Value> iterator);
// Implements GetMethod(iterator, "return").
bool GetReturnMethod(JSContext* cx, Handle<Value> iterator,
MutableHandle<Value> result);
} // namespace JS
#endif /* js_Iterator_h */

Просмотреть файл

@ -68,6 +68,57 @@ function GetIteratorSync(obj) {
// Step 6. Let iteratorRecord be the Record { [[Iterator]]: iterator, [[NextMethod]]: nextMethod, [[Done]]: false }.
var iteratorRecord = {
__proto__: null,
iterator,
nextMethod,
done: false
};
// Step 7. Return iteratorRecord.
return iteratorRecord;
}
// https://tc39.es/ecma262/#sec-getiterator
function GetIterator(obj, isAsync, method) {
// Step 1. If hint is not present, set hint to sync.
// Step 2. If method is not present, then
if (!method) {
// Step 2.a. If hint is async, then
if (isAsync) {
// Step 2.a.i. Set method to ? GetMethod(obj, @@asyncIterator).
method = GetMethod(obj, GetBuiltinSymbol("asyncIterator"));
// Step 2.a.ii. If method is undefined, then
if (!method) {
// Step 2.a.ii.1. Let syncMethod be ? GetMethod(obj, @@iterator).
var syncMethod = GetMethod(obj, GetBuiltinSymbol("iterator"));
// Step 2.a.ii.2. Let syncIteratorRecord be ? GetIterator(obj, sync, syncMethod).
var syncIteratorRecord = GetIterator(obj, false, syncMethod);
// Step 2.a.ii.2. Return CreateAsyncFromSyncIterator(syncIteratorRecord).
return CreateAsyncFromSyncIterator(syncIteratorRecord.iterator, syncIteratorRecord.nextMethod);
}
} else {
// Step 2.b. Otherwise, set method to ? GetMethod(obj, @@iterator).
method = GetMethod(obj, GetBuiltinSymbol("iterator"));
}
}
// Step 3. Let iterator be ? Call(method, obj).
var iterator = callContentFunction(method, obj);
// Step 4. If Type(iterator) is not Object, throw a TypeError exception.
if (!IsObject(iterator)) {
ThrowTypeError(JSMSG_NOT_ITERABLE, obj === null ? "null" : typeof obj);
}
// Step 5. Let nextMethod be ? GetV(iterator, "next").
var nextMethod = iterator.next;
// Step 6. Let iteratorRecord be the Record { [[Iterator]]: iterator, [[NextMethod]]: nextMethod, [[Done]]: false }.
var iteratorRecord = {
__proto__: null,
iterator,
nextMethod,
done: false,

Просмотреть файл

@ -159,6 +159,7 @@ EXPORTS.js += [
"../public/Id.h",
"../public/Initialization.h",
"../public/Interrupt.h",
"../public/Iterator.h",
"../public/JitCodeAPI.h",
"../public/JSON.h",
"../public/LocaleSensitive.h",
@ -377,6 +378,7 @@ UNIFIED_SOURCES += [
"vm/Initialization.cpp",
"vm/InternalThreadPool.cpp",
"vm/Iteration.cpp",
"vm/Iterator.cpp",
"vm/JitActivation.cpp",
"vm/JSAtom.cpp",
"vm/JSContext.cpp",

Просмотреть файл

@ -237,6 +237,7 @@
MACRO_(GetBuiltinSymbol, GetBuiltinSymbol, "GetBuiltinSymbol") \
MACRO_(GetInternalError, GetInternalError, "GetInternalError") \
MACRO_(getInternals, getInternals, "getInternals") \
MACRO_(GetIterator, GetIterator, "GetIterator") \
MACRO_(GetModuleNamespace, GetModuleNamespace, "GetModuleNamespace") \
MACRO_(getOffsetNanosecondsFor, getOffsetNanosecondsFor, \
"getOffsetNanosecondsFor") \
@ -331,6 +332,7 @@
MACRO_(isSubsetOf, isSubsetOf, "isSubsetOf") \
MACRO_(isSupersetOf, isSupersetOf, "isSupersetOf") \
MACRO_(IterableToList, IterableToList, "IterableToList") \
MACRO_(IteratorNext, IteratorNext, "IteratorNext") \
MACRO_(iterate, iterate, "iterate") \
MACRO_(join, join, "join") \
MACRO2(js, js, "js") \
@ -402,6 +404,7 @@
MACRO_(NegativeInfinity, NegativeInfinity, "-Infinity") \
MACRO_(new, new_, "new") \
MACRO_(next, next, "next") \
MACRO_(nextMethod, nextMethod, "nextMethod") \
MACRO_(NFC, NFC, "NFC") \
MACRO_(NFD, NFD, "NFD") \
MACRO_(NFKC, NFKC, "NFKC") \

102
js/src/vm/Iterator.cpp Normal file
Просмотреть файл

@ -0,0 +1,102 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "js/Iterator.h"
#include "js/Conversions.h"
#include "vm/Interpreter.h"
#include "vm/JSAtomState.h"
#include "vm/JSContext.h"
#include "vm/ObjectOperations.h"
#include "vm/SelfHosting.h"
#include "vm/StringType.h"
#include "vm/JSObject-inl.h"
using namespace js;
namespace JS {
// https://tc39.es/ecma262/#sec-getiterator
// GetIterator(obj [, hint [, method]])
JSObject* GetIteratorObject(JSContext* cx, HandleValue obj, bool isAsync) {
FixedInvokeArgs<3> args(cx);
args[0].set(obj);
args[1].setBoolean(isAsync);
args[2].setUndefined(); // method
RootedValue rval(cx);
if (!CallSelfHostedFunction(cx, cx->names().GetIterator, UndefinedHandleValue,
args, &rval)) {
return nullptr;
}
MOZ_ASSERT(rval.isObject());
return &rval.toObject();
}
// https://tc39.es/ecma262/#sec-iteratornext
bool IteratorNext(JSContext* cx, HandleObject iteratorRecord,
MutableHandleValue result) {
FixedInvokeArgs<1> args(cx);
args[0].setObject(*iteratorRecord);
return CallSelfHostedFunction(cx, cx->names().IteratorNext,
UndefinedHandleValue, args, result);
}
// https://tc39.es/ecma262/#sec-iteratorcomplete
bool IteratorComplete(JSContext* cx, HandleObject iterResult, bool* done) {
RootedValue doneV(cx);
if (!GetProperty(cx, iterResult, iterResult, cx->names().done, &doneV)) {
return false;
}
*done = ToBoolean(doneV);
return true;
}
// https://tc39.es/ecma262/#sec-iteratorvalue
bool IteratorValue(JSContext* cx, HandleObject iterResult,
MutableHandleValue value) {
return GetProperty(cx, iterResult, iterResult, cx->names().value, value);
}
bool GetIteratorRecordIterator(JSContext* cx, HandleObject iteratorRecord,
MutableHandleValue iterator) {
return GetProperty(cx, iteratorRecord, iteratorRecord, cx->names().iterator,
iterator);
}
static bool GetMethod(JSContext* cx, HandleValue v, Handle<PropertyName*> name,
MutableHandleValue result) {
// Step 1. Let func be ? GetV(V, P).
RootedValue func(cx);
if (!GetProperty(cx, v, name, &func)) {
return false;
}
// Step 2. If func is either undefined or null, return undefined.
if (func.isNullOrUndefined()) {
result.setUndefined();
return true;
}
// Step 3. If IsCallable(func) is false, throw a TypeError exception.
if (!IsCallable(func)) {
return ReportIsNotFunction(cx, func, -1);
}
// Step 4. Return func.
result.set(func);
return true;
}
bool GetReturnMethod(JSContext* cx, HandleValue iterator,
MutableHandleValue result) {
// Step 2. Let returnMethod be GetMethod(iterator, "return").
return GetMethod(cx, iterator, cx->names().return_, result);
}
} // namespace JS

Просмотреть файл

@ -1788,6 +1788,64 @@ static bool intrinsic_NewAsyncIteratorHelper(JSContext* cx, unsigned argc,
return true;
}
static JSObject* NewIteratorRecord(JSContext* cx, HandleObject iterator,
HandleValue nextMethod) {
gc::AllocKind allocKind = gc::GetGCObjectKind(3);
Rooted<PlainObject*> obj(
cx, NewPlainObjectWithProtoAndAllocKind(cx, nullptr, allocKind));
if (!obj) {
return nullptr;
}
RootedId propid(cx, NameToId(cx->names().iterator));
RootedValue value(cx, ObjectValue(*iterator));
if (!NativeDefineDataProperty(cx, obj, propid, value, JSPROP_ENUMERATE)) {
return nullptr;
}
propid = NameToId(cx->names().nextMethod);
value.set(nextMethod);
if (!NativeDefineDataProperty(cx, obj, propid, value, JSPROP_ENUMERATE)) {
return nullptr;
}
propid = NameToId(cx->names().done);
value.setBoolean(false);
if (!NativeDefineDataProperty(cx, obj, propid, value, JSPROP_ENUMERATE)) {
return nullptr;
}
return obj;
}
static bool intrinsic_CreateAsyncFromSyncIterator(JSContext* cx, unsigned argc,
Value* vp) {
CallArgs args = CallArgsFromVp(argc, vp);
MOZ_ASSERT(args.length() == 2);
RootedObject iterator(cx, &args[0].toObject());
RootedObject asyncIterator(
cx, CreateAsyncFromSyncIterator(cx, iterator, args[1]));
if (!asyncIterator) {
return false;
}
RootedValue nextMethod(cx);
if (!GetProperty(cx, asyncIterator, asyncIterator, cx->names().next,
&nextMethod)) {
return false;
}
RootedObject iteratorRecord(cx,
NewIteratorRecord(cx, asyncIterator, nextMethod));
if (!iteratorRecord) {
return false;
}
args.rval().setObject(*iteratorRecord);
return true;
}
static bool intrinsic_NoPrivateGetter(JSContext* cx, unsigned argc, Value* vp) {
CallArgs args = CallArgsFromVp(argc, vp);
MOZ_ASSERT(args.length() == 0);
@ -1858,6 +1916,8 @@ static const JSFunctionSpec intrinsic_functions[] = {
JS_FN("ConstructorForTypedArray", intrinsic_ConstructorForTypedArray, 1, 0),
JS_FN("CopyDataPropertiesOrGetOwnKeys",
intrinsic_CopyDataPropertiesOrGetOwnKeys, 3, 0),
JS_FN("CreateAsyncFromSyncIterator", intrinsic_CreateAsyncFromSyncIterator,
2, 0),
JS_FN("CreateMapIterationResultPair",
intrinsic_CreateMapIterationResultPair, 0, 0),
JS_FN("CreateSetIterationResult", intrinsic_CreateSetIterationResult, 0, 0),

Просмотреть файл

@ -3983,6 +3983,12 @@
value: true
mirror: always
# ReadableStream.from(asyncIterable)
- name: dom.streams.from.enabled
type: RelaxedAtomicBool
value: true
mirror: always
- name: dom.workers.pFetch.enabled
type: RelaxedAtomicBool
value: true

Просмотреть файл

@ -1,446 +0,0 @@
[from.any.serviceworker.html]
[ReadableStream.from accepts an array of values]
expected: FAIL
[ReadableStream.from accepts an array of promises]
expected: FAIL
[ReadableStream.from accepts an array iterator]
expected: FAIL
[ReadableStream.from accepts a string]
expected: FAIL
[ReadableStream.from accepts a Set]
expected: FAIL
[ReadableStream.from accepts a Set iterator]
expected: FAIL
[ReadableStream.from accepts a sync generator]
expected: FAIL
[ReadableStream.from accepts an async generator]
expected: FAIL
[ReadableStream.from accepts a sync iterable of values]
expected: FAIL
[ReadableStream.from accepts a sync iterable of promises]
expected: FAIL
[ReadableStream.from accepts an async iterable]
expected: FAIL
[ReadableStream.from accepts a ReadableStream]
expected: FAIL
[ReadableStream.from accepts a ReadableStream async iterator]
expected: FAIL
[ReadableStream.from re-throws errors from calling the @@iterator method]
expected: FAIL
[ReadableStream.from re-throws errors from calling the @@asyncIterator method]
expected: FAIL
[ReadableStream.from ignores @@iterator if @@asyncIterator exists]
expected: FAIL
[ReadableStream.from accepts an empty iterable]
expected: FAIL
[ReadableStream.from: stream errors when next() rejects]
expected: FAIL
[ReadableStream.from: stream stalls when next() never settles]
expected: FAIL
[ReadableStream.from: calls next() after first read()]
expected: FAIL
[ReadableStream.from: cancelling the returned stream calls and awaits return()]
expected: FAIL
[ReadableStream.from: return() is not called when iterator completes normally]
expected: FAIL
[ReadableStream.from: cancel() rejects when return() fulfills with a non-object]
expected: FAIL
[ReadableStream.from: reader.read() inside next()]
expected: FAIL
[ReadableStream.from: reader.cancel() inside next()]
expected: FAIL
[ReadableStream.from: reader.cancel() inside return()]
expected: FAIL
[ReadableStream.from(array), push() to array while reading]
expected: FAIL
[from.any.worker.html]
[ReadableStream.from accepts an array of values]
expected: FAIL
[ReadableStream.from accepts an array of promises]
expected: FAIL
[ReadableStream.from accepts an array iterator]
expected: FAIL
[ReadableStream.from accepts a string]
expected: FAIL
[ReadableStream.from accepts a Set]
expected: FAIL
[ReadableStream.from accepts a Set iterator]
expected: FAIL
[ReadableStream.from accepts a sync generator]
expected: FAIL
[ReadableStream.from accepts an async generator]
expected: FAIL
[ReadableStream.from accepts a sync iterable of values]
expected: FAIL
[ReadableStream.from accepts a sync iterable of promises]
expected: FAIL
[ReadableStream.from accepts an async iterable]
expected: FAIL
[ReadableStream.from accepts a ReadableStream]
expected: FAIL
[ReadableStream.from accepts a ReadableStream async iterator]
expected: FAIL
[ReadableStream.from re-throws errors from calling the @@iterator method]
expected: FAIL
[ReadableStream.from re-throws errors from calling the @@asyncIterator method]
expected: FAIL
[ReadableStream.from ignores @@iterator if @@asyncIterator exists]
expected: FAIL
[ReadableStream.from accepts an empty iterable]
expected: FAIL
[ReadableStream.from: stream errors when next() rejects]
expected: FAIL
[ReadableStream.from: stream stalls when next() never settles]
expected: FAIL
[ReadableStream.from: calls next() after first read()]
expected: FAIL
[ReadableStream.from: cancelling the returned stream calls and awaits return()]
expected: FAIL
[ReadableStream.from: return() is not called when iterator completes normally]
expected: FAIL
[ReadableStream.from: cancel() rejects when return() fulfills with a non-object]
expected: FAIL
[ReadableStream.from: reader.read() inside next()]
expected: FAIL
[ReadableStream.from: reader.cancel() inside next()]
expected: FAIL
[ReadableStream.from: reader.cancel() inside return()]
expected: FAIL
[ReadableStream.from(array), push() to array while reading]
expected: FAIL
[from.any.html]
[ReadableStream.from accepts an array of values]
expected: FAIL
[ReadableStream.from accepts an array of promises]
expected: FAIL
[ReadableStream.from accepts an array iterator]
expected: FAIL
[ReadableStream.from accepts a string]
expected: FAIL
[ReadableStream.from accepts a Set]
expected: FAIL
[ReadableStream.from accepts a Set iterator]
expected: FAIL
[ReadableStream.from accepts a sync generator]
expected: FAIL
[ReadableStream.from accepts an async generator]
expected: FAIL
[ReadableStream.from accepts a sync iterable of values]
expected: FAIL
[ReadableStream.from accepts a sync iterable of promises]
expected: FAIL
[ReadableStream.from accepts an async iterable]
expected: FAIL
[ReadableStream.from accepts a ReadableStream]
expected: FAIL
[ReadableStream.from accepts a ReadableStream async iterator]
expected: FAIL
[ReadableStream.from re-throws errors from calling the @@iterator method]
expected: FAIL
[ReadableStream.from re-throws errors from calling the @@asyncIterator method]
expected: FAIL
[ReadableStream.from ignores @@iterator if @@asyncIterator exists]
expected: FAIL
[ReadableStream.from accepts an empty iterable]
expected: FAIL
[ReadableStream.from: stream errors when next() rejects]
expected: FAIL
[ReadableStream.from: stream stalls when next() never settles]
expected: FAIL
[ReadableStream.from: calls next() after first read()]
expected: FAIL
[ReadableStream.from: cancelling the returned stream calls and awaits return()]
expected: FAIL
[ReadableStream.from: return() is not called when iterator completes normally]
expected: FAIL
[ReadableStream.from: cancel() rejects when return() fulfills with a non-object]
expected: FAIL
[ReadableStream.from: reader.read() inside next()]
expected: FAIL
[ReadableStream.from: reader.cancel() inside next()]
expected: FAIL
[ReadableStream.from: reader.cancel() inside return()]
expected: FAIL
[ReadableStream.from(array), push() to array while reading]
expected: FAIL
[from.any.sharedworker.html]
[ReadableStream.from accepts an array of values]
expected: FAIL
[ReadableStream.from accepts an array of promises]
expected: FAIL
[ReadableStream.from accepts an array iterator]
expected: FAIL
[ReadableStream.from accepts a string]
expected: FAIL
[ReadableStream.from accepts a Set]
expected: FAIL
[ReadableStream.from accepts a Set iterator]
expected: FAIL
[ReadableStream.from accepts a sync generator]
expected: FAIL
[ReadableStream.from accepts an async generator]
expected: FAIL
[ReadableStream.from accepts a sync iterable of values]
expected: FAIL
[ReadableStream.from accepts a sync iterable of promises]
expected: FAIL
[ReadableStream.from accepts an async iterable]
expected: FAIL
[ReadableStream.from accepts a ReadableStream]
expected: FAIL
[ReadableStream.from accepts a ReadableStream async iterator]
expected: FAIL
[ReadableStream.from re-throws errors from calling the @@iterator method]
expected: FAIL
[ReadableStream.from re-throws errors from calling the @@asyncIterator method]
expected: FAIL
[ReadableStream.from ignores @@iterator if @@asyncIterator exists]
expected: FAIL
[ReadableStream.from accepts an empty iterable]
expected: FAIL
[ReadableStream.from: stream errors when next() rejects]
expected: FAIL
[ReadableStream.from: stream stalls when next() never settles]
expected: FAIL
[ReadableStream.from: calls next() after first read()]
expected: FAIL
[ReadableStream.from: cancelling the returned stream calls and awaits return()]
expected: FAIL
[ReadableStream.from: return() is not called when iterator completes normally]
expected: FAIL
[ReadableStream.from: cancel() rejects when return() fulfills with a non-object]
expected: FAIL
[ReadableStream.from: reader.read() inside next()]
expected: FAIL
[ReadableStream.from: reader.cancel() inside next()]
expected: FAIL
[ReadableStream.from: reader.cancel() inside return()]
expected: FAIL
[ReadableStream.from(array), push() to array while reading]
expected: FAIL
[from.any.js]
[ReadableStream.from accepts an array of values]
expected: FAIL
[ReadableStream.from accepts an array of promises]
expected: FAIL
[ReadableStream.from accepts an array iterator]
expected: FAIL
[ReadableStream.from accepts a string]
expected: FAIL
[ReadableStream.from accepts a Set]
expected: FAIL
[ReadableStream.from accepts a Set iterator]
expected: FAIL
[ReadableStream.from accepts a sync generator]
expected: FAIL
[ReadableStream.from accepts an async generator]
expected: FAIL
[ReadableStream.from accepts a sync iterable of values]
expected: FAIL
[ReadableStream.from accepts a sync iterable of promises]
expected: FAIL
[ReadableStream.from accepts an async iterable]
expected: FAIL
[ReadableStream.from accepts a ReadableStream]
expected: FAIL
[ReadableStream.from accepts a ReadableStream async iterator]
expected: FAIL
[ReadableStream.from re-throws errors from calling the @@iterator method]
expected: FAIL
[ReadableStream.from re-throws errors from calling the @@asyncIterator method]
expected: FAIL
[ReadableStream.from ignores @@iterator if @@asyncIterator exists]
expected: FAIL
[ReadableStream.from accepts an empty iterable]
expected: FAIL
[ReadableStream.from: stream errors when next() rejects]
expected: FAIL
[ReadableStream.from: stream stalls when next() never settles]
expected: FAIL
[ReadableStream.from: calls next() after first read()]
expected: FAIL
[ReadableStream.from: cancelling the returned stream calls and awaits return()]
expected: FAIL
[ReadableStream.from: return() is not called when iterator completes normally]
expected: FAIL
[ReadableStream.from: cancel() rejects when return() fulfills with a non-object]
expected: FAIL
[ReadableStream.from: reader.read() inside next()]
expected: FAIL
[ReadableStream.from: reader.cancel() inside next()]
expected: FAIL
[ReadableStream.from: reader.cancel() inside return()]
expected: FAIL
[ReadableStream.from(array), push() to array while reading]
expected: FAIL
[ReadableStream.from throws on invalid iterables; specifically null]
expected: FAIL
[ReadableStream.from throws on invalid iterables; specifically undefined]
expected: FAIL
[ReadableStream.from throws on invalid iterables; specifically 0]
expected: FAIL
[ReadableStream.from throws on invalid iterables; specifically NaN]
expected: FAIL
[ReadableStream.from throws on invalid iterables; specifically true]
expected: FAIL
[ReadableStream.from throws on invalid iterables; specifically {}]
expected: FAIL
[ReadableStream.from throws on invalid iterables; specifically Object.create(null)]
expected: FAIL
[ReadableStream.from throws on invalid iterables; specifically a function]
expected: FAIL
[ReadableStream.from throws on invalid iterables; specifically a symbol]
expected: FAIL
[ReadableStream.from throws on invalid iterables; specifically an object with a non-callable @@iterator method]
expected: FAIL
[ReadableStream.from throws on invalid iterables; specifically an object with a non-callable @@asyncIterator method]
expected: FAIL

Просмотреть файл

@ -1,4 +1,4 @@
// META: global=window,worker,jsshell
// META: global=window,worker
// META: script=../resources/test-utils.js
'use strict';