From e0eee318c6bc14d8b6f107cdb2726941881ae311 Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Sat, 14 Dec 2019 10:35:26 -0500 Subject: Bug 1390082 - Implement AsyncGeneratorQueue with simpler array operations. Tag #1287 Note: Without ReadableStream implementation --- js/src/vm/AsyncIteration.cpp | 62 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 52 insertions(+), 10 deletions(-) diff --git a/js/src/vm/AsyncIteration.cpp b/js/src/vm/AsyncIteration.cpp index 256f247b0..300179374 100644 --- a/js/src/vm/AsyncIteration.cpp +++ b/js/src/vm/AsyncIteration.cpp @@ -315,6 +315,53 @@ AsyncGeneratorObject::create(JSContext* cx, HandleFunction asyncGen, HandleValue return asyncGenObj; } +static MOZ_MUST_USE bool +InternalEnqueue(JSContext* cx, HandleArrayObject queue, HandleValue val) +{ + uint32_t length; + if (!GetLengthProperty(cx, queue, &length)) + return false; + + if (length >= MAX_ARRAY_INDEX) { + ReportOutOfMemory(cx); + return false; + } + + if (!DefineElement(cx, queue, length, val)) + return false; + return SetLengthProperty(cx, queue, length + 1); +} + +static MOZ_MUST_USE bool +InternalDequeue(JSContext* cx, HandleArrayObject queue, MutableHandleValue val) +{ + uint32_t length; + if (!GetLengthProperty(cx, queue, &length)) + return false; + + MOZ_ASSERT(length != 0, "Queue should not be empty here"); + + if (!GetElement(cx, queue, queue, 0, val)) + return false; + + uint32_t newlength = length - 1; + RootedValue tmp(cx); + for (uint32_t i = 0; i < newlength; i++) { + if (!GetElement(cx, queue, queue, i + 1, &tmp)) + return false; + if (!DefineElement(cx, queue, i, tmp)) + return false; + } + ObjectOpResult result; + if (!DeleteElement(cx, queue, newlength, result)) + return false; + if (!result) { + RootedId id(cx, INT_TO_JSID(newlength)); + return result.reportError(cx, queue, id); + } + return SetLengthProperty(cx, queue, newlength); +} + /* static */ MOZ_MUST_USE bool AsyncGeneratorObject::enqueueRequest(JSContext* cx, Handle asyncGenObj, Handle request) @@ -339,11 +386,8 @@ AsyncGeneratorObject::enqueueRequest(JSContext* cx, Handlequeue()); - - FixedInvokeArgs<1> args(cx); - args[0].setObject(*request); - args.setThis(ObjectValue(*queue)); - return CallJSNative(cx, array_push, args); + RootedValue requestVal(cx, ObjectValue(*request)); + return InternalEnqueue(cx, queue, requestVal); } /* static */ AsyncGeneratorRequest* @@ -356,13 +400,11 @@ AsyncGeneratorObject::dequeueRequest(JSContext* cx, Handlequeue()); - - FixedInvokeArgs<0> args(cx); - args.setThis(ObjectValue(*queue)); - if (!CallJSNative(cx, array_shift, args)) + RootedValue requestVal(cx); + if (!InternalDequeue(cx, queue, &requestVal)) return nullptr; - return &args.rval().toObject().as(); + return &requestVal.toObject().as(); } /* static */ AsyncGeneratorRequest* -- cgit v1.2.3