Bug 966575 part 03 -- Extend Type Descr to include all data from type repr r=sfink

This commit is contained in:
Nicholas D. Matsakis 2014-01-27 19:49:36 -05:00
parent 89a94ef82e
commit af656b7f6b
7 changed files with 124 additions and 81 deletions

View File

@ -99,7 +99,7 @@ extern const JSFunctionSpec Int32x4Methods[];
const Class X4TypeDescr::class_ = { const Class X4TypeDescr::class_ = {
"X4", "X4",
JSCLASS_HAS_RESERVED_SLOTS(JS_TYPEOBJ_X4_SLOTS), JSCLASS_HAS_RESERVED_SLOTS(JS_DESCR_SLOTS),
JS_PropertyStub, /* addProperty */ JS_PropertyStub, /* addProperty */
JS_DeletePropertyStub, /* delProperty */ JS_DeletePropertyStub, /* delProperty */
JS_PropertyStub, /* getProperty */ JS_PropertyStub, /* getProperty */
@ -201,16 +201,14 @@ CreateX4Class(JSContext *cx, Handle<GlobalObject*> global)
if (!proto) if (!proto)
return nullptr; return nullptr;
// Create type constructor itself. // Create type constructor itself and initialize its reserved slots.
Rooted<X4TypeDescr*> x4(cx); Rooted<X4TypeDescr*> x4(cx);
x4 = NewObjectWithProto<X4TypeDescr>(cx, funcProto, global); x4 = NewObjectWithProto<X4TypeDescr>(cx, funcProto, global);
if (!x4 || !InitializeCommonTypeDescriptorProperties(cx, x4, typeReprObj)) if (!x4 || !InitializeCommonTypeDescriptorProperties(cx, x4, typeReprObj))
return nullptr; return nullptr;
x4->initReservedSlot(JS_DESCR_SLOT_TYPE_REPR, ObjectValue(*typeReprObj));
// Link type constructor to the type representation. x4->initReservedSlot(JS_DESCR_SLOT_TYPE, Int32Value(T::type));
x4->initReservedSlot(JS_TYPEOBJ_SLOT_TYPE_REPR, ObjectValue(*typeReprObj));
// Link constructor to prototype and install properties. // Link constructor to prototype and install properties.

View File

@ -186,7 +186,7 @@ GetPrototype(JSContext *cx, HandleObject obj)
const Class js::ScalarTypeDescr::class_ = { const Class js::ScalarTypeDescr::class_ = {
"Scalar", "Scalar",
JSCLASS_HAS_RESERVED_SLOTS(JS_TYPEOBJ_SCALAR_SLOTS), JSCLASS_HAS_RESERVED_SLOTS(JS_DESCR_SLOTS),
JS_PropertyStub, /* addProperty */ JS_PropertyStub, /* addProperty */
JS_DeletePropertyStub, /* delProperty */ JS_DeletePropertyStub, /* delProperty */
JS_PropertyStub, /* getProperty */ JS_PropertyStub, /* getProperty */
@ -257,7 +257,7 @@ ScalarTypeDescr::call(JSContext *cx, unsigned argc, Value *vp)
const Class js::ReferenceTypeDescr::class_ = { const Class js::ReferenceTypeDescr::class_ = {
"Reference", "Reference",
JSCLASS_HAS_RESERVED_SLOTS(JS_TYPEOBJ_REFERENCE_SLOTS), JSCLASS_HAS_RESERVED_SLOTS(JS_DESCR_SLOTS),
JS_PropertyStub, /* addProperty */ JS_PropertyStub, /* addProperty */
JS_DeletePropertyStub, /* delProperty */ JS_DeletePropertyStub, /* delProperty */
JS_PropertyStub, /* getProperty */ JS_PropertyStub, /* getProperty */
@ -375,7 +375,7 @@ CreatePrototypeObjectForComplexTypeInstance(JSContext *cx,
const Class UnsizedArrayTypeDescr::class_ = { const Class UnsizedArrayTypeDescr::class_ = {
"ArrayType", "ArrayType",
JSCLASS_HAS_RESERVED_SLOTS(JS_TYPEOBJ_ARRAY_SLOTS), JSCLASS_HAS_RESERVED_SLOTS(JS_DESCR_SLOTS),
JS_PropertyStub, JS_PropertyStub,
JS_DeletePropertyStub, JS_DeletePropertyStub,
JS_PropertyStub, JS_PropertyStub,
@ -392,7 +392,7 @@ const Class UnsizedArrayTypeDescr::class_ = {
const Class SizedArrayTypeDescr::class_ = { const Class SizedArrayTypeDescr::class_ = {
"ArrayType", "ArrayType",
JSCLASS_HAS_RESERVED_SLOTS(JS_TYPEOBJ_ARRAY_SLOTS), JSCLASS_HAS_RESERVED_SLOTS(JS_DESCR_SLOTS),
JS_PropertyStub, JS_PropertyStub,
JS_DeletePropertyStub, JS_DeletePropertyStub,
JS_PropertyStub, JS_PropertyStub,
@ -450,6 +450,17 @@ js::InitializeCommonTypeDescriptorProperties(JSContext *cx,
TypeRepresentation *typeRepr = TypeRepresentation *typeRepr =
TypeRepresentation::fromOwnerObject(*typeReprOwnerObj); TypeRepresentation::fromOwnerObject(*typeReprOwnerObj);
// Regardless of whether the data is transparent, we always
// store the internal size/alignment slots.
if (typeRepr->isSized()) {
SizedTypeRepresentation *sizedTypeRepr = typeRepr->asSized();
obj->initReservedSlot(JS_DESCR_SLOT_SIZE,
Int32Value(sizedTypeRepr->size()));
obj->initReservedSlot(JS_DESCR_SLOT_ALIGNMENT,
Int32Value(sizedTypeRepr->alignment()));
}
// If data is transparent, also store the public slots.
if (typeRepr->transparent() && typeRepr->isSized()) { if (typeRepr->transparent() && typeRepr->isSized()) {
SizedTypeRepresentation *sizedTypeRepr = typeRepr->asSized(); SizedTypeRepresentation *sizedTypeRepr = typeRepr->asSized();
@ -518,7 +529,7 @@ ArrayMetaTypeDescr::create(JSContext *cx,
Rooted<T*> obj(cx, NewObjectWithProto<T>(cx, arrayTypePrototype, nullptr)); Rooted<T*> obj(cx, NewObjectWithProto<T>(cx, arrayTypePrototype, nullptr));
if (!obj) if (!obj)
return nullptr; return nullptr;
obj->initReservedSlot(JS_TYPEOBJ_SLOT_TYPE_REPR, obj->initReservedSlot(JS_DESCR_SLOT_TYPE_REPR,
ObjectValue(*arrayTypeReprObj)); ObjectValue(*arrayTypeReprObj));
RootedValue elementTypeVal(cx, ObjectValue(*elementType)); RootedValue elementTypeVal(cx, ObjectValue(*elementType));
@ -527,7 +538,7 @@ ArrayMetaTypeDescr::create(JSContext *cx,
JSPROP_READONLY | JSPROP_PERMANENT)) JSPROP_READONLY | JSPROP_PERMANENT))
return nullptr; return nullptr;
obj->initReservedSlot(JS_TYPEOBJ_SLOT_ARRAY_ELEM_TYPE, elementTypeVal); obj->initReservedSlot(JS_DESCR_SLOT_ARRAY_ELEM_TYPE, elementTypeVal);
if (!InitializeCommonTypeDescriptorProperties(cx, obj, arrayTypeReprObj)) if (!InitializeCommonTypeDescriptorProperties(cx, obj, arrayTypeReprObj))
return nullptr; return nullptr;
@ -634,7 +645,7 @@ UnsizedArrayTypeDescr::dimension(JSContext *cx, unsigned int argc, jsval *vp)
// Create the sized type object. // Create the sized type object.
Rooted<SizedTypeDescr*> elementType(cx, &unsizedTypeDescr->elementType()); Rooted<SizedTypeDescr*> elementType(cx, &unsizedTypeDescr->elementType());
RootedObject obj(cx); Rooted<SizedArrayTypeDescr*> obj(cx);
obj = ArrayMetaTypeDescr::create<SizedArrayTypeDescr>( obj = ArrayMetaTypeDescr::create<SizedArrayTypeDescr>(
cx, unsizedTypeDescr, sizedTypeReprObj, elementType); cx, unsizedTypeDescr, sizedTypeReprObj, elementType);
if (!obj) if (!obj)
@ -665,7 +676,7 @@ UnsizedArrayTypeDescr::dimension(JSContext *cx, unsigned int argc, jsval *vp)
const Class StructTypeDescr::class_ = { const Class StructTypeDescr::class_ = {
"StructType", "StructType",
JSCLASS_HAS_RESERVED_SLOTS(JS_TYPEOBJ_STRUCT_SLOTS) | JSCLASS_HAS_RESERVED_SLOTS(JS_DESCR_SLOTS) |
JSCLASS_HAS_PRIVATE, // used to store FieldList JSCLASS_HAS_PRIVATE, // used to store FieldList
JS_PropertyStub, JS_PropertyStub,
JS_DeletePropertyStub, JS_DeletePropertyStub,
@ -765,7 +776,7 @@ StructMetaTypeDescr::layout(JSContext *cx,
return false; return false;
StructTypeRepresentation *typeRepr = StructTypeRepresentation *typeRepr =
TypeRepresentation::fromOwnerObject(*typeReprObj)->asStruct(); TypeRepresentation::fromOwnerObject(*typeReprObj)->asStruct();
structType->initReservedSlot(JS_TYPEOBJ_SLOT_TYPE_REPR, structType->initReservedSlot(JS_DESCR_SLOT_TYPE_REPR,
ObjectValue(*typeReprObj)); ObjectValue(*typeReprObj));
// Construct for internal use an array with the type object for each field. // Construct for internal use an array with the type object for each field.
@ -775,7 +786,7 @@ StructMetaTypeDescr::layout(JSContext *cx,
if (!fieldTypeVec) if (!fieldTypeVec)
return false; return false;
structType->initReservedSlot(JS_TYPEOBJ_SLOT_STRUCT_FIELD_TYPES, structType->initReservedSlot(JS_DESCR_SLOT_STRUCT_FIELD_TYPES,
ObjectValue(*fieldTypeVec)); ObjectValue(*fieldTypeVec));
// Construct the fieldNames vector // Construct the fieldNames vector
@ -966,12 +977,14 @@ DefineSimpleTypeDescr(JSContext *cx,
if (!typeReprObj) if (!typeReprObj)
return false; return false;
numFun->initReservedSlot(JS_TYPEOBJ_SLOT_TYPE_REPR, numFun->initReservedSlot(JS_DESCR_SLOT_TYPE_REPR,
ObjectValue(*typeReprObj)); ObjectValue(*typeReprObj));
if (!InitializeCommonTypeDescriptorProperties(cx, numFun, typeReprObj)) if (!InitializeCommonTypeDescriptorProperties(cx, numFun, typeReprObj))
return false; return false;
numFun->initReservedSlot(JS_DESCR_SLOT_TYPE, Int32Value(type));
if (!JS_DefineFunctions(cx, numFun, T::typeObjectMethods)) if (!JS_DefineFunctions(cx, numFun, T::typeObjectMethods))
return false; return false;
@ -1603,7 +1616,7 @@ StructFieldType(JSContext *cx,
// In this scenario, line1.start.type() === Point1 and // In this scenario, line1.start.type() === Point1 and
// line2.start.type() === Point2. // line2.start.type() === Point2.
RootedObject fieldTypes( RootedObject fieldTypes(
cx, &type->getReservedSlot(JS_TYPEOBJ_SLOT_STRUCT_FIELD_TYPES).toObject()); cx, &type->getReservedSlot(JS_DESCR_SLOT_STRUCT_FIELD_TYPES).toObject());
RootedValue fieldTypeVal(cx); RootedValue fieldTypeVal(cx);
if (!JSObject::getElement(cx, fieldTypes, fieldTypes, if (!JSObject::getElement(cx, fieldTypes, fieldTypes,
fieldIndex, &fieldTypeVal)) fieldIndex, &fieldTypeVal))

View File

@ -143,7 +143,7 @@ class TypeDescr : public JSObject
{ {
public: public:
JSObject &typeRepresentationOwnerObj() const { JSObject &typeRepresentationOwnerObj() const {
return getReservedSlot(JS_TYPEOBJ_SLOT_TYPE_REPR).toObject(); return getReservedSlot(JS_DESCR_SLOT_TYPE_REPR).toObject();
} }
TypeRepresentation *typeRepresentation() const { TypeRepresentation *typeRepresentation() const {
@ -274,7 +274,7 @@ class UnsizedArrayTypeDescr : public TypeDescr
static bool dimension(JSContext *cx, unsigned int argc, jsval *vp); static bool dimension(JSContext *cx, unsigned int argc, jsval *vp);
SizedTypeDescr &elementType() { SizedTypeDescr &elementType() {
return getReservedSlot(JS_TYPEOBJ_SLOT_ARRAY_ELEM_TYPE).toObject().as<SizedTypeDescr>(); return getReservedSlot(JS_DESCR_SLOT_ARRAY_ELEM_TYPE).toObject().as<SizedTypeDescr>();
} }
}; };
@ -287,7 +287,7 @@ class SizedArrayTypeDescr : public SizedTypeDescr
static const Class class_; static const Class class_;
SizedTypeDescr &elementType() { SizedTypeDescr &elementType() {
return getReservedSlot(JS_TYPEOBJ_SLOT_ARRAY_ELEM_TYPE).toObject().as<SizedTypeDescr>(); return getReservedSlot(JS_DESCR_SLOT_ARRAY_ELEM_TYPE).toObject().as<SizedTypeDescr>();
} }
}; };

View File

@ -17,15 +17,13 @@
// Type object slots // Type object slots
#define DESCR_TYPE_REPR(obj) \ #define DESCR_TYPE_REPR(obj) \
UnsafeGetReservedSlot(obj, JS_TYPEOBJ_SLOT_TYPE_REPR) UnsafeGetReservedSlot(obj, JS_DESCR_SLOT_TYPE_REPR)
#define DESCR_KIND(obj) \ #define DESCR_KIND(obj) \
REPR_KIND(DESCR_TYPE_REPR(obj)) REPR_KIND(DESCR_TYPE_REPR(obj))
#define DESCR_SIZE(obj) \ #define DESCR_SIZE(obj) \
REPR_SIZE(DESCR_TYPE_REPR(obj)) UnsafeGetReservedSlot(obj, JS_DESCR_SLOT_SIZE)
#define DESCR_LENGTH(obj) \
REPR_LENGTH(DESCR_TYPE_REPR(obj))
#define DESCR_TYPE(obj) \ #define DESCR_TYPE(obj) \
REPR_TYPE(DESCR_TYPE_REPR(obj)) UnsafeGetReservedSlot(obj, JS_DESCR_SLOT_TYPE)
// Typed object slots // Typed object slots
@ -118,7 +116,7 @@ function DescrToSource(descr) {
var result = ".array"; var result = ".array";
var sep = "("; var sep = "(";
while (DESCR_KIND(descr) == JS_TYPEREPR_SIZED_ARRAY_KIND) { while (DESCR_KIND(descr) == JS_TYPEREPR_SIZED_ARRAY_KIND) {
result += sep + DESCR_LENGTH(descr); result += sep + descr.length;
descr = descr.elementType; descr = descr.elementType;
sep = ", "; sep = ", ";
} }
@ -149,6 +147,10 @@ function DescrToSource(descr) {
// code. // code.
function TypedObjectPointer(descr, datum, offset) { function TypedObjectPointer(descr, datum, offset) {
assert(IsObject(descr) && ObjectIsTypeDescr(descr), "Not descr");
assert(IsObject(datum) && ObjectIsTypedDatum(datum), "Not datum");
assert(TO_INT32(offset) === offset, "offset not int");
this.descr = descr; this.descr = descr;
this.datum = datum; this.datum = datum;
this.offset = offset; this.offset = offset;
@ -181,16 +183,18 @@ TypedObjectPointer.prototype.kind = function() {
return DESCR_KIND(this.descr); return DESCR_KIND(this.descr);
} }
// Extract the length. This does a switch on kind, so it's
// best if we can avoid it.
TypedObjectPointer.prototype.length = function() { TypedObjectPointer.prototype.length = function() {
switch (this.kind()) { switch (this.kind()) {
case JS_TYPEREPR_SIZED_ARRAY_KIND: case JS_TYPEREPR_SIZED_ARRAY_KIND:
return DESCR_LENGTH(this.descr); return this.descr.length;
case JS_TYPEREPR_UNSIZED_ARRAY_KIND: case JS_TYPEREPR_UNSIZED_ARRAY_KIND:
return DATUM_LENGTH(this.datum); return this.datum.length;
} }
assert(false, "length() invoked on non-array-type"); assert(false, "Invalid kind for length");
return 0; return false;
} }
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
@ -209,15 +213,10 @@ TypedObjectPointer.prototype.moveTo = function(propName) {
break; break;
case JS_TYPEREPR_SIZED_ARRAY_KIND: case JS_TYPEREPR_SIZED_ARRAY_KIND:
return this.moveToArray(propName, this.descr.length);
case JS_TYPEREPR_UNSIZED_ARRAY_KIND: case JS_TYPEREPR_UNSIZED_ARRAY_KIND:
// For an array, property must be an element. Note that we use the return this.moveToArray(propName, this.datum.length);
// length as loaded from the type *representation* as opposed to
// the type *object*; this is because some type objects represent
// unsized arrays and hence do not have a length.
var index = TO_INT32(propName);
if (index === propName && index >= 0 && index < this.length())
return this.moveToElem(index);
break;
case JS_TYPEREPR_STRUCT_KIND: case JS_TYPEREPR_STRUCT_KIND:
if (HAS_PROPERTY(this.descr.fieldTypes, propName)) if (HAS_PROPERTY(this.descr.fieldTypes, propName))
@ -229,6 +228,20 @@ TypedObjectPointer.prototype.moveTo = function(propName) {
return undefined; return undefined;
}; };
TypedObjectPointer.prototype.moveToArray = function(propName, length) {
// For an array, property must be an element. Note that we take
// the length as an argument rather than loading it from the descriptor.
// This is because this same helper is used for *unsized arrays*, where
// the length is drawn from the datum, and *sized arrays*, where the
// length is drawn from the type.
var index = TO_INT32(propName);
if (index === propName && index >= 0 && index < length)
return this.moveToElem(index);
ThrowError(JSMSG_TYPEDOBJECT_NO_SUCH_PROP, propName);
return undefined;
}
// Adjust `this` in place to point at the element `index`. `this` // Adjust `this` in place to point at the element `index`. `this`
// must be a array type and `index` must be within bounds. Returns // must be a array type and `index` must be within bounds. Returns
// `this`. // `this`.
@ -239,7 +252,7 @@ TypedObjectPointer.prototype.moveToElem = function(index) {
assert(TO_INT32(index) === index, assert(TO_INT32(index) === index,
"moveToElem invoked with non-integer index"); "moveToElem invoked with non-integer index");
assert(index >= 0 && index < this.length(), assert(index >= 0 && index < this.length(),
"moveToElem invoked with out-of-bounds index: " + index); "moveToElem invoked with negative index: " + index);
var elementDescr = this.descr.elementType; var elementDescr = this.descr.elementType;
this.descr = elementDescr; this.descr = elementDescr;
@ -261,12 +274,21 @@ TypedObjectPointer.prototype.moveToField = function(propName) {
assert(HAS_PROPERTY(this.descr.fieldTypes, propName), assert(HAS_PROPERTY(this.descr.fieldTypes, propName),
"moveToField invoked with undefined field"); "moveToField invoked with undefined field");
// FIXME(Bug 966575) -- the fieldOffsets array that we are using
// below is only available on transparent types. This is fixed
// in part 6 of this patch series.
var fieldDescr = this.descr.fieldTypes[propName]; var fieldDescr = this.descr.fieldTypes[propName];
var fieldOffset = TO_INT32(this.descr.fieldOffsets[propName]); var fieldOffset = TO_INT32(this.descr.fieldOffsets[propName]);
this.descr = fieldDescr;
// Note: we do not allow construction of structs where the assert(IsObject(fieldDescr) && ObjectIsTypeDescr(fieldDescr),
// offset of a field cannot be represented by an int32. "bad field descr");
assert(TO_INT32(fieldOffset) === fieldOffset,
"bad field offset");
assert(fieldOffset >= 0 && fieldOffset < DESCR_SIZE(this.descr),
"out of bounds field offset");
this.descr = fieldDescr;
this.offset += fieldOffset; this.offset += fieldOffset;
return this; return this;
@ -423,25 +445,14 @@ TypedObjectPointer.prototype.set = function(fromValue) {
return; return;
case JS_TYPEREPR_SIZED_ARRAY_KIND: case JS_TYPEREPR_SIZED_ARRAY_KIND:
if (this.setArray(fromValue, this.descr.length))
return;
break;
case JS_TYPEREPR_UNSIZED_ARRAY_KIND: case JS_TYPEREPR_UNSIZED_ARRAY_KIND:
if (!IsObject(fromValue)) if (this.setArray(fromValue, this.datum.length))
break; return;
break;
// Check that "array-like" fromValue has an appropriate length.
var length = this.length();
if (fromValue.length !== length)
break;
// Adapt each element.
if (length > 0) {
var tempPtr = this.copy().moveToElem(0);
var size = DESCR_SIZE(tempPtr.descr);
for (var i = 0; i < length; i++) {
tempPtr.set(fromValue[i]);
tempPtr.offset += size;
}
}
return;
case JS_TYPEREPR_STRUCT_KIND: case JS_TYPEREPR_STRUCT_KIND:
if (!IsObject(fromValue)) if (!IsObject(fromValue))
@ -462,6 +473,27 @@ TypedObjectPointer.prototype.set = function(fromValue) {
DescrToSource(this.descr)); DescrToSource(this.descr));
} }
TypedObjectPointer.prototype.setArray = function(fromValue, length) {
if (!IsObject(fromValue))
return false;
// Check that "array-like" fromValue has an appropriate length.
if (fromValue.length !== length)
return false;
// Adapt each element.
if (length > 0) {
var tempPtr = this.copy().moveToElem(0);
var size = DESCR_SIZE(tempPtr.descr);
for (var i = 0; i < length; i++) {
tempPtr.set(fromValue[i]);
tempPtr.offset += size;
}
}
return true;
}
// Sets `fromValue` to `this` assuming that `this` is a scalar type. // Sets `fromValue` to `this` assuming that `this` is a scalar type.
TypedObjectPointer.prototype.setScalar = function(fromValue) { TypedObjectPointer.prototype.setScalar = function(fromValue) {
assert(this.kind() == JS_TYPEREPR_SCALAR_KIND, assert(this.kind() == JS_TYPEREPR_SCALAR_KIND,
@ -582,7 +614,7 @@ function FillTypedArrayWithValue(destArray, fromValue) {
"FillTypedArrayWithValue: not typed handle"); "FillTypedArrayWithValue: not typed handle");
var descr = DATUM_TYPE_DESCR(destArray); var descr = DATUM_TYPE_DESCR(destArray);
var length = DESCR_LENGTH(descr); var length = descr.length;
if (length === 0) if (length === 0)
return; return;

View File

@ -13,29 +13,26 @@
// Slots for type objects // Slots for type objects
// //
// Some slots apply to all type objects and some are specific to // Some slots apply to all type objects and some are specific to
// particular kinds of type objects. Because all type objects, at // particular kinds of type objects. For simplicity we use the same
// least for now, have a distinct class, we can assign them distinct // number of slots no matter what kind of type descriptor we are
// numbers of slots depending on their kind. // working with, even though this is mildly wasteful.
// Slots on all type objects // Slots on all type objects
#define JS_TYPEOBJ_SLOT_TYPE_REPR 0 // Associated Type Representation #define JS_DESCR_SLOT_TYPE_REPR 0 // Associated Type Representation
#define JS_DESCR_SLOT_SIZE 1 // Size in bytes, if sized
#define JS_DESCR_SLOT_ALIGNMENT 2 // Alignment in bytes, if sized
// Slots on scalars // Slots on scalars, references, and x4s
#define JS_TYPEOBJ_SCALAR_SLOTS 1 // Maximum number #define JS_DESCR_SLOT_TYPE 3 // Type code
// Slots on references // Slots on all array descriptors
#define JS_TYPEOBJ_REFERENCE_SLOTS 1 // Maximum number #define JS_DESCR_SLOT_ARRAY_ELEM_TYPE 3
// Slots on x4s // Slots on struct type objects
#define JS_TYPEOBJ_X4_SLOTS 1 // Maximum number #define JS_DESCR_SLOT_STRUCT_FIELD_TYPES 3
// Slots on array type objects // Maximum number of slots for any descriptor
#define JS_TYPEOBJ_SLOT_ARRAY_ELEM_TYPE 1 #define JS_DESCR_SLOTS 4
#define JS_TYPEOBJ_ARRAY_SLOTS 3 // Maximum number
// Slots on structs
#define JS_TYPEOBJ_SLOT_STRUCT_FIELD_TYPES 1
#define JS_TYPEOBJ_STRUCT_SLOTS 2 // Maximum number
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Slots for type representation objects // Slots for type representation objects

View File

@ -9994,7 +9994,7 @@ IonBuilder::lookupTypedObjectField(MDefinition *typedObj,
MDefinition * MDefinition *
IonBuilder::typeObjectForElementFromArrayStructType(MDefinition *typeObj) IonBuilder::typeObjectForElementFromArrayStructType(MDefinition *typeObj)
{ {
MInstruction *elemType = MLoadFixedSlot::New(alloc(), typeObj, JS_TYPEOBJ_SLOT_ARRAY_ELEM_TYPE); MInstruction *elemType = MLoadFixedSlot::New(alloc(), typeObj, JS_DESCR_SLOT_ARRAY_ELEM_TYPE);
current->add(elemType); current->add(elemType);
MInstruction *unboxElemType = MUnbox::New(alloc(), elemType, MIRType_Object, MUnbox::Infallible); MInstruction *unboxElemType = MUnbox::New(alloc(), elemType, MIRType_Object, MUnbox::Infallible);
@ -10009,7 +10009,7 @@ IonBuilder::typeObjectForFieldFromStructType(MDefinition *typeObj,
{ {
// Load list of field type objects. // Load list of field type objects.
MInstruction *fieldTypes = MLoadFixedSlot::New(alloc(), typeObj, JS_TYPEOBJ_SLOT_STRUCT_FIELD_TYPES); MInstruction *fieldTypes = MLoadFixedSlot::New(alloc(), typeObj, JS_DESCR_SLOT_STRUCT_FIELD_TYPES);
current->add(fieldTypes); current->add(fieldTypes);
MInstruction *unboxFieldTypes = MUnbox::New(alloc(), fieldTypes, MIRType_Object, MUnbox::Infallible); MInstruction *unboxFieldTypes = MUnbox::New(alloc(), fieldTypes, MIRType_Object, MUnbox::Infallible);

View File

@ -14,6 +14,7 @@ function runTests() {
print(BUGNUMBER + ": " + summary); print(BUGNUMBER + ": " + summary);
(function SimpleArrayOfTwoObjects() { (function SimpleArrayOfTwoObjects() {
print("SimpleArrayOfTwoObjects");
var Objects = new ArrayType(ObjectType); var Objects = new ArrayType(ObjectType);
var objects2 = new Objects(2, [{f: "Hello"}, var objects2 = new Objects(2, [{f: "Hello"},
{f: "World"}]); {f: "World"}]);
@ -23,12 +24,14 @@ function runTests() {
})(); })();
(function EmbedUnsizedArraysBad() { (function EmbedUnsizedArraysBad() {
print("EmbedUnsizedArraysBad");
var Objects = new ArrayType(ObjectType); var Objects = new ArrayType(ObjectType);
assertThrows(() => new ArrayType(Objects)); assertThrows(() => new ArrayType(Objects));
assertThrows(() => new StructType({f: Objects})); assertThrows(() => new StructType({f: Objects}));
})(); })();
(function MultipleSizes() { (function MultipleSizes() {
print("MultipleSizes");
var Uints = new ArrayType(uint32); var Uints = new ArrayType(uint32);
var Point = new StructType({values: new ArrayType(uint32).dimension(3)}); var Point = new StructType({values: new ArrayType(uint32).dimension(3)});