Bug 1582348 - Implement |WritableStreamAbort| and |WritableStreamDefaultWriter.prototype.abort|. r=arai
authorJeff Walden <jwalden@mit.edu>
Tue, 05 Nov 2019 05:10:42 +0000
changeset 500538 31081d27ff05e2cbacd19fd86864bd2ae0e319c9
parent 500537 18a51ecc0e31374905349ef3a34f8bdf7f6dc81d
child 500539 97f48c45c1d0d619d48271cbd22cd556fc973c76
push id114166
push userapavel@mozilla.com
push dateThu, 07 Nov 2019 10:04:01 +0000
treeherdermozilla-inbound@d271c572a9bc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersarai
bugs1582348
milestone72.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1582348 - Implement |WritableStreamAbort| and |WritableStreamDefaultWriter.prototype.abort|. r=arai Differential Revision: https://phabricator.services.mozilla.com/D50107
js/src/builtin/streams/WritableStreamDefaultWriter.cpp
js/src/builtin/streams/WritableStreamWriterOperations.cpp
js/src/builtin/streams/WritableStreamWriterOperations.h
--- a/js/src/builtin/streams/WritableStreamDefaultWriter.cpp
+++ b/js/src/builtin/streams/WritableStreamDefaultWriter.cpp
@@ -13,17 +13,17 @@
 
 #include "jsapi.h"        // JS_ReportErrorASCII, JS_ReportErrorNumberASCII
 #include "jsfriendapi.h"  // js::GetErrorMessage, JSMSG_*
 
 #include "builtin/streams/ClassSpecMacro.h"  // JS_STREAMS_CLASS_SPEC
 #include "builtin/streams/MiscellaneousOperations.h"  // js::ReturnPromiseRejectedWithPendingError
 #include "builtin/streams/WritableStream.h"           // js::WritableStream
 #include "builtin/streams/WritableStreamOperations.h"  // js::WritableStreamCloseQueuedOrInFlight
-#include "builtin/streams/WritableStreamWriterOperations.h"  // js::WritableStreamDefaultWriter{GetDesiredSize,Release,Write}
+#include "builtin/streams/WritableStreamWriterOperations.h"  // js::WritableStreamDefaultWriter{Abort,GetDesiredSize,Release,Write}
 #include "js/CallArgs.h"                              // JS::CallArgs{,FromVp}
 #include "js/Class.h"                        // js::ClassSpec, JS_NULL_CLASS_OPS
 #include "js/PropertySpec.h"  // JS{Function,Property}Spec, JS_{FS,PS}_END, JS_{FN,PSG}
 #include "js/RootingAPI.h"    // JS::Handle
 #include "js/Value.h"         // JS::Value
 #include "vm/Compartment.h"   // JS::Compartment
 #include "vm/JSContext.h"     // JSContext
 
@@ -150,16 +150,52 @@ static MOZ_MUST_USE bool WritableStream_
     return false;
   }
 
   args.rval().setObject(*readyPromise);
   return true;
 }
 
 /**
+ * Streams spec, 4.5.4.4. abort(reason)
+ */
+static MOZ_MUST_USE bool WritableStream_abort(JSContext* cx, unsigned argc,
+                                              Value* vp) {
+  CallArgs args = CallArgsFromVp(argc, vp);
+
+  // Step 1: If ! IsWritableStreamDefaultWriter(this) is false, return a promise
+  //         rejected with a TypeError exception.
+  Rooted<WritableStreamDefaultWriter*> unwrappedWriter(
+      cx,
+      UnwrapAndTypeCheckThis<WritableStreamDefaultWriter>(cx, args, "abort"));
+  if (!unwrappedWriter) {
+    return ReturnPromiseRejectedWithPendingError(cx, args);
+  }
+
+  // Step 2: If this.[[ownerWritableStream]] is undefined, return a promise
+  //         rejected with a TypeError exception.
+  if (!unwrappedWriter->hasStream()) {
+    JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
+                              JSMSG_WRITABLESTREAMWRITER_NOT_OWNED, "abort");
+    return ReturnPromiseRejectedWithPendingError(cx, args);
+  }
+
+  // Step 3: Return ! WritableStreamDefaultWriterAbort(this, reason).
+  JSObject* promise =
+      WritableStreamDefaultWriterAbort(cx, unwrappedWriter, args.get(0));
+  if (!promise) {
+    return false;
+  }
+  cx->check(promise);
+
+  args.rval().setObject(*promise);
+  return true;
+}
+
+/**
  * Streams spec, 4.5.4.5. close()
  */
 static MOZ_MUST_USE bool WritableStream_close(JSContext* cx, unsigned argc,
                                               Value* vp) {
   CallArgs args = CallArgsFromVp(argc, vp);
 
   // Step 1: If ! IsWritableStreamDefaultWriter(this) is false, return a promise
   //         rejected with a TypeError exception.
@@ -284,14 +320,15 @@ static MOZ_MUST_USE bool WritableStream_
 }
 
 static const JSPropertySpec WritableStreamDefaultWriter_properties[] = {
     JS_PSG("closed", WritableStream_closed, 0),
     JS_PSG("desiredSize", WritableStream_desiredSize, 0),
     JS_PSG("ready", WritableStream_ready, 0), JS_PS_END};
 
 static const JSFunctionSpec WritableStreamDefaultWriter_methods[] = {
+    JS_FN("abort", WritableStream_abort, 1, 0),
     JS_FN("close", WritableStream_close, 0, 0),
     JS_FN("releaseLock", WritableStream_releaseLock, 0, 0),
     JS_FN("write", WritableStream_write, 1, 0), JS_FS_END};
 
 JS_STREAMS_CLASS_SPEC(WritableStreamDefaultWriter, 0, SlotCount,
                       ClassSpec::DontDefineConstructor, 0, JS_NULL_CLASS_OPS);
--- a/js/src/builtin/streams/WritableStreamWriterOperations.cpp
+++ b/js/src/builtin/streams/WritableStreamWriterOperations.cpp
@@ -15,17 +15,17 @@
 #include "jsfriendapi.h"  // js::GetErrorMessage, JSMSG_*
 
 #include "builtin/Promise.h"                          // js::PromiseObject
 #include "builtin/streams/MiscellaneousOperations.h"  // js::PromiseRejectedWithPendingError
 #include "builtin/streams/WritableStream.h"  // js::WritableStream
 #include "builtin/streams/WritableStreamDefaultController.h"  // js::WritableStream::controller
 #include "builtin/streams/WritableStreamDefaultControllerOperations.h"  // js::WritableStreamDefaultController{Close,GetDesiredSize}
 #include "builtin/streams/WritableStreamDefaultWriter.h"  // js::WritableStreamDefaultWriter
-#include "builtin/streams/WritableStreamOperations.h"  // js::WritableStreamCloseQueuedOrInFlight
+#include "builtin/streams/WritableStreamOperations.h"  // js::WritableStream{Abort,CloseQueuedOrInFlight}
 #include "js/Value.h"  // JS::Value, JS::{Int32,Null}Value
 #include "vm/Compartment.h"  // JS::Compartment
 #include "vm/JSContext.h"    // JSContext
 
 #include "builtin/streams/MiscellaneousOperations-inl.h"  // js::ResolveUnwrappedPromiseWithUndefined
 #include "builtin/streams/WritableStream-inl.h"  // js::WritableStream::setCloseRequest
 #include "builtin/streams/WritableStreamDefaultWriter-inl.h"  // js::UnwrapStreamFromWriter
 #include "vm/Compartment-inl.h"  // js::UnwrapAndTypeCheckThis
@@ -40,16 +40,38 @@ using JS::NumberValue;
 using JS::Rooted;
 using JS::Value;
 
 using js::PromiseObject;
 
 /*** 4.6. Writable stream writer abstract operations ************************/
 
 /**
+ * Streams spec, 4.6.2.
+ * WritableStreamDefaultWriterAbort ( writer, reason )
+ */
+JSObject* js::WritableStreamDefaultWriterAbort(
+    JSContext* cx, Handle<WritableStreamDefaultWriter*> unwrappedWriter,
+    Handle<Value> reason) {
+  cx->check(reason);
+
+  // Step 1: Let stream be writer.[[ownerWritableStream]].
+  // Step 2: Assert: stream is not undefined.
+  MOZ_ASSERT(unwrappedWriter->hasStream());
+  Rooted<WritableStream*> unwrappedStream(
+      cx, UnwrapStreamFromWriter(cx, unwrappedWriter));
+  if (!unwrappedStream) {
+    return nullptr;
+  }
+
+  // Step 3: Return ! WritableStreamAbort(stream, reason).
+  return WritableStreamAbort(cx, unwrappedStream, reason);
+}
+
+/**
  * Streams spec, 4.6.3.
  * WritableStreamDefaultWriterClose ( writer )
  */
 JSObject* js::WritableStreamDefaultWriterClose(
     JSContext* cx, Handle<WritableStreamDefaultWriter*> unwrappedWriter) {
   // Step 1: Let stream be writer.[[ownerWritableStream]].
   // Step 2: Assert: stream is not undefined.
   MOZ_ASSERT(unwrappedWriter->hasStream());
--- a/js/src/builtin/streams/WritableStreamWriterOperations.h
+++ b/js/src/builtin/streams/WritableStreamWriterOperations.h
@@ -16,16 +16,20 @@
 
 struct JS_PUBLIC_API JSContext;
 class JS_PUBLIC_API JSObject;
 
 namespace js {
 
 class WritableStreamDefaultWriter;
 
+extern JSObject* WritableStreamDefaultWriterAbort(
+    JSContext* cx, JS::Handle<WritableStreamDefaultWriter*> unwrappedWriter,
+    JS::Handle<JS::Value> reason);
+
 extern JSObject* WritableStreamDefaultWriterClose(
     JSContext* cx, JS::Handle<WritableStreamDefaultWriter*> unwrappedWriter);
 
 extern MOZ_MUST_USE bool WritableStreamDefaultWriterEnsureClosedPromiseRejected(
     JSContext* cx, JS::Handle<WritableStreamDefaultWriter*> unwrappedWriter,
     JS::Handle<JS::Value> error);
 
 extern MOZ_MUST_USE bool WritableStreamDefaultWriterEnsureReadyPromiseRejected(