bool ArrayPushDense(JSContext *cx, HandleObject obj, HandleValue v, uint32_t *length) { JS_ASSERT(obj->is<ArrayObject>()); if (MOZ_LIKELY(obj->as<ArrayObject>().lengthIsWritable())) { uint32_t idx = obj->as<ArrayObject>().length(); JSObject::EnsureDenseResult result = obj->ensureDenseElements(cx, idx, 1); if (result == JSObject::ED_FAILED) return false; if (result == JSObject::ED_OK) { obj->setDenseElement(idx, v); MOZ_ASSERT(idx < INT32_MAX); *length = idx + 1; obj->as<ArrayObject>().setLengthInt32(*length); return true; } } JS::AutoValueArray<3> argv(cx); argv[0].setUndefined(); argv[1].setObject(*obj); argv[2].set(v); if (!js::array_push(cx, 1, argv.begin())) return false; *length = argv[0].toInt32(); return true; }
bool SetDenseElement(JSContext *cx, HandleObject obj, int32_t index, HandleValue value, bool strict) { // This function is called from Ion code for StoreElementHole's OOL path. // In this case we know the object is native, has no indexed properties // and we can use setDenseElement instead of setDenseElementWithType. MOZ_ASSERT(obj->isNative()); MOZ_ASSERT(!obj->isIndexed()); JSObject::EnsureDenseResult result = JSObject::ED_SPARSE; do { if (index < 0) break; bool isArray = obj->is<ArrayObject>(); if (isArray && !obj->as<ArrayObject>().lengthIsWritable()) break; uint32_t idx = uint32_t(index); result = obj->ensureDenseElements(cx, idx, 1); if (result != JSObject::ED_OK) break; if (isArray) { ArrayObject &arr = obj->as<ArrayObject>(); if (idx >= arr.length()) arr.setLengthInt32(idx + 1); } obj->setDenseElement(idx, value); return true; } while (false); if (result == JSObject::ED_FAILED) return false; MOZ_ASSERT(result == JSObject::ED_SPARSE); RootedValue indexVal(cx, Int32Value(index)); return SetObjectElement(cx, obj, indexVal, value, strict); }