diff options
Diffstat (limited to 'chromium/third_party/blink/renderer/core')
12 files changed, 235 insertions, 117 deletions
diff --git a/chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc b/chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc index 2ef7a11feae..8d6ec61bf2a 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc +++ b/chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc @@ -156,6 +156,9 @@ void HTMLCanvasElement::Dispose() { if (PlaceholderFrame()) ReleasePlaceholderFrame(); + // We need to drop frame dispatcher, to prevent mojo calls from completing. + frame_dispatcher_ = nullptr; + if (context_) { context_->DetachHost(); context_ = nullptr; diff --git a/chromium/third_party/blink/renderer/core/layout/layout_block_flow.cc b/chromium/third_party/blink/renderer/core/layout/layout_block_flow.cc index 6c5b8516a05..1568f9c8f06 100644 --- a/chromium/third_party/blink/renderer/core/layout/layout_block_flow.cc +++ b/chromium/third_party/blink/renderer/core/layout/layout_block_flow.cc @@ -55,6 +55,7 @@ #include "third_party/blink/renderer/core/layout/line/line_width.h" #include "third_party/blink/renderer/core/layout/logical_values.h" #include "third_party/blink/renderer/core/layout/ng/inline/ng_line_height_metrics.h" +#include "third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.h" #include "third_party/blink/renderer/core/layout/ng/layout_ng_block_flow.h" #include "third_party/blink/renderer/core/layout/ng/legacy_layout_tree_walking.h" #include "third_party/blink/renderer/core/layout/ng/ng_absolute_utils.h" @@ -446,6 +447,9 @@ void LayoutBlockFlow::UpdateBlockLayout(bool relayout_children) { if (RuntimeEnabledFeatures::TrackLayoutPassesPerBlockEnabled()) IncrementLayoutPassCount(); + if (rare_data_) + ClearOffsetMapping(); + if (!relayout_children && SimplifiedLayout()) return; @@ -4943,4 +4947,37 @@ int LayoutBlockFlow::GetLayoutPassCountForTesting() { return GetLayoutPassCountMap().find(this)->value; } +LayoutBlockFlow::LayoutBlockFlowRareData::LayoutBlockFlowRareData( + const LayoutBlockFlow* block) + : margins_(PositiveMarginBeforeDefault(block), + NegativeMarginBeforeDefault(block), + PositiveMarginAfterDefault(block), + NegativeMarginAfterDefault(block)), + break_before_(static_cast<unsigned>(EBreakBetween::kAuto)), + break_after_(static_cast<unsigned>(EBreakBetween::kAuto)), + line_break_to_avoid_widow_(-1), + did_break_at_line_to_avoid_widow_(false), + discard_margin_before_(false), + discard_margin_after_(false) {} + +LayoutBlockFlow::LayoutBlockFlowRareData::~LayoutBlockFlowRareData() = default; + +void LayoutBlockFlow::ClearOffsetMapping() { + DCHECK(!IsLayoutNGObject()); + DCHECK(rare_data_); + rare_data_->offset_mapping_.reset(); +} + +const NGOffsetMapping* LayoutBlockFlow::GetOffsetMapping() const { + DCHECK(!IsLayoutNGObject()); + return rare_data_ ? rare_data_->offset_mapping_.get() : nullptr; +} + +void LayoutBlockFlow::SetOffsetMapping( + std::unique_ptr<NGOffsetMapping> offset_mapping) { + DCHECK(!IsLayoutNGObject()); + DCHECK(offset_mapping); + EnsureRareData().offset_mapping_ = std::move(offset_mapping); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/layout/layout_block_flow.h b/chromium/third_party/blink/renderer/core/layout/layout_block_flow.h index 14a179e2e71..7ca9232b862 100644 --- a/chromium/third_party/blink/renderer/core/layout/layout_block_flow.h +++ b/chromium/third_party/blink/renderer/core/layout/layout_block_flow.h @@ -63,6 +63,7 @@ class NGBlockBreakToken; class NGBreakToken; class NGConstraintSpace; class NGLayoutResult; +class NGOffsetMapping; class NGPaintFragment; class NGPhysicalFragment; @@ -769,18 +770,8 @@ class CORE_EXPORT LayoutBlockFlow : public LayoutBlock { USING_FAST_MALLOC(LayoutBlockFlowRareData); public: - LayoutBlockFlowRareData(const LayoutBlockFlow* block) - : margins_(PositiveMarginBeforeDefault(block), - NegativeMarginBeforeDefault(block), - PositiveMarginAfterDefault(block), - NegativeMarginAfterDefault(block)), - multi_column_flow_thread_(nullptr), - break_before_(static_cast<unsigned>(EBreakBetween::kAuto)), - break_after_(static_cast<unsigned>(EBreakBetween::kAuto)), - line_break_to_avoid_widow_(-1), - did_break_at_line_to_avoid_widow_(false), - discard_margin_before_(false), - discard_margin_after_(false) {} + explicit LayoutBlockFlowRareData(const LayoutBlockFlow* block); + ~LayoutBlockFlowRareData(); static LayoutUnit PositiveMarginBeforeDefault( const LayoutBlockFlow* block) { @@ -802,7 +793,13 @@ class CORE_EXPORT LayoutBlockFlow : public LayoutBlock { LayoutUnit first_forced_break_offset_; - LayoutMultiColumnFlowThread* multi_column_flow_thread_; + LayoutMultiColumnFlowThread* multi_column_flow_thread_ = nullptr; + + // |offset_mapping_| is used only for legacy layout tree for caching offset + // mapping for |NGInlineNode::GetOffsetMapping()|. + // TODO(yosin): Once we have no legacy support, we should get rid of + // |offset_mapping_| here. + std::unique_ptr<NGOffsetMapping> offset_mapping_; unsigned break_before_ : 4; unsigned break_after_ : 4; @@ -813,6 +810,10 @@ class CORE_EXPORT LayoutBlockFlow : public LayoutBlock { DISALLOW_COPY_AND_ASSIGN(LayoutBlockFlowRareData); }; + void ClearOffsetMapping(); + const NGOffsetMapping* GetOffsetMapping() const; + void SetOffsetMapping(std::unique_ptr<NGOffsetMapping>); + const FloatingObjects* GetFloatingObjects() const { return floating_objects_.get(); } diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc index 4154e5f1c01..78a603324f6 100644 --- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc +++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc @@ -487,22 +487,20 @@ const NGOffsetMapping* NGInlineNode::GetOffsetMapping( // If |layout_block_flow| is LayoutNG, compute from |NGInlineNode|. if (layout_block_flow->IsLayoutNGMixin()) { NGInlineNode node(layout_block_flow); - if (node.IsPrepareLayoutFinished()) - return node.ComputeOffsetMappingIfNeeded(); - - // When this is not laid out yet, compute each time it is requested. - // TODO(kojii): We could still keep the result for later uses but it would - // add more states. Reconsider if this turned out to be needed. + CHECK(node.IsPrepareLayoutFinished()); + return node.ComputeOffsetMappingIfNeeded(); } - // If this is not LayoutNG, compute the offset mapping and store in |storage|. - // The caller is responsible to keep |storage| for the life cycle. + // If this is not LayoutNG, compute the offset mapping and store into + // |LayoutBlockFlowRateData|. + if (const NGOffsetMapping* mapping = layout_block_flow->GetOffsetMapping()) + return mapping; DCHECK(storage); NGInlineNodeData data; ComputeOffsetMapping(layout_block_flow, &data); - *storage = std::move(data.offset_mapping); - DCHECK(*storage); - return storage->get(); + NGOffsetMapping* const mapping = data.offset_mapping.get(); + layout_block_flow->SetOffsetMapping(std::move(data.offset_mapping)); + return mapping; } // Depth-first-scan of all LayoutInline and LayoutText nodes that make up this diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h index 0007417e25a..aa1fab7bc42 100644 --- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h +++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h @@ -83,6 +83,8 @@ class CORE_EXPORT NGInlineNode : public NGLayoutInputNode { // Otherwise, this function computes |NGOffsetMapping| and store in |storage| // as well as returning the pointer. The caller is responsible for keeping // |storage| for the life cycle of the returned |NGOffsetMapping|. + // TODO(yosin): We should get rid of |storage| parameter, since it is no + // longer used. static const NGOffsetMapping* GetOffsetMapping( LayoutBlockFlow* layout_block_flow, std::unique_ptr<NGOffsetMapping>* storage); diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_test.cc b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_test.cc index b6d5ace7e32..bf212e716df 100644 --- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_test.cc +++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_test.cc @@ -1186,7 +1186,6 @@ TEST_P(NGOffsetMappingGetterTest, Get) { const NGOffsetMapping* mapping = NGInlineNode::GetOffsetMapping(layout_block_flow, &storage); EXPECT_TRUE(mapping); - EXPECT_EQ(!storage, GetParam()); // |storage| is used only for legacy. const String& text_content = mapping->GetText(); EXPECT_EQ(text_content, "Whitespaces in this text should be collapsed."); diff --git a/chromium/third_party/blink/renderer/core/loader/frame_loader.cc b/chromium/third_party/blink/renderer/core/loader/frame_loader.cc index b6bdefc799a..24932e050bf 100644 --- a/chromium/third_party/blink/renderer/core/loader/frame_loader.cc +++ b/chromium/third_party/blink/renderer/core/loader/frame_loader.cc @@ -730,6 +730,10 @@ bool FrameLoader::PrepareRequestForThisFrame(FrameLoadRequest& request) { if (frame_->Owner() && frame_->Owner()->GetSandboxFlags() & kSandboxOrigin) return false; + + frame_->GetDocument()->ProcessJavaScriptUrl( + url, request.ShouldCheckMainWorldContentSecurityPolicy()); + return false; } if (!request.OriginDocument()->GetSecurityOrigin()->CanDisplay(url)) { @@ -964,12 +968,6 @@ void FrameLoader::StartNavigation(const FrameLoadRequest& passed_request, LocalFrame::ConsumeTransientUserActivation(frame_); } - if (url.ProtocolIsJavaScript()) { - frame_->GetDocument()->ProcessJavaScriptUrl( - url, request.ShouldCheckMainWorldContentSecurityPolicy()); - return; - } - Client()->BeginNavigation( resource_request, origin_document, nullptr /* document_loader */, navigation_type, policy, has_transient_activation, frame_load_type, diff --git a/chromium/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.cc b/chromium/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.cc index abd95ee3b6e..90874dd5c8b 100644 --- a/chromium/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.cc +++ b/chromium/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.cc @@ -67,6 +67,9 @@ void OffscreenCanvas::Commit(scoped_refptr<CanvasResource> canvas_resource, } void OffscreenCanvas::Dispose() { + // We need to drop frame dispatcher, to prevent mojo calls from completing. + frame_dispatcher_ = nullptr; + if (context_) { context_->DetachHost(); context_ = nullptr; diff --git a/chromium/third_party/blink/renderer/core/streams/CommonOperations.js b/chromium/third_party/blink/renderer/core/streams/CommonOperations.js index 9423a115435..24dc719f2be 100644 --- a/chromium/third_party/blink/renderer/core/streams/CommonOperations.js +++ b/chromium/third_party/blink/renderer/core/streams/CommonOperations.js @@ -13,6 +13,11 @@ const _queue = v8.createPrivateSymbol('[[queue]]'); const _queueTotalSize = v8.createPrivateSymbol('[[queueTotalSize]]'); + // A symbol to protect against double-resolution of promises. This + // functionality is not explicit in the standard, but is implied in the way + // the operations are defined. + const _isSettled = v8.createPrivateSymbol('isSettled'); + // Javascript functions. It is important to use these copies for security and // robustness. See "V8 Extras Design Doc", section "Security Considerations". // https://docs.google.com/document/d/1AT5-T0aHGp7Lt29vPWFr2-qG8r3l9CByyvKwEuA8Ec0/edit#heading=h.9yixony1a18r @@ -68,20 +73,76 @@ throw new RangeError('Stream API Internal Error'); } + // For safety, this must always be used in place of calling v8.createPromise() + // directly. + function createPromise() { + const p = v8.createPromise(); + p[_isSettled] = false; + return p; + } + + // Calling v8.rejectPromise() directly is very dangerous. Always use this + // wrapper. function rejectPromise(p, reason) { if (!v8.isPromise(p)) { streamInternalError(); } + + // assert(typeof p[_isSettled] === 'boolean', + // 'Type(p.[[isSettled]]) is `"boolean"`'); + + // Note that this makes the function a no-op for promises that were not + // created via createPromise(). This is critical for security. + if (p[_isSettled] !== false) { + return; + } + p[_isSettled] = true; + v8.rejectPromise(p, reason); } + // This must always be used instead of Promise.reject(). + function createRejectedPromise(reason) { + const p = createPromise(); + rejectPromise(p, reason); + return p; + } + + // Calling v8.resolvePromise() directly is very dangerous. Always use this + // wrapper. If |value| is an object this will look up Object.prototype.then + // and so may be re-entrant. function resolvePromise(p, value) { if (!v8.isPromise(p)) { streamInternalError(); } + + // assert(typeof p[_isSettled] === 'boolean', + // 'Type(p.[[isSettled]]) is `"boolean"`'); + + // Note that this makes the function a no-op for promises that were not + // created via createPromise(). This is critical for security. + if (p[_isSettled] !== false) { + return; + } + p[_isSettled] = true; + v8.resolvePromise(p, value); } + // This must always be used instead of Promise.resolve(). If |value| is an + // object this will look up Object.prototype.then and so may be re-entrant. + function createResolvedPromise(value) { + if (v8.isPromise(value)) { + // This case applies when an underlying method returns a promise. Promises + // that are passed through in this way are not used with resolvePromise() + // or rejectPromise(). + return value; + } + const p = createPromise(); + resolvePromise(p, value); + return p; + } + function markPromiseAsHandled(p) { if (!v8.isPromise(p)) { streamInternalError(); @@ -190,8 +251,6 @@ const callFunction = v8.uncurryThis(global.Function.prototype.call); const errTmplMustBeFunctionOrUndefined = name => `${name} must be a function or undefined`; - const Promise_resolve = Promise.resolve.bind(Promise); - const Promise_reject = Promise.reject.bind(Promise); const Function_bind = v8.uncurryThis(global.Function.prototype.bind); function resolveMethod(O, P, nameForError) { @@ -220,7 +279,7 @@ // The implementation uses bound functions rather than lambdas where // possible to give the compiler the maximum opportunity to optimise. if (method === undefined) { - return () => Promise_resolve(); + return () => createResolvedPromise(); } if (algoArgCount === 0) { @@ -246,7 +305,7 @@ const method = resolveMethod(underlyingObject, methodName, methodNameForError); if (method === undefined) { - return () => Promise_resolve(); + return () => createResolvedPromise(); } if (algoArgCount === 0) { @@ -271,9 +330,9 @@ // assert(typeof F === 'function', 'IsCallable(F) is true.'); // assert(V !== undefined, 'V is not undefined.'); try { - return Promise_resolve(callFunction(F, V)); + return createResolvedPromise(callFunction(F, V)); } catch (e) { - return Promise_reject(e); + return createRejectedPromise(e); } } @@ -281,9 +340,9 @@ // assert(typeof F === 'function', 'IsCallable(F) is true.'); // assert(V !== undefined, 'V is not undefined.'); try { - return Promise_resolve(callFunction(F, V, arg0)); + return createResolvedPromise(callFunction(F, V, arg0)); } catch (e) { - return Promise_reject(e); + return createRejectedPromise(e); } } @@ -291,9 +350,9 @@ // assert(typeof F === 'function', 'IsCallable(F) is true.'); // assert(V !== undefined, 'V is not undefined.'); try { - return Promise_resolve(callFunction(F, V, arg0, arg1)); + return createResolvedPromise(callFunction(F, V, arg0, arg1)); } catch (e) { - return Promise_reject(e); + return createRejectedPromise(e); } } @@ -391,7 +450,7 @@ } function CreateCrossRealmTransformWritable(port) { - let backpressurePromise = v8.createPromise(); + let backpressurePromise = createPromise(); callFunction(binding.EventTarget_addEventListener, port, 'message', evt => { const {type, value} = callFunction(binding.MessageEvent_data_get, evt); @@ -429,7 +488,7 @@ callFunction(binding.MessagePort_start, port); function doWrite(chunk) { - backpressurePromise = v8.createPromise(); + backpressurePromise = createPromise(); try { callFunction( binding.MessagePort_postMessage, port, @@ -456,14 +515,14 @@ binding.MessagePort_postMessage, port, {type: kClose, value: undefined}); callFunction(binding.MessagePort_close, port); - return Promise_resolve(); + return createResolvedPromise(); }, reason => { callFunction( binding.MessagePort_postMessage, port, {type: kAbort, value: packReason(reason)}); callFunction(binding.MessagePort_close, port); - return Promise_resolve(); + return createResolvedPromise(); }); const controller = binding.getWritableStreamController(stream); @@ -471,7 +530,7 @@ } function CreateCrossRealmTransformReadable(port) { - let backpressurePromise = v8.createPromise(); + let backpressurePromise = createPromise(); let finished = false; callFunction(binding.EventTarget_addEventListener, port, 'message', evt => { @@ -485,7 +544,7 @@ case kChunk: binding.ReadableStreamDefaultControllerEnqueue(controller, value); resolvePromise(backpressurePromise); - backpressurePromise = v8.createPromise(); + backpressurePromise = createPromise(); break; case kClose: @@ -530,7 +589,7 @@ binding.MessagePort_postMessage, port, {type: kCancel, value: packReason(reason)}); callFunction(binding.MessagePort_close, port); - return Promise_resolve(); + return createResolvedPromise(); }, /* highWaterMark = */ 0); @@ -541,6 +600,9 @@ binding.streamOperations = { _queue, _queueTotalSize, + createPromise, + createRejectedPromise, + createResolvedPromise, hasOwnPropertyNoThrow, rejectPromise, resolvePromise, diff --git a/chromium/third_party/blink/renderer/core/streams/ReadableStream.js b/chromium/third_party/blink/renderer/core/streams/ReadableStream.js index d28d8c076ed..797fe38d9b5 100644 --- a/chromium/third_party/blink/renderer/core/streams/ReadableStream.js +++ b/chromium/third_party/blink/renderer/core/streams/ReadableStream.js @@ -63,13 +63,14 @@ const Promise = global.Promise; const thenPromise = v8.uncurryThis(Promise.prototype.then); - const Promise_resolve = Promise.resolve.bind(Promise); - const Promise_reject = Promise.reject.bind(Promise); // From CommonOperations.js const { _queue, _queueTotalSize, + createPromise, + createRejectedPromise, + createResolvedPromise, hasOwnPropertyNoThrow, rejectPromise, resolvePromise, @@ -175,7 +176,7 @@ const reader = AcquireReadableStreamDefaultReader(readable); const writer = binding.AcquireWritableStreamDefaultWriter(dest); let shuttingDown = false; - const promise = v8.createPromise(); + const promise = createPromise(); let reading = false; let lastWrite; @@ -366,7 +367,7 @@ // rejects. return thenPromise(lastWrite, () => undefined, () => undefined); } - return Promise_resolve(undefined); + return createResolvedPromise(undefined); } return promise; @@ -430,7 +431,7 @@ let canceled2 = false; let reason1; let reason2; - const cancelPromise = v8.createPromise(); + const cancelPromise = createPromise(); function pullAlgorithm() { return thenPromise( @@ -515,7 +516,7 @@ // function ReadableStreamAddReadRequest(stream, forAuthorCode) { - const promise = v8.createPromise(); + const promise = createPromise(); stream[_reader][_readRequests].push({promise, forAuthorCode}); return promise; } @@ -525,10 +526,10 @@ const state = ReadableStreamGetState(stream); if (state === STATE_CLOSED) { - return Promise_resolve(undefined); + return createResolvedPromise(undefined); } if (state === STATE_ERRORED) { - return Promise_reject(stream[_storedError]); + return createRejectedPromise(stream[_storedError]); } ReadableStreamClose(stream); @@ -631,7 +632,8 @@ get closed() { if (IsReadableStreamDefaultReader(this) === false) { - return Promise_reject(new TypeError(streamErrors.illegalInvocation)); + return createRejectedPromise( + new TypeError(streamErrors.illegalInvocation)); } return this[_closedPromise]; @@ -639,11 +641,12 @@ cancel(reason) { if (IsReadableStreamDefaultReader(this) === false) { - return Promise_reject(new TypeError(streamErrors.illegalInvocation)); + return createRejectedPromise( + new TypeError(streamErrors.illegalInvocation)); } if (this[_ownerReadableStream] === undefined) { - return Promise_reject(new TypeError(errCancelReleasedReader)); + return createRejectedPromise(new TypeError(errCancelReleasedReader)); } return ReadableStreamReaderGenericCancel(this, reason); @@ -651,11 +654,12 @@ read() { if (IsReadableStreamDefaultReader(this) === false) { - return Promise_reject(new TypeError(streamErrors.illegalInvocation)); + return createRejectedPromise( + new TypeError(streamErrors.illegalInvocation)); } if (this[_ownerReadableStream] === undefined) { - return Promise_reject(new TypeError(errReadReleasedReader)); + return createRejectedPromise(new TypeError(errReadReleasedReader)); } return ReadableStreamDefaultReaderRead(this, true); @@ -707,13 +711,13 @@ switch (ReadableStreamGetState(stream)) { case STATE_READABLE: - reader[_closedPromise] = v8.createPromise(); + reader[_closedPromise] = createPromise(); break; case STATE_CLOSED: - reader[_closedPromise] = Promise_resolve(undefined); + reader[_closedPromise] = createResolvedPromise(undefined); break; case STATE_ERRORED: - reader[_closedPromise] = Promise_reject(stream[_storedError]); + reader[_closedPromise] = createRejectedPromise(stream[_storedError]); markPromiseAsHandled(reader[_closedPromise]); break; } @@ -738,7 +742,7 @@ new TypeError(errReleasedReaderClosedPromise)); } else { reader[_closedPromise] = - Promise_reject(new TypeError(errReleasedReaderClosedPromise)); + createRejectedPromise(new TypeError(errReleasedReaderClosedPromise)); } markPromiseAsHandled(reader[_closedPromise]); @@ -752,11 +756,11 @@ switch (ReadableStreamGetState(stream)) { case STATE_CLOSED: - return Promise_resolve(ReadableStreamCreateReadResult(undefined, true, - forAuthorCode)); + return createResolvedPromise( + ReadableStreamCreateReadResult(undefined, true, forAuthorCode)); case STATE_ERRORED: - return Promise_reject(stream[_storedError]); + return createRejectedPromise(stream[_storedError]); default: return ReadableStreamDefaultControllerPull(stream[_controller], @@ -854,8 +858,8 @@ ReadableStreamDefaultControllerCallPullIfNeeded(controller); } - return Promise_resolve(ReadableStreamCreateReadResult(chunk, false, - forAuthorCode)); + return createResolvedPromise( + ReadableStreamCreateReadResult(chunk, false, forAuthorCode)); } const pendingPromise = ReadableStreamAddReadRequest(stream, forAuthorCode); @@ -1008,7 +1012,7 @@ controller[_cancelAlgorithm] = cancelAlgorithm; stream[_controller] = controller; - thenPromise(Promise_resolve(startAlgorithm()), () => { + thenPromise(createResolvedPromise(startAlgorithm()), () => { controller[_readableStreamDefaultControllerBits] |= STARTED; ReadableStreamDefaultControllerCallPullIfNeeded(controller); }, r => ReadableStreamDefaultControllerError(controller, r)); diff --git a/chromium/third_party/blink/renderer/core/streams/TransformStream.js b/chromium/third_party/blink/renderer/core/streams/TransformStream.js index cafce4170f1..a339a49bb5d 100644 --- a/chromium/third_party/blink/renderer/core/streams/TransformStream.js +++ b/chromium/third_party/blink/renderer/core/streams/TransformStream.js @@ -42,11 +42,12 @@ const Promise = global.Promise; const thenPromise = v8.uncurryThis(Promise.prototype.then); - const Promise_resolve = Promise.resolve.bind(Promise); - const Promise_reject = Promise.reject.bind(Promise); // From CommonOperations.js const { + createPromise, + createRejectedPromise, + createResolvedPromise, hasOwnPropertyNoThrow, resolvePromise, CreateAlgorithmFromUnderlyingMethod, @@ -103,7 +104,7 @@ readableHighWaterMark = ValidateAndNormalizeHighWaterMark(readableHighWaterMark); - const startPromise = v8.createPromise(); + const startPromise = createPromise(); InitializeTransformStream( this, startPromise, writableHighWaterMark, writableSizeAlgorithm, readableHighWaterMark, readableSizeAlgorithm); @@ -159,7 +160,7 @@ // readableHighWaterMark >= 0, // '! IsNonNegativeNumber(_readableHighWaterMark_) is true'); const stream = ObjectCreate(TransformStream_prototype); - const startPromise = v8.createPromise(); + const startPromise = createPromise(); InitializeTransformStream( stream, startPromise, writableHighWaterMark, writableSizeAlgorithm, readableHighWaterMark, readableSizeAlgorithm); @@ -188,7 +189,7 @@ TransformStreamDefaultSourcePullAlgorithm(stream); const cancelAlgorithm = reason => { TransformStreamErrorWritableAndUnblockWrite(stream, reason); - return Promise_resolve(undefined); + return createResolvedPromise(undefined); }; stream[_readable] = binding.CreateReadableStream( startAlgorithm, pullAlgorithm, cancelAlgorithm, readableHighWaterMark, @@ -234,7 +235,7 @@ resolvePromise(stream[_backpressureChangePromise], undefined); } - stream[_backpressureChangePromise] = v8.createPromise(); + stream[_backpressureChangePromise] = createPromise(); stream[_backpressure] = backpressure; } @@ -316,9 +317,9 @@ transformAlgorithm = chunk => { try { TransformStreamDefaultControllerEnqueue(controller, chunk); - return Promise_resolve(); + return createResolvedPromise(); } catch (resultValue) { - return Promise_reject(resultValue); + return createRejectedPromise(resultValue); } }; } @@ -415,7 +416,7 @@ function TransformStreamDefaultSinkAbortAlgorithm(stream, reason) { TransformStreamError(stream, reason); - return Promise_resolve(); + return createResolvedPromise(); } function TransformStreamDefaultSinkCloseAlgorithm(stream) { @@ -458,7 +459,7 @@ // blink::TransformStream needs. |transformAlgorithm| and |flushAlgorithm| are // passed the controller, unlike in the standard. function createTransformStreamSimple(transformAlgorithm, flushAlgorithm) { - return CreateTransformStream(() => Promise_resolve(), + return CreateTransformStream(() => createResolvedPromise(), transformAlgorithm, flushAlgorithm); } function createTransformStream( diff --git a/chromium/third_party/blink/renderer/core/streams/WritableStream.js b/chromium/third_party/blink/renderer/core/streams/WritableStream.js index 8c3a75160fd..339a28fd470 100644 --- a/chromium/third_party/blink/renderer/core/streams/WritableStream.js +++ b/chromium/third_party/blink/renderer/core/streams/WritableStream.js @@ -73,13 +73,14 @@ const Promise = global.Promise; const thenPromise = v8.uncurryThis(Promise.prototype.then); - const Promise_resolve = Promise.resolve.bind(Promise); - const Promise_reject = Promise.reject.bind(Promise); // From CommonOperations.js const { _queue, _queueTotalSize, + createPromise, + createRejectedPromise, + createResolvedPromise, hasOwnPropertyNoThrow, rejectPromise, resolvePromise, @@ -218,7 +219,7 @@ function WritableStreamAbort(stream, reason) { const state = stream[_stateAndFlags] & STATE_MASK; if (state === CLOSED || state === ERRORED) { - return Promise_resolve(undefined); + return createResolvedPromise(undefined); } if (stream[_pendingAbortRequest] !== undefined) { return stream[_pendingAbortRequest].promise; @@ -232,7 +233,7 @@ reason = undefined; } - const promise = v8.createPromise(); + const promise = createPromise(); stream[_pendingAbortRequest] = {promise, reason, wasAlreadyErroring}; if (!wasAlreadyErroring) { @@ -248,7 +249,7 @@ // '! IsWritableStreamLocked(writer) is true.'); // assert((stream[_stateAndFlags] & STATE_MASK) === WRITABLE, // 'stream.[[state]] is "writable".'); - const promise = v8.createPromise(); + const promise = createPromise(); stream[_writeRequests].push(promise); return promise; } @@ -455,7 +456,7 @@ if (writer !== undefined && backpressure !== Boolean(stream[_stateAndFlags] & BACKPRESSURE_FLAG)) { if (backpressure) { - writer[_readyPromise] = v8.createPromise(); + writer[_readyPromise] = createPromise(); } else { // assert(!backpressure, '_backpressure_ is *false*.'); resolvePromise(writer[_readyPromise], undefined); @@ -559,33 +560,33 @@ case WRITABLE: { if (!WritableStreamCloseQueuedOrInFlight(stream) && stream[_stateAndFlags] & BACKPRESSURE_FLAG) { - this[_readyPromise] = v8.createPromise(); + this[_readyPromise] = createPromise(); } else { - this[_readyPromise] = Promise_resolve(undefined); + this[_readyPromise] = createResolvedPromise(undefined); } - this[_closedPromise] = v8.createPromise(); + this[_closedPromise] = createPromise(); break; } case ERRORING: { - this[_readyPromise] = Promise_reject(stream[_storedError]); + this[_readyPromise] = createRejectedPromise(stream[_storedError]); markPromiseAsHandled(this[_readyPromise]); - this[_closedPromise] = v8.createPromise(); + this[_closedPromise] = createPromise(); break; } case CLOSED: { - this[_readyPromise] = Promise_resolve(undefined); - this[_closedPromise] = Promise_resolve(undefined); + this[_readyPromise] = createResolvedPromise(undefined); + this[_closedPromise] = createResolvedPromise(undefined); break; } default: { // assert(state === ERRORED, '_state_ is `"errored"`.'); const storedError = stream[_storedError]; - this[_readyPromise] = Promise_reject(storedError); + this[_readyPromise] = createRejectedPromise(storedError); markPromiseAsHandled(this[_readyPromise]); - this[_closedPromise] = Promise_reject(storedError); + this[_closedPromise] = createRejectedPromise(storedError); markPromiseAsHandled(this[_closedPromise]); break; } @@ -594,7 +595,8 @@ get closed() { if (!IsWritableStreamDefaultWriter(this)) { - return Promise_reject(new TypeError(streamErrors.illegalInvocation)); + return createRejectedPromise( + new TypeError(streamErrors.illegalInvocation)); } return this[_closedPromise]; } @@ -611,31 +613,36 @@ get ready() { if (!IsWritableStreamDefaultWriter(this)) { - return Promise_reject(new TypeError(streamErrors.illegalInvocation)); + return createRejectedPromise( + new TypeError(streamErrors.illegalInvocation)); } return this[_readyPromise]; } abort(reason) { if (!IsWritableStreamDefaultWriter(this)) { - return Promise_reject(new TypeError(streamErrors.illegalInvocation)); + return createRejectedPromise( + new TypeError(streamErrors.illegalInvocation)); } if (this[_ownerWritableStream] === undefined) { - return Promise_reject(createWriterLockReleasedError(verbAborted)); + return createRejectedPromise( + createWriterLockReleasedError(verbAborted)); } return WritableStreamDefaultWriterAbort(this, reason); } close() { if (!IsWritableStreamDefaultWriter(this)) { - return Promise_reject(new TypeError(streamErrors.illegalInvocation)); + return createRejectedPromise( + new TypeError(streamErrors.illegalInvocation)); } const stream = this[_ownerWritableStream]; if (stream === undefined) { - return Promise_reject(createWriterLockReleasedError(verbClosed)); + return createRejectedPromise(createWriterLockReleasedError(verbClosed)); } if (WritableStreamCloseQueuedOrInFlight(stream)) { - return Promise_reject(new TypeError(errCloseCloseRequestedStream)); + return createRejectedPromise( + new TypeError(errCloseCloseRequestedStream)); } return WritableStreamDefaultWriterClose(this); } @@ -655,10 +662,12 @@ write(chunk) { if (!IsWritableStreamDefaultWriter(this)) { - return Promise_reject(new TypeError(streamErrors.illegalInvocation)); + return createRejectedPromise( + new TypeError(streamErrors.illegalInvocation)); } if (this[_ownerWritableStream] === undefined) { - return Promise_reject(createWriterLockReleasedError(verbWrittenTo)); + return createRejectedPromise( + createWriterLockReleasedError(verbWrittenTo)); } return WritableStreamDefaultWriterWrite(this, chunk); } @@ -682,7 +691,7 @@ // assert(stream !== undefined, 'stream is not undefined.'); const state = stream[_stateAndFlags] & STATE_MASK; if (state === CLOSED || state === ERRORED) { - return Promise_reject( + return createRejectedPromise( createCannotActionOnStateStreamError('close', state)); } @@ -690,7 +699,7 @@ // '_state_ is `"writable"` or `"erroring"`.'); // assert(!WritableStreamCloseQueuedOrInFlight(stream), // '! WritableStreamCloseQueuedOrInFlight(_stream_) is *false*.'); - const promise = v8.createPromise(); + const promise = createPromise(); stream[_closeRequest] = promise; if ((stream[_stateAndFlags] & BACKPRESSURE_FLAG) && state === WRITABLE) { @@ -705,10 +714,10 @@ // assert(stream !== undefined, 'stream is not undefined.'); const state = stream[_stateAndFlags] & STATE_MASK; if (WritableStreamCloseQueuedOrInFlight(stream) || state === CLOSED) { - return Promise_resolve(undefined); + return createResolvedPromise(undefined); } if (state === ERRORED) { - return Promise_reject(stream[_storedError]); + return createRejectedPromise(stream[_storedError]); } // assert(state === WRITABLE || state === ERRORING, @@ -722,7 +731,7 @@ if (promiseState(writer[_closedPromise]) === v8.kPROMISE_PENDING) { rejectPromise(writer[_closedPromise], error); } else { - writer[_closedPromise] = Promise_reject(error); + writer[_closedPromise] = createRejectedPromise(error); } markPromiseAsHandled(writer[_closedPromise]); } @@ -733,7 +742,7 @@ if (promiseState(writer[_readyPromise]) === v8.kPROMISE_PENDING) { rejectPromise(writer[_readyPromise], error); } else { - writer[_readyPromise] = Promise_reject(error); + writer[_readyPromise] = createRejectedPromise(error); } markPromiseAsHandled(writer[_readyPromise]); } @@ -773,22 +782,23 @@ const chunkSize = WritableStreamDefaultControllerGetChunkSize(controller, chunk); if (stream !== writer[_ownerWritableStream]) { - return Promise_reject(createWriterLockReleasedError(verbWrittenTo)); + return createRejectedPromise( + createWriterLockReleasedError(verbWrittenTo)); } const state = stream[_stateAndFlags] & STATE_MASK; if (state === ERRORED) { - return Promise_reject(stream[_storedError]); + return createRejectedPromise(stream[_storedError]); } if (WritableStreamCloseQueuedOrInFlight(stream)) { - return Promise_reject(new TypeError( + return createRejectedPromise(new TypeError( templateErrorCannotActionOnStateStream('write to', 'closing'))); } if (state === CLOSED) { - return Promise_reject( + return createRejectedPromise( createCannotActionOnStateStreamError('write to', CLOSED)); } if (state === ERRORING) { - return Promise_reject(stream[_storedError]); + return createRejectedPromise(stream[_storedError]); } // assert(state === WRITABLE, '_state_ is `"writable"`'); const promise = WritableStreamAddWriteRequest(stream); @@ -878,7 +888,7 @@ WritableStreamDefaultControllerGetBackpressure(controller); WritableStreamUpdateBackpressure(stream, backpressure); const startResult = startAlgorithm(); - const startPromise = Promise_resolve(startResult); + const startPromise = createResolvedPromise(startResult); thenPromise( startPromise, () => { |