| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 // Implementation of WritableStream for Blink. See | 5 // Implementation of WritableStream for Blink. See |
| 6 // https://streams.spec.whatwg.org/#ws. The implementation closely follows the | 6 // https://streams.spec.whatwg.org/#ws. The implementation closely follows the |
| 7 // standard, except where required for performance or integration with Blink. In | 7 // standard, except where required for performance or integration with Blink. In |
| 8 // particular, classes, methods and abstract operations are implemented in the | 8 // particular, classes, methods and abstract operations are implemented in the |
| 9 // same order as in the standard, to simplify side-by-side reading. | 9 // same order as in the standard, to simplify side-by-side reading. |
| 10 | 10 |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 100 const verbClosed = 'closed'; | 100 const verbClosed = 'closed'; |
| 101 const verbWrittenTo = 'written to'; | 101 const verbWrittenTo = 'written to'; |
| 102 | 102 |
| 103 // Utility functions (not from the standard). | 103 // Utility functions (not from the standard). |
| 104 function createWriterLockReleasedError(verb) { | 104 function createWriterLockReleasedError(verb) { |
| 105 return new TypeError(errWriterLockReleasedPrefix + verb); | 105 return new TypeError(errWriterLockReleasedPrefix + verb); |
| 106 } | 106 } |
| 107 | 107 |
| 108 const stateNames = {[CLOSED]: 'closed', [ERRORED]: 'errored'}; | 108 const stateNames = {[CLOSED]: 'closed', [ERRORED]: 'errored'}; |
| 109 function createCannotActionOnStateStreamError(action, state) { | 109 function createCannotActionOnStateStreamError(action, state) { |
| 110 TEMP_ASSERT(stateNames[state] !== undefined, | 110 // assert(stateNames[state] !== undefined, |
| 111 `name for state ${state} exists in stateNames`); | 111 // `name for state ${state} exists in stateNames`); |
| 112 return new TypeError( | 112 return new TypeError( |
| 113 templateErrorCannotActionOnStateStream(action, stateNames[state])); | 113 templateErrorCannotActionOnStateStream(action, stateNames[state])); |
| 114 } | 114 } |
| 115 | 115 |
| 116 function rejectPromises(queue, e) { | 116 function rejectPromises(queue, e) { |
| 117 queue.forEach(promise => v8.rejectPromise(promise, e)); | 117 queue.forEach(promise => v8.rejectPromise(promise, e)); |
| 118 } | 118 } |
| 119 | 119 |
| 120 // https://tc39.github.io/ecma262/#sec-ispropertykey | |
| 121 // TODO(ricea): Remove this when the asserts using it are removed. | |
| 122 function IsPropertyKey(argument) { | |
| 123 return typeof argument === 'string' || typeof argument === 'symbol'; | |
| 124 } | |
| 125 | |
| 126 // TODO(ricea): Remove all asserts once the implementation has stabilised. | |
| 127 function TEMP_ASSERT(predicate, message) { | |
| 128 if (predicate) { | |
| 129 return; | |
| 130 } | |
| 131 v8.log(`Assertion failed: ${message}\n`); | |
| 132 v8.logStackTrace(); | |
| 133 class WritableStreamInternalError extends Error { | |
| 134 constructor(message) { | |
| 135 super(message); | |
| 136 } | |
| 137 } | |
| 138 throw new WritableStreamInternalError(message); | |
| 139 } | |
| 140 | |
| 141 class WritableStream { | 120 class WritableStream { |
| 142 constructor(underlyingSink = {}, { size, highWaterMark = 1 } = {}) { | 121 constructor(underlyingSink = {}, { size, highWaterMark = 1 } = {}) { |
| 143 this[_stateAndFlags] = WRITABLE; | 122 this[_stateAndFlags] = WRITABLE; |
| 144 this[_storedError] = undefined; | 123 this[_storedError] = undefined; |
| 145 this[_writer] = undefined; | 124 this[_writer] = undefined; |
| 146 this[_writableStreamController] = undefined; | 125 this[_writableStreamController] = undefined; |
| 147 this[_inFlightWriteRequest] = undefined; | 126 this[_inFlightWriteRequest] = undefined; |
| 148 this[_closeRequest] = undefined; | 127 this[_closeRequest] = undefined; |
| 149 this[_inFlightCloseRequest] = undefined; | 128 this[_inFlightCloseRequest] = undefined; |
| 150 this[_pendingAbortRequest] = undefined; | 129 this[_pendingAbortRequest] = undefined; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 188 | 167 |
| 189 function AcquireWritableStreamDefaultWriter(stream) { | 168 function AcquireWritableStreamDefaultWriter(stream) { |
| 190 return new WritableStreamDefaultWriter(stream); | 169 return new WritableStreamDefaultWriter(stream); |
| 191 } | 170 } |
| 192 | 171 |
| 193 function IsWritableStream(x) { | 172 function IsWritableStream(x) { |
| 194 return hasOwnProperty(x, _writableStreamController); | 173 return hasOwnProperty(x, _writableStreamController); |
| 195 } | 174 } |
| 196 | 175 |
| 197 function IsWritableStreamLocked(stream) { | 176 function IsWritableStreamLocked(stream) { |
| 198 TEMP_ASSERT(IsWritableStream(stream), | 177 // assert(IsWritableStream(stream), |
| 199 '! IsWritableStream(stream) is true.'); | 178 // '! IsWritableStream(stream) is true.'); |
| 200 return stream[_writer] !== undefined; | 179 return stream[_writer] !== undefined; |
| 201 } | 180 } |
| 202 | 181 |
| 203 function WritableStreamAbort(stream, reason) { | 182 function WritableStreamAbort(stream, reason) { |
| 204 const state = stream[_stateAndFlags] & STATE_MASK; | 183 const state = stream[_stateAndFlags] & STATE_MASK; |
| 205 if (state === CLOSED) { | 184 if (state === CLOSED) { |
| 206 return Promise_resolve(undefined); | 185 return Promise_resolve(undefined); |
| 207 } | 186 } |
| 208 if (state === ERRORED) { | 187 if (state === ERRORED) { |
| 209 return Promise_reject(stream[_storedError]); | 188 return Promise_reject(stream[_storedError]); |
| 210 } | 189 } |
| 211 const error = new TypeError(errStreamAborting); | 190 const error = new TypeError(errStreamAborting); |
| 212 if (stream[_pendingAbortRequest] !== undefined) { | 191 if (stream[_pendingAbortRequest] !== undefined) { |
| 213 return Promise_reject(error); | 192 return Promise_reject(error); |
| 214 } | 193 } |
| 215 | 194 |
| 216 TEMP_ASSERT(state === WRITABLE || state === ERRORING, | 195 // assert(state === WRITABLE || state === ERRORING, |
| 217 '_state_ is `"writable"` or `"erroring"`'); | 196 // '_state_ is `"writable"` or `"erroring"`'); |
| 218 | 197 |
| 219 const wasAlreadyErroring = state === ERRORING; | 198 const wasAlreadyErroring = state === ERRORING; |
| 220 if (wasAlreadyErroring) { | 199 if (wasAlreadyErroring) { |
| 221 reason = undefined; | 200 reason = undefined; |
| 222 } | 201 } |
| 223 | 202 |
| 224 const promise = v8.createPromise(); | 203 const promise = v8.createPromise(); |
| 225 stream[_pendingAbortRequest] = {promise, reason, wasAlreadyErroring}; | 204 stream[_pendingAbortRequest] = {promise, reason, wasAlreadyErroring}; |
| 226 | 205 |
| 227 if (!wasAlreadyErroring) { | 206 if (!wasAlreadyErroring) { |
| 228 WritableStreamStartErroring(stream, error); | 207 WritableStreamStartErroring(stream, error); |
| 229 } | 208 } |
| 230 return promise; | 209 return promise; |
| 231 } | 210 } |
| 232 | 211 |
| 233 // Writable Stream Abstract Operations Used by Controllers | 212 // Writable Stream Abstract Operations Used by Controllers |
| 234 | 213 |
| 235 function WritableStreamAddWriteRequest(stream) { | 214 function WritableStreamAddWriteRequest(stream) { |
| 236 TEMP_ASSERT(IsWritableStreamLocked(stream), | 215 // assert(IsWritableStreamLocked(stream), |
| 237 '! IsWritableStreamLocked(writer) is true.'); | 216 // '! IsWritableStreamLocked(writer) is true.'); |
| 238 TEMP_ASSERT((stream[_stateAndFlags] & STATE_MASK) === WRITABLE, | 217 // assert((stream[_stateAndFlags] & STATE_MASK) === WRITABLE, |
| 239 'stream.[[state]] is "writable".'); | 218 // 'stream.[[state]] is "writable".'); |
| 240 const promise = v8.createPromise(); | 219 const promise = v8.createPromise(); |
| 241 stream[_writeRequests].push(promise); | 220 stream[_writeRequests].push(promise); |
| 242 return promise; | 221 return promise; |
| 243 } | 222 } |
| 244 | 223 |
| 245 function WritableStreamDealWithRejection(stream, error) { | 224 function WritableStreamDealWithRejection(stream, error) { |
| 246 const state = stream[_stateAndFlags] & STATE_MASK; | 225 const state = stream[_stateAndFlags] & STATE_MASK; |
| 247 if (state === WRITABLE) { | 226 if (state === WRITABLE) { |
| 248 WritableStreamStartErroring(stream, error); | 227 WritableStreamStartErroring(stream, error); |
| 249 return; | 228 return; |
| 250 } | 229 } |
| 251 | 230 |
| 252 TEMP_ASSERT(state === ERRORING, '_state_ is `"erroring"`'); | 231 // assert(state === ERRORING, '_state_ is `"erroring"`'); |
| 253 WritableStreamFinishErroring(stream); | 232 WritableStreamFinishErroring(stream); |
| 254 } | 233 } |
| 255 | 234 |
| 256 function WritableStreamStartErroring(stream, reason) { | 235 function WritableStreamStartErroring(stream, reason) { |
| 257 TEMP_ASSERT(stream[_storedError] === undefined, | 236 // assert(stream[_storedError] === undefined, |
| 258 '_stream_.[[storedError]] is *undefined*'); | 237 // '_stream_.[[storedError]] is *undefined*'); |
| 259 TEMP_ASSERT((stream[_stateAndFlags] & STATE_MASK) === WRITABLE, | 238 // assert((stream[_stateAndFlags] & STATE_MASK) === WRITABLE, |
| 260 '_stream_.[[state]] is `"writable"`'); | 239 // '_stream_.[[state]] is `"writable"`'); |
| 261 | 240 |
| 262 const controller = stream[_writableStreamController]; | 241 const controller = stream[_writableStreamController]; |
| 263 TEMP_ASSERT(controller !== undefined, '_controller_ is not *undefined*'); | 242 // assert(controller !== undefined, '_controller_ is not *undefined*'); |
| 264 | 243 |
| 265 stream[_stateAndFlags] = (stream[_stateAndFlags] & ~STATE_MASK) | ERRORING; | 244 stream[_stateAndFlags] = (stream[_stateAndFlags] & ~STATE_MASK) | ERRORING; |
| 266 stream[_storedError] = reason; | 245 stream[_storedError] = reason; |
| 267 | 246 |
| 268 const writer = stream[_writer]; | 247 const writer = stream[_writer]; |
| 269 if (writer !== undefined) { | 248 if (writer !== undefined) { |
| 270 WritableStreamDefaultWriterEnsureReadyPromiseRejected(writer, reason); | 249 WritableStreamDefaultWriterEnsureReadyPromiseRejected(writer, reason); |
| 271 } | 250 } |
| 272 | 251 |
| 273 if (!WritableStreamHasOperationMarkedInFlight(stream) && | 252 if (!WritableStreamHasOperationMarkedInFlight(stream) && |
| 274 controller[_started]) { | 253 controller[_started]) { |
| 275 WritableStreamFinishErroring(stream); | 254 WritableStreamFinishErroring(stream); |
| 276 } | 255 } |
| 277 } | 256 } |
| 278 | 257 |
| 279 function WritableStreamFinishErroring(stream) { | 258 function WritableStreamFinishErroring(stream) { |
| 280 TEMP_ASSERT((stream[_stateAndFlags] & STATE_MASK) === ERRORING, | 259 // assert((stream[_stateAndFlags] & STATE_MASK) === ERRORING, |
| 281 '_stream_.[[state]] is `"erroring"`'); | 260 // '_stream_.[[state]] is `"erroring"`'); |
| 282 TEMP_ASSERT( | 261 // assert(!WritableStreamHasOperationMarkedInFlight(stream), |
| 283 !WritableStreamHasOperationMarkedInFlight(stream), | 262 // '! WritableStreamHasOperationMarkedInFlight(_stream_) is *false*')
; |
| 284 '! WritableStreamHasOperationMarkedInFlight(_stream_) is *false*'); | |
| 285 | 263 |
| 286 stream[_stateAndFlags] = (stream[_stateAndFlags] & ~STATE_MASK) | ERRORED; | 264 stream[_stateAndFlags] = (stream[_stateAndFlags] & ~STATE_MASK) | ERRORED; |
| 287 | 265 |
| 288 WritableStreamDefaultControllerErrorSteps( | 266 WritableStreamDefaultControllerErrorSteps( |
| 289 stream[_writableStreamController]); | 267 stream[_writableStreamController]); |
| 290 | 268 |
| 291 const storedError = stream[_storedError]; | 269 const storedError = stream[_storedError]; |
| 292 rejectPromises(stream[_writeRequests], storedError); | 270 rejectPromises(stream[_writeRequests], storedError); |
| 293 stream[_writeRequests] = new binding.SimpleQueue(); | 271 stream[_writeRequests] = new binding.SimpleQueue(); |
| 294 | 272 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 315 v8.resolvePromise(abortRequest.promise, undefined); | 293 v8.resolvePromise(abortRequest.promise, undefined); |
| 316 WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream); | 294 WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream); |
| 317 }, | 295 }, |
| 318 reason => { | 296 reason => { |
| 319 v8.rejectPromise(abortRequest.promise, reason); | 297 v8.rejectPromise(abortRequest.promise, reason); |
| 320 WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream); | 298 WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream); |
| 321 }); | 299 }); |
| 322 } | 300 } |
| 323 | 301 |
| 324 function WritableStreamFinishInFlightWrite(stream) { | 302 function WritableStreamFinishInFlightWrite(stream) { |
| 325 TEMP_ASSERT(stream[_inFlightWriteRequest] !== undefined, | 303 // assert(stream[_inFlightWriteRequest] !== undefined, |
| 326 '_stream_.[[inFlightWriteRequest]] is not *undefined*.'); | 304 // '_stream_.[[inFlightWriteRequest]] is not *undefined*.'); |
| 327 v8.resolvePromise(stream[_inFlightWriteRequest], undefined); | 305 v8.resolvePromise(stream[_inFlightWriteRequest], undefined); |
| 328 stream[_inFlightWriteRequest] = undefined; | 306 stream[_inFlightWriteRequest] = undefined; |
| 329 } | 307 } |
| 330 | 308 |
| 331 function WritableStreamFinishInFlightWriteWithError(stream, error) { | 309 function WritableStreamFinishInFlightWriteWithError(stream, error) { |
| 332 TEMP_ASSERT(stream[_inFlightWriteRequest] !== undefined, | 310 // assert(stream[_inFlightWriteRequest] !== undefined, |
| 333 '_stream_.[[inFlightWriteRequest]] is not *undefined*.'); | 311 // '_stream_.[[inFlightWriteRequest]] is not *undefined*.'); |
| 334 v8.rejectPromise(stream[_inFlightWriteRequest], error); | 312 v8.rejectPromise(stream[_inFlightWriteRequest], error); |
| 335 stream[_inFlightWriteRequest] = undefined; | 313 stream[_inFlightWriteRequest] = undefined; |
| 336 | 314 |
| 337 let state = stream[_stateAndFlags] & STATE_MASK; | 315 let state = stream[_stateAndFlags] & STATE_MASK; |
| 338 TEMP_ASSERT(state === WRITABLE || state === ERRORING, | 316 // assert(state === WRITABLE || state === ERRORING, |
| 339 '_stream_.[[state]] is `"writable"` or `"erroring"`'); | 317 // '_stream_.[[state]] is `"writable"` or `"erroring"`'); |
| 340 | 318 |
| 341 WritableStreamDealWithRejection(stream, error); | 319 WritableStreamDealWithRejection(stream, error); |
| 342 } | 320 } |
| 343 | 321 |
| 344 function WritableStreamFinishInFlightClose(stream) { | 322 function WritableStreamFinishInFlightClose(stream) { |
| 345 TEMP_ASSERT(stream[_inFlightCloseRequest] !== undefined, | 323 // assert(stream[_inFlightCloseRequest] !== undefined, |
| 346 '_stream_.[[inFlightCloseRequest]] is not *undefined*.'); | 324 // '_stream_.[[inFlightCloseRequest]] is not *undefined*.'); |
| 347 v8.resolvePromise(stream[_inFlightCloseRequest], undefined); | 325 v8.resolvePromise(stream[_inFlightCloseRequest], undefined); |
| 348 stream[_inFlightCloseRequest] = undefined; | 326 stream[_inFlightCloseRequest] = undefined; |
| 349 | 327 |
| 350 const state = stream[_stateAndFlags] & STATE_MASK; | 328 const state = stream[_stateAndFlags] & STATE_MASK; |
| 351 TEMP_ASSERT(state === WRITABLE || state === ERRORING, | 329 // assert(state === WRITABLE || state === ERRORING, |
| 352 '_stream_.[[state]] is `"writable"` or `"erroring"`'); | 330 // '_stream_.[[state]] is `"writable"` or `"erroring"`'); |
| 353 | 331 |
| 354 if (state === ERRORING) { | 332 if (state === ERRORING) { |
| 355 stream[_storedError] = undefined; | 333 stream[_storedError] = undefined; |
| 356 if (stream[_pendingAbortRequest] !== undefined) { | 334 if (stream[_pendingAbortRequest] !== undefined) { |
| 357 v8.resolvePromise(stream[_pendingAbortRequest].promise, undefined); | 335 v8.resolvePromise(stream[_pendingAbortRequest].promise, undefined); |
| 358 stream[_pendingAbortRequest] = undefined; | 336 stream[_pendingAbortRequest] = undefined; |
| 359 } | 337 } |
| 360 } | 338 } |
| 361 | 339 |
| 362 stream[_stateAndFlags] = (stream[_stateAndFlags] & ~STATE_MASK) | CLOSED; | 340 stream[_stateAndFlags] = (stream[_stateAndFlags] & ~STATE_MASK) | CLOSED; |
| 363 const writer = stream[_writer]; | 341 const writer = stream[_writer]; |
| 364 if (writer !== undefined) { | 342 if (writer !== undefined) { |
| 365 v8.resolvePromise(writer[_closedPromise], undefined); | 343 v8.resolvePromise(writer[_closedPromise], undefined); |
| 366 } | 344 } |
| 367 | 345 |
| 368 TEMP_ASSERT(stream[_pendingAbortRequest] === undefined, | 346 // assert(stream[_pendingAbortRequest] === undefined, |
| 369 '_stream_.[[pendingAbortRequest]] is *undefined*'); | 347 // '_stream_.[[pendingAbortRequest]] is *undefined*'); |
| 370 TEMP_ASSERT(stream[_storedError] === undefined, | 348 // assert(stream[_storedError] === undefined, |
| 371 '_stream_.[[storedError]] is *undefined*'); | 349 // '_stream_.[[storedError]] is *undefined*'); |
| 372 } | 350 } |
| 373 | 351 |
| 374 function WritableStreamFinishInFlightCloseWithError(stream, error) { | 352 function WritableStreamFinishInFlightCloseWithError(stream, error) { |
| 375 TEMP_ASSERT(stream[_inFlightCloseRequest] !== undefined, | 353 // assert(stream[_inFlightCloseRequest] !== undefined, |
| 376 '_stream_.[[inFlightCloseRequest]] is not *undefined*.'); | 354 // '_stream_.[[inFlightCloseRequest]] is not *undefined*.'); |
| 377 v8.rejectPromise(stream[_inFlightCloseRequest], error); | 355 v8.rejectPromise(stream[_inFlightCloseRequest], error); |
| 378 stream[_inFlightCloseRequest] = undefined; | 356 stream[_inFlightCloseRequest] = undefined; |
| 379 | 357 |
| 380 const state = stream[_stateAndFlags] & STATE_MASK; | 358 const state = stream[_stateAndFlags] & STATE_MASK; |
| 381 TEMP_ASSERT(state === WRITABLE || state === ERRORING, | 359 // assert(state === WRITABLE || state === ERRORING, |
| 382 '_stream_.[[state]] is `"writable"` or `"erroring"`'); | 360 // '_stream_.[[state]] is `"writable"` or `"erroring"`'); |
| 383 | 361 |
| 384 if (stream[_pendingAbortRequest] !== undefined) { | 362 if (stream[_pendingAbortRequest] !== undefined) { |
| 385 v8.rejectPromise(stream[_pendingAbortRequest].promise, error); | 363 v8.rejectPromise(stream[_pendingAbortRequest].promise, error); |
| 386 stream[_pendingAbortRequest] = undefined; | 364 stream[_pendingAbortRequest] = undefined; |
| 387 } | 365 } |
| 388 | 366 |
| 389 WritableStreamDealWithRejection(stream, error); | 367 WritableStreamDealWithRejection(stream, error); |
| 390 } | 368 } |
| 391 | 369 |
| 392 function WritableStreamCloseQueuedOrInFlight(stream) { | 370 function WritableStreamCloseQueuedOrInFlight(stream) { |
| 393 return stream[_closeRequest] !== undefined || | 371 return stream[_closeRequest] !== undefined || |
| 394 stream[_inFlightCloseRequest] !== undefined; | 372 stream[_inFlightCloseRequest] !== undefined; |
| 395 } | 373 } |
| 396 | 374 |
| 397 function WritableStreamHasOperationMarkedInFlight(stream) { | 375 function WritableStreamHasOperationMarkedInFlight(stream) { |
| 398 return stream[_inFlightWriteRequest] !== undefined || | 376 return stream[_inFlightWriteRequest] !== undefined || |
| 399 stream[_inFlightCloseRequest] !== undefined; | 377 stream[_inFlightCloseRequest] !== undefined; |
| 400 } | 378 } |
| 401 | 379 |
| 402 function WritableStreamMarkCloseRequestInFlight(stream) { | 380 function WritableStreamMarkCloseRequestInFlight(stream) { |
| 403 TEMP_ASSERT(stream[_inFlightCloseRequest] === undefined, | 381 // assert(stream[_inFlightCloseRequest] === undefined, |
| 404 '_stream_.[[inFlightCloseRequest]] is *undefined*.'); | 382 // '_stream_.[[inFlightCloseRequest]] is *undefined*.'); |
| 405 TEMP_ASSERT(stream[_closeRequest] !== undefined, | 383 // assert(stream[_closeRequest] !== undefined, |
| 406 '_stream_.[[closeRequest]] is not *undefined*.'); | 384 // '_stream_.[[closeRequest]] is not *undefined*.'); |
| 407 stream[_inFlightCloseRequest] = stream[_closeRequest]; | 385 stream[_inFlightCloseRequest] = stream[_closeRequest]; |
| 408 stream[_closeRequest] = undefined; | 386 stream[_closeRequest] = undefined; |
| 409 } | 387 } |
| 410 | 388 |
| 411 function WritableStreamMarkFirstWriteRequestInFlight(stream) { | 389 function WritableStreamMarkFirstWriteRequestInFlight(stream) { |
| 412 TEMP_ASSERT(stream[_inFlightWriteRequest] === undefined, | 390 // assert(stream[_inFlightWriteRequest] === undefined, |
| 413 '_stream_.[[inFlightWriteRequest]] is *undefined*.'); | 391 // '_stream_.[[inFlightWriteRequest]] is *undefined*.'); |
| 414 TEMP_ASSERT(stream[_writeRequests].length !== 0, | 392 // assert(stream[_writeRequests].length !== 0, |
| 415 '_stream_.[[writeRequests]] is not empty.'); | 393 // '_stream_.[[writeRequests]] is not empty.'); |
| 416 const writeRequest = stream[_writeRequests].shift(); | 394 const writeRequest = stream[_writeRequests].shift(); |
| 417 stream[_inFlightWriteRequest] = writeRequest; | 395 stream[_inFlightWriteRequest] = writeRequest; |
| 418 } | 396 } |
| 419 | 397 |
| 420 function WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream) { | 398 function WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream) { |
| 421 TEMP_ASSERT((stream[_stateAndFlags] & STATE_MASK) === ERRORED, | 399 // assert((stream[_stateAndFlags] & STATE_MASK) === ERRORED, |
| 422 '_stream_.[[state]] is `"errored"`'); | 400 // '_stream_.[[state]] is `"errored"`'); |
| 423 | 401 |
| 424 if (stream[_closeRequest] !== undefined) { | 402 if (stream[_closeRequest] !== undefined) { |
| 425 TEMP_ASSERT(stream[_inFlightCloseRequest] === undefined, | 403 // assert(stream[_inFlightCloseRequest] === undefined, |
| 426 '_stream_.[[inFlightCloseRequest]] is *undefined*'); | 404 // '_stream_.[[inFlightCloseRequest]] is *undefined*'); |
| 427 v8.rejectPromise(stream[_closeRequest], stream[_storedError]); | 405 v8.rejectPromise(stream[_closeRequest], stream[_storedError]); |
| 428 stream[_closeRequest] = undefined; | 406 stream[_closeRequest] = undefined; |
| 429 } | 407 } |
| 430 | 408 |
| 431 const writer = stream[_writer]; | 409 const writer = stream[_writer]; |
| 432 if (writer !== undefined) { | 410 if (writer !== undefined) { |
| 433 v8.rejectPromise(writer[_closedPromise], stream[_storedError]); | 411 v8.rejectPromise(writer[_closedPromise], stream[_storedError]); |
| 434 v8.markPromiseAsHandled(writer[_closedPromise]); | 412 v8.markPromiseAsHandled(writer[_closedPromise]); |
| 435 } | 413 } |
| 436 } | 414 } |
| 437 | 415 |
| 438 function WritableStreamUpdateBackpressure(stream, backpressure) { | 416 function WritableStreamUpdateBackpressure(stream, backpressure) { |
| 439 TEMP_ASSERT((stream[_stateAndFlags] & STATE_MASK) === WRITABLE, | 417 // assert((stream[_stateAndFlags] & STATE_MASK) === WRITABLE, |
| 440 'stream.[[state]] is "writable".'); | 418 // 'stream.[[state]] is "writable".'); |
| 441 TEMP_ASSERT(!WritableStreamCloseQueuedOrInFlight(stream), | 419 // assert(!WritableStreamCloseQueuedOrInFlight(stream), |
| 442 'WritableStreamCloseQueuedOrInFlight(_stream_) is *false*.'); | 420 // 'WritableStreamCloseQueuedOrInFlight(_stream_) is *false*.'); |
| 443 const writer = stream[_writer]; | 421 const writer = stream[_writer]; |
| 444 if (writer !== undefined && | 422 if (writer !== undefined && |
| 445 backpressure !== Boolean(stream[_stateAndFlags] & BACKPRESSURE_FLAG)) { | 423 backpressure !== Boolean(stream[_stateAndFlags] & BACKPRESSURE_FLAG)) { |
| 446 if (backpressure) { | 424 if (backpressure) { |
| 447 writer[_readyPromise] = v8.createPromise(); | 425 writer[_readyPromise] = v8.createPromise(); |
| 448 } else { | 426 } else { |
| 449 TEMP_ASSERT(!backpressure, '_backpressure_ is *false*.'); | 427 // assert(!backpressure, '_backpressure_ is *false*.'); |
| 450 v8.resolvePromise(writer[_readyPromise], undefined); | 428 v8.resolvePromise(writer[_readyPromise], undefined); |
| 451 } | 429 } |
| 452 } | 430 } |
| 453 if (backpressure) { | 431 if (backpressure) { |
| 454 stream[_stateAndFlags] |= BACKPRESSURE_FLAG; | 432 stream[_stateAndFlags] |= BACKPRESSURE_FLAG; |
| 455 } else { | 433 } else { |
| 456 stream[_stateAndFlags] &= ~BACKPRESSURE_FLAG; | 434 stream[_stateAndFlags] &= ~BACKPRESSURE_FLAG; |
| 457 } | 435 } |
| 458 } | 436 } |
| 459 | 437 |
| 460 // Functions to expose internals for ReadableStream.pipeTo. These are not | 438 // Functions to expose internals for ReadableStream.pipeTo. These are not |
| 461 // part of the standard. | 439 // part of the standard. |
| 462 function isWritableStreamErrored(stream) { | 440 function isWritableStreamErrored(stream) { |
| 463 TEMP_ASSERT( | 441 // assert( |
| 464 IsWritableStream(stream), '! IsWritableStream(stream) is true.'); | 442 // IsWritableStream(stream), '! IsWritableStream(stream) is true.'); |
| 465 return (stream[_stateAndFlags] & STATE_MASK) === ERRORED; | 443 return (stream[_stateAndFlags] & STATE_MASK) === ERRORED; |
| 466 } | 444 } |
| 467 | 445 |
| 468 function isWritableStreamClosingOrClosed(stream) { | 446 function isWritableStreamClosingOrClosed(stream) { |
| 469 TEMP_ASSERT( | 447 // assert( |
| 470 IsWritableStream(stream), '! IsWritableStream(stream) is true.'); | 448 // IsWritableStream(stream), '! IsWritableStream(stream) is true.'); |
| 471 return WritableStreamCloseQueuedOrInFlight(stream) || | 449 return WritableStreamCloseQueuedOrInFlight(stream) || |
| 472 (stream[_stateAndFlags] & STATE_MASK) === CLOSED; | 450 (stream[_stateAndFlags] & STATE_MASK) === CLOSED; |
| 473 } | 451 } |
| 474 | 452 |
| 475 function getWritableStreamStoredError(stream) { | 453 function getWritableStreamStoredError(stream) { |
| 476 TEMP_ASSERT( | 454 // assert( |
| 477 IsWritableStream(stream), '! IsWritableStream(stream) is true.'); | 455 // IsWritableStream(stream), '! IsWritableStream(stream) is true.'); |
| 478 return stream[_storedError]; | 456 return stream[_storedError]; |
| 479 } | 457 } |
| 480 | 458 |
| 481 class WritableStreamDefaultWriter { | 459 class WritableStreamDefaultWriter { |
| 482 constructor(stream) { | 460 constructor(stream) { |
| 483 if (!IsWritableStream(stream)) { | 461 if (!IsWritableStream(stream)) { |
| 484 throw new TypeError(streamErrors.illegalConstructor); | 462 throw new TypeError(streamErrors.illegalConstructor); |
| 485 } | 463 } |
| 486 if (IsWritableStreamLocked(stream)) { | 464 if (IsWritableStreamLocked(stream)) { |
| 487 throw new TypeError(streamErrors.illegalConstructor); | 465 throw new TypeError(streamErrors.illegalConstructor); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 512 | 490 |
| 513 case CLOSED: | 491 case CLOSED: |
| 514 { | 492 { |
| 515 this[_readyPromise] = Promise_resolve(undefined); | 493 this[_readyPromise] = Promise_resolve(undefined); |
| 516 this[_closedPromise] = Promise_resolve(undefined); | 494 this[_closedPromise] = Promise_resolve(undefined); |
| 517 break; | 495 break; |
| 518 } | 496 } |
| 519 | 497 |
| 520 default: | 498 default: |
| 521 { | 499 { |
| 522 TEMP_ASSERT(state === ERRORED, '_state_ is `"errored"`.'); | 500 // assert(state === ERRORED, '_state_ is `"errored"`.'); |
| 523 const storedError = stream[_storedError]; | 501 const storedError = stream[_storedError]; |
| 524 this[_readyPromise] = Promise_reject(storedError); | 502 this[_readyPromise] = Promise_reject(storedError); |
| 525 v8.markPromiseAsHandled(this[_readyPromise]); | 503 v8.markPromiseAsHandled(this[_readyPromise]); |
| 526 this[_closedPromise] = Promise_reject(storedError); | 504 this[_closedPromise] = Promise_reject(storedError); |
| 527 v8.markPromiseAsHandled(this[_closedPromise]); | 505 v8.markPromiseAsHandled(this[_closedPromise]); |
| 528 break; | 506 break; |
| 529 } | 507 } |
| 530 } | 508 } |
| 531 } | 509 } |
| 532 | 510 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 579 } | 557 } |
| 580 | 558 |
| 581 releaseLock() { | 559 releaseLock() { |
| 582 if (!IsWritableStreamDefaultWriter(this)) { | 560 if (!IsWritableStreamDefaultWriter(this)) { |
| 583 throw new TypeError(streamErrors.illegalInvocation); | 561 throw new TypeError(streamErrors.illegalInvocation); |
| 584 } | 562 } |
| 585 const stream = this[_ownerWritableStream]; | 563 const stream = this[_ownerWritableStream]; |
| 586 if (stream === undefined) { | 564 if (stream === undefined) { |
| 587 return; | 565 return; |
| 588 } | 566 } |
| 589 TEMP_ASSERT(stream[_writer] !== undefined, | 567 // assert(stream[_writer] !== undefined, |
| 590 'stream.[[writer]] is not undefined.'); | 568 // 'stream.[[writer]] is not undefined.'); |
| 591 WritableStreamDefaultWriterRelease(this); | 569 WritableStreamDefaultWriterRelease(this); |
| 592 } | 570 } |
| 593 | 571 |
| 594 write(chunk) { | 572 write(chunk) { |
| 595 if (!IsWritableStreamDefaultWriter(this)) { | 573 if (!IsWritableStreamDefaultWriter(this)) { |
| 596 return Promise_reject(new TypeError(streamErrors.illegalInvocation)); | 574 return Promise_reject(new TypeError(streamErrors.illegalInvocation)); |
| 597 } | 575 } |
| 598 if (this[_ownerWritableStream] === undefined) { | 576 if (this[_ownerWritableStream] === undefined) { |
| 599 return Promise_reject(createWriterLockReleasedError(verbWrittenTo)); | 577 return Promise_reject(createWriterLockReleasedError(verbWrittenTo)); |
| 600 } | 578 } |
| 601 return WritableStreamDefaultWriterWrite(this, chunk); | 579 return WritableStreamDefaultWriterWrite(this, chunk); |
| 602 } | 580 } |
| 603 } | 581 } |
| 604 | 582 |
| 605 // Writable Stream Writer Abstract Operations | 583 // Writable Stream Writer Abstract Operations |
| 606 | 584 |
| 607 function IsWritableStreamDefaultWriter(x) { | 585 function IsWritableStreamDefaultWriter(x) { |
| 608 return hasOwnProperty(x, _ownerWritableStream); | 586 return hasOwnProperty(x, _ownerWritableStream); |
| 609 } | 587 } |
| 610 | 588 |
| 611 function WritableStreamDefaultWriterAbort(writer, reason) { | 589 function WritableStreamDefaultWriterAbort(writer, reason) { |
| 612 const stream = writer[_ownerWritableStream]; | 590 const stream = writer[_ownerWritableStream]; |
| 613 TEMP_ASSERT(stream !== undefined, | 591 // assert(stream !== undefined, |
| 614 'stream is not undefined.'); | 592 // 'stream is not undefined.'); |
| 615 return WritableStreamAbort(stream, reason); | 593 return WritableStreamAbort(stream, reason); |
| 616 } | 594 } |
| 617 | 595 |
| 618 function WritableStreamDefaultWriterClose(writer) { | 596 function WritableStreamDefaultWriterClose(writer) { |
| 619 const stream = writer[_ownerWritableStream]; | 597 const stream = writer[_ownerWritableStream]; |
| 620 TEMP_ASSERT(stream !== undefined, 'stream is not undefined.'); | 598 // assert(stream !== undefined, 'stream is not undefined.'); |
| 621 const state = stream[_stateAndFlags] & STATE_MASK; | 599 const state = stream[_stateAndFlags] & STATE_MASK; |
| 622 if (state === CLOSED || state === ERRORED) { | 600 if (state === CLOSED || state === ERRORED) { |
| 623 return Promise_reject( | 601 return Promise_reject( |
| 624 createCannotActionOnStateStreamError('close', state)); | 602 createCannotActionOnStateStreamError('close', state)); |
| 625 } | 603 } |
| 626 | 604 |
| 627 TEMP_ASSERT(state === WRITABLE || state === ERRORING, | 605 // assert(state === WRITABLE || state === ERRORING, |
| 628 '_state_ is `"writable"` or `"erroring"`.'); | 606 // '_state_ is `"writable"` or `"erroring"`.'); |
| 629 TEMP_ASSERT(!WritableStreamCloseQueuedOrInFlight(stream), | 607 // assert(!WritableStreamCloseQueuedOrInFlight(stream), |
| 630 '! WritableStreamCloseQueuedOrInFlight(_stream_) is *false*.'); | 608 // '! WritableStreamCloseQueuedOrInFlight(_stream_) is *false*.'); |
| 631 const promise = v8.createPromise(); | 609 const promise = v8.createPromise(); |
| 632 stream[_closeRequest] = promise; | 610 stream[_closeRequest] = promise; |
| 633 | 611 |
| 634 if ((stream[_stateAndFlags] & BACKPRESSURE_FLAG) && | 612 if ((stream[_stateAndFlags] & BACKPRESSURE_FLAG) && |
| 635 state === WRITABLE) { | 613 state === WRITABLE) { |
| 636 v8.resolvePromise(writer[_readyPromise], undefined); | 614 v8.resolvePromise(writer[_readyPromise], undefined); |
| 637 } | 615 } |
| 638 WritableStreamDefaultControllerClose(stream[_writableStreamController]); | 616 WritableStreamDefaultControllerClose(stream[_writableStreamController]); |
| 639 return promise; | 617 return promise; |
| 640 } | 618 } |
| 641 | 619 |
| 642 function WritableStreamDefaultWriterCloseWithErrorPropagation(writer) { | 620 function WritableStreamDefaultWriterCloseWithErrorPropagation(writer) { |
| 643 const stream = writer[_ownerWritableStream]; | 621 const stream = writer[_ownerWritableStream]; |
| 644 TEMP_ASSERT(stream !== undefined, 'stream is not undefined.'); | 622 // assert(stream !== undefined, 'stream is not undefined.'); |
| 645 const state = stream[_stateAndFlags] & STATE_MASK; | 623 const state = stream[_stateAndFlags] & STATE_MASK; |
| 646 if (WritableStreamCloseQueuedOrInFlight(stream) || state === CLOSED) { | 624 if (WritableStreamCloseQueuedOrInFlight(stream) || state === CLOSED) { |
| 647 return Promise_resolve(undefined); | 625 return Promise_resolve(undefined); |
| 648 } | 626 } |
| 649 if (state === ERRORED) { | 627 if (state === ERRORED) { |
| 650 return Promise_reject(stream[_storedError]); | 628 return Promise_reject(stream[_storedError]); |
| 651 } | 629 } |
| 652 | 630 |
| 653 TEMP_ASSERT(state === WRITABLE || state === ERRORING, | 631 // assert(state === WRITABLE || state === ERRORING, |
| 654 '_state_ is `"writable"` or `"erroring"`.'); | 632 // '_state_ is `"writable"` or `"erroring"`.'); |
| 655 | 633 |
| 656 return WritableStreamDefaultWriterClose(writer); | 634 return WritableStreamDefaultWriterClose(writer); |
| 657 } | 635 } |
| 658 | 636 |
| 659 function WritableStreamDefaultWriterEnsureClosedPromiseRejected( | 637 function WritableStreamDefaultWriterEnsureClosedPromiseRejected( |
| 660 writer, error) { | 638 writer, error) { |
| 661 if (v8.promiseState(writer[_closedPromise]) === v8.kPROMISE_PENDING) { | 639 if (v8.promiseState(writer[_closedPromise]) === v8.kPROMISE_PENDING) { |
| 662 v8.rejectPromise(writer[_closedPromise], error); | 640 v8.rejectPromise(writer[_closedPromise], error); |
| 663 } else { | 641 } else { |
| 664 writer[_closedPromise] = Promise_reject(error); | 642 writer[_closedPromise] = Promise_reject(error); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 685 } | 663 } |
| 686 if (state === CLOSED) { | 664 if (state === CLOSED) { |
| 687 return 0; | 665 return 0; |
| 688 } | 666 } |
| 689 return WritableStreamDefaultControllerGetDesiredSize( | 667 return WritableStreamDefaultControllerGetDesiredSize( |
| 690 stream[_writableStreamController]); | 668 stream[_writableStreamController]); |
| 691 } | 669 } |
| 692 | 670 |
| 693 function WritableStreamDefaultWriterRelease(writer) { | 671 function WritableStreamDefaultWriterRelease(writer) { |
| 694 const stream = writer[_ownerWritableStream]; | 672 const stream = writer[_ownerWritableStream]; |
| 695 TEMP_ASSERT(stream !== undefined, | 673 // assert(stream !== undefined, |
| 696 'stream is not undefined.'); | 674 // 'stream is not undefined.'); |
| 697 TEMP_ASSERT(stream[_writer] === writer, | 675 // assert(stream[_writer] === writer, |
| 698 'stream.[[writer]] is writer.'); | 676 // 'stream.[[writer]] is writer.'); |
| 699 const releasedError = new TypeError(errReleasedWriterClosedPromise); | 677 const releasedError = new TypeError(errReleasedWriterClosedPromise); |
| 700 WritableStreamDefaultWriterEnsureReadyPromiseRejected( | 678 WritableStreamDefaultWriterEnsureReadyPromiseRejected( |
| 701 writer, releasedError); | 679 writer, releasedError); |
| 702 WritableStreamDefaultWriterEnsureClosedPromiseRejected( | 680 WritableStreamDefaultWriterEnsureClosedPromiseRejected( |
| 703 writer, releasedError); | 681 writer, releasedError); |
| 704 stream[_writer] = undefined; | 682 stream[_writer] = undefined; |
| 705 writer[_ownerWritableStream] = undefined; | 683 writer[_ownerWritableStream] = undefined; |
| 706 } | 684 } |
| 707 | 685 |
| 708 function WritableStreamDefaultWriterWrite(writer, chunk) { | 686 function WritableStreamDefaultWriterWrite(writer, chunk) { |
| 709 const stream = writer[_ownerWritableStream]; | 687 const stream = writer[_ownerWritableStream]; |
| 710 TEMP_ASSERT(stream !== undefined, 'stream is not undefined.'); | 688 // assert(stream !== undefined, 'stream is not undefined.'); |
| 711 const controller = stream[_writableStreamController]; | 689 const controller = stream[_writableStreamController]; |
| 712 const chunkSize = | 690 const chunkSize = |
| 713 WritableStreamDefaultControllerGetChunkSize(controller, chunk); | 691 WritableStreamDefaultControllerGetChunkSize(controller, chunk); |
| 714 if (stream !== writer[_ownerWritableStream]) { | 692 if (stream !== writer[_ownerWritableStream]) { |
| 715 return Promise_reject(createWriterLockReleasedError(verbWrittenTo)); | 693 return Promise_reject(createWriterLockReleasedError(verbWrittenTo)); |
| 716 } | 694 } |
| 717 const state = stream[_stateAndFlags] & STATE_MASK; | 695 const state = stream[_stateAndFlags] & STATE_MASK; |
| 718 if (state === ERRORED) { | 696 if (state === ERRORED) { |
| 719 return Promise_reject(stream[_storedError]); | 697 return Promise_reject(stream[_storedError]); |
| 720 } | 698 } |
| 721 if (WritableStreamCloseQueuedOrInFlight(stream)) { | 699 if (WritableStreamCloseQueuedOrInFlight(stream)) { |
| 722 return Promise_reject(new TypeError( | 700 return Promise_reject(new TypeError( |
| 723 templateErrorCannotActionOnStateStream('write to', 'closing'))); | 701 templateErrorCannotActionOnStateStream('write to', 'closing'))); |
| 724 } | 702 } |
| 725 if (state === CLOSED) { | 703 if (state === CLOSED) { |
| 726 return Promise_reject( | 704 return Promise_reject( |
| 727 createCannotActionOnStateStreamError('write to', CLOSED)); | 705 createCannotActionOnStateStreamError('write to', CLOSED)); |
| 728 } | 706 } |
| 729 if (state === ERRORING) { | 707 if (state === ERRORING) { |
| 730 return Promise_reject(stream[_storedError]); | 708 return Promise_reject(stream[_storedError]); |
| 731 } | 709 } |
| 732 TEMP_ASSERT(state === WRITABLE, '_state_ is `"writable"`'); | 710 // assert(state === WRITABLE, '_state_ is `"writable"`'); |
| 733 const promise = WritableStreamAddWriteRequest(stream); | 711 const promise = WritableStreamAddWriteRequest(stream); |
| 734 WritableStreamDefaultControllerWrite(controller, chunk, chunkSize); | 712 WritableStreamDefaultControllerWrite(controller, chunk, chunkSize); |
| 735 return promise; | 713 return promise; |
| 736 } | 714 } |
| 737 | 715 |
| 738 // Functions to expose internals for ReadableStream.pipeTo. These do not | 716 // Functions to expose internals for ReadableStream.pipeTo. These do not |
| 739 // appear in the standard. | 717 // appear in the standard. |
| 740 function getWritableStreamDefaultWriterClosedPromise(writer) { | 718 function getWritableStreamDefaultWriterClosedPromise(writer) { |
| 741 TEMP_ASSERT( | 719 // assert( |
| 742 IsWritableStreamDefaultWriter(writer), | 720 // IsWritableStreamDefaultWriter(writer), |
| 743 'writer is a WritableStreamDefaultWriter.'); | 721 // 'writer is a WritableStreamDefaultWriter.'); |
| 744 return writer[_closedPromise]; | 722 return writer[_closedPromise]; |
| 745 } | 723 } |
| 746 | 724 |
| 747 function getWritableStreamDefaultWriterReadyPromise(writer) { | 725 function getWritableStreamDefaultWriterReadyPromise(writer) { |
| 748 TEMP_ASSERT( | 726 // assert( |
| 749 IsWritableStreamDefaultWriter(writer), | 727 // IsWritableStreamDefaultWriter(writer), |
| 750 'writer is a WritableStreamDefaultWriter.'); | 728 // 'writer is a WritableStreamDefaultWriter.'); |
| 751 return writer[_readyPromise]; | 729 return writer[_readyPromise]; |
| 752 } | 730 } |
| 753 | 731 |
| 754 class WritableStreamDefaultController { | 732 class WritableStreamDefaultController { |
| 755 constructor(stream, underlyingSink, size, highWaterMark) { | 733 constructor(stream, underlyingSink, size, highWaterMark) { |
| 756 if (!IsWritableStream(stream)) { | 734 if (!IsWritableStream(stream)) { |
| 757 throw new TypeError(streamErrors.illegalConstructor); | 735 throw new TypeError(streamErrors.illegalConstructor); |
| 758 } | 736 } |
| 759 if (stream[_writableStreamController] !== undefined) { | 737 if (stream[_writableStreamController] !== undefined) { |
| 760 throw new TypeError(streamErrors.illegalConstructor); | 738 throw new TypeError(streamErrors.illegalConstructor); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 803 | 781 |
| 804 function WritableStreamDefaultControllerStartSteps(controller) { | 782 function WritableStreamDefaultControllerStartSteps(controller) { |
| 805 const startResult = | 783 const startResult = |
| 806 InvokeOrNoop(controller[_underlyingSink], 'start', [controller]); | 784 InvokeOrNoop(controller[_underlyingSink], 'start', [controller]); |
| 807 const stream = controller[_controlledWritableStream]; | 785 const stream = controller[_controlledWritableStream]; |
| 808 const startPromise = Promise_resolve(startResult); | 786 const startPromise = Promise_resolve(startResult); |
| 809 thenPromise( | 787 thenPromise( |
| 810 startPromise, | 788 startPromise, |
| 811 () => { | 789 () => { |
| 812 const state = stream[_stateAndFlags] & STATE_MASK; | 790 const state = stream[_stateAndFlags] & STATE_MASK; |
| 813 TEMP_ASSERT(state === WRITABLE || state === ERRORING, | 791 // assert(state === WRITABLE || state === ERRORING, |
| 814 '_stream_.[[state]] is `"writable"` or `"erroring"`'); | 792 // '_stream_.[[state]] is `"writable"` or `"erroring"`'); |
| 815 controller[_started] = true; | 793 controller[_started] = true; |
| 816 WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller); | 794 WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller); |
| 817 }, | 795 }, |
| 818 r => { | 796 r => { |
| 819 const state = stream[_stateAndFlags] & STATE_MASK; | 797 const state = stream[_stateAndFlags] & STATE_MASK; |
| 820 TEMP_ASSERT(state === WRITABLE || state === ERRORING, | 798 // assert(state === WRITABLE || state === ERRORING, |
| 821 '_stream_.[[state]] is `"writable"` or `"erroring"`'); | 799 // '_stream_.[[state]] is `"writable"` or `"erroring"`'); |
| 822 controller[_started] = true; | 800 controller[_started] = true; |
| 823 WritableStreamDealWithRejection(stream, r); | 801 WritableStreamDealWithRejection(stream, r); |
| 824 }); | 802 }); |
| 825 } | 803 } |
| 826 | 804 |
| 827 // Writable Stream Default Controller Abstract Operations | 805 // Writable Stream Default Controller Abstract Operations |
| 828 | 806 |
| 829 function IsWritableStreamDefaultController(x) { | 807 function IsWritableStreamDefaultController(x) { |
| 830 return hasOwnProperty(x, _underlyingSink); | 808 return hasOwnProperty(x, _underlyingSink); |
| 831 } | 809 } |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 905 controller[_controlledWritableStream][_stateAndFlags] & STATE_MASK; | 883 controller[_controlledWritableStream][_stateAndFlags] & STATE_MASK; |
| 906 if (state === WRITABLE) { | 884 if (state === WRITABLE) { |
| 907 WritableStreamDefaultControllerError(controller, error); | 885 WritableStreamDefaultControllerError(controller, error); |
| 908 } | 886 } |
| 909 } | 887 } |
| 910 | 888 |
| 911 function WritableStreamDefaultControllerProcessClose(controller) { | 889 function WritableStreamDefaultControllerProcessClose(controller) { |
| 912 const stream = controller[_controlledWritableStream]; | 890 const stream = controller[_controlledWritableStream]; |
| 913 WritableStreamMarkCloseRequestInFlight(stream); | 891 WritableStreamMarkCloseRequestInFlight(stream); |
| 914 DequeueValue(controller); | 892 DequeueValue(controller); |
| 915 TEMP_ASSERT(controller[_queue].length === 0, | 893 // assert(controller[_queue].length === 0, |
| 916 'controller.[[queue]] is empty.'); | 894 // 'controller.[[queue]] is empty.'); |
| 917 const sinkClosePromise = PromiseInvokeOrNoop( | 895 const sinkClosePromise = PromiseInvokeOrNoop( |
| 918 controller[_underlyingSink], 'close', []); | 896 controller[_underlyingSink], 'close', []); |
| 919 thenPromise( | 897 thenPromise( |
| 920 sinkClosePromise, | 898 sinkClosePromise, |
| 921 () => WritableStreamFinishInFlightClose(stream), | 899 () => WritableStreamFinishInFlightClose(stream), |
| 922 reason => WritableStreamFinishInFlightCloseWithError(stream, reason) | 900 reason => WritableStreamFinishInFlightCloseWithError(stream, reason) |
| 923 ); | 901 ); |
| 924 } | 902 } |
| 925 | 903 |
| 926 function WritableStreamDefaultControllerProcessWrite(controller, chunk) { | 904 function WritableStreamDefaultControllerProcessWrite(controller, chunk) { |
| 927 const stream = controller[_controlledWritableStream]; | 905 const stream = controller[_controlledWritableStream]; |
| 928 WritableStreamMarkFirstWriteRequestInFlight(stream); | 906 WritableStreamMarkFirstWriteRequestInFlight(stream); |
| 929 const sinkWritePromise = PromiseInvokeOrNoop(controller[_underlyingSink], | 907 const sinkWritePromise = PromiseInvokeOrNoop(controller[_underlyingSink], |
| 930 'write', [chunk, controller]); | 908 'write', [chunk, controller]); |
| 931 thenPromise( | 909 thenPromise( |
| 932 sinkWritePromise, | 910 sinkWritePromise, |
| 933 () => { | 911 () => { |
| 934 WritableStreamFinishInFlightWrite(stream); | 912 WritableStreamFinishInFlightWrite(stream); |
| 935 const state = stream[_stateAndFlags] & STATE_MASK; | 913 const state = stream[_stateAndFlags] & STATE_MASK; |
| 936 TEMP_ASSERT(state === WRITABLE || state === ERRORING, | 914 // assert(state === WRITABLE || state === ERRORING, |
| 937 '_state_ is `"writable"` or `"erroring"`'); | 915 // '_state_ is `"writable"` or `"erroring"`'); |
| 938 DequeueValue(controller); | 916 DequeueValue(controller); |
| 939 if (!WritableStreamCloseQueuedOrInFlight(stream) && | 917 if (!WritableStreamCloseQueuedOrInFlight(stream) && |
| 940 state === WRITABLE) { | 918 state === WRITABLE) { |
| 941 const backpressure = | 919 const backpressure = |
| 942 WritableStreamDefaultControllerGetBackpressure(controller); | 920 WritableStreamDefaultControllerGetBackpressure(controller); |
| 943 WritableStreamUpdateBackpressure(stream, backpressure); | 921 WritableStreamUpdateBackpressure(stream, backpressure); |
| 944 } | 922 } |
| 945 WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller); | 923 WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller); |
| 946 }, | 924 }, |
| 947 reason => { | 925 reason => { |
| 948 WritableStreamFinishInFlightWriteWithError(stream, reason); | 926 WritableStreamFinishInFlightWriteWithError(stream, reason); |
| 949 }); | 927 }); |
| 950 } | 928 } |
| 951 | 929 |
| 952 function WritableStreamDefaultControllerGetBackpressure(controller) { | 930 function WritableStreamDefaultControllerGetBackpressure(controller) { |
| 953 const desiredSize = | 931 const desiredSize = |
| 954 WritableStreamDefaultControllerGetDesiredSize(controller); | 932 WritableStreamDefaultControllerGetDesiredSize(controller); |
| 955 return desiredSize <= 0; | 933 return desiredSize <= 0; |
| 956 } | 934 } |
| 957 | 935 |
| 958 function WritableStreamDefaultControllerError(controller, error) { | 936 function WritableStreamDefaultControllerError(controller, error) { |
| 959 const stream = controller[_controlledWritableStream]; | 937 const stream = controller[_controlledWritableStream]; |
| 960 TEMP_ASSERT((stream[_stateAndFlags] & STATE_MASK) === WRITABLE, | 938 // assert((stream[_stateAndFlags] & STATE_MASK) === WRITABLE, |
| 961 '_stream_.[[state]] is `"writable"`.'); | 939 // '_stream_.[[state]] is `"writable"`.'); |
| 962 WritableStreamStartErroring(stream, error); | 940 WritableStreamStartErroring(stream, error); |
| 963 } | 941 } |
| 964 | 942 |
| 965 // Queue-with-Sizes Operations | 943 // Queue-with-Sizes Operations |
| 966 // | 944 // |
| 967 // TODO(ricea): Share these operations with ReadableStream.js. | 945 // TODO(ricea): Share these operations with ReadableStream.js. |
| 968 function DequeueValue(container) { | 946 function DequeueValue(container) { |
| 969 TEMP_ASSERT( | 947 // assert( |
| 970 hasOwnProperty(container, _queue) && | 948 // hasOwnProperty(container, _queue) && |
| 971 hasOwnProperty(container, _queueTotalSize), | 949 // hasOwnProperty(container, _queueTotalSize), |
| 972 'Assert: _container_ has [[queue]] and [[queueTotalSize]] internal ' + | 950 // 'Assert: _container_ has [[queue]] and [[queueTotalSize]] internal '
+ |
| 973 'slots.'); | 951 // 'slots.'); |
| 974 TEMP_ASSERT(container[_queue].length !== 0, | 952 // assert(container[_queue].length !== 0, |
| 975 '_container_.[[queue]] is not empty.'); | 953 // '_container_.[[queue]] is not empty.'); |
| 976 const pair = container[_queue].shift(); | 954 const pair = container[_queue].shift(); |
| 977 container[_queueTotalSize] -= pair.size; | 955 container[_queueTotalSize] -= pair.size; |
| 978 if (container[_queueTotalSize] < 0) { | 956 if (container[_queueTotalSize] < 0) { |
| 979 container[_queueTotalSize] = 0; | 957 container[_queueTotalSize] = 0; |
| 980 } | 958 } |
| 981 return pair.value; | 959 return pair.value; |
| 982 } | 960 } |
| 983 | 961 |
| 984 function EnqueueValueWithSize(container, value, size) { | 962 function EnqueueValueWithSize(container, value, size) { |
| 985 TEMP_ASSERT( | 963 // assert( |
| 986 hasOwnProperty(container, _queue) && | 964 // hasOwnProperty(container, _queue) && |
| 987 hasOwnProperty(container, _queueTotalSize), | 965 // hasOwnProperty(container, _queueTotalSize), |
| 988 'Assert: _container_ has [[queue]] and [[queueTotalSize]] internal ' + | 966 // 'Assert: _container_ has [[queue]] and [[queueTotalSize]] internal '
+ |
| 989 'slots.'); | 967 // 'slots.'); |
| 990 size = Number(size); | 968 size = Number(size); |
| 991 if (!IsFiniteNonNegativeNumber(size)) { | 969 if (!IsFiniteNonNegativeNumber(size)) { |
| 992 throw new RangeError(streamErrors.invalidSize); | 970 throw new RangeError(streamErrors.invalidSize); |
| 993 } | 971 } |
| 994 | 972 |
| 995 container[_queue].push({value, size}); | 973 container[_queue].push({value, size}); |
| 996 container[_queueTotalSize] += size; | 974 container[_queueTotalSize] += size; |
| 997 } | 975 } |
| 998 | 976 |
| 999 function PeekQueueValue(container) { | 977 function PeekQueueValue(container) { |
| 1000 TEMP_ASSERT( | 978 // assert( |
| 1001 hasOwnProperty(container, _queue) && | 979 // hasOwnProperty(container, _queue) && |
| 1002 hasOwnProperty(container, _queueTotalSize), | 980 // hasOwnProperty(container, _queueTotalSize), |
| 1003 'Assert: _container_ has [[queue]] and [[queueTotalSize]] internal ' + | 981 // 'Assert: _container_ has [[queue]] and [[queueTotalSize]] internal '
+ |
| 1004 'slots.'); | 982 // 'slots.'); |
| 1005 TEMP_ASSERT(container[_queue].length !== 0, | 983 // assert(container[_queue].length !== 0, |
| 1006 '_container_.[[queue]] is not empty.'); | 984 // '_container_.[[queue]] is not empty.'); |
| 1007 const pair = container[_queue].peek(); | 985 const pair = container[_queue].peek(); |
| 1008 return pair.value; | 986 return pair.value; |
| 1009 } | 987 } |
| 1010 | 988 |
| 1011 function ResetQueue(container) { | 989 function ResetQueue(container) { |
| 1012 TEMP_ASSERT( | 990 // assert( |
| 1013 hasOwnProperty(container, _queue) && | 991 // hasOwnProperty(container, _queue) && |
| 1014 hasOwnProperty(container, _queueTotalSize), | 992 // hasOwnProperty(container, _queueTotalSize), |
| 1015 'Assert: _container_ has [[queue]] and [[queueTotalSize]] internal ' + | 993 // 'Assert: _container_ has [[queue]] and [[queueTotalSize]] internal '
+ |
| 1016 'slots.'); | 994 // 'slots.'); |
| 1017 container[_queue] = new binding.SimpleQueue(); | 995 container[_queue] = new binding.SimpleQueue(); |
| 1018 container[_queueTotalSize] = 0; | 996 container[_queueTotalSize] = 0; |
| 1019 } | 997 } |
| 1020 | 998 |
| 1021 // Miscellaneous Operations | 999 // Miscellaneous Operations |
| 1022 | 1000 |
| 1023 // This differs from "CallOrNoop" in the ReadableStream implementation in | 1001 // This differs from "CallOrNoop" in the ReadableStream implementation in |
| 1024 // that it takes the arguments as an array, so that multiple arguments can be | 1002 // that it takes the arguments as an array, so that multiple arguments can be |
| 1025 // passed. | 1003 // passed. |
| 1026 // | 1004 // |
| 1027 // TODO(ricea): Consolidate with ReadableStream implementation. | 1005 // TODO(ricea): Consolidate with ReadableStream implementation. |
| 1028 function InvokeOrNoop(O, P, args) { | 1006 function InvokeOrNoop(O, P, args) { |
| 1029 TEMP_ASSERT(IsPropertyKey(P), | 1007 // assert(IsPropertyKey(P), |
| 1030 'P is a valid property key.'); | 1008 // 'P is a valid property key.'); |
| 1031 if (args === undefined) { | 1009 if (args === undefined) { |
| 1032 args = []; | 1010 args = []; |
| 1033 } | 1011 } |
| 1034 const method = O[P]; | 1012 const method = O[P]; |
| 1035 if (method === undefined) { | 1013 if (method === undefined) { |
| 1036 return undefined; | 1014 return undefined; |
| 1037 } | 1015 } |
| 1038 if (typeof method !== 'function') { | 1016 if (typeof method !== 'function') { |
| 1039 throw new TypeError(templateErrorIsNotAFunction(P)); | 1017 throw new TypeError(templateErrorIsNotAFunction(P)); |
| 1040 } | 1018 } |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1097 getWritableStreamDefaultWriterClosedPromise; | 1075 getWritableStreamDefaultWriterClosedPromise; |
| 1098 binding.WritableStreamDefaultWriterGetDesiredSize = | 1076 binding.WritableStreamDefaultWriterGetDesiredSize = |
| 1099 WritableStreamDefaultWriterGetDesiredSize; | 1077 WritableStreamDefaultWriterGetDesiredSize; |
| 1100 binding.getWritableStreamDefaultWriterReadyPromise = | 1078 binding.getWritableStreamDefaultWriterReadyPromise = |
| 1101 getWritableStreamDefaultWriterReadyPromise; | 1079 getWritableStreamDefaultWriterReadyPromise; |
| 1102 binding.WritableStreamDefaultWriterRelease = | 1080 binding.WritableStreamDefaultWriterRelease = |
| 1103 WritableStreamDefaultWriterRelease; | 1081 WritableStreamDefaultWriterRelease; |
| 1104 binding.WritableStreamDefaultWriterWrite = WritableStreamDefaultWriterWrite; | 1082 binding.WritableStreamDefaultWriterWrite = WritableStreamDefaultWriterWrite; |
| 1105 binding.getWritableStreamStoredError = getWritableStreamStoredError; | 1083 binding.getWritableStreamStoredError = getWritableStreamStoredError; |
| 1106 }); | 1084 }); |
| OLD | NEW |