From eeab147fc2959fe855ccefeec7acdc252aad4678 Mon Sep 17 00:00:00 2001 From: Tomasz Andrzejak Date: Mon, 23 Dec 2024 21:12:33 +0100 Subject: [PATCH] Add File::create function --- builtins/web/blob.cpp | 4 ++++ builtins/web/blob.h | 2 +- builtins/web/file.cpp | 43 +++++++++++++++++++++++++++++-------------- builtins/web/file.h | 1 + 4 files changed, 35 insertions(+), 15 deletions(-) diff --git a/builtins/web/blob.cpp b/builtins/web/blob.cpp index c760b4a..aa5b35a 100644 --- a/builtins/web/blob.cpp +++ b/builtins/web/blob.cpp @@ -677,6 +677,8 @@ JSObject *Blob::create(JSContext *cx, UniqueChars data, size_t data_len, HandleS SetReservedSlot(self, static_cast(Slots::Type), JS::StringValue(type)); SetReservedSlot(self, static_cast(Slots::Endings), JS::Int32Value(LineEndings::Transparent)); SetReservedSlot(self, static_cast(Slots::Readers), JS::PrivateValue(new ReadersMap)); + SetReservedSlot(self, static_cast(Slots::Reserved1), JS::NullValue()); + SetReservedSlot(self, static_cast(Slots::Reserved2), JS::NullValue()); return self; } @@ -695,6 +697,8 @@ bool Blob::constructor(JSContext *cx, unsigned argc, JS::Value *vp) { SetReservedSlot(self, static_cast(Slots::Endings), JS::Int32Value(LineEndings::Transparent)); SetReservedSlot(self, static_cast(Slots::Data), JS::PrivateValue(new ByteBuffer)); SetReservedSlot(self, static_cast(Slots::Readers), JS::PrivateValue(new ReadersMap)); + SetReservedSlot(self, static_cast(Slots::Reserved1), JS::NullValue()); + SetReservedSlot(self, static_cast(Slots::Reserved2), JS::NullValue()); // Walk the blob parts and append them to the blob's buffer. if (blobParts.isNull()) { diff --git a/builtins/web/blob.h b/builtins/web/blob.h index 857b789..27c3694 100644 --- a/builtins/web/blob.h +++ b/builtins/web/blob.h @@ -51,7 +51,7 @@ class Blob : public TraceableBuiltinImpl { static const JSPropertySpec properties[]; static constexpr unsigned ctor_length = 0; - enum Slots { Data, Type, Endings, Readers, Reserved2, Reserved1, Count }; + enum Slots { Data, Type, Endings, Readers, Reserved1, Reserved2, Count }; enum LineEndings { Transparent, Native }; using HeapObj = Heap; diff --git a/builtins/web/file.cpp b/builtins/web/file.cpp index 435c085..0b36b36 100644 --- a/builtins/web/file.cpp +++ b/builtins/web/file.cpp @@ -102,26 +102,26 @@ bool File::lastModified_get(JSContext *cx, unsigned argc, JS::Value *vp) { } bool File::is_instance(const JSObject *obj) { - return obj != nullptr && (JS::GetClass(obj) == &class_ || JS::GetClass(obj) == &Blob::class_); + return obj != nullptr + && JS::GetClass(obj) == &Blob::class_ + && !JS::GetReservedSlot( + (JSObject *)obj, + static_cast(ParentSlots::Name)).isNullOrUndefined(); } -bool File::is_instance(const Value val) { return val.isObject() && is_instance(&val.toObject()); } - -bool File::constructor(JSContext *cx, unsigned argc, JS::Value *vp) { - CTOR_HEADER("File", 2); - - RootedValue fileBits(cx, args.get(0)); - RootedValue fileName(cx, args.get(1)); - RootedValue opts(cx, args.get(2)); +bool File::is_instance(const Value val) { + return val.isObject() && is_instance(&val.toObject()); +} +JSObject *File::create(JSContext *cx, HandleValue fileBits, HandleValue fileName, HandleValue opts) { RootedObject blob_ctor(cx, JS_GetConstructor(cx, Blob::proto_obj)); if (!blob_ctor) { - return false; + return nullptr; } RootedObject this_ctor(cx, JS_GetConstructor(cx, File::proto_obj)); if (!this_ctor) { - return false; + return nullptr; } MOZ_ASSERT(JS::IsConstructor(blob_ctor)); @@ -138,13 +138,13 @@ bool File::constructor(JSContext *cx, unsigned argc, JS::Value *vp) { RootedValue blob_ctor_val(cx, JS::ObjectValue(*blob_ctor)); RootedObject self(cx); if (!JS::Construct(cx, blob_ctor_val, this_ctor, blob_args, &self)) { - return false; + return nullptr; } // 2. Let n be the fileName argument to the constructor. RootedString name(cx, JS::ToString(cx, fileName)); if (!name) { - return false; + return nullptr; } // 3. Process `FilePropertyBag` dictionary argument by running the following substeps: @@ -154,7 +154,7 @@ bool File::constructor(JSContext *cx, unsigned argc, JS::Value *vp) { // milliseconds since the Unix Epoch. RootedValue lastModified(cx); if (!init_last_modified(cx, opts, &lastModified)) { - return false; + return nullptr; } // Return a new File object F such that: @@ -169,6 +169,21 @@ bool File::constructor(JSContext *cx, unsigned argc, JS::Value *vp) { SetReservedSlot(self, static_cast(ParentSlots::Name), JS::StringValue(name)); SetReservedSlot(self, static_cast(ParentSlots::LastModified), lastModified); + return self; +} + +bool File::constructor(JSContext *cx, unsigned argc, JS::Value *vp) { + CTOR_HEADER("File", 2); + + RootedValue fileBits(cx, args.get(0)); + RootedValue fileName(cx, args.get(1)); + RootedValue opts(cx, args.get(2)); + + RootedObject self(cx, create(cx, fileBits, fileName, opts)); + if (!self) { + return false; + } + args.rval().setObject(*self); return true; } diff --git a/builtins/web/file.h b/builtins/web/file.h index a3aaf08..05e7216 100644 --- a/builtins/web/file.h +++ b/builtins/web/file.h @@ -24,6 +24,7 @@ class File : public BuiltinImpl { static bool is_instance(const JSObject *obj); static bool is_instance(const Value val); + static JSObject *create(JSContext *cx, HandleValue fileBits, HandleValue fileName, HandleValue opts); static bool init_class(JSContext *cx, HandleObject global); static bool constructor(JSContext *cx, unsigned argc, Value *vp); };