blob: 2163fac6d65c2b41654eb58689d3f9830825a540 [file] [log] [blame]
commit-queue@webkit.org26209092017-08-30 00:39:26 +00001/*
mark.lam@apple.com6452c9d2020-07-03 05:51:58 +00002 * Copyright (C) 2017-2020 Apple Inc. All rights reserved.
commit-queue@webkit.org26209092017-08-30 00:39:26 +00003 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY CANON INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CANON INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "ReadableStream.h"
28
mark.lam@apple.com6452c9d2020-07-03 05:51:58 +000029#include "Exception.h"
30#include "ExceptionCode.h"
commit-queue@webkit.orga57234a2017-08-31 20:03:42 +000031#include "JSDOMConvertSequences.h"
commit-queue@webkit.org48672fa2017-09-01 22:53:23 +000032#include "JSReadableStreamSink.h"
commit-queue@webkit.org26209092017-08-30 00:39:26 +000033#include "JSReadableStreamSource.h"
34#include "WebCoreJSClientData.h"
35
commit-queue@webkit.org26209092017-08-30 00:39:26 +000036
37namespace WebCore {
keith_miller@apple.comce64b732017-10-17 07:10:58 +000038using namespace JSC;
commit-queue@webkit.org26209092017-08-30 00:39:26 +000039
mark.lam@apple.com6452c9d2020-07-03 05:51:58 +000040ExceptionOr<Ref<ReadableStream>> ReadableStream::create(JSC::JSGlobalObject& lexicalGlobalObject, RefPtr<ReadableStreamSource>&& source)
commit-queue@webkit.org26209092017-08-30 00:39:26 +000041{
ysuzuki@apple.com52e98bb2019-10-22 09:24:48 +000042 VM& vm = lexicalGlobalObject.vm();
mark.lam@apple.com6452c9d2020-07-03 05:51:58 +000043 auto scope = DECLARE_THROW_SCOPE(vm);
commit-queue@webkit.org47214d92017-09-07 23:23:57 +000044
commit-queue@webkit.org26209092017-08-30 00:39:26 +000045 auto& clientData = *static_cast<JSVMClientData*>(vm.clientData);
ysuzuki@apple.com52e98bb2019-10-22 09:24:48 +000046 auto& globalObject = *JSC::jsCast<JSDOMGlobalObject*>(&lexicalGlobalObject);
commit-queue@webkit.org26209092017-08-30 00:39:26 +000047
ysuzuki@apple.com52e98bb2019-10-22 09:24:48 +000048 auto* constructor = JSC::asObject(globalObject.get(&lexicalGlobalObject, clientData.builtinNames().ReadableStreamPrivateName()));
commit-queue@webkit.org26209092017-08-30 00:39:26 +000049
ross.kirsling@sony.com924e7502020-04-27 09:09:32 +000050 auto constructData = getConstructData(vm, constructor);
51 ASSERT(constructData.type != CallData::Type::None);
commit-queue@webkit.org26209092017-08-30 00:39:26 +000052
53 MarkedArgumentBuffer args;
ysuzuki@apple.com52e98bb2019-10-22 09:24:48 +000054 args.append(source ? toJSNewlyCreated(&lexicalGlobalObject, &globalObject, source.releaseNonNull()) : JSC::jsUndefined());
mark.lam@apple.comaad22312017-11-02 01:54:43 +000055 ASSERT(!args.hasOverflowed());
commit-queue@webkit.org26209092017-08-30 00:39:26 +000056
mark.lam@apple.com6452c9d2020-07-03 05:51:58 +000057 JSObject* object = JSC::construct(&lexicalGlobalObject, constructor, constructData, args);
58 ASSERT(!!scope.exception() == !object);
59 RETURN_IF_EXCEPTION(scope, Exception { ExistingExceptionError });
commit-queue@webkit.org26209092017-08-30 00:39:26 +000060
mark.lam@apple.com6452c9d2020-07-03 05:51:58 +000061 return create(globalObject, *jsCast<JSReadableStream*>(object));
commit-queue@webkit.org26209092017-08-30 00:39:26 +000062}
63
keith_miller@apple.comce64b732017-10-17 07:10:58 +000064namespace ReadableStreamInternal {
ysuzuki@apple.com52e98bb2019-10-22 09:24:48 +000065static inline JSC::JSValue callFunction(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue jsFunction, JSC::JSValue thisValue, const JSC::ArgList& arguments)
commit-queue@webkit.org9a040ee2017-09-06 21:25:19 +000066{
ysuzuki@apple.com52e98bb2019-10-22 09:24:48 +000067 VM& vm = lexicalGlobalObject.vm();
utatane.tea@gmail.comb860d692018-05-31 06:19:33 +000068 auto scope = DECLARE_CATCH_SCOPE(vm);
ross.kirsling@sony.com924e7502020-04-27 09:09:32 +000069 auto callData = JSC::getCallData(vm, jsFunction);
70 ASSERT(callData.type != JSC::CallData::Type::None);
71 auto result = call(&lexicalGlobalObject, jsFunction, callData, thisValue, arguments);
commit-queue@webkit.org9a040ee2017-09-06 21:25:19 +000072 scope.assertNoException();
73 return result;
74}
keith_miller@apple.comce64b732017-10-17 07:10:58 +000075}
commit-queue@webkit.org9a040ee2017-09-06 21:25:19 +000076
commit-queue@webkit.org48672fa2017-09-01 22:53:23 +000077void ReadableStream::pipeTo(ReadableStreamSink& sink)
78{
ysuzuki@apple.com52e98bb2019-10-22 09:24:48 +000079 auto& lexicalGlobalObject = *m_globalObject;
80 JSVMClientData* clientData = static_cast<JSVMClientData*>(lexicalGlobalObject.vm().clientData);
commit-queue@webkit.org48672fa2017-09-01 22:53:23 +000081 const Identifier& privateName = clientData->builtinFunctions().readableStreamInternalsBuiltins().readableStreamPipeToPrivateName();
82
ysuzuki@apple.com52e98bb2019-10-22 09:24:48 +000083 auto readableStreamPipeTo = m_globalObject->get(&lexicalGlobalObject, privateName);
ross.kirsling@sony.com5e63a212020-04-28 21:51:37 +000084 ASSERT(readableStreamPipeTo.isCallable(lexicalGlobalObject.vm()));
commit-queue@webkit.org48672fa2017-09-01 22:53:23 +000085
commit-queue@webkit.org48672fa2017-09-01 22:53:23 +000086 MarkedArgumentBuffer arguments;
87 arguments.append(readableStream());
ysuzuki@apple.com52e98bb2019-10-22 09:24:48 +000088 arguments.append(toJS(&lexicalGlobalObject, m_globalObject.get(), sink));
mark.lam@apple.comaad22312017-11-02 01:54:43 +000089 ASSERT(!arguments.hasOverflowed());
ysuzuki@apple.com52e98bb2019-10-22 09:24:48 +000090 ReadableStreamInternal::callFunction(lexicalGlobalObject, readableStreamPipeTo, JSC::jsUndefined(), arguments);
commit-queue@webkit.org48672fa2017-09-01 22:53:23 +000091}
92
commit-queue@webkit.orga57234a2017-08-31 20:03:42 +000093std::pair<Ref<ReadableStream>, Ref<ReadableStream>> ReadableStream::tee()
94{
ysuzuki@apple.com52e98bb2019-10-22 09:24:48 +000095 auto& lexicalGlobalObject = *m_globalObject;
96 JSVMClientData* clientData = static_cast<JSVMClientData*>(lexicalGlobalObject.vm().clientData);
commit-queue@webkit.orga57234a2017-08-31 20:03:42 +000097 const Identifier& privateName = clientData->builtinFunctions().readableStreamInternalsBuiltins().readableStreamTeePrivateName();
98
ysuzuki@apple.com52e98bb2019-10-22 09:24:48 +000099 auto readableStreamTee = m_globalObject->get(&lexicalGlobalObject, privateName);
ross.kirsling@sony.com5e63a212020-04-28 21:51:37 +0000100 ASSERT(readableStreamTee.isCallable(lexicalGlobalObject.vm()));
commit-queue@webkit.orga57234a2017-08-31 20:03:42 +0000101
commit-queue@webkit.orga57234a2017-08-31 20:03:42 +0000102 MarkedArgumentBuffer arguments;
103 arguments.append(readableStream());
104 arguments.append(JSC::jsBoolean(true));
mark.lam@apple.comaad22312017-11-02 01:54:43 +0000105 ASSERT(!arguments.hasOverflowed());
ysuzuki@apple.com52e98bb2019-10-22 09:24:48 +0000106 auto returnedValue = ReadableStreamInternal::callFunction(lexicalGlobalObject, readableStreamTee, JSC::jsUndefined(), arguments);
commit-queue@webkit.orga57234a2017-08-31 20:03:42 +0000107
ysuzuki@apple.com52e98bb2019-10-22 09:24:48 +0000108 auto results = Detail::SequenceConverter<IDLInterface<ReadableStream>>::convert(lexicalGlobalObject, returnedValue);
commit-queue@webkit.orga57234a2017-08-31 20:03:42 +0000109
110 ASSERT(results.size() == 2);
111 return std::make_pair(results[0].releaseNonNull(), results[1].releaseNonNull());
112}
113
commit-queue@webkit.org47214d92017-09-07 23:23:57 +0000114void ReadableStream::lock()
115{
ysuzuki@apple.com52e98bb2019-10-22 09:24:48 +0000116 auto& lexicalGlobalObject = *m_globalObject;
117 VM& vm = lexicalGlobalObject.vm();
commit-queue@webkit.org47214d92017-09-07 23:23:57 +0000118 auto scope = DECLARE_CATCH_SCOPE(vm);
119
120 auto& clientData = *static_cast<JSVMClientData*>(vm.clientData);
121
ysuzuki@apple.com52e98bb2019-10-22 09:24:48 +0000122 auto* constructor = JSC::asObject(m_globalObject->get(&lexicalGlobalObject, clientData.builtinNames().ReadableStreamDefaultReaderPrivateName()));
commit-queue@webkit.org47214d92017-09-07 23:23:57 +0000123
ross.kirsling@sony.com924e7502020-04-27 09:09:32 +0000124 auto constructData = getConstructData(vm, constructor);
125 ASSERT(constructData.type != CallData::Type::None);
commit-queue@webkit.org47214d92017-09-07 23:23:57 +0000126
127 MarkedArgumentBuffer args;
128 args.append(readableStream());
mark.lam@apple.comaad22312017-11-02 01:54:43 +0000129 ASSERT(!args.hasOverflowed());
commit-queue@webkit.org47214d92017-09-07 23:23:57 +0000130
ross.kirsling@sony.com924e7502020-04-27 09:09:32 +0000131 JSC::construct(&lexicalGlobalObject, constructor, constructData, args);
commit-queue@webkit.org47214d92017-09-07 23:23:57 +0000132 scope.assertNoException();
133}
134
commit-queue@webkit.org9a040ee2017-09-06 21:25:19 +0000135static inline bool checkReadableStream(JSDOMGlobalObject& globalObject, JSReadableStream* readableStream, JSC::JSValue function)
136{
ysuzuki@apple.com52e98bb2019-10-22 09:24:48 +0000137 auto& lexicalGlobalObject = globalObject;
commit-queue@webkit.org9a040ee2017-09-06 21:25:19 +0000138
139 ASSERT(function);
140 JSC::MarkedArgumentBuffer arguments;
141 arguments.append(readableStream);
mark.lam@apple.comaad22312017-11-02 01:54:43 +0000142 ASSERT(!arguments.hasOverflowed());
ysuzuki@apple.com52e98bb2019-10-22 09:24:48 +0000143 return ReadableStreamInternal::callFunction(lexicalGlobalObject, function, JSC::jsUndefined(), arguments).isTrue();
commit-queue@webkit.org9a040ee2017-09-06 21:25:19 +0000144}
145
146bool ReadableStream::isLocked() const
147{
148 return checkReadableStream(*globalObject(), readableStream(), globalObject()->builtinInternalFunctions().readableStreamInternals().m_isReadableStreamLockedFunction.get());
149}
150
151bool ReadableStream::isDisturbed() const
152{
153 return checkReadableStream(*globalObject(), readableStream(), globalObject()->builtinInternalFunctions().readableStreamInternals().m_isReadableStreamDisturbedFunction.get());
154}
155
ysuzuki@apple.com52e98bb2019-10-22 09:24:48 +0000156bool ReadableStream::isDisturbed(JSGlobalObject& lexicalGlobalObject, JSValue value)
commit-queue@webkit.org9a040ee2017-09-06 21:25:19 +0000157{
ysuzuki@apple.com52e98bb2019-10-22 09:24:48 +0000158 auto& vm = lexicalGlobalObject.vm();
159 auto& globalObject = *jsDynamicCast<JSDOMGlobalObject*>(vm, &lexicalGlobalObject);
utatane.tea@gmail.com5ec91b72018-03-08 18:38:09 +0000160 auto* readableStream = jsDynamicCast<JSReadableStream*>(vm, value);
commit-queue@webkit.org9a040ee2017-09-06 21:25:19 +0000161
162 return checkReadableStream(globalObject, readableStream, globalObject.builtinInternalFunctions().readableStreamInternals().m_isReadableStreamDisturbedFunction.get());
163}
164
commit-queue@webkit.org26209092017-08-30 00:39:26 +0000165}