diff --git a/js/src/builtin/TypedObject.cpp b/js/src/builtin/TypedObject.cpp index 9d3bb3dd4b8d..7151fa3b5d64 100644 --- a/js/src/builtin/TypedObject.cpp +++ b/js/src/builtin/TypedObject.cpp @@ -1478,11 +1478,11 @@ TypedObject::createUnattachedWithClass(JSContext *cx, if (!obj) return nullptr; - obj->setPrivate(nullptr); - obj->initReservedSlot(JS_TYPEDOBJ_SLOT_BYTEOFFSET, Int32Value(0)); - obj->initReservedSlot(JS_TYPEDOBJ_SLOT_LENGTH, Int32Value(length)); - obj->initReservedSlot(JS_TYPEDOBJ_SLOT_OWNER, NullValue()); - obj->initReservedSlot(JS_TYPEDOBJ_SLOT_NEXT_VIEW, PrivateValue(nullptr)); + obj->initPrivate(nullptr); + obj->initReservedSlot(JS_BUFVIEW_SLOT_BYTEOFFSET, Int32Value(0)); + obj->initReservedSlot(JS_BUFVIEW_SLOT_LENGTH, Int32Value(length)); + obj->initReservedSlot(JS_BUFVIEW_SLOT_OWNER, NullValue()); + obj->initReservedSlot(JS_BUFVIEW_SLOT_NEXT_VIEW, PrivateValue(nullptr)); obj->initReservedSlot(JS_TYPEDOBJ_SLOT_TYPE_DESCR, ObjectValue(*type)); // Tag the type object for this instance with the type @@ -1506,8 +1506,8 @@ TypedObject::attach(ArrayBufferObject &buffer, int32_t offset) buffer.addView(this); InitArrayBufferViewDataPointer(this, &buffer, offset); - setReservedSlot(JS_TYPEDOBJ_SLOT_BYTEOFFSET, Int32Value(offset)); - setReservedSlot(JS_TYPEDOBJ_SLOT_OWNER, ObjectValue(buffer)); + setReservedSlot(JS_BUFVIEW_SLOT_BYTEOFFSET, Int32Value(offset)); + setReservedSlot(JS_BUFVIEW_SLOT_OWNER, ObjectValue(buffer)); } void @@ -2216,27 +2216,35 @@ TypedObject::obj_enumerate(JSContext *cx, HandleObject obj, JSIterateOp enum_op, /* static */ size_t TypedObject::offsetOfOwnerSlot() { - return JSObject::getFixedSlotOffset(JS_TYPEDOBJ_SLOT_OWNER); + return JSObject::getFixedSlotOffset(JS_BUFVIEW_SLOT_OWNER); } /* static */ size_t TypedObject::offsetOfDataSlot() { - // the offset of 7 is based on the alloc kind +# ifdef DEBUG + // Compute offset of private data based on TransparentTypedObject; + // both OpaqueTypedObject and TransparentTypedObject have the same + // number of slots, so no problem there. + gc::AllocKind allocKind = gc::GetGCObjectKind(&TransparentTypedObject::class_); + size_t nfixed = gc::GetGCKindSlots(allocKind); + JS_ASSERT(JS_TYPEDOBJ_SLOT_DATA == nfixed - 1); +# endif + return JSObject::getPrivateDataOffset(JS_TYPEDOBJ_SLOT_DATA); } /* static */ size_t TypedObject::offsetOfByteOffsetSlot() { - return JSObject::getFixedSlotOffset(JS_TYPEDOBJ_SLOT_BYTEOFFSET); + return JSObject::getFixedSlotOffset(JS_BUFVIEW_SLOT_BYTEOFFSET); } void TypedObject::neuter(void *newData) { - setSlot(JS_TYPEDOBJ_SLOT_LENGTH, Int32Value(0)); - setSlot(JS_TYPEDOBJ_SLOT_BYTEOFFSET, Int32Value(0)); + setSlot(JS_BUFVIEW_SLOT_LENGTH, Int32Value(0)); + setSlot(JS_BUFVIEW_SLOT_BYTEOFFSET, Int32Value(0)); setPrivate(newData); } @@ -2721,7 +2729,7 @@ js::SetTypedObjectOffset(ThreadSafeContext *, unsigned argc, Value *vp) JS_ASSERT(typedObj.typedMem() != nullptr); // must be attached already typedObj.setPrivate(typedObj.owner().dataPointer() + offset); - typedObj.setReservedSlot(JS_TYPEDOBJ_SLOT_BYTEOFFSET, Int32Value(offset)); + typedObj.setReservedSlot(JS_BUFVIEW_SLOT_BYTEOFFSET, Int32Value(offset)); args.rval().setUndefined(); return true; } diff --git a/js/src/builtin/TypedObject.h b/js/src/builtin/TypedObject.h index 837d737ea300..d4cffa24467d 100644 --- a/js/src/builtin/TypedObject.h +++ b/js/src/builtin/TypedObject.h @@ -648,11 +648,11 @@ class TypedObject : public ArrayBufferViewObject void neuter(void *newData); int32_t offset() const { - return getReservedSlot(JS_TYPEDOBJ_SLOT_BYTEOFFSET).toInt32(); + return getReservedSlot(JS_BUFVIEW_SLOT_BYTEOFFSET).toInt32(); } ArrayBufferObject &owner() const { - return getReservedSlot(JS_TYPEDOBJ_SLOT_OWNER).toObject().as(); + return getReservedSlot(JS_BUFVIEW_SLOT_OWNER).toObject().as(); } TypeDescr &typeDescr() const { @@ -664,7 +664,7 @@ class TypedObject : public ArrayBufferViewObject } int32_t length() const { - return getReservedSlot(JS_TYPEDOBJ_SLOT_LENGTH).toInt32(); + return getReservedSlot(JS_BUFVIEW_SLOT_LENGTH).toInt32(); } int32_t size() const { diff --git a/js/src/builtin/TypedObject.js b/js/src/builtin/TypedObject.js index 3dee0c1bb626..1763c9bc2818 100644 --- a/js/src/builtin/TypedObject.js +++ b/js/src/builtin/TypedObject.js @@ -31,13 +31,13 @@ // Typed object slots #define TYPEDOBJ_BYTEOFFSET(obj) \ - TO_INT32(UnsafeGetReservedSlot(obj, JS_TYPEDOBJ_SLOT_BYTEOFFSET)) + TO_INT32(UnsafeGetReservedSlot(obj, JS_BUFVIEW_SLOT_BYTEOFFSET)) #define TYPEDOBJ_TYPE_DESCR(obj) \ UnsafeGetReservedSlot(obj, JS_TYPEDOBJ_SLOT_TYPE_DESCR) #define TYPEDOBJ_OWNER(obj) \ - UnsafeGetReservedSlot(obj, JS_TYPEDOBJ_SLOT_OWNER) + UnsafeGetReservedSlot(obj, JS_BUFVIEW_SLOT_OWNER) #define TYPEDOBJ_LENGTH(obj) \ - TO_INT32(UnsafeGetReservedSlot(obj, JS_TYPEDOBJ_SLOT_LENGTH)) + TO_INT32(UnsafeGetReservedSlot(obj, JS_BUFVIEW_SLOT_LENGTH)) #define HAS_PROPERTY(obj, prop) \ callFunction(std_Object_hasOwnProperty, obj, prop) diff --git a/js/src/builtin/TypedObjectConstants.h b/js/src/builtin/TypedObjectConstants.h index 4115e0ab6d63..4bb1da0d55a7 100644 --- a/js/src/builtin/TypedObjectConstants.h +++ b/js/src/builtin/TypedObjectConstants.h @@ -91,21 +91,37 @@ /////////////////////////////////////////////////////////////////////////// // Slots for typed objects -#define JS_TYPEDOBJ_SLOT_BYTEOFFSET 0 -#define JS_TYPEDOBJ_SLOT_LENGTH 1 // Length of array (see (*) below) -#define JS_TYPEDOBJ_SLOT_OWNER 2 -#define JS_TYPEDOBJ_SLOT_NEXT_VIEW 3 -#define JS_DATAVIEW_SLOTS 4 // Number of slots for data views +// Common to data view, typed arrays, and typed objects: +#define JS_BUFVIEW_SLOT_BYTEOFFSET 0 +#define JS_BUFVIEW_SLOT_LENGTH 1 // see (*) below +#define JS_BUFVIEW_SLOT_OWNER 2 +#define JS_BUFVIEW_SLOT_NEXT_VIEW 3 -#define JS_TYPEDOBJ_SLOT_TYPE_DESCR 4 // For typed objects, type descr +// Specific to data view: +#define JS_DATAVIEW_SLOT_DATA 7 // see (**) below +#define JS_DATAVIEW_SLOTS 4 // Number of slots for data views -#define JS_TYPEDOBJ_SLOT_DATA 7 // private slot, based on alloc kind -#define JS_TYPEDOBJ_SLOTS 5 // Number of slots for typed objs +// Specific to typed arrays: +#define JS_TYPEDARR_SLOT_TYPE 4 // A ScalarTypeDescr::Type constant +#define JS_TYPEDARR_SLOT_DATA 7 // see (**) below +#define JS_TYPEDARR_SLOTS 5 // Number of slots for typed arrays -// (*) The JS_TYPEDOBJ_SLOT_LENGTH slot stores the length for typed objects of -// sized and unsized array type. The slot contains 0 for non-arrays. -// The slot also contains 0 for *unattached* typed objects, no matter what -// type they have. +// Specific to typed objects: +#define JS_TYPEDOBJ_SLOT_TYPE_DESCR 4 // A ScalarTypeDescr::Type constant +#define JS_TYPEDOBJ_SLOT_DATA 7 +#define JS_TYPEDOBJ_SLOTS 5 // Number of slots for typed objs + +// (*) The interpretation of the JS_BUFVIEW_SLOT_LENGTH slot depends on +// the kind of view: +// - DataView: stores the length in bytes +// - TypedArray: stores the array length +// - TypedObject: for arrays, stores the array length, else 0 + +// (**) This is the index of the slot that will be used for private data. +// It is hardcoded here based on the GC Kind that will be assigned. It is +// a function of the total number of slots, but it is non-trivial to encode +// that function at compile-time, so we instead use a hardcoded constant +// coupled with some handy assertions. #endif diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index b2f5c774b1ff..2f78b5b131e6 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -6844,7 +6844,7 @@ IonBuilder::checkTypedObjectIndexInBounds(int32_t elemSize, // then we still need to check if the object was neutered. *canBeNeutered = true; } else { - MInstruction *lengthValue = MLoadFixedSlot::New(alloc(), obj, JS_TYPEDOBJ_SLOT_LENGTH); + MInstruction *lengthValue = MLoadFixedSlot::New(alloc(), obj, JS_BUFVIEW_SLOT_LENGTH); current->add(lengthValue); MInstruction *length32 = MTruncateToInt32::New(alloc(), lengthValue); diff --git a/js/src/vm/ArrayBufferObject.h b/js/src/vm/ArrayBufferObject.h index 90e3d7414803..e1a1ac438cc4 100644 --- a/js/src/vm/ArrayBufferObject.h +++ b/js/src/vm/ArrayBufferObject.h @@ -237,16 +237,16 @@ class ArrayBufferViewObject : public JSObject { protected: /* Offset of view in underlying ArrayBufferObject */ - static const size_t BYTEOFFSET_SLOT = JS_TYPEDOBJ_SLOT_BYTEOFFSET; + static const size_t BYTEOFFSET_SLOT = JS_BUFVIEW_SLOT_BYTEOFFSET; /* Byte length of view */ - static const size_t LENGTH_SLOT = JS_TYPEDOBJ_SLOT_LENGTH; + static const size_t LENGTH_SLOT = JS_BUFVIEW_SLOT_LENGTH; /* Underlying ArrayBufferObject */ - static const size_t BUFFER_SLOT = JS_TYPEDOBJ_SLOT_OWNER; + static const size_t BUFFER_SLOT = JS_BUFVIEW_SLOT_OWNER; /* ArrayBufferObjects point to a linked list of views, chained through this slot */ - static const size_t NEXT_VIEW_SLOT = JS_TYPEDOBJ_SLOT_NEXT_VIEW; + static const size_t NEXT_VIEW_SLOT = JS_BUFVIEW_SLOT_NEXT_VIEW; public: static ArrayBufferObject *bufferObject(JSContext *cx, Handle obj); diff --git a/js/src/vm/TypedArrayObject.h b/js/src/vm/TypedArrayObject.h index bf395f40dc8c..7c452b0d6aac 100644 --- a/js/src/vm/TypedArrayObject.h +++ b/js/src/vm/TypedArrayObject.h @@ -31,10 +31,9 @@ class TypedArrayObject : public ArrayBufferViewObject protected: // Typed array properties stored in slots, beyond those shared by all // ArrayBufferViews. - static const size_t LENGTH_SLOT = JS_TYPEDOBJ_SLOT_LENGTH; - static const size_t TYPE_SLOT = JS_TYPEDOBJ_SLOT_TYPE_DESCR; - static const size_t RESERVED_SLOTS = JS_TYPEDOBJ_SLOTS; - static const size_t DATA_SLOT = JS_TYPEDOBJ_SLOT_DATA; + static const size_t TYPE_SLOT = JS_TYPEDARR_SLOT_TYPE; + static const size_t RESERVED_SLOTS = JS_TYPEDARR_SLOTS; + static const size_t DATA_SLOT = JS_TYPEDARR_SLOT_DATA; static_assert(js::detail::TypedArrayLengthSlot == LENGTH_SLOT, "bad inlined constant in jsfriendapi.h"); @@ -222,7 +221,7 @@ TypedArrayShift(ArrayBufferView::ViewType viewType) class DataViewObject : public ArrayBufferViewObject { static const size_t RESERVED_SLOTS = JS_DATAVIEW_SLOTS; - static const size_t DATA_SLOT = JS_TYPEDOBJ_SLOT_DATA; + static const size_t DATA_SLOT = JS_DATAVIEW_SLOT_DATA; private: static const Class protoClass;