| 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 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 const Number = global.Number; | 63 const Number = global.Number; |
| 64 const Number_isNaN = Number.isNaN; | 64 const Number_isNaN = Number.isNaN; |
| 65 const Number_isFinite = Number.isFinite; | 65 const Number_isFinite = Number.isFinite; |
| 66 | 66 |
| 67 const Promise = global.Promise; | 67 const Promise = global.Promise; |
| 68 const thenPromise = v8.uncurryThis(Promise.prototype.then); | 68 const thenPromise = v8.uncurryThis(Promise.prototype.then); |
| 69 const Promise_resolve = v8.simpleBind(Promise.resolve, Promise); | 69 const Promise_resolve = v8.simpleBind(Promise.resolve, Promise); |
| 70 const Promise_reject = v8.simpleBind(Promise.reject, Promise); | 70 const Promise_reject = v8.simpleBind(Promise.reject, Promise); |
| 71 | 71 |
| 72 // User-visible strings. | 72 // User-visible strings. |
| 73 // TODO(ricea): Share strings with ReadableStream that are identical in both. | 73 const streamErrors = binding.streamErrors; |
| 74 const errIllegalInvocation = 'Illegal invocation'; | 74 const errAbortLockedStream = 'Cannot abort a writable stream that is locked to
a writer'; |
| 75 const errIllegalConstructor = 'Illegal constructor'; | |
| 76 const errInvalidType = 'Invalid type is specified'; | |
| 77 const errAbortLockedStream = 'Cannot abort a writable stream that is locked t
o a writer'; | |
| 78 const errStreamAborted = 'The stream has been aborted'; | 75 const errStreamAborted = 'The stream has been aborted'; |
| 79 const errWriterLockReleasedPrefix = 'This writable stream writer has been rele
ased and cannot be '; | 76 const errWriterLockReleasedPrefix = 'This writable stream writer has been rele
ased and cannot be '; |
| 80 const errCloseCloseRequestedStream = | 77 const errCloseCloseRequestedStream = |
| 81 'Cannot close a writable stream that has already been requested to be clos
ed'; | 78 'Cannot close a writable stream that has already been requested to be clos
ed'; |
| 82 const errWriteCloseRequestedStream = | 79 const errWriteCloseRequestedStream = |
| 83 'Cannot write to a writable stream that is due to be closed'; | 80 'Cannot write to a writable stream that is due to be closed'; |
| 84 const templateErrorCannotActionOnStateStream = | 81 const templateErrorCannotActionOnStateStream = |
| 85 (action, state) => `Cannot ${action} a ${state} writable stream`; | 82 (action, state) => `Cannot ${action} a ${state} writable stream`; |
| 86 const errReleasedWriterClosedPromise = | 83 const errReleasedWriterClosedPromise = |
| 87 'This writable stream writer has been released and cannot be used to monit
or the stream\'s state'; | 84 'This writable stream writer has been released and cannot be used to monit
or the stream\'s state'; |
| 88 const templateErrorIsNotAFunction = f => `${f} is not a function`; | 85 const templateErrorIsNotAFunction = f => `${f} is not a function`; |
| 89 const errSizeNotAFunction = | |
| 90 'A queuing strategy\'s size property must be a function'; | |
| 91 const errInvalidHWM = | |
| 92 'A queuing strategy\'s highWaterMark property must be a non-negative, non-
NaN number'; | |
| 93 const errInvalidSize = | |
| 94 'The return value of a queuing strategy\'s size function must be a finite,
non-NaN, non-negative number'; | |
| 95 | 86 |
| 96 // These verbs are used after errWriterLockReleasedPrefix | 87 // These verbs are used after errWriterLockReleasedPrefix |
| 97 const verbUsedToGetTheDesiredSize = 'used to get the desiredSize'; | 88 const verbUsedToGetTheDesiredSize = 'used to get the desiredSize'; |
| 98 const verbAborted = 'aborted'; | 89 const verbAborted = 'aborted'; |
| 99 const verbClosed = 'closed'; | 90 const verbClosed = 'closed'; |
| 100 const verbWrittenTo = 'written to'; | 91 const verbWrittenTo = 'written to'; |
| 101 | 92 |
| 102 // Utility functions (not from the standard). | 93 // Utility functions (not from the standard). |
| 103 function createWriterLockReleasedError(verb) { | 94 function createWriterLockReleasedError(verb) { |
| 104 return new TypeError(errWriterLockReleasedPrefix + verb); | 95 return new TypeError(errWriterLockReleasedPrefix + verb); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 165 | 156 |
| 166 class WritableStream { | 157 class WritableStream { |
| 167 constructor(underlyingSink = {}, { size, highWaterMark = 1 } = {}) { | 158 constructor(underlyingSink = {}, { size, highWaterMark = 1 } = {}) { |
| 168 this[_state] = WRITABLE; | 159 this[_state] = WRITABLE; |
| 169 this[_storedError] = undefined; | 160 this[_storedError] = undefined; |
| 170 this[_writer] = undefined; | 161 this[_writer] = undefined; |
| 171 this[_writableStreamController] = undefined; | 162 this[_writableStreamController] = undefined; |
| 172 this[_writeRequests] = new v8.InternalPackedArray(); | 163 this[_writeRequests] = new v8.InternalPackedArray(); |
| 173 const type = underlyingSink.type; | 164 const type = underlyingSink.type; |
| 174 if (type !== undefined) { | 165 if (type !== undefined) { |
| 175 throw new RangeError(errInvalidType); | 166 throw new RangeError(streamErrors.invalidType); |
| 176 } | 167 } |
| 177 this[_writableStreamController] = | 168 this[_writableStreamController] = |
| 178 new WritableStreamDefaultController(this, underlyingSink, size, | 169 new WritableStreamDefaultController(this, underlyingSink, size, |
| 179 highWaterMark); | 170 highWaterMark); |
| 180 } | 171 } |
| 181 | 172 |
| 182 get locked() { | 173 get locked() { |
| 183 if (!IsWritableStream(this)) { | 174 if (!IsWritableStream(this)) { |
| 184 throw new TypeError(errIllegalInvocation); | 175 throw new TypeError(streamErrors.illegalInvocation); |
| 185 } | 176 } |
| 186 return IsWritableStreamLocked(this); | 177 return IsWritableStreamLocked(this); |
| 187 } | 178 } |
| 188 | 179 |
| 189 abort(reason) { | 180 abort(reason) { |
| 190 if (!IsWritableStream(this)) { | 181 if (!IsWritableStream(this)) { |
| 191 return Promise_reject(new TypeError(errIllegalInvocation)); | 182 return Promise_reject(new TypeError(streamErrors.illegalInvocation)); |
| 192 } | 183 } |
| 193 if (IsWritableStreamLocked(this)) { | 184 if (IsWritableStreamLocked(this)) { |
| 194 return Promise_reject(new TypeError(errAbortLockedStream)); | 185 return Promise_reject(new TypeError(errAbortLockedStream)); |
| 195 } | 186 } |
| 196 return WritableStreamAbort(this, reason); | 187 return WritableStreamAbort(this, reason); |
| 197 } | 188 } |
| 198 | 189 |
| 199 getWriter() { | 190 getWriter() { |
| 200 if (!IsWritableStream(this)) { | 191 if (!IsWritableStream(this)) { |
| 201 throw new TypeError(errIllegalInvocation); | 192 throw new TypeError(streamErrors.illegalInvocation); |
| 202 } | 193 } |
| 203 return AcquireWritableStreamDefaultWriter(this); | 194 return AcquireWritableStreamDefaultWriter(this); |
| 204 } | 195 } |
| 205 } | 196 } |
| 206 | 197 |
| 207 // General Writable Stream Abstract Operations | 198 // General Writable Stream Abstract Operations |
| 208 | 199 |
| 209 function AcquireWritableStreamDefaultWriter(stream) { | 200 function AcquireWritableStreamDefaultWriter(stream) { |
| 210 return new WritableStreamDefaultWriter(stream); | 201 return new WritableStreamDefaultWriter(stream); |
| 211 } | 202 } |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 297 } else { | 288 } else { |
| 298 TEMP_ASSERT(backpressure === false, | 289 TEMP_ASSERT(backpressure === false, |
| 299 'backpressure is false.'); | 290 'backpressure is false.'); |
| 300 v8.resolvePromise(writer[_readyPromise], undefined); | 291 v8.resolvePromise(writer[_readyPromise], undefined); |
| 301 } | 292 } |
| 302 } | 293 } |
| 303 | 294 |
| 304 class WritableStreamDefaultWriter { | 295 class WritableStreamDefaultWriter { |
| 305 constructor(stream) { | 296 constructor(stream) { |
| 306 if (!IsWritableStream(stream)) { | 297 if (!IsWritableStream(stream)) { |
| 307 throw new TypeError(errIllegalConstructor); | 298 throw new TypeError(streamErrors.illegalConstructor); |
| 308 } | 299 } |
| 309 if (IsWritableStreamLocked(stream)) { | 300 if (IsWritableStreamLocked(stream)) { |
| 310 throw new TypeError(errIllegalConstructor); | 301 throw new TypeError(streamErrors.illegalConstructor); |
| 311 } | 302 } |
| 312 this[_ownerWritableStream] = stream; | 303 this[_ownerWritableStream] = stream; |
| 313 stream[_writer] = this; | 304 stream[_writer] = this; |
| 314 const state = stream[_state]; | 305 const state = stream[_state]; |
| 315 if (state === WRITABLE || state === CLOSING) { | 306 if (state === WRITABLE || state === CLOSING) { |
| 316 this[_closedPromise] = v8.createPromise(); | 307 this[_closedPromise] = v8.createPromise(); |
| 317 } else if (state === CLOSED) { | 308 } else if (state === CLOSED) { |
| 318 this[_closedPromise] = Promise_resolve(undefined); | 309 this[_closedPromise] = Promise_resolve(undefined); |
| 319 } else { | 310 } else { |
| 320 TEMP_ASSERT(state === ERRORED, | 311 TEMP_ASSERT(state === ERRORED, |
| 321 'state is "errored".'); | 312 'state is "errored".'); |
| 322 this[_closedPromise] = Promise_reject(stream[_storedError]); | 313 this[_closedPromise] = Promise_reject(stream[_storedError]); |
| 323 } | 314 } |
| 324 if (state === WRITABLE && | 315 if (state === WRITABLE && |
| 325 WritableStreamDefaultControllerGetBackpressure( | 316 WritableStreamDefaultControllerGetBackpressure( |
| 326 stream[_writableStreamController])) { | 317 stream[_writableStreamController])) { |
| 327 this[_readyPromise] = v8.createPromise(); | 318 this[_readyPromise] = v8.createPromise(); |
| 328 } else { | 319 } else { |
| 329 this[_readyPromise] = Promise_resolve(undefined); | 320 this[_readyPromise] = Promise_resolve(undefined); |
| 330 } | 321 } |
| 331 } | 322 } |
| 332 | 323 |
| 333 get closed() { | 324 get closed() { |
| 334 if (!IsWritableStreamDefaultWriter(this)) { | 325 if (!IsWritableStreamDefaultWriter(this)) { |
| 335 return Promise_reject(new TypeError(errIllegalInvocation)); | 326 return Promise_reject(new TypeError(streamErrors.illegalInvocation)); |
| 336 } | 327 } |
| 337 return this[_closedPromise]; | 328 return this[_closedPromise]; |
| 338 } | 329 } |
| 339 | 330 |
| 340 get desiredSize() { | 331 get desiredSize() { |
| 341 if (!IsWritableStreamDefaultWriter(this)) { | 332 if (!IsWritableStreamDefaultWriter(this)) { |
| 342 throw new TypeError(errIllegalInvocation); | 333 throw new TypeError(streamErrors.illegalInvocation); |
| 343 } | 334 } |
| 344 if (this[_ownerWritableStream] === undefined) { | 335 if (this[_ownerWritableStream] === undefined) { |
| 345 throw createWriterLockReleasedError(verbUsedToGetTheDesiredSize); | 336 throw createWriterLockReleasedError(verbUsedToGetTheDesiredSize); |
| 346 } | 337 } |
| 347 return WritableStreamDefaultWriterGetDesiredSize(this); | 338 return WritableStreamDefaultWriterGetDesiredSize(this); |
| 348 } | 339 } |
| 349 | 340 |
| 350 get ready() { | 341 get ready() { |
| 351 if (!IsWritableStreamDefaultWriter(this)) { | 342 if (!IsWritableStreamDefaultWriter(this)) { |
| 352 return Promise_reject(new TypeError(errIllegalInvocation)); | 343 return Promise_reject(new TypeError(streamErrors.illegalInvocation)); |
| 353 } | 344 } |
| 354 return this[_readyPromise]; | 345 return this[_readyPromise]; |
| 355 } | 346 } |
| 356 | 347 |
| 357 abort(reason) { | 348 abort(reason) { |
| 358 if (!IsWritableStreamDefaultWriter(this)) { | 349 if (!IsWritableStreamDefaultWriter(this)) { |
| 359 return Promise_reject(new TypeError(errIllegalInvocation)); | 350 return Promise_reject(new TypeError(streamErrors.illegalInvocation)); |
| 360 } | 351 } |
| 361 if (this[_ownerWritableStream] === undefined) { | 352 if (this[_ownerWritableStream] === undefined) { |
| 362 return Promise_reject(createWriterLockReleasedError(verbAborted)); | 353 return Promise_reject(createWriterLockReleasedError(verbAborted)); |
| 363 } | 354 } |
| 364 return WritableStreamDefaultWriterAbort(this, reason); | 355 return WritableStreamDefaultWriterAbort(this, reason); |
| 365 } | 356 } |
| 366 | 357 |
| 367 close() { | 358 close() { |
| 368 if (!IsWritableStreamDefaultWriter(this)) { | 359 if (!IsWritableStreamDefaultWriter(this)) { |
| 369 return Promise_reject(new TypeError(errIllegalInvocation)); | 360 return Promise_reject(new TypeError(streamErrors.illegalInvocation)); |
| 370 } | 361 } |
| 371 const stream = this[_ownerWritableStream]; | 362 const stream = this[_ownerWritableStream]; |
| 372 if (stream === undefined) { | 363 if (stream === undefined) { |
| 373 return Promise_reject(createWriterLockReleasedError(verbClosed)); | 364 return Promise_reject(createWriterLockReleasedError(verbClosed)); |
| 374 } | 365 } |
| 375 if (stream[_state] === CLOSING) { | 366 if (stream[_state] === CLOSING) { |
| 376 return Promise_reject(new TypeError(errCloseCloseRequestedStream)); | 367 return Promise_reject(new TypeError(errCloseCloseRequestedStream)); |
| 377 } | 368 } |
| 378 return WritableStreamDefaultWriterClose(this); | 369 return WritableStreamDefaultWriterClose(this); |
| 379 } | 370 } |
| 380 | 371 |
| 381 releaseLock() { | 372 releaseLock() { |
| 382 if (!IsWritableStreamDefaultWriter(this)) { | 373 if (!IsWritableStreamDefaultWriter(this)) { |
| 383 throw new TypeError(errIllegalInvocation); | 374 throw new TypeError(streamErrors.illegalInvocation); |
| 384 } | 375 } |
| 385 const stream = this[_ownerWritableStream]; | 376 const stream = this[_ownerWritableStream]; |
| 386 if (stream === undefined) { | 377 if (stream === undefined) { |
| 387 return; | 378 return; |
| 388 } | 379 } |
| 389 TEMP_ASSERT(stream[_writer] !== undefined, | 380 TEMP_ASSERT(stream[_writer] !== undefined, |
| 390 'stream.[[writer]] is not undefined.'); | 381 'stream.[[writer]] is not undefined.'); |
| 391 WritableStreamDefaultWriterRelease(this); | 382 WritableStreamDefaultWriterRelease(this); |
| 392 } | 383 } |
| 393 | 384 |
| 394 write(chunk) { | 385 write(chunk) { |
| 395 if (!IsWritableStreamDefaultWriter(this)) { | 386 if (!IsWritableStreamDefaultWriter(this)) { |
| 396 return Promise_reject(new TypeError(errIllegalInvocation)); | 387 return Promise_reject(new TypeError(streamErrors.illegalInvocation)); |
| 397 } | 388 } |
| 398 const stream = this[_ownerWritableStream]; | 389 const stream = this[_ownerWritableStream]; |
| 399 if (stream === undefined) { | 390 if (stream === undefined) { |
| 400 return Promise_reject(createWriterLockReleasedError(verbWrittenTo)); | 391 return Promise_reject(createWriterLockReleasedError(verbWrittenTo)); |
| 401 } | 392 } |
| 402 if (stream[_state] === CLOSING) { | 393 if (stream[_state] === CLOSING) { |
| 403 return Promise_reject(new TypeError(errWriteCloseRequestedStream)); | 394 return Promise_reject(new TypeError(errWriteCloseRequestedStream)); |
| 404 } | 395 } |
| 405 return WritableStreamDefaultWriterWrite(this, chunk); | 396 return WritableStreamDefaultWriterWrite(this, chunk); |
| 406 } | 397 } |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 490 'state is "writable".'); | 481 'state is "writable".'); |
| 491 const promise = WritableStreamAddWriteRequest(stream); | 482 const promise = WritableStreamAddWriteRequest(stream); |
| 492 WritableStreamDefaultControllerWrite(stream[_writableStreamController], | 483 WritableStreamDefaultControllerWrite(stream[_writableStreamController], |
| 493 chunk); | 484 chunk); |
| 494 return promise; | 485 return promise; |
| 495 } | 486 } |
| 496 | 487 |
| 497 class WritableStreamDefaultController { | 488 class WritableStreamDefaultController { |
| 498 constructor(stream, underlyingSink, size, highWaterMark) { | 489 constructor(stream, underlyingSink, size, highWaterMark) { |
| 499 if (!IsWritableStream(stream)) { | 490 if (!IsWritableStream(stream)) { |
| 500 throw new TypeError(errIllegalConstructor); | 491 throw new TypeError(streamErrors.illegalConstructor); |
| 501 } | 492 } |
| 502 if (stream[_writableStreamController] !== undefined) { | 493 if (stream[_writableStreamController] !== undefined) { |
| 503 throw new TypeError(errIllegalConstructor); | 494 throw new TypeError(streamErrors.illegalConstructor); |
| 504 } | 495 } |
| 505 this[_controlledWritableStream] = stream; | 496 this[_controlledWritableStream] = stream; |
| 506 this[_underlyingSink] = underlyingSink; | 497 this[_underlyingSink] = underlyingSink; |
| 507 this[_queue] = new v8.InternalPackedArray(); | 498 this[_queue] = new v8.InternalPackedArray(); |
| 508 this[_queueSize] = 0; | 499 this[_queueSize] = 0; |
| 509 this[_defaultControllerFlags] = 0; | 500 this[_defaultControllerFlags] = 0; |
| 510 const normalizedStrategy = | 501 const normalizedStrategy = |
| 511 ValidateAndNormalizeQueuingStrategy(size, highWaterMark); | 502 ValidateAndNormalizeQueuingStrategy(size, highWaterMark); |
| 512 this[_strategySize] = normalizedStrategy.size; | 503 this[_strategySize] = normalizedStrategy.size; |
| 513 this[_strategyHWM] = normalizedStrategy.highWaterMark; | 504 this[_strategyHWM] = normalizedStrategy.highWaterMark; |
| 514 const backpressure = WritableStreamDefaultControllerGetBackpressure(this); | 505 const backpressure = WritableStreamDefaultControllerGetBackpressure(this); |
| 515 if (backpressure) { | 506 if (backpressure) { |
| 516 WritableStreamUpdateBackpressure(stream, backpressure); | 507 WritableStreamUpdateBackpressure(stream, backpressure); |
| 517 } | 508 } |
| 518 const controller = this; | 509 const controller = this; |
| 519 const startResult = InvokeOrNoop(underlyingSink, 'start', [this]); | 510 const startResult = InvokeOrNoop(underlyingSink, 'start', [this]); |
| 520 const onFulfilled = () => { | 511 const onFulfilled = () => { |
| 521 setDefaultControllerStartedFlag(controller, true); | 512 setDefaultControllerStartedFlag(controller, true); |
| 522 WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller); | 513 WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller); |
| 523 }; | 514 }; |
| 524 const onRejected = r => { | 515 const onRejected = r => { |
| 525 WritableStreamDefaultControllerErrorIfNeeded(controller, r); | 516 WritableStreamDefaultControllerErrorIfNeeded(controller, r); |
| 526 }; | 517 }; |
| 527 thenPromise(Promise_resolve(startResult), onFulfilled, onRejected); | 518 thenPromise(Promise_resolve(startResult), onFulfilled, onRejected); |
| 528 } | 519 } |
| 529 | 520 |
| 530 error(e) { | 521 error(e) { |
| 531 if (!IsWritableStreamDefaultController(this)) { | 522 if (!IsWritableStreamDefaultController(this)) { |
| 532 throw new TypeError(errIllegalInvocation); | 523 throw new TypeError(streamErrors.illegalInvocation); |
| 533 } | 524 } |
| 534 const state = this[_controlledWritableStream][_state]; | 525 const state = this[_controlledWritableStream][_state]; |
| 535 if (state === CLOSED || state === ERRORED) { | 526 if (state === CLOSED || state === ERRORED) { |
| 536 throw createCannotActionOnStateStreamError('error', state); | 527 throw createCannotActionOnStateStreamError('error', state); |
| 537 } | 528 } |
| 538 WritableStreamDefaultControllerError(this, e); | 529 WritableStreamDefaultControllerError(this, e); |
| 539 } | 530 } |
| 540 } | 531 } |
| 541 | 532 |
| 542 // Writable Stream Default Controller Abstract Operations | 533 // Writable Stream Default Controller Abstract Operations |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 706 TEMP_ASSERT(controller[_queue].length !== 0, | 697 TEMP_ASSERT(controller[_queue].length !== 0, |
| 707 'queue is not empty.'); | 698 'queue is not empty.'); |
| 708 const result = controller[_queue].shift(); | 699 const result = controller[_queue].shift(); |
| 709 controller[_queueSize] -= result.size; | 700 controller[_queueSize] -= result.size; |
| 710 return result.value; | 701 return result.value; |
| 711 } | 702 } |
| 712 | 703 |
| 713 function EnqueueValueWithSizeForController(controller, value, size) { | 704 function EnqueueValueWithSizeForController(controller, value, size) { |
| 714 size = Number(size); | 705 size = Number(size); |
| 715 if (!IsFiniteNonNegativeNumber(size)) { | 706 if (!IsFiniteNonNegativeNumber(size)) { |
| 716 throw new RangeError(errInvalidSize); | 707 throw new RangeError(streamErrors.invalidSize); |
| 717 } | 708 } |
| 718 | 709 |
| 719 controller[_queueSize] += size; | 710 controller[_queueSize] += size; |
| 720 controller[_queue].push({value, size}); | 711 controller[_queue].push({value, size}); |
| 721 } | 712 } |
| 722 | 713 |
| 723 function GetTotalQueueSizeForController(controller) { | 714 function GetTotalQueueSizeForController(controller) { |
| 724 return controller[_queueSize]; | 715 return controller[_queueSize]; |
| 725 } | 716 } |
| 726 | 717 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 780 try { | 771 try { |
| 781 return Promise_resolve(InvokeOrNoop(O, P, args)); | 772 return Promise_resolve(InvokeOrNoop(O, P, args)); |
| 782 } catch (e) { | 773 } catch (e) { |
| 783 return Promise_reject(e); | 774 return Promise_reject(e); |
| 784 } | 775 } |
| 785 } | 776 } |
| 786 | 777 |
| 787 // TODO(ricea): Share this operation with ReadableStream.js. | 778 // TODO(ricea): Share this operation with ReadableStream.js. |
| 788 function ValidateAndNormalizeQueuingStrategy(size, highWaterMark) { | 779 function ValidateAndNormalizeQueuingStrategy(size, highWaterMark) { |
| 789 if (size !== undefined && typeof size !== 'function') { | 780 if (size !== undefined && typeof size !== 'function') { |
| 790 throw new TypeError(errSizeNotAFunction); | 781 throw new TypeError(streamErrors.sizeNotAFunction); |
| 791 } | 782 } |
| 792 | 783 |
| 793 highWaterMark = Number(highWaterMark); | 784 highWaterMark = Number(highWaterMark); |
| 794 if (Number_isNaN(highWaterMark) || highWaterMark < 0) { | 785 if (Number_isNaN(highWaterMark)) { |
| 795 throw new RangeError(errInvalidHWM); | 786 throw new RangeError(streamErrors.errInvalidHWM); |
| 787 } |
| 788 if (highWaterMark < 0) { |
| 789 throw new RangeError(streamErrors.invalidHWM); |
| 796 } | 790 } |
| 797 | 791 |
| 798 return {size, highWaterMark}; | 792 return {size, highWaterMark}; |
| 799 } | 793 } |
| 800 | 794 |
| 801 // | 795 // |
| 802 // Additions to the global object | 796 // Additions to the global object |
| 803 // | 797 // |
| 804 | 798 |
| 805 defineProperty(global, 'WritableStream', { | 799 defineProperty(global, 'WritableStream', { |
| 806 value: WritableStream, | 800 value: WritableStream, |
| 807 enumerable: false, | 801 enumerable: false, |
| 808 configurable: true, | 802 configurable: true, |
| 809 writable: true | 803 writable: true |
| 810 }); | 804 }); |
| 811 | 805 |
| 812 // TODO(ricea): Exports to Blink | 806 // TODO(ricea): Exports to Blink |
| 813 }); | 807 }); |
| OLD | NEW |