OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 (function(global, binding, v8) { | 5 (function(global, binding, v8) { |
6 'use strict'; | 6 'use strict'; |
7 | 7 |
8 const readableStreamController = v8.createPrivateSymbol('[[controller]]'); | 8 const readableStreamController = v8.createPrivateSymbol('[[controller]]'); |
9 const readableStreamQueue = v8.createPrivateSymbol('[[queue]]'); | 9 const readableStreamQueue = v8.createPrivateSymbol('[[queue]]'); |
10 const readableStreamQueueSize = | 10 const readableStreamQueueSize = |
11 v8.createPrivateSymbol('[[queue]] total size'); | 11 v8.createPrivateSymbol('[[queue]] total size'); |
12 const readableStreamReader = v8.createPrivateSymbol('[[reader]]'); | 12 const readableStreamReader = v8.createPrivateSymbol('[[reader]]'); |
13 const readableStreamState = v8.createPrivateSymbol('[[state]]'); | 13 const readableStreamState = v8.createPrivateSymbol('[[state]]'); |
14 const readableStreamStoredError = v8.createPrivateSymbol('[[storedError]]'); | 14 const readableStreamStoredError = v8.createPrivateSymbol('[[storedError]]'); |
15 const readableStreamStrategySize = v8.createPrivateSymbol('[[strategySize]]'); | 15 const readableStreamStrategySize = v8.createPrivateSymbol('[[strategySize]]'); |
16 const readableStreamStrategyHWM = v8.createPrivateSymbol('[[strategyHWM]]'); | 16 const readableStreamStrategyHWM = v8.createPrivateSymbol('[[strategyHWM]]'); |
17 const readableStreamUnderlyingSource = | 17 const readableStreamUnderlyingSource = |
18 v8.createPrivateSymbol('[[underlyingSource]]'); | 18 v8.createPrivateSymbol('[[underlyingSource]]'); |
19 | 19 |
20 const readableStreamControllerControlledReadableStream = | 20 const readableStreamControllerControlledReadableStream = |
21 v8.createPrivateSymbol('[[controlledReadableStream]]'); | 21 v8.createPrivateSymbol('[[controlledReadableStream]]'); |
22 | 22 |
23 const readableStreamReaderClosedPromise = | 23 const readableStreamReaderClosedPromise = |
24 v8.createPrivateSymbol('[[closedPromise]]'); | 24 v8.createPrivateSymbol('[[closedPromise]]'); |
25 const readableStreamReaderOwnerReadableStream = | 25 const readableStreamReaderOwnerReadableStream = |
26 v8.createPrivateSymbol('[[ownerReadableStream]]'); | 26 v8.createPrivateSymbol('[[ownerReadableStream]]'); |
27 const readableStreamReaderReadRequests = | 27 const readableStreamReaderReadRequests = |
28 v8.createPrivateSymbol('[[readRequests]]'); | 28 v8.createPrivateSymbol('[[readRequests]]'); |
29 | 29 |
| 30 const createWithExternalControllerSentinel = |
| 31 v8.createPrivateSymbol('flag for UA-created ReadableStream to pass'); |
| 32 |
30 const STATE_READABLE = 0; | 33 const STATE_READABLE = 0; |
31 const STATE_CLOSED = 1; | 34 const STATE_CLOSED = 1; |
32 const STATE_ERRORED = 2; | 35 const STATE_ERRORED = 2; |
33 | 36 |
34 const readableStreamBits = v8.createPrivateSymbol( | 37 const readableStreamBits = v8.createPrivateSymbol( |
35 'bit field for [[started]], [[closeRequested]], [[pulling]], [[pullAgain]]
, [[disturbed]]'); | 38 'bit field for [[started]], [[closeRequested]], [[pulling]], [[pullAgain]]
, [[disturbed]]'); |
36 const STARTED = 0b1; | 39 const STARTED = 0b1; |
37 const CLOSE_REQUESTED = 0b10; | 40 const CLOSE_REQUESTED = 0b10; |
38 const PULLING = 0b100; | 41 const PULLING = 0b100; |
39 const PULL_AGAIN = 0b1000; | 42 const PULL_AGAIN = 0b1000; |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 this[readableStreamQueueSize] = 0; | 115 this[readableStreamQueueSize] = 0; |
113 | 116 |
114 this[readableStreamState] = STATE_READABLE; | 117 this[readableStreamState] = STATE_READABLE; |
115 this[readableStreamBits] = 0b0; | 118 this[readableStreamBits] = 0b0; |
116 this[readableStreamReader] = undefined; | 119 this[readableStreamReader] = undefined; |
117 this[readableStreamStoredError] = undefined; | 120 this[readableStreamStoredError] = undefined; |
118 | 121 |
119 this[readableStreamStrategySize] = normalizedStrategy.size; | 122 this[readableStreamStrategySize] = normalizedStrategy.size; |
120 this[readableStreamStrategyHWM] = normalizedStrategy.highWaterMark; | 123 this[readableStreamStrategyHWM] = normalizedStrategy.highWaterMark; |
121 | 124 |
122 const controller = new ReadableStreamController(this); | 125 // Avoid allocating the controller if the stream is going to be controlled |
| 126 // externally (i.e. from C++) anyway. All calls to underlyingSource |
| 127 // methods will disregard their controller argument in such situations |
| 128 // (but see below). |
| 129 |
| 130 const isControlledExternally = |
| 131 arguments[2] === createWithExternalControllerSentinel; |
| 132 const controller = |
| 133 isControlledExternally ? null : new ReadableStreamController(this); |
123 this[readableStreamController] = controller; | 134 this[readableStreamController] = controller; |
124 | 135 |
| 136 // We need to pass ourself to the underlyingSource start method for |
| 137 // externally-controlled streams. We use the now-useless controller |
| 138 // argument to do so. |
| 139 const argToStart = isControlledExternally ? this : controller; |
| 140 |
125 const startResult = CallOrNoop( | 141 const startResult = CallOrNoop( |
126 underlyingSource, 'start', controller, 'underlyingSource.start'); | 142 underlyingSource, 'start', argToStart, 'underlyingSource.start'); |
127 thenPromise(Promise_resolve(startResult), | 143 thenPromise(Promise_resolve(startResult), |
128 () => { | 144 () => { |
129 this[readableStreamBits] |= STARTED; | 145 this[readableStreamBits] |= STARTED; |
130 RequestReadableStreamPull(this); | 146 RequestReadableStreamPull(this); |
131 }, | 147 }, |
132 r => { | 148 r => { |
133 if (this[readableStreamState] === STATE_READABLE) { | 149 if (this[readableStreamState] === STATE_READABLE) { |
134 return ErrorReadableStream(this, r); | 150 return ErrorReadableStream(this, r); |
135 } | 151 } |
136 }); | 152 }); |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
323 } | 339 } |
324 | 340 |
325 if (this[readableStreamReaderReadRequests].length > 0) { | 341 if (this[readableStreamReaderReadRequests].length > 0) { |
326 throw new TypeError(errReleaseReaderWithPendingRead); | 342 throw new TypeError(errReleaseReaderWithPendingRead); |
327 } | 343 } |
328 | 344 |
329 if (stream[readableStreamState] === STATE_READABLE) { | 345 if (stream[readableStreamState] === STATE_READABLE) { |
330 v8.rejectPromise(this[readableStreamReaderClosedPromise], | 346 v8.rejectPromise(this[readableStreamReaderClosedPromise], |
331 new TypeError(errReleasedReaderClosedPromise)); | 347 new TypeError(errReleasedReaderClosedPromise)); |
332 } else { | 348 } else { |
333 this[readableStreamReaderClosedPromise] = Promise_reject(new TypeError( | 349 this[readableStreamReaderClosedPromise] = |
334 errReleasedReaderClosedPromise)); | 350 Promise_reject(new TypeError(errReleasedReaderClosedPromise)); |
335 } | 351 } |
336 | 352 |
337 this[readableStreamReaderOwnerReadableStream][readableStreamReader] = | 353 this[readableStreamReaderOwnerReadableStream][readableStreamReader] = |
338 undefined; | 354 undefined; |
339 this[readableStreamReaderOwnerReadableStream] = undefined; | 355 this[readableStreamReaderOwnerReadableStream] = undefined; |
340 } | 356 } |
341 } | 357 } |
342 | 358 |
343 // | 359 // |
344 // Readable stream abstract operations | 360 // Readable stream abstract operations |
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
764 // | 780 // |
765 // Exports to Blink | 781 // Exports to Blink |
766 // | 782 // |
767 | 783 |
768 binding.AcquireReadableStreamReader = AcquireReadableStreamReader; | 784 binding.AcquireReadableStreamReader = AcquireReadableStreamReader; |
769 binding.IsReadableStream = IsReadableStream; | 785 binding.IsReadableStream = IsReadableStream; |
770 binding.IsReadableStreamDisturbed = IsReadableStreamDisturbed; | 786 binding.IsReadableStreamDisturbed = IsReadableStreamDisturbed; |
771 binding.IsReadableStreamLocked = IsReadableStreamLocked; | 787 binding.IsReadableStreamLocked = IsReadableStreamLocked; |
772 binding.IsReadableStreamReader = IsReadableStreamReader; | 788 binding.IsReadableStreamReader = IsReadableStreamReader; |
773 binding.ReadFromReadableStreamReader = ReadFromReadableStreamReader; | 789 binding.ReadFromReadableStreamReader = ReadFromReadableStreamReader; |
| 790 |
| 791 binding.CloseReadableStream = CloseReadableStream; |
| 792 binding.GetReadableStreamDesiredSize = GetReadableStreamDesiredSize; |
| 793 binding.EnqueueInReadableStream = EnqueueInReadableStream; |
| 794 binding.ErrorReadableStream = ErrorReadableStream; |
| 795 |
| 796 binding.createReadableStreamWithExternalController = |
| 797 (underlyingSource, strategy) => { |
| 798 return new ReadableStream( |
| 799 underlyingSource, strategy, createWithExternalControllerSentinel); |
| 800 }; |
774 }); | 801 }); |
OLD | NEW |