Original challenge Gecko-dev commit: be1b849fa2645d5be11f2a80315837ef6a88c469, although patch was modified to be applicable to latest SpiderMonkey version as of the time this writeup was written (JavaScript-C90.0a1). Challenge is available over 0vercl0k's repository here
If we check the patch, we see the following:
--- a/js/src/builtin/Array.cpp 2021-05-19 08:43:50.526955220 -0700
+++ b/js/src/builtin/Array.cpp 2021-05-19 08:59:36.383191816 -0700
@@ -151,6 +151,16 @@
return ToLength(cx, value, lengthp);
}
+static MOZ_ALWAYS_INLINE bool BlazeSetLengthProperty(JSContext* cx, HandleObject obj, uint64_t* lengthp) {
+ if (obj->is<ArrayObject>()) {
+ obj->as<ArrayObject>().setLength(length);
+ obj->as<ArrayObject>().setCapacityInt32(length);
+ obj->as<ArrayObject>().setInitializedLengthInt32(length);
+ return true;
+ }
+ return false;
+}
+
// Fast path for array functions where the object is expected to be an array.
static MOZ_ALWAYS_INLINE bool GetLengthPropertyInlined(JSContext* cx,
HandleObject obj,
@@ -1503,6 +1513,22 @@
return DenseElementResult::Success;
}
+ bool js::array_blaze(JSContext* cx, unsigned argc, Value* vp) {
+ CallArgs args = CallArgsFromVp(argc, vp);
+ RootedObject obj(cx, ToObject(cx, args.thisv()));
+ if (!obj)
+ return false;
+
+ if (!BlazeSetLengthProperty(cx, obj, 420))
+ return false;
+
+ //uint64_t l = obj.as<ArrayObject>().setLength(cx, 420);
+
+ args.rval().setObject(*obj);
+ return true;
+}
+
+
auto setElementMaybeHole = [](JSContext* cx, HandleNativeObject obj,
uint32_t index, const Value& val) {
if (MOZ_LIKELY(!val.isMagic(JS_ELEMENTS_HOLE))) {
@@ -3582,6 +3608,7 @@
JS_INLINABLE_FN("shift", array_shift, 0, 0, ArrayShift),
JS_FN("unshift", array_unshift, 1, 0),
JS_FNINFO("splice", array_splice, &array_splice_info, 2, 0),
+ JS_FN("blaze", array_blaze, 0,0),
/* Pythonic sequence methods. */
JS_SELF_HOSTED_FN("concat", "ArrayConcat", 1, 0),
@@ -4237,3 +4264,6 @@
return SetLengthProperty(cx, obj, length);
}
+
+
+
--- a/js/src/builtin/Array.h 2021-05-19 08:43:50.526955220 -0700
+++ b/js/src/builtin/Array.h 2021-05-19 09:01:56.870722172 -0700
@@ -81,7 +81,7 @@
HandleShape shape);
extern bool ToLength(JSContext* cx, HandleValue v, uint64_t* out);
-
+extern bool array_blaze(JSContext* cx, unsigned argc, js::Value* vp);
extern bool GetLengthProperty(JSContext* cx, HandleObject obj,
uint64_t* lengthp);
--- a/js/src/vm/ArrayObject.h 2021-05-19 08:43:53.422928009 -0700
+++ b/js/src/vm/ArrayObject.h 2021-05-19 09:04:07.373414299 -0700
@@ -40,6 +40,14 @@
!denseElementsAreFrozen());
getElementsHeader()->length = length;
}
+
+ void setCapacityInt32(uint32_t length) {
+ getElementsHeader()->capacity = length;
+ }
+
+ void setInitializedLengthInt32(uint32_t length) {
+ getElementsHeader()->initializedLength = length;
+ }
// Make an array object with the specified initial state.
static inline ArrayObject* createArray(JSContext* cx, gc::AllocKind kind,
@@ -59,6 +67,7 @@
ArrayObject* obj, HandleShape shape, AutoSetNewObjectMetadata& metadata);
};
+
} // namespace js
#endif // vm_ArrayObject_hBasically ArrayObjects have a property called blaze, that extends the dimensions of the Array to 420.