Chromium Code Reviews| 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( |
| 283 !WritableStreamHasOperationMarkedInFlight(stream), | 262 // !WritableStreamHasOperationMarkedInFlight(stream), |
| 284 '! WritableStreamHasOperationMarkedInFlight(_stream_) is *false*'); | 263 // '! WritableStreamHasOperationMarkedInFlight(_stream_) is *false*'); |
|
tyoshino (SeeGerritForStatus)
2017/04/19 07:13:32
indent
Adam Rice
2017/04/20 06:30:20
Done.
| |
| 285 | 264 |
| 286 stream[_stateAndFlags] = (stream[_stateAndFlags] & ~STATE_MASK) | ERRORED; | 265 stream[_stateAndFlags] = (stream[_stateAndFlags] & ~STATE_MASK) | ERRORED; |
| 287 | 266 |
| 288 WritableStreamDefaultControllerErrorSteps( | 267 WritableStreamDefaultControllerErrorSteps( |
| 289 stream[_writableStreamController]); | 268 stream[_writableStreamController]); |
| 290 | 269 |
| 291 const storedError = stream[_storedError]; | 270 const storedError = stream[_storedError]; |
| 292 rejectPromises(stream[_writeRequests], storedError); | 271 rejectPromises(stream[_writeRequests], storedError); |
| 293 stream[_writeRequests] = new binding.SimpleQueue(); | 272 stream[_writeRequests] = new binding.SimpleQueue(); |
| 294 | 273 |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 315 v8.resolvePromise(abortRequest.promise, undefined); | 294 v8.resolvePromise(abortRequest.promise, undefined); |
| 316 WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream); | 295 WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream); |
| 317 }, | 296 }, |
| 318 reason => { | 297 reason => { |
| 319 v8.rejectPromise(abortRequest.promise, reason); | 298 v8.rejectPromise(abortRequest.promise, reason); |
| 320 WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream); | 299 WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream); |
| 321 }); | 300 }); |
| 322 } | 301 } |
| 323 | 302 |
| 324 function WritableStreamFinishInFlightWrite(stream) { | 303 function WritableStreamFinishInFlightWrite(stream) { |
| 325 TEMP_ASSERT(stream[_inFlightWriteRequest] !== undefined, | 304 // assert(stream[_inFlightWriteRequest] !== undefined, |
| 326 '_stream_.[[inFlightWriteRequest]] is not *undefined*.'); | 305 // '_stream_.[[inFlightWriteRequest]] is not *undefined*.'); |
| 327 v8.resolvePromise(stream[_inFlightWriteRequest], undefined); | 306 v8.resolvePromise(stream[_inFlightWriteRequest], undefined); |
| 328 stream[_inFlightWriteRequest] = undefined; | 307 stream[_inFlightWriteRequest] = undefined; |
| 329 } | 308 } |
| 330 | 309 |
| 331 function WritableStreamFinishInFlightWriteWithError(stream, error) { | 310 function WritableStreamFinishInFlightWriteWithError(stream, error) { |
| 332 TEMP_ASSERT(stream[_inFlightWriteRequest] !== undefined, | 311 // assert(stream[_inFlightWriteRequest] !== undefined, |
| 333 '_stream_.[[inFlightWriteRequest]] is not *undefined*.'); | 312 // '_stream_.[[inFlightWriteRequest]] is not *undefined*.'); |
| 334 v8.rejectPromise(stream[_inFlightWriteRequest], error); | 313 v8.rejectPromise(stream[_inFlightWriteRequest], error); |
| 335 stream[_inFlightWriteRequest] = undefined; | 314 stream[_inFlightWriteRequest] = undefined; |
| 336 | 315 |
| 337 let state = stream[_stateAndFlags] & STATE_MASK; | 316 let state = stream[_stateAndFlags] & STATE_MASK; |
| 338 TEMP_ASSERT(state === WRITABLE || state === ERRORING, | 317 // assert(state === WRITABLE || state === ERRORING, |
| 339 '_stream_.[[state]] is `"writable"` or `"erroring"`'); | 318 // '_stream_.[[state]] is `"writable"` or `"erroring"`'); |
| 340 | 319 |
| 341 WritableStreamDealWithRejection(stream, error); | 320 WritableStreamDealWithRejection(stream, error); |
| 342 } | 321 } |
| 343 | 322 |
| 344 function WritableStreamFinishInFlightClose(stream) { | 323 function WritableStreamFinishInFlightClose(stream) { |
| 345 TEMP_ASSERT(stream[_inFlightCloseRequest] !== undefined, | 324 // assert(stream[_inFlightCloseRequest] !== undefined, |
| 346 '_stream_.[[inFlightCloseRequest]] is not *undefined*.'); | 325 // '_stream_.[[inFlightCloseRequest]] is not *undefined*.'); |
| 347 v8.resolvePromise(stream[_inFlightCloseRequest], undefined); | 326 v8.resolvePromise(stream[_inFlightCloseRequest], undefined); |
| 348 stream[_inFlightCloseRequest] = undefined; | 327 stream[_inFlightCloseRequest] = undefined; |
| 349 | 328 |
| 350 const state = stream[_stateAndFlags] & STATE_MASK; | 329 const state = stream[_stateAndFlags] & STATE_MASK; |
| 351 TEMP_ASSERT(state === WRITABLE || state === ERRORING, | 330 // assert(state === WRITABLE || state === ERRORING, |
| 352 '_stream_.[[state]] is `"writable"` or `"erroring"`'); | 331 // '_stream_.[[state]] is `"writable"` or `"erroring"`'); |
| 353 | 332 |
| 354 if (state === ERRORING) { | 333 if (state === ERRORING) { |
| 355 stream[_storedError] = undefined; | 334 stream[_storedError] = undefined; |
| 356 if (stream[_pendingAbortRequest] !== undefined) { | 335 if (stream[_pendingAbortRequest] !== undefined) { |
| 357 v8.resolvePromise(stream[_pendingAbortRequest].promise, undefined); | 336 v8.resolvePromise(stream[_pendingAbortRequest].promise, undefined); |
| 358 stream[_pendingAbortRequest] = undefined; | 337 stream[_pendingAbortRequest] = undefined; |
| 359 } | 338 } |
| 360 } | 339 } |
| 361 | 340 |
| 362 stream[_stateAndFlags] = (stream[_stateAndFlags] & ~STATE_MASK) | CLOSED; | 341 stream[_stateAndFlags] = (stream[_stateAndFlags] & ~STATE_MASK) | CLOSED; |
| 363 const writer = stream[_writer]; | 342 const writer = stream[_writer]; |
| 364 if (writer !== undefined) { | 343 if (writer !== undefined) { |
| 365 v8.resolvePromise(writer[_closedPromise], undefined); | 344 v8.resolvePromise(writer[_closedPromise], undefined); |
| 366 } | 345 } |
| 367 | 346 |
| 368 TEMP_ASSERT(stream[_pendingAbortRequest] === undefined, | 347 // assert(stream[_pendingAbortRequest] === undefined, |
| 369 '_stream_.[[pendingAbortRequest]] is *undefined*'); | 348 // '_stream_.[[pendingAbortRequest]] is *undefined*'); |
| 370 TEMP_ASSERT(stream[_storedError] === undefined, | 349 // assert(stream[_storedError] === undefined, |
| 371 '_stream_.[[storedError]] is *undefined*'); | 350 // '_stream_.[[storedError]] is *undefined*'); |
| 372 } | 351 } |
| 373 | 352 |
| 374 function WritableStreamFinishInFlightCloseWithError(stream, error) { | 353 function WritableStreamFinishInFlightCloseWithError(stream, error) { |
| 375 TEMP_ASSERT(stream[_inFlightCloseRequest] !== undefined, | 354 // assert(stream[_inFlightCloseRequest] !== undefined, |
| 376 '_stream_.[[inFlightCloseRequest]] is not *undefined*.'); | 355 // '_stream_.[[inFlightCloseRequest]] is not *undefined*.'); |
| 377 v8.rejectPromise(stream[_inFlightCloseRequest], error); | 356 v8.rejectPromise(stream[_inFlightCloseRequest], error); |
| 378 stream[_inFlightCloseRequest] = undefined; | 357 stream[_inFlightCloseRequest] = undefined; |
| 379 | 358 |
| 380 const state = stream[_stateAndFlags] & STATE_MASK; | 359 const state = stream[_stateAndFlags] & STATE_MASK; |
| 381 TEMP_ASSERT(state === WRITABLE || state === ERRORING, | 360 // assert(state === WRITABLE || state === ERRORING, |
| 382 '_stream_.[[state]] is `"writable"` or `"erroring"`'); | 361 // '_stream_.[[state]] is `"writable"` or `"erroring"`'); |
| 383 | 362 |
| 384 if (stream[_pendingAbortRequest] !== undefined) { | 363 if (stream[_pendingAbortRequest] !== undefined) { |
| 385 v8.rejectPromise(stream[_pendingAbortRequest].promise, error); | 364 v8.rejectPromise(stream[_pendingAbortRequest].promise, error); |
| 386 stream[_pendingAbortRequest] = undefined; | 365 stream[_pendingAbortRequest] = undefined; |
| 387 } | 366 } |
| 388 | 367 |
| 389 WritableStreamDealWithRejection(stream, error); | 368 WritableStreamDealWithRejection(stream, error); |
| 390 } | 369 } |
| 391 | 370 |
| 392 function WritableStreamCloseQueuedOrInFlight(stream) { | 371 function WritableStreamCloseQueuedOrInFlight(stream) { |
| 393 return stream[_closeRequest] !== undefined || | 372 return stream[_closeRequest] !== undefined || |
| 394 stream[_inFlightCloseRequest] !== undefined; | 373 stream[_inFlightCloseRequest] !== undefined; |
| 395 } | 374 } |
| 396 | 375 |
| 397 function WritableStreamHasOperationMarkedInFlight(stream) { | 376 function WritableStreamHasOperationMarkedInFlight(stream) { |
| 398 return stream[_inFlightWriteRequest] !== undefined || | 377 return stream[_inFlightWriteRequest] !== undefined || |
| 399 stream[_inFlightCloseRequest] !== undefined; | 378 stream[_inFlightCloseRequest] !== undefined; |
| 400 } | 379 } |
| 401 | 380 |
| 402 function WritableStreamMarkCloseRequestInFlight(stream) { | 381 function WritableStreamMarkCloseRequestInFlight(stream) { |
| 403 TEMP_ASSERT(stream[_inFlightCloseRequest] === undefined, | 382 // assert(stream[_inFlightCloseRequest] === undefined, |
| 404 '_stream_.[[inFlightCloseRequest]] is *undefined*.'); | 383 // '_stream_.[[inFlightCloseRequest]] is *undefined*.'); |
| 405 TEMP_ASSERT(stream[_closeRequest] !== undefined, | 384 // assert(stream[_closeRequest] !== undefined, |
| 406 '_stream_.[[closeRequest]] is not *undefined*.'); | 385 // '_stream_.[[closeRequest]] is not *undefined*.'); |
| 407 stream[_inFlightCloseRequest] = stream[_closeRequest]; | 386 stream[_inFlightCloseRequest] = stream[_closeRequest]; |
| 408 stream[_closeRequest] = undefined; | 387 stream[_closeRequest] = undefined; |
| 409 } | 388 } |
| 410 | 389 |
| 411 function WritableStreamMarkFirstWriteRequestInFlight(stream) { | 390 function WritableStreamMarkFirstWriteRequestInFlight(stream) { |
| 412 TEMP_ASSERT(stream[_inFlightWriteRequest] === undefined, | 391 // assert(stream[_inFlightWriteRequest] === undefined, |
| 413 '_stream_.[[inFlightWriteRequest]] is *undefined*.'); | 392 // '_stream_.[[inFlightWriteRequest]] is *undefined*.'); |
| 414 TEMP_ASSERT(stream[_writeRequests].length !== 0, | 393 // assert(stream[_writeRequests].length !== 0, |
| 415 '_stream_.[[writeRequests]] is not empty.'); | 394 // '_stream_.[[writeRequests]] is not empty.'); |
| 416 const writeRequest = stream[_writeRequests].shift(); | 395 const writeRequest = stream[_writeRequests].shift(); |
| 417 stream[_inFlightWriteRequest] = writeRequest; | 396 stream[_inFlightWriteRequest] = writeRequest; |
| 418 } | 397 } |
| 419 | 398 |
| 420 function WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream) { | 399 function WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream) { |
| 421 TEMP_ASSERT((stream[_stateAndFlags] & STATE_MASK) === ERRORED, | 400 // assert((stream[_stateAndFlags] & STATE_MASK) === ERRORED, |
| 422 '_stream_.[[state]] is `"errored"`'); | 401 // '_stream_.[[state]] is `"errored"`'); |
| 423 | 402 |
| 424 if (stream[_closeRequest] !== undefined) { | 403 if (stream[_closeRequest] !== undefined) { |
| 425 TEMP_ASSERT(stream[_inFlightCloseRequest] === undefined, | 404 // assert(stream[_inFlightCloseRequest] === undefined, |
| 426 '_stream_.[[inFlightCloseRequest]] is *undefined*'); | 405 // '_stream_.[[inFlightCloseRequest]] is *undefined*'); |
| 427 v8.rejectPromise(stream[_closeRequest], stream[_storedError]); | 406 v8.rejectPromise(stream[_closeRequest], stream[_storedError]); |
| 428 stream[_closeRequest] = undefined; | 407 stream[_closeRequest] = undefined; |
| 429 } | 408 } |
| 430 | 409 |
| 431 const writer = stream[_writer]; | 410 const writer = stream[_writer]; |
| 432 if (writer !== undefined) { | 411 if (writer !== undefined) { |
| 433 v8.rejectPromise(writer[_closedPromise], stream[_storedError]); | 412 v8.rejectPromise(writer[_closedPromise], stream[_storedError]); |
| 434 v8.markPromiseAsHandled(writer[_closedPromise]); | 413 v8.markPromiseAsHandled(writer[_closedPromise]); |
| 435 } | 414 } |
| 436 } | 415 } |
| 437 | 416 |
| 438 function WritableStreamUpdateBackpressure(stream, backpressure) { | 417 function WritableStreamUpdateBackpressure(stream, backpressure) { |
| 439 TEMP_ASSERT((stream[_stateAndFlags] & STATE_MASK) === WRITABLE, | 418 // assert((stream[_stateAndFlags] & STATE_MASK) === WRITABLE, |
| 440 'stream.[[state]] is "writable".'); | 419 // 'stream.[[state]] is "writable".'); |
| 441 TEMP_ASSERT(!WritableStreamCloseQueuedOrInFlight(stream), | 420 // assert(!WritableStreamCloseQueuedOrInFlight(stream), |
| 442 'WritableStreamCloseQueuedOrInFlight(_stream_) is *false*.'); | 421 // 'WritableStreamCloseQueuedOrInFlight(_stream_) is *false*.'); |
| 443 const writer = stream[_writer]; | 422 const writer = stream[_writer]; |
| 444 if (writer !== undefined && | 423 if (writer !== undefined && |
| 445 backpressure !== Boolean(stream[_stateAndFlags] & BACKPRESSURE_FLAG)) { | 424 backpressure !== Boolean(stream[_stateAndFlags] & BACKPRESSURE_FLAG)) { |
| 446 if (backpressure) { | 425 if (backpressure) { |
| 447 writer[_readyPromise] = v8.createPromise(); | 426 writer[_readyPromise] = v8.createPromise(); |
| 448 } else { | 427 } else { |
| 449 TEMP_ASSERT(!backpressure, '_backpressure_ is *false*.'); | 428 // assert(!backpressure, '_backpressure_ is *false*.'); |
| 450 v8.resolvePromise(writer[_readyPromise], undefined); | 429 v8.resolvePromise(writer[_readyPromise], undefined); |
| 451 } | 430 } |
| 452 } | 431 } |
| 453 if (backpressure) { | 432 if (backpressure) { |
| 454 stream[_stateAndFlags] |= BACKPRESSURE_FLAG; | 433 stream[_stateAndFlags] |= BACKPRESSURE_FLAG; |
| 455 } else { | 434 } else { |
| 456 stream[_stateAndFlags] &= ~BACKPRESSURE_FLAG; | 435 stream[_stateAndFlags] &= ~BACKPRESSURE_FLAG; |
| 457 } | 436 } |
| 458 } | 437 } |
| 459 | 438 |
| 460 // Functions to expose internals for ReadableStream.pipeTo. These are not | 439 // Functions to expose internals for ReadableStream.pipeTo. These are not |
| 461 // part of the standard. | 440 // part of the standard. |
| 462 function isWritableStreamErrored(stream) { | 441 function isWritableStreamErrored(stream) { |
| 463 TEMP_ASSERT( | 442 // assert( |
| 464 IsWritableStream(stream), '! IsWritableStream(stream) is true.'); | 443 // IsWritableStream(stream), '! IsWritableStream(stream) is true.'); |
| 465 return (stream[_stateAndFlags] & STATE_MASK) === ERRORED; | 444 return (stream[_stateAndFlags] & STATE_MASK) === ERRORED; |
| 466 } | 445 } |
| 467 | 446 |
| 468 function isWritableStreamClosingOrClosed(stream) { | 447 function isWritableStreamClosingOrClosed(stream) { |
| 469 TEMP_ASSERT( | 448 // assert( |
| 470 IsWritableStream(stream), '! IsWritableStream(stream) is true.'); | 449 // IsWritableStream(stream), '! IsWritableStream(stream) is true.'); |
| 471 return WritableStreamCloseQueuedOrInFlight(stream) || | 450 return WritableStreamCloseQueuedOrInFlight(stream) || |
| 472 (stream[_stateAndFlags] & STATE_MASK) === CLOSED; | 451 (stream[_stateAndFlags] & STATE_MASK) === CLOSED; |
| 473 } | 452 } |
| 474 | 453 |
| 475 function getWritableStreamStoredError(stream) { | 454 function getWritableStreamStoredError(stream) { |
| 476 TEMP_ASSERT( | 455 // assert( |
| 477 IsWritableStream(stream), '! IsWritableStream(stream) is true.'); | 456 // IsWritableStream(stream), '! IsWritableStream(stream) is true.'); |
| 478 return stream[_storedError]; | 457 return stream[_storedError]; |
| 479 } | 458 } |
| 480 | 459 |
| 481 class WritableStreamDefaultWriter { | 460 class WritableStreamDefaultWriter { |
| 482 constructor(stream) { | 461 constructor(stream) { |
| 483 if (!IsWritableStream(stream)) { | 462 if (!IsWritableStream(stream)) { |
| 484 throw new TypeError(streamErrors.illegalConstructor); | 463 throw new TypeError(streamErrors.illegalConstructor); |
| 485 } | 464 } |
| 486 if (IsWritableStreamLocked(stream)) { | 465 if (IsWritableStreamLocked(stream)) { |
| 487 throw new TypeError(streamErrors.illegalConstructor); | 466 throw new TypeError(streamErrors.illegalConstructor); |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 512 | 491 |
| 513 case CLOSED: | 492 case CLOSED: |
| 514 { | 493 { |
| 515 this[_readyPromise] = Promise_resolve(undefined); | 494 this[_readyPromise] = Promise_resolve(undefined); |
| 516 this[_closedPromise] = Promise_resolve(undefined); | 495 this[_closedPromise] = Promise_resolve(undefined); |
| 517 break; | 496 break; |
| 518 } | 497 } |
| 519 | 498 |
| 520 default: | 499 default: |
| 521 { | 500 { |
| 522 TEMP_ASSERT(state === ERRORED, '_state_ is `"errored"`.'); | 501 // assert(state === ERRORED, '_state_ is `"errored"`.'); |
| 523 const storedError = stream[_storedError]; | 502 const storedError = stream[_storedError]; |
| 524 this[_readyPromise] = Promise_reject(storedError); | 503 this[_readyPromise] = Promise_reject(storedError); |
| 525 v8.markPromiseAsHandled(this[_readyPromise]); | 504 v8.markPromiseAsHandled(this[_readyPromise]); |
| 526 this[_closedPromise] = Promise_reject(storedError); | 505 this[_closedPromise] = Promise_reject(storedError); |
| 527 v8.markPromiseAsHandled(this[_closedPromise]); | 506 v8.markPromiseAsHandled(this[_closedPromise]); |
| 528 break; | 507 break; |
| 529 } | 508 } |
| 530 } | 509 } |
| 531 } | 510 } |
| 532 | 511 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 579 } | 558 } |
| 580 | 559 |
| 581 releaseLock() { | 560 releaseLock() { |
| 582 if (!IsWritableStreamDefaultWriter(this)) { | 561 if (!IsWritableStreamDefaultWriter(this)) { |
| 583 throw new TypeError(streamErrors.illegalInvocation); | 562 throw new TypeError(streamErrors.illegalInvocation); |
| 584 } | 563 } |
| 585 const stream = this[_ownerWritableStream]; | 564 const stream = this[_ownerWritableStream]; |
| 586 if (stream === undefined) { | 565 if (stream === undefined) { |
| 587 return; | 566 return; |
| 588 } | 567 } |
| 589 TEMP_ASSERT(stream[_writer] !== undefined, | 568 // assert(stream[_writer] !== undefined, |
| 590 'stream.[[writer]] is not undefined.'); | 569 // 'stream.[[writer]] is not undefined.'); |
| 591 WritableStreamDefaultWriterRelease(this); | 570 WritableStreamDefaultWriterRelease(this); |
| 592 } | 571 } |
| 593 | 572 |
| 594 write(chunk) { | 573 write(chunk) { |
| 595 if (!IsWritableStreamDefaultWriter(this)) { | 574 if (!IsWritableStreamDefaultWriter(this)) { |
| 596 return Promise_reject(new TypeError(streamErrors.illegalInvocation)); | 575 return Promise_reject(new TypeError(streamErrors.illegalInvocation)); |
| 597 } | 576 } |
| 598 if (this[_ownerWritableStream] === undefined) { | 577 if (this[_ownerWritableStream] === undefined) { |
| 599 return Promise_reject(createWriterLockReleasedError(verbWrittenTo)); | 578 return Promise_reject(createWriterLockReleasedError(verbWrittenTo)); |
| 600 } | 579 } |
| 601 return WritableStreamDefaultWriterWrite(this, chunk); | 580 return WritableStreamDefaultWriterWrite(this, chunk); |
| 602 } | 581 } |
| 603 } | 582 } |
| 604 | 583 |
| 605 // Writable Stream Writer Abstract Operations | 584 // Writable Stream Writer Abstract Operations |
| 606 | 585 |
| 607 function IsWritableStreamDefaultWriter(x) { | 586 function IsWritableStreamDefaultWriter(x) { |
| 608 return hasOwnProperty(x, _ownerWritableStream); | 587 return hasOwnProperty(x, _ownerWritableStream); |
| 609 } | 588 } |
| 610 | 589 |
| 611 function WritableStreamDefaultWriterAbort(writer, reason) { | 590 function WritableStreamDefaultWriterAbort(writer, reason) { |
| 612 const stream = writer[_ownerWritableStream]; | 591 const stream = writer[_ownerWritableStream]; |
| 613 TEMP_ASSERT(stream !== undefined, | 592 // assert(stream !== undefined, |
| 614 'stream is not undefined.'); | 593 // 'stream is not undefined.'); |
| 615 return WritableStreamAbort(stream, reason); | 594 return WritableStreamAbort(stream, reason); |
| 616 } | 595 } |
| 617 | 596 |
| 618 function WritableStreamDefaultWriterClose(writer) { | 597 function WritableStreamDefaultWriterClose(writer) { |
| 619 const stream = writer[_ownerWritableStream]; | 598 const stream = writer[_ownerWritableStream]; |
| 620 TEMP_ASSERT(stream !== undefined, 'stream is not undefined.'); | 599 // assert(stream !== undefined, 'stream is not undefined.'); |
| 621 const state = stream[_stateAndFlags] & STATE_MASK; | 600 const state = stream[_stateAndFlags] & STATE_MASK; |
| 622 if (state === CLOSED || state === ERRORED) { | 601 if (state === CLOSED || state === ERRORED) { |
| 623 return Promise_reject( | 602 return Promise_reject( |
| 624 createCannotActionOnStateStreamError('close', state)); | 603 createCannotActionOnStateStreamError('close', state)); |
| 625 } | 604 } |
| 626 | 605 |
| 627 TEMP_ASSERT(state === WRITABLE || state === ERRORING, | 606 // assert(state === WRITABLE || state === ERRORING, |
| 628 '_state_ is `"writable"` or `"erroring"`.'); | 607 // '_state_ is `"writable"` or `"erroring"`.'); |
| 629 TEMP_ASSERT(!WritableStreamCloseQueuedOrInFlight(stream), | 608 // assert(!WritableStreamCloseQueuedOrInFlight(stream), |
| 630 '! WritableStreamCloseQueuedOrInFlight(_stream_) is *false*.'); | 609 // '! WritableStreamCloseQueuedOrInFlight(_stream_) is *false*.'); |
| 631 const promise = v8.createPromise(); | 610 const promise = v8.createPromise(); |
| 632 stream[_closeRequest] = promise; | 611 stream[_closeRequest] = promise; |
| 633 | 612 |
| 634 if ((stream[_stateAndFlags] & BACKPRESSURE_FLAG) && | 613 if ((stream[_stateAndFlags] & BACKPRESSURE_FLAG) && |
| 635 state === WRITABLE) { | 614 state === WRITABLE) { |
| 636 v8.resolvePromise(writer[_readyPromise], undefined); | 615 v8.resolvePromise(writer[_readyPromise], undefined); |
| 637 } | 616 } |
| 638 WritableStreamDefaultControllerClose(stream[_writableStreamController]); | 617 WritableStreamDefaultControllerClose(stream[_writableStreamController]); |
| 639 return promise; | 618 return promise; |
| 640 } | 619 } |
| 641 | 620 |
| 642 function WritableStreamDefaultWriterCloseWithErrorPropagation(writer) { | 621 function WritableStreamDefaultWriterCloseWithErrorPropagation(writer) { |
| 643 const stream = writer[_ownerWritableStream]; | 622 const stream = writer[_ownerWritableStream]; |
| 644 TEMP_ASSERT(stream !== undefined, 'stream is not undefined.'); | 623 // assert(stream !== undefined, 'stream is not undefined.'); |
| 645 const state = stream[_stateAndFlags] & STATE_MASK; | 624 const state = stream[_stateAndFlags] & STATE_MASK; |
| 646 if (WritableStreamCloseQueuedOrInFlight(stream) || state === CLOSED) { | 625 if (WritableStreamCloseQueuedOrInFlight(stream) || state === CLOSED) { |
| 647 return Promise_resolve(undefined); | 626 return Promise_resolve(undefined); |
| 648 } | 627 } |
| 649 if (state === ERRORED) { | 628 if (state === ERRORED) { |
| 650 return Promise_reject(stream[_storedError]); | 629 return Promise_reject(stream[_storedError]); |
| 651 } | 630 } |
| 652 | 631 |
| 653 TEMP_ASSERT(state === WRITABLE || state === ERRORING, | 632 // assert(state === WRITABLE || state === ERRORING, |
| 654 '_state_ is `"writable"` or `"erroring"`.'); | 633 // '_state_ is `"writable"` or `"erroring"`.'); |
| 655 | 634 |
| 656 return WritableStreamDefaultWriterClose(writer); | 635 return WritableStreamDefaultWriterClose(writer); |
| 657 } | 636 } |
| 658 | 637 |
| 659 function WritableStreamDefaultWriterEnsureClosedPromiseRejected( | 638 function WritableStreamDefaultWriterEnsureClosedPromiseRejected( |
| 660 writer, error) { | 639 writer, error) { |
| 661 if (v8.promiseState(writer[_closedPromise]) === v8.kPROMISE_PENDING) { | 640 if (v8.promiseState(writer[_closedPromise]) === v8.kPROMISE_PENDING) { |
| 662 v8.rejectPromise(writer[_closedPromise], error); | 641 v8.rejectPromise(writer[_closedPromise], error); |
| 663 } else { | 642 } else { |
| 664 writer[_closedPromise] = Promise_reject(error); | 643 writer[_closedPromise] = Promise_reject(error); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 685 } | 664 } |
| 686 if (state === CLOSED) { | 665 if (state === CLOSED) { |
| 687 return 0; | 666 return 0; |
| 688 } | 667 } |
| 689 return WritableStreamDefaultControllerGetDesiredSize( | 668 return WritableStreamDefaultControllerGetDesiredSize( |
| 690 stream[_writableStreamController]); | 669 stream[_writableStreamController]); |
| 691 } | 670 } |
| 692 | 671 |
| 693 function WritableStreamDefaultWriterRelease(writer) { | 672 function WritableStreamDefaultWriterRelease(writer) { |
| 694 const stream = writer[_ownerWritableStream]; | 673 const stream = writer[_ownerWritableStream]; |
| 695 TEMP_ASSERT(stream !== undefined, | 674 // assert(stream !== undefined, |
| 696 'stream is not undefined.'); | 675 // 'stream is not undefined.'); |
| 697 TEMP_ASSERT(stream[_writer] === writer, | 676 // assert(stream[_writer] === writer, |
| 698 'stream.[[writer]] is writer.'); | 677 // 'stream.[[writer]] is writer.'); |
| 699 const releasedError = new TypeError(errReleasedWriterClosedPromise); | 678 const releasedError = new TypeError(errReleasedWriterClosedPromise); |
| 700 WritableStreamDefaultWriterEnsureReadyPromiseRejected( | 679 WritableStreamDefaultWriterEnsureReadyPromiseRejected( |
| 701 writer, releasedError); | 680 writer, releasedError); |
| 702 WritableStreamDefaultWriterEnsureClosedPromiseRejected( | 681 WritableStreamDefaultWriterEnsureClosedPromiseRejected( |
| 703 writer, releasedError); | 682 writer, releasedError); |
| 704 stream[_writer] = undefined; | 683 stream[_writer] = undefined; |
| 705 writer[_ownerWritableStream] = undefined; | 684 writer[_ownerWritableStream] = undefined; |
| 706 } | 685 } |
| 707 | 686 |
| 708 function WritableStreamDefaultWriterWrite(writer, chunk) { | 687 function WritableStreamDefaultWriterWrite(writer, chunk) { |
| 709 const stream = writer[_ownerWritableStream]; | 688 const stream = writer[_ownerWritableStream]; |
| 710 TEMP_ASSERT(stream !== undefined, 'stream is not undefined.'); | 689 // assert(stream !== undefined, 'stream is not undefined.'); |
| 711 const controller = stream[_writableStreamController]; | 690 const controller = stream[_writableStreamController]; |
| 712 const chunkSize = | 691 const chunkSize = |
| 713 WritableStreamDefaultControllerGetChunkSize(controller, chunk); | 692 WritableStreamDefaultControllerGetChunkSize(controller, chunk); |
| 714 if (stream !== writer[_ownerWritableStream]) { | 693 if (stream !== writer[_ownerWritableStream]) { |
| 715 return Promise_reject(createWriterLockReleasedError(verbWrittenTo)); | 694 return Promise_reject(createWriterLockReleasedError(verbWrittenTo)); |
| 716 } | 695 } |
| 717 const state = stream[_stateAndFlags] & STATE_MASK; | 696 const state = stream[_stateAndFlags] & STATE_MASK; |
| 718 if (state === ERRORED) { | 697 if (state === ERRORED) { |
| 719 return Promise_reject(stream[_storedError]); | 698 return Promise_reject(stream[_storedError]); |
| 720 } | 699 } |
| 721 if (WritableStreamCloseQueuedOrInFlight(stream)) { | 700 if (WritableStreamCloseQueuedOrInFlight(stream)) { |
| 722 return Promise_reject(new TypeError( | 701 return Promise_reject(new TypeError( |
| 723 templateErrorCannotActionOnStateStream('write to', 'closing'))); | 702 templateErrorCannotActionOnStateStream('write to', 'closing'))); |
| 724 } | 703 } |
| 725 if (state === CLOSED) { | 704 if (state === CLOSED) { |
| 726 return Promise_reject( | 705 return Promise_reject( |
| 727 createCannotActionOnStateStreamError('write to', CLOSED)); | 706 createCannotActionOnStateStreamError('write to', CLOSED)); |
| 728 } | 707 } |
| 729 if (state === ERRORING) { | 708 if (state === ERRORING) { |
| 730 return Promise_reject(stream[_storedError]); | 709 return Promise_reject(stream[_storedError]); |
| 731 } | 710 } |
| 732 TEMP_ASSERT(state === WRITABLE, '_state_ is `"writable"`'); | 711 // assert(state === WRITABLE, '_state_ is `"writable"`'); |
| 733 const promise = WritableStreamAddWriteRequest(stream); | 712 const promise = WritableStreamAddWriteRequest(stream); |
| 734 WritableStreamDefaultControllerWrite(controller, chunk, chunkSize); | 713 WritableStreamDefaultControllerWrite(controller, chunk, chunkSize); |
| 735 return promise; | 714 return promise; |
| 736 } | 715 } |
| 737 | 716 |
| 738 // Functions to expose internals for ReadableStream.pipeTo. These do not | 717 // Functions to expose internals for ReadableStream.pipeTo. These do not |
| 739 // appear in the standard. | 718 // appear in the standard. |
| 740 function getWritableStreamDefaultWriterClosedPromise(writer) { | 719 function getWritableStreamDefaultWriterClosedPromise(writer) { |
| 741 TEMP_ASSERT( | 720 // assert( |
| 742 IsWritableStreamDefaultWriter(writer), | 721 // IsWritableStreamDefaultWriter(writer), |
| 743 'writer is a WritableStreamDefaultWriter.'); | 722 // 'writer is a WritableStreamDefaultWriter.'); |
| 744 return writer[_closedPromise]; | 723 return writer[_closedPromise]; |
| 745 } | 724 } |
| 746 | 725 |
| 747 function getWritableStreamDefaultWriterReadyPromise(writer) { | 726 function getWritableStreamDefaultWriterReadyPromise(writer) { |
| 748 TEMP_ASSERT( | 727 // assert( |
| 749 IsWritableStreamDefaultWriter(writer), | 728 // IsWritableStreamDefaultWriter(writer), |
| 750 'writer is a WritableStreamDefaultWriter.'); | 729 // 'writer is a WritableStreamDefaultWriter.'); |
| 751 return writer[_readyPromise]; | 730 return writer[_readyPromise]; |
| 752 } | 731 } |
| 753 | 732 |
| 754 class WritableStreamDefaultController { | 733 class WritableStreamDefaultController { |
| 755 constructor(stream, underlyingSink, size, highWaterMark) { | 734 constructor(stream, underlyingSink, size, highWaterMark) { |
| 756 if (!IsWritableStream(stream)) { | 735 if (!IsWritableStream(stream)) { |
| 757 throw new TypeError(streamErrors.illegalConstructor); | 736 throw new TypeError(streamErrors.illegalConstructor); |
| 758 } | 737 } |
| 759 if (stream[_writableStreamController] !== undefined) { | 738 if (stream[_writableStreamController] !== undefined) { |
| 760 throw new TypeError(streamErrors.illegalConstructor); | 739 throw new TypeError(streamErrors.illegalConstructor); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 803 | 782 |
| 804 function WritableStreamDefaultControllerStartSteps(controller) { | 783 function WritableStreamDefaultControllerStartSteps(controller) { |
| 805 const startResult = | 784 const startResult = |
| 806 InvokeOrNoop(controller[_underlyingSink], 'start', [controller]); | 785 InvokeOrNoop(controller[_underlyingSink], 'start', [controller]); |
| 807 const stream = controller[_controlledWritableStream]; | 786 const stream = controller[_controlledWritableStream]; |
| 808 const startPromise = Promise_resolve(startResult); | 787 const startPromise = Promise_resolve(startResult); |
| 809 thenPromise( | 788 thenPromise( |
| 810 startPromise, | 789 startPromise, |
| 811 () => { | 790 () => { |
| 812 const state = stream[_stateAndFlags] & STATE_MASK; | 791 const state = stream[_stateAndFlags] & STATE_MASK; |
| 813 TEMP_ASSERT(state === WRITABLE || state === ERRORING, | 792 // assert(state === WRITABLE || state === ERRORING, |
| 814 '_stream_.[[state]] is `"writable"` or `"erroring"`'); | 793 // '_stream_.[[state]] is `"writable"` or `"erroring"`'); |
| 815 controller[_started] = true; | 794 controller[_started] = true; |
| 816 WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller); | 795 WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller); |
| 817 }, | 796 }, |
| 818 r => { | 797 r => { |
| 819 const state = stream[_stateAndFlags] & STATE_MASK; | 798 const state = stream[_stateAndFlags] & STATE_MASK; |
| 820 TEMP_ASSERT(state === WRITABLE || state === ERRORING, | 799 // assert(state === WRITABLE || state === ERRORING, |
| 821 '_stream_.[[state]] is `"writable"` or `"erroring"`'); | 800 // '_stream_.[[state]] is `"writable"` or `"erroring"`'); |
| 822 controller[_started] = true; | 801 controller[_started] = true; |
| 823 WritableStreamDealWithRejection(stream, r); | 802 WritableStreamDealWithRejection(stream, r); |
| 824 }); | 803 }); |
| 825 } | 804 } |
| 826 | 805 |
| 827 // Writable Stream Default Controller Abstract Operations | 806 // Writable Stream Default Controller Abstract Operations |
| 828 | 807 |
| 829 function IsWritableStreamDefaultController(x) { | 808 function IsWritableStreamDefaultController(x) { |
| 830 return hasOwnProperty(x, _underlyingSink); | 809 return hasOwnProperty(x, _underlyingSink); |
| 831 } | 810 } |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 905 controller[_controlledWritableStream][_stateAndFlags] & STATE_MASK; | 884 controller[_controlledWritableStream][_stateAndFlags] & STATE_MASK; |
| 906 if (state === WRITABLE) { | 885 if (state === WRITABLE) { |
| 907 WritableStreamDefaultControllerError(controller, error); | 886 WritableStreamDefaultControllerError(controller, error); |
| 908 } | 887 } |
| 909 } | 888 } |
| 910 | 889 |
| 911 function WritableStreamDefaultControllerProcessClose(controller) { | 890 function WritableStreamDefaultControllerProcessClose(controller) { |
| 912 const stream = controller[_controlledWritableStream]; | 891 const stream = controller[_controlledWritableStream]; |
| 913 WritableStreamMarkCloseRequestInFlight(stream); | 892 WritableStreamMarkCloseRequestInFlight(stream); |
| 914 DequeueValue(controller); | 893 DequeueValue(controller); |
| 915 TEMP_ASSERT(controller[_queue].length === 0, | 894 // assert(controller[_queue].length === 0, |
| 916 'controller.[[queue]] is empty.'); | 895 // 'controller.[[queue]] is empty.'); |
| 917 const sinkClosePromise = PromiseInvokeOrNoop( | 896 const sinkClosePromise = PromiseInvokeOrNoop( |
| 918 controller[_underlyingSink], 'close', []); | 897 controller[_underlyingSink], 'close', []); |
| 919 thenPromise( | 898 thenPromise( |
| 920 sinkClosePromise, | 899 sinkClosePromise, |
| 921 () => WritableStreamFinishInFlightClose(stream), | 900 () => WritableStreamFinishInFlightClose(stream), |
| 922 reason => WritableStreamFinishInFlightCloseWithError(stream, reason) | 901 reason => WritableStreamFinishInFlightCloseWithError(stream, reason) |
| 923 ); | 902 ); |
| 924 } | 903 } |
| 925 | 904 |
| 926 function WritableStreamDefaultControllerProcessWrite(controller, chunk) { | 905 function WritableStreamDefaultControllerProcessWrite(controller, chunk) { |
| 927 const stream = controller[_controlledWritableStream]; | 906 const stream = controller[_controlledWritableStream]; |
| 928 WritableStreamMarkFirstWriteRequestInFlight(stream); | 907 WritableStreamMarkFirstWriteRequestInFlight(stream); |
| 929 const sinkWritePromise = PromiseInvokeOrNoop(controller[_underlyingSink], | 908 const sinkWritePromise = PromiseInvokeOrNoop(controller[_underlyingSink], |
| 930 'write', [chunk, controller]); | 909 'write', [chunk, controller]); |
| 931 thenPromise( | 910 thenPromise( |
| 932 sinkWritePromise, | 911 sinkWritePromise, |
| 933 () => { | 912 () => { |
| 934 WritableStreamFinishInFlightWrite(stream); | 913 WritableStreamFinishInFlightWrite(stream); |
| 935 const state = stream[_stateAndFlags] & STATE_MASK; | 914 const state = stream[_stateAndFlags] & STATE_MASK; |
| 936 TEMP_ASSERT(state === WRITABLE || state === ERRORING, | 915 // assert(state === WRITABLE || state === ERRORING, |
| 937 '_state_ is `"writable"` or `"erroring"`'); | 916 // '_state_ is `"writable"` or `"erroring"`'); |
| 938 DequeueValue(controller); | 917 DequeueValue(controller); |
| 939 if (!WritableStreamCloseQueuedOrInFlight(stream) && | 918 if (!WritableStreamCloseQueuedOrInFlight(stream) && |
| 940 state === WRITABLE) { | 919 state === WRITABLE) { |
| 941 const backpressure = | 920 const backpressure = |
| 942 WritableStreamDefaultControllerGetBackpressure(controller); | 921 WritableStreamDefaultControllerGetBackpressure(controller); |
| 943 WritableStreamUpdateBackpressure(stream, backpressure); | 922 WritableStreamUpdateBackpressure(stream, backpressure); |
| 944 } | 923 } |
| 945 WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller); | 924 WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller); |
| 946 }, | 925 }, |
| 947 reason => { | 926 reason => { |
| 948 WritableStreamFinishInFlightWriteWithError(stream, reason); | 927 WritableStreamFinishInFlightWriteWithError(stream, reason); |
| 949 }); | 928 }); |
| 950 } | 929 } |
| 951 | 930 |
| 952 function WritableStreamDefaultControllerGetBackpressure(controller) { | 931 function WritableStreamDefaultControllerGetBackpressure(controller) { |
| 953 const desiredSize = | 932 const desiredSize = |
| 954 WritableStreamDefaultControllerGetDesiredSize(controller); | 933 WritableStreamDefaultControllerGetDesiredSize(controller); |
| 955 return desiredSize <= 0; | 934 return desiredSize <= 0; |
| 956 } | 935 } |
| 957 | 936 |
| 958 function WritableStreamDefaultControllerError(controller, error) { | 937 function WritableStreamDefaultControllerError(controller, error) { |
| 959 const stream = controller[_controlledWritableStream]; | 938 const stream = controller[_controlledWritableStream]; |
| 960 TEMP_ASSERT((stream[_stateAndFlags] & STATE_MASK) === WRITABLE, | 939 // assert((stream[_stateAndFlags] & STATE_MASK) === WRITABLE, |
| 961 '_stream_.[[state]] is `"writable"`.'); | 940 // '_stream_.[[state]] is `"writable"`.'); |
| 962 WritableStreamStartErroring(stream, error); | 941 WritableStreamStartErroring(stream, error); |
| 963 } | 942 } |
| 964 | 943 |
| 965 // Queue-with-Sizes Operations | 944 // Queue-with-Sizes Operations |
| 966 // | 945 // |
| 967 // TODO(ricea): Share these operations with ReadableStream.js. | 946 // TODO(ricea): Share these operations with ReadableStream.js. |
| 968 function DequeueValue(container) { | 947 function DequeueValue(container) { |
| 969 TEMP_ASSERT( | 948 // assert( |
| 970 hasOwnProperty(container, _queue) && | 949 // hasOwnProperty(container, _queue) && |
| 971 hasOwnProperty(container, _queueTotalSize), | 950 // hasOwnProperty(container, _queueTotalSize), |
| 972 'Assert: _container_ has [[queue]] and [[queueTotalSize]] internal ' + | 951 // 'Assert: _container_ has [[queue]] and [[queueTotalSize]] internal ' + |
| 973 'slots.'); | 952 // 'slots.'); |
| 974 TEMP_ASSERT(container[_queue].length !== 0, | 953 // assert(container[_queue].length !== 0, |
| 975 '_container_.[[queue]] is not empty.'); | 954 // '_container_.[[queue]] is not empty.'); |
| 976 const pair = container[_queue].shift(); | 955 const pair = container[_queue].shift(); |
| 977 container[_queueTotalSize] -= pair.size; | 956 container[_queueTotalSize] -= pair.size; |
| 978 if (container[_queueTotalSize] < 0) { | 957 if (container[_queueTotalSize] < 0) { |
| 979 container[_queueTotalSize] = 0; | 958 container[_queueTotalSize] = 0; |
| 980 } | 959 } |
| 981 return pair.value; | 960 return pair.value; |
| 982 } | 961 } |
| 983 | 962 |
| 984 function EnqueueValueWithSize(container, value, size) { | 963 function EnqueueValueWithSize(container, value, size) { |
| 985 TEMP_ASSERT( | 964 // assert( |
| 986 hasOwnProperty(container, _queue) && | 965 // hasOwnProperty(container, _queue) && |
| 987 hasOwnProperty(container, _queueTotalSize), | 966 // hasOwnProperty(container, _queueTotalSize), |
| 988 'Assert: _container_ has [[queue]] and [[queueTotalSize]] internal ' + | 967 // 'Assert: _container_ has [[queue]] and [[queueTotalSize]] internal ' + |
| 989 'slots.'); | 968 // 'slots.'); |
| 990 size = Number(size); | 969 size = Number(size); |
| 991 if (!IsFiniteNonNegativeNumber(size)) { | 970 if (!IsFiniteNonNegativeNumber(size)) { |
| 992 throw new RangeError(streamErrors.invalidSize); | 971 throw new RangeError(streamErrors.invalidSize); |
| 993 } | 972 } |
| 994 | 973 |
| 995 container[_queue].push({value, size}); | 974 container[_queue].push({value, size}); |
| 996 container[_queueTotalSize] += size; | 975 container[_queueTotalSize] += size; |
| 997 } | 976 } |
| 998 | 977 |
| 999 function PeekQueueValue(container) { | 978 function PeekQueueValue(container) { |
| 1000 TEMP_ASSERT( | 979 // assert( |
| 1001 hasOwnProperty(container, _queue) && | 980 // hasOwnProperty(container, _queue) && |
| 1002 hasOwnProperty(container, _queueTotalSize), | 981 // hasOwnProperty(container, _queueTotalSize), |
| 1003 'Assert: _container_ has [[queue]] and [[queueTotalSize]] internal ' + | 982 // 'Assert: _container_ has [[queue]] and [[queueTotalSize]] internal ' + |
| 1004 'slots.'); | 983 // 'slots.'); |
| 1005 TEMP_ASSERT(container[_queue].length !== 0, | 984 // assert(container[_queue].length !== 0, |
| 1006 '_container_.[[queue]] is not empty.'); | 985 // '_container_.[[queue]] is not empty.'); |
| 1007 const pair = container[_queue].peek(); | 986 const pair = container[_queue].peek(); |
| 1008 return pair.value; | 987 return pair.value; |
| 1009 } | 988 } |
| 1010 | 989 |
| 1011 function ResetQueue(container) { | 990 function ResetQueue(container) { |
| 1012 TEMP_ASSERT( | 991 // assert( |
| 1013 hasOwnProperty(container, _queue) && | 992 // hasOwnProperty(container, _queue) && |
| 1014 hasOwnProperty(container, _queueTotalSize), | 993 // hasOwnProperty(container, _queueTotalSize), |
| 1015 'Assert: _container_ has [[queue]] and [[queueTotalSize]] internal ' + | 994 // 'Assert: _container_ has [[queue]] and [[queueTotalSize]] internal ' + |
| 1016 'slots.'); | 995 // 'slots.'); |
| 1017 container[_queue] = new binding.SimpleQueue(); | 996 container[_queue] = new binding.SimpleQueue(); |
| 1018 container[_queueTotalSize] = 0; | 997 container[_queueTotalSize] = 0; |
| 1019 } | 998 } |
| 1020 | 999 |
| 1021 // Miscellaneous Operations | 1000 // Miscellaneous Operations |
| 1022 | 1001 |
| 1023 // This differs from "CallOrNoop" in the ReadableStream implementation in | 1002 // This differs from "CallOrNoop" in the ReadableStream implementation in |
| 1024 // that it takes the arguments as an array, so that multiple arguments can be | 1003 // that it takes the arguments as an array, so that multiple arguments can be |
| 1025 // passed. | 1004 // passed. |
| 1026 // | 1005 // |
| 1027 // TODO(ricea): Consolidate with ReadableStream implementation. | 1006 // TODO(ricea): Consolidate with ReadableStream implementation. |
| 1028 function InvokeOrNoop(O, P, args) { | 1007 function InvokeOrNoop(O, P, args) { |
| 1029 TEMP_ASSERT(IsPropertyKey(P), | 1008 // assert(IsPropertyKey(P), |
| 1030 'P is a valid property key.'); | 1009 // 'P is a valid property key.'); |
| 1031 if (args === undefined) { | 1010 if (args === undefined) { |
| 1032 args = []; | 1011 args = []; |
| 1033 } | 1012 } |
| 1034 const method = O[P]; | 1013 const method = O[P]; |
| 1035 if (method === undefined) { | 1014 if (method === undefined) { |
| 1036 return undefined; | 1015 return undefined; |
| 1037 } | 1016 } |
| 1038 if (typeof method !== 'function') { | 1017 if (typeof method !== 'function') { |
| 1039 throw new TypeError(templateErrorIsNotAFunction(P)); | 1018 throw new TypeError(templateErrorIsNotAFunction(P)); |
| 1040 } | 1019 } |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1097 getWritableStreamDefaultWriterClosedPromise; | 1076 getWritableStreamDefaultWriterClosedPromise; |
| 1098 binding.WritableStreamDefaultWriterGetDesiredSize = | 1077 binding.WritableStreamDefaultWriterGetDesiredSize = |
| 1099 WritableStreamDefaultWriterGetDesiredSize; | 1078 WritableStreamDefaultWriterGetDesiredSize; |
| 1100 binding.getWritableStreamDefaultWriterReadyPromise = | 1079 binding.getWritableStreamDefaultWriterReadyPromise = |
| 1101 getWritableStreamDefaultWriterReadyPromise; | 1080 getWritableStreamDefaultWriterReadyPromise; |
| 1102 binding.WritableStreamDefaultWriterRelease = | 1081 binding.WritableStreamDefaultWriterRelease = |
| 1103 WritableStreamDefaultWriterRelease; | 1082 WritableStreamDefaultWriterRelease; |
| 1104 binding.WritableStreamDefaultWriterWrite = WritableStreamDefaultWriterWrite; | 1083 binding.WritableStreamDefaultWriterWrite = WritableStreamDefaultWriterWrite; |
| 1105 binding.getWritableStreamStoredError = getWritableStreamStoredError; | 1084 binding.getWritableStreamStoredError = getWritableStreamStoredError; |
| 1106 }); | 1085 }); |
| OLD | NEW |