Bug 938728 - Add float32x4 and int32x4 data constructors r=till

This commit is contained in:
Nicholas D. Matsakis 2013-11-20 15:11:45 -05:00
parent 4f0894ce81
commit f99c3f2826
21 changed files with 1035 additions and 59 deletions

View File

@ -62,6 +62,9 @@ TypeRepresentationHasher::match(TypeRepresentation *key1,
case TypeRepresentation::Reference:
return matchReferences(key1->asReference(), key2->asReference());
case TypeRepresentation::X4:
return matchX4s(key1->asX4(), key2->asX4());
case TypeRepresentation::Struct:
return matchStructs(key1->asStruct(), key2->asStruct());
@ -86,6 +89,13 @@ TypeRepresentationHasher::matchReferences(ReferenceTypeRepresentation *key1,
return key1->type() == key2->type();
}
bool
TypeRepresentationHasher::matchX4s(X4TypeRepresentation *key1,
X4TypeRepresentation *key2)
{
return key1->type() == key2->type();
}
bool
TypeRepresentationHasher::matchStructs(StructTypeRepresentation *key1,
StructTypeRepresentation *key2)
@ -122,6 +132,9 @@ TypeRepresentationHasher::hash(TypeRepresentation *key) {
case TypeRepresentation::Reference:
return hashReference(key->asReference());
case TypeRepresentation::X4:
return hashX4(key->asX4());
case TypeRepresentation::Struct:
return hashStruct(key->asStruct());
@ -144,6 +157,12 @@ TypeRepresentationHasher::hashReference(ReferenceTypeRepresentation *key)
return HashGeneric(key->kind(), key->type());
}
HashNumber
TypeRepresentationHasher::hashX4(X4TypeRepresentation *key)
{
return HashGeneric(key->kind(), key->type());
}
HashNumber
TypeRepresentationHasher::hashStruct(StructTypeRepresentation *key)
{
@ -172,32 +191,30 @@ TypeRepresentation::TypeRepresentation(Kind kind, size_t size,
opaque_(opaque)
{}
static size_t ScalarSizes[] = {
#define SCALAR_SIZE(_kind, _type, _name) \
sizeof(_type),
JS_FOR_EACH_SCALAR_TYPE_REPR(SCALAR_SIZE) 0
#undef SCALAR_SIZE
};
ScalarTypeRepresentation::ScalarTypeRepresentation(Type type)
: TypeRepresentation(Scalar, 0, 1, false),
: TypeRepresentation(Scalar, ScalarSizes[type], ScalarSizes[type], false),
type_(type)
{
switch (type) {
case TYPE_INT8:
case TYPE_UINT8:
case TYPE_UINT8_CLAMPED:
size_ = alignment_ = 1;
break;
}
case TYPE_INT16:
case TYPE_UINT16:
size_ = alignment_ = 2;
break;
static size_t X4Sizes[] = {
#define X4_SIZE(_kind, _type, _name) \
sizeof(_type) * 4,
JS_FOR_EACH_X4_TYPE_REPR(X4_SIZE) 0
#undef X4_SIZE
};
case TYPE_INT32:
case TYPE_UINT32:
case TYPE_FLOAT32:
size_ = alignment_ = 4;
break;
case TYPE_FLOAT64:
size_ = alignment_ = 8;
break;
}
X4TypeRepresentation::X4TypeRepresentation(Type type)
: TypeRepresentation(X4, X4Sizes[type], X4Sizes[type], false),
type_(type)
{
}
ReferenceTypeRepresentation::ReferenceTypeRepresentation(Type type)
@ -358,6 +375,11 @@ TypeRepresentation::addToTableOrFree(JSContext *cx,
Int32Value(asReference()->type()));
break;
case X4:
ownerObject->initReservedSlot(JS_TYPEREPR_SLOT_TYPE,
Int32Value(asX4()->type()));
break;
case Struct:
break;
}
@ -366,27 +388,43 @@ TypeRepresentation::addToTableOrFree(JSContext *cx,
return &*ownerObject;
}
namespace js {
class TypeRepresentationHelper {
public:
template<typename T>
static JSObject *CreateSimple(JSContext *cx, typename T::Type type) {
JSCompartment *comp = cx->compartment();
T sample(type);
TypeRepresentationHash::AddPtr p = comp->typeReprs.lookupForAdd(&sample);
if (p)
return (*p)->ownerObject();
// Note: cannot use cx->new_ because constructor is private.
T *ptr = (T *) cx->malloc_(sizeof(T));
if (!ptr)
return nullptr;
new(ptr) T(type);
return ptr->addToTableOrFree(cx, p);
}
};
} // namespace js
/*static*/
JSObject *
ScalarTypeRepresentation::Create(JSContext *cx,
ScalarTypeRepresentation::Type type)
{
JSCompartment *comp = cx->compartment();
return TypeRepresentationHelper::CreateSimple<ScalarTypeRepresentation>(cx, type);
}
ScalarTypeRepresentation sample(type);
TypeRepresentationHash::AddPtr p = comp->typeReprs.lookupForAdd(&sample);
if (p)
return (*p)->ownerObject();
// Note: cannot use cx->new_ because constructor is private.
ScalarTypeRepresentation *ptr =
(ScalarTypeRepresentation *) cx->malloc_(
sizeof(ScalarTypeRepresentation));
if (!ptr)
return nullptr;
new(ptr) ScalarTypeRepresentation(type);
return ptr->addToTableOrFree(cx, p);
/*static*/
JSObject *
X4TypeRepresentation::Create(JSContext *cx,
X4TypeRepresentation::Type type)
{
return TypeRepresentationHelper::CreateSimple<X4TypeRepresentation>(cx, type);
}
/*static*/
@ -499,6 +537,7 @@ TypeRepresentation::traceFields(JSTracer *trace)
switch (kind()) {
case Scalar:
case Reference:
case X4:
break;
case Struct:
@ -552,6 +591,9 @@ TypeRepresentation::appendString(JSContext *cx, StringBuffer &contents)
case Reference:
return asReference()->appendStringReference(cx, contents);
case X4:
return asX4()->appendStringX4(cx, contents);
case Array:
return asArray()->appendStringArray(cx, contents);
@ -607,6 +649,18 @@ ReferenceTypeRepresentation::appendStringReference(JSContext *cx, StringBuffer &
MOZ_ASSUME_UNREACHABLE("Invalid type");
}
bool
X4TypeRepresentation::appendStringX4(JSContext *cx, StringBuffer &contents)
{
switch (type()) {
case TYPE_FLOAT32:
return contents.append("float32x4");
case TYPE_INT32:
return contents.append("int32x4");
}
MOZ_ASSUME_UNREACHABLE("Invalid type");
}
bool
ArrayTypeRepresentation::appendStringArray(JSContext *cx, StringBuffer &contents)
{
@ -672,6 +726,7 @@ visitReferences(TypeRepresentation *repr, uint8_t *mem, V& visitor)
switch (repr->kind()) {
case TypeRepresentation::Scalar:
case TypeRepresentation::X4:
return;
case TypeRepresentation::Reference:

View File

@ -68,6 +68,7 @@ namespace js {
class TypeRepresentation;
class ScalarTypeRepresentation;
class ReferenceTypeRepresentation;
class X4TypeRepresentation;
class ArrayTypeRepresentation;
class StructTypeRepresentation;
@ -83,6 +84,7 @@ struct TypeRepresentationHasher
private:
static HashNumber hashScalar(ScalarTypeRepresentation *key);
static HashNumber hashReference(ReferenceTypeRepresentation *key);
static HashNumber hashX4(X4TypeRepresentation *key);
static HashNumber hashStruct(StructTypeRepresentation *key);
static HashNumber hashArray(ArrayTypeRepresentation *key);
@ -90,6 +92,8 @@ struct TypeRepresentationHasher
ScalarTypeRepresentation *key2);
static bool matchReferences(ReferenceTypeRepresentation *key1,
ReferenceTypeRepresentation *key2);
static bool matchX4s(X4TypeRepresentation *key1,
X4TypeRepresentation *key2);
static bool matchStructs(StructTypeRepresentation *key1,
StructTypeRepresentation *key2);
static bool matchArrays(ArrayTypeRepresentation *key1,
@ -100,11 +104,14 @@ typedef js::HashSet<TypeRepresentation *,
TypeRepresentationHasher,
RuntimeAllocPolicy> TypeRepresentationHash;
class TypeRepresentationHelper;
class TypeRepresentation {
public:
enum Kind {
Scalar = JS_TYPEREPR_SCALAR_KIND,
Reference = JS_TYPEREPR_REFERENCE_KIND,
X4 = JS_TYPEREPR_X4_KIND,
Struct = JS_TYPEREPR_STRUCT_KIND,
Array = JS_TYPEREPR_ARRAY_KIND
};
@ -112,6 +119,9 @@ class TypeRepresentation {
protected:
TypeRepresentation(Kind kind, size_t size, size_t align, bool opaque);
// in order to call addToTableOrFree()
friend class TypeRepresentationHelper;
size_t size_;
size_t alignment_;
Kind kind_;
@ -167,6 +177,15 @@ class TypeRepresentation {
return (ReferenceTypeRepresentation*) this;
}
bool isX4() const {
return kind() == X4;
}
X4TypeRepresentation *asX4() {
JS_ASSERT(isX4());
return (X4TypeRepresentation*) this;
}
bool isArray() const {
return kind() == Array;
}
@ -213,7 +232,10 @@ class ScalarTypeRepresentation : public TypeRepresentation {
// so TypeRepresentation can call appendStringScalar() etc
friend class TypeRepresentation;
Type type_;
// in order to call constructor
friend class TypeRepresentationHelper;
const Type type_;
explicit ScalarTypeRepresentation(Type type);
@ -290,6 +312,40 @@ class ReferenceTypeRepresentation : public TypeRepresentation {
macro_(ReferenceTypeRepresentation::TYPE_OBJECT, HeapPtrObject, Object) \
macro_(ReferenceTypeRepresentation::TYPE_STRING, HeapPtrString, string)
class X4TypeRepresentation : public TypeRepresentation {
public:
enum Type {
TYPE_INT32 = JS_X4TYPEREPR_INT32,
TYPE_FLOAT32 = JS_X4TYPEREPR_FLOAT32,
};
private:
// so TypeRepresentation can call appendStringScalar() etc
friend class TypeRepresentation;
// in order to call constructor
friend class TypeRepresentationHelper;
const Type type_;
explicit X4TypeRepresentation(Type type);
// See TypeRepresentation::appendString()
bool appendStringX4(JSContext *cx, StringBuffer &buffer);
public:
Type type() const {
return type_;
}
static JSObject *Create(JSContext *cx, Type type);
};
// Must be in same order as the enum ScalarTypeRepresentation::Type:
#define JS_FOR_EACH_X4_TYPE_REPR(macro_) \
macro_(X4TypeRepresentation::TYPE_INT32, int32_t, int32) \
macro_(X4TypeRepresentation::TYPE_FLOAT32, float, float32)
class ArrayTypeRepresentation : public TypeRepresentation {
private:
// so TypeRepresentation can call appendStringArray() etc

View File

@ -134,11 +134,25 @@ IsStructTypeObject(JSObject &type)
return type.hasClass(&StructType::class_);
}
static inline bool
IsX4TypeObject(JSObject &type)
{
return type.hasClass(&X4Type::class_);
}
static inline bool
IsComplexTypeObject(JSObject &type)
{
return IsArrayTypeObject(type) || IsStructTypeObject(type);
}
static inline bool
IsTypeObject(JSObject &type)
{
return IsScalarTypeObject(type) || IsArrayTypeObject(type) ||
IsStructTypeObject(type) || IsReferenceTypeObject(type);
return IsScalarTypeObject(type) ||
IsReferenceTypeObject(type) ||
IsX4TypeObject(type) ||
IsComplexTypeObject(type);
}
static inline bool
@ -1270,6 +1284,164 @@ DefineSimpleTypeObject(JSContext *cx,
return true;
}
///////////////////////////////////////////////////////////////////////////
// X4
const Class X4Type::class_ = {
"X4",
JSCLASS_HAS_RESERVED_SLOTS(JS_TYPEOBJ_X4_SLOTS),
JS_PropertyStub,
JS_DeletePropertyStub,
JS_PropertyStub,
JS_StrictPropertyStub,
JS_EnumerateStub,
JS_ResolveStub,
JS_ConvertStub,
nullptr,
nullptr,
call,
nullptr,
nullptr,
nullptr
};
// These classes just exist to group together various properties and so on.
namespace js {
class Int32x4Defn {
public:
static const X4TypeRepresentation::Type type = X4TypeRepresentation::TYPE_INT32;
static const JSPropertySpec TypedObjectProperties[];
static const JSFunctionSpec TypedObjectMethods[];
};
class Float32x4Defn {
public:
static const X4TypeRepresentation::Type type = X4TypeRepresentation::TYPE_FLOAT32;
static const JSPropertySpec TypedObjectProperties[];
static const JSFunctionSpec TypedObjectMethods[];
};
} // namespace js
const JSPropertySpec js::Int32x4Defn::TypedObjectProperties[] = {
JS_SELF_HOSTED_GET("x", "Int32x4Lane0", JSPROP_PERMANENT),
JS_SELF_HOSTED_GET("y", "Int32x4Lane1", JSPROP_PERMANENT),
JS_SELF_HOSTED_GET("z", "Int32x4Lane2", JSPROP_PERMANENT),
JS_SELF_HOSTED_GET("w", "Int32x4Lane3", JSPROP_PERMANENT),
JS_PS_END
};
const JSFunctionSpec js::Int32x4Defn::TypedObjectMethods[] = {
JS_SELF_HOSTED_FN("toSource", "X4ToSource", 0, 0),
JS_FS_END
};
const JSPropertySpec js::Float32x4Defn::TypedObjectProperties[] = {
JS_SELF_HOSTED_GET("x", "Float32x4Lane0", JSPROP_PERMANENT),
JS_SELF_HOSTED_GET("y", "Float32x4Lane1", JSPROP_PERMANENT),
JS_SELF_HOSTED_GET("z", "Float32x4Lane2", JSPROP_PERMANENT),
JS_SELF_HOSTED_GET("w", "Float32x4Lane3", JSPROP_PERMANENT),
JS_PS_END
};
const JSFunctionSpec js::Float32x4Defn::TypedObjectMethods[] = {
JS_SELF_HOSTED_FN("toSource", "X4ToSource", 0, 0),
JS_FS_END
};
template<typename T>
static JSObject *
CreateX4Class(JSContext *cx, Handle<GlobalObject*> global)
{
RootedObject funcProto(cx, global->getOrCreateFunctionPrototype(cx));
if (!funcProto)
return nullptr;
// Create type representation
RootedObject typeReprObj(cx);
typeReprObj = X4TypeRepresentation::Create(cx, T::type);
if (!typeReprObj)
return nullptr;
// Create prototype property, which inherits from Object.prototype
RootedObject objProto(cx, global->getOrCreateObjectPrototype(cx));
if (!objProto)
return nullptr;
RootedObject proto(cx);
proto = NewObjectWithGivenProto(cx, &JSObject::class_, objProto, global, SingletonObject);
if (!proto)
return nullptr;
// Create type constructor itself
RootedObject x4(cx);
x4 = NewObjectWithClassProto(cx, &X4Type::class_, funcProto, global);
if (!x4 ||
!InitializeCommonTypeDescriptorProperties(cx, x4, typeReprObj) ||
!DefinePropertiesAndBrand(cx, proto, nullptr, nullptr))
{
return nullptr;
}
// Link type constructor to the type representation
x4->initReservedSlot(JS_TYPEOBJ_SLOT_TYPE_REPR, ObjectValue(*typeReprObj));
// Link constructor to prototype and install properties
if (!LinkConstructorAndPrototype(cx, x4, proto) ||
!DefinePropertiesAndBrand(cx, proto, T::TypedObjectProperties,
T::TypedObjectMethods))
{
return nullptr;
}
return x4;
}
bool
X4Type::call(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
const uint32_t LANES = 4;
if (args.length() < LANES) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_MORE_ARGS_NEEDED,
args.callee().getClass()->name, "3", "s");
return false;
}
double values[LANES];
for (uint32_t i = 0; i < LANES; i++) {
if (!ToNumber(cx, args[i], &values[i]))
return false;
}
RootedObject typeObj(cx, &args.callee());
RootedObject result(cx, TypedObject::createZeroed(cx, typeObj));
if (!result)
return false;
X4TypeRepresentation *typeRepr = typeRepresentation(*typeObj)->asX4();
switch (typeRepr->type()) {
#define STORE_LANES(_constant, _type, _name) \
case _constant: \
{ \
_type *mem = (_type*) TypedMem(*result); \
for (uint32_t i = 0; i < LANES; i++) { \
mem[i] = values[i]; \
} \
break; \
}
JS_FOR_EACH_X4_TYPE_REPR(STORE_LANES)
#undef STORE_LANES
}
args.rval().setObject(*result);
return true;
}
///////////////////////////////////////////////////////////////////////////
template<typename T>
static JSObject *
DefineMetaTypeObject(JSContext *cx,
@ -1377,6 +1549,38 @@ js_InitTypedObjectClass(JSContext *cx, HandleObject obj)
JS_FOR_EACH_REFERENCE_TYPE_REPR(BINARYDATA_REFERENCE_DEFINE)
#undef BINARYDATA_REFERENCE_DEFINE
// float32x4
RootedObject float32x4Object(cx);
float32x4Object = CreateX4Class<Float32x4Defn>(cx, global);
if (!float32x4Object)
return nullptr;
RootedValue float32x4Value(cx, ObjectValue(*float32x4Object));
if (!JSObject::defineProperty(cx, module, cx->names().float32x4,
float32x4Value,
nullptr, nullptr,
JSPROP_READONLY | JSPROP_PERMANENT))
{
return nullptr;
}
// int32x4
RootedObject int32x4Object(cx);
int32x4Object = CreateX4Class<Int32x4Defn>(cx, global);
if (!int32x4Object)
return nullptr;
RootedValue int32x4Value(cx, ObjectValue(*int32x4Object));
if (!JSObject::defineProperty(cx, module, cx->names().int32x4,
int32x4Value,
nullptr, nullptr,
JSPROP_READONLY | JSPROP_PERMANENT))
{
return nullptr;
}
// ArrayType.
RootedObject arrayType(cx, DefineMetaTypeObject<ArrayType>(cx, global));
@ -1617,7 +1821,7 @@ TypedDatum::obj_finalize(js::FreeOp *op, JSObject *obj)
bool
TypedDatum::obj_lookupGeneric(JSContext *cx, HandleObject obj, HandleId id,
MutableHandleObject objp, MutableHandleShape propp)
MutableHandleObject objp, MutableHandleShape propp)
{
JS_ASSERT(IsTypedDatum(*obj));
@ -1627,6 +1831,7 @@ TypedDatum::obj_lookupGeneric(JSContext *cx, HandleObject obj, HandleId id,
switch (typeRepr->kind()) {
case TypeRepresentation::Scalar:
case TypeRepresentation::Reference:
case TypeRepresentation::X4:
break;
case TypeRepresentation::Array:
@ -1805,6 +2010,9 @@ TypedDatum::obj_getGeneric(JSContext *cx, HandleObject obj, HandleObject receive
case TypeRepresentation::Reference:
break;
case TypeRepresentation::X4:
break;
case TypeRepresentation::Array:
if (JSID_IS_ATOM(id, cx->names().length)) {
vp.setInt32(typeRepr->asArray()->length());
@ -1862,6 +2070,7 @@ TypedDatum::obj_getElementIfPresent(JSContext *cx, HandleObject obj,
switch (typeRepr->kind()) {
case TypeRepresentation::Scalar:
case TypeRepresentation::Reference:
case TypeRepresentation::X4:
case TypeRepresentation::Struct:
break;
@ -1915,6 +2124,9 @@ TypedDatum::obj_setGeneric(JSContext *cx, HandleObject obj, HandleId id,
case TypeRepresentation::Reference:
break;
case ScalarTypeRepresentation::X4:
break;
case ScalarTypeRepresentation::Array:
if (JSID_IS_ATOM(id, cx->names().length)) {
JS_ReportErrorNumber(cx, js_GetErrorMessage,
@ -1958,6 +2170,7 @@ TypedDatum::obj_setElement(JSContext *cx, HandleObject obj, uint32_t index,
switch (typeRepr->kind()) {
case TypeRepresentation::Scalar:
case TypeRepresentation::Reference:
case TypeRepresentation::X4:
case TypeRepresentation::Struct:
break;
@ -1990,7 +2203,7 @@ TypedDatum::obj_setSpecial(JSContext *cx, HandleObject obj,
bool
TypedDatum::obj_getGenericAttributes(JSContext *cx, HandleObject obj,
HandleId id, unsigned *attrsp)
HandleId id, unsigned *attrsp)
{
uint32_t index;
RootedObject type(cx, GetType(*obj));
@ -2001,6 +2214,9 @@ TypedDatum::obj_getGenericAttributes(JSContext *cx, HandleObject obj,
case TypeRepresentation::Reference:
break;
case TypeRepresentation::X4:
break;
case TypeRepresentation::Array:
if (js_IdIsIndex(id, &index)) {
*attrsp = JSPROP_ENUMERATE | JSPROP_PERMANENT;
@ -2039,6 +2255,7 @@ IsOwnId(JSContext *cx, HandleObject obj, HandleId id)
switch (typeRepr->kind()) {
case TypeRepresentation::Scalar:
case TypeRepresentation::Reference:
case TypeRepresentation::X4:
return false;
case TypeRepresentation::Array:
@ -2131,6 +2348,7 @@ TypedDatum::obj_enumerate(JSContext *cx, HandleObject obj, JSIterateOp enum_op,
switch (typeRepr->kind()) {
case TypeRepresentation::Scalar:
case TypeRepresentation::Reference:
case TypeRepresentation::X4:
switch (enum_op) {
case JSENUMERATE_INIT_ALL:
case JSENUMERATE_INIT:

View File

@ -130,6 +130,18 @@ class ReferenceType
static bool call(JSContext *cx, unsigned argc, Value *vp);
};
/*
* Type descriptors `float32x4` and `int32x4`
*/
class X4Type : public JSObject
{
private:
public:
static const Class class_;
static bool call(JSContext *cx, unsigned argc, Value *vp);
};
/*
* Type descriptor created by `new ArrayType(...)`
*/

View File

@ -107,6 +107,7 @@ TypedObjectPointer.prototype.moveTo = function(propName) {
switch (this.kind()) {
case JS_TYPEREPR_SCALAR_KIND:
case JS_TYPEREPR_REFERENCE_KIND:
case JS_TYPEREPR_X4_KIND:
break;
case JS_TYPEREPR_ARRAY_KIND:
@ -188,13 +189,22 @@ TypedObjectPointer.prototype.moveToField = function(propName) {
TypedObjectPointer.prototype.get = function() {
assert(ObjectIsAttached(this.datum), "get() called with unattached datum");
if (REPR_KIND(this.typeRepr) == JS_TYPEREPR_SCALAR_KIND)
switch (REPR_KIND(this.typeRepr)) {
case JS_TYPEREPR_SCALAR_KIND:
return this.getScalar();
if (REPR_KIND(this.typeRepr) == JS_TYPEREPR_REFERENCE_KIND)
case JS_TYPEREPR_REFERENCE_KIND:
return this.getReference();
return NewDerivedTypedDatum(this.typeObj, this.datum, this.offset);
case JS_TYPEREPR_X4_KIND:
return this.getX4();
case JS_TYPEREPR_ARRAY_KIND:
case JS_TYPEREPR_STRUCT_KIND:
return NewDerivedTypedDatum(this.typeObj, this.datum, this.offset);
}
assert(false, "Unhandled kind: " + REPR_KIND(this.typeRepr));
}
TypedObjectPointer.prototype.getScalar = function() {
@ -245,6 +255,27 @@ TypedObjectPointer.prototype.getReference = function() {
assert(false, "Unhandled scalar type: " + type);
}
TypedObjectPointer.prototype.getX4 = function() {
var type = REPR_TYPE(this.typeRepr);
var T = StandardTypeObjectDescriptors();
switch (type) {
case JS_X4TYPEREPR_FLOAT32:
var x = Load_float32(this.datum, this.offset + 0);
var y = Load_float32(this.datum, this.offset + 4);
var z = Load_float32(this.datum, this.offset + 8);
var w = Load_float32(this.datum, this.offset + 12);
return T.float32x4(x, y, z, w);
case JS_X4TYPEREPR_INT32:
var x = Load_int32(this.datum, this.offset + 0);
var y = Load_int32(this.datum, this.offset + 4);
var z = Load_int32(this.datum, this.offset + 8);
var w = Load_int32(this.datum, this.offset + 12);
return T.int32x4(x, y, z, w);
}
assert(false, "Unhandled x4 type: " + type);
}
///////////////////////////////////////////////////////////////////////////
// Setting values
//
@ -281,6 +312,10 @@ TypedObjectPointer.prototype.set = function(fromValue) {
this.setReference(fromValue);
return;
case JS_TYPEREPR_X4_KIND:
this.setX4(fromValue);
return;
case JS_TYPEREPR_ARRAY_KIND:
if (!IsObject(fromValue))
break;
@ -382,6 +417,17 @@ TypedObjectPointer.prototype.setReference = function(fromValue) {
assert(false, "Unhandled scalar type: " + type);
}
// Sets `fromValue` to `this` assuming that `this` is a scalar type.
TypedObjectPointer.prototype.setX4 = function(fromValue) {
// It is only permitted to set a float32x4/int32x4 value from another
// float32x4/int32x4; in that case, the "fast path" that uses memcopy will
// have already matched. So if we get to this point, we're supposed
// to "adapt" fromValue, but there are no legal adaptions.
ThrowError(JSMSG_CANT_CONVERT_TO,
typeof(fromValue),
this.typeRepr.toSource())
}
///////////////////////////////////////////////////////////////////////////
// C++ Wrappers
//
@ -605,6 +651,65 @@ function HandleTest(obj) {
return IsObject(obj) && ObjectIsTypedHandle(obj);
}
///////////////////////////////////////////////////////////////////////////
// X4
function X4ProtoString(type) {
switch (type) {
case JS_X4TYPEREPR_INT32:
return "int32x4";
case JS_X4TYPEREPR_FLOAT32:
return "float32x4";
}
assert(false, "Unhandled type constant");
}
X4LaneStrings = ["x", "y", "z", "w"];
// Generalized handler for the various properties for accessing a
// single lane of an X4 vector value. Note that this is the slow path;
// the fast path will be inlined into ion code.
function X4GetLane(datum, type, lane) {
if (!IsObject(datum) || !ObjectIsTypedDatum(datum))
ThrowError(JSMSG_INCOMPATIBLE_PROTO, X4ProtoString(type),
X4LaneStrings[lane], typeof this);
var repr = DATUM_TYPE_REPR(datum);
if (REPR_KIND(repr) != JS_TYPEREPR_X4_KIND || REPR_TYPE(repr) != type)
ThrowError(JSMSG_INCOMPATIBLE_PROTO, X4ProtoString(type),
X4LaneStrings[lane], typeof this);
switch (type) {
case JS_X4TYPEREPR_INT32:
return Load_int32(datum, lane * 4);
case JS_X4TYPEREPR_FLOAT32:
return Load_float32(datum, lane * 4);
}
assert(false, "Unhandled type constant");
}
function Float32x4Lane0() { return X4GetLane(this, JS_X4TYPEREPR_FLOAT32, 0); }
function Float32x4Lane1() { return X4GetLane(this, JS_X4TYPEREPR_FLOAT32, 1); }
function Float32x4Lane2() { return X4GetLane(this, JS_X4TYPEREPR_FLOAT32, 2); }
function Float32x4Lane3() { return X4GetLane(this, JS_X4TYPEREPR_FLOAT32, 3); }
function Int32x4Lane0() { return X4GetLane(this, JS_X4TYPEREPR_INT32, 0); }
function Int32x4Lane1() { return X4GetLane(this, JS_X4TYPEREPR_INT32, 1); }
function Int32x4Lane2() { return X4GetLane(this, JS_X4TYPEREPR_INT32, 2); }
function Int32x4Lane3() { return X4GetLane(this, JS_X4TYPEREPR_INT32, 3); }
function X4ToSource() {
if (!IsObject(this) || !ObjectIsTypedDatum(this))
ThrowError(JSMSG_INCOMPATIBLE_PROTO, "X4", "toSource", typeof this);
var repr = DATUM_TYPE_REPR(this);
if (REPR_KIND(repr) != JS_TYPEREPR_X4_KIND)
ThrowError(JSMSG_INCOMPATIBLE_PROTO, "X4", "toSource", typeof this);
var type = REPR_TYPE(repr);
return X4ProtoString(type)+"("+this.x+", "+this.y+", "+this.z+", "+this.w+")";
}
///////////////////////////////////////////////////////////////////////////
// Miscellaneous

View File

@ -26,6 +26,9 @@
// Slots on references
#define JS_TYPEOBJ_REFERENCE_SLOTS 1 // Maximum number
// Slots on x4s
#define JS_TYPEOBJ_X4_SLOTS 1 // Maximum number
// Slots on arrays
#define JS_TYPEOBJ_SLOT_ARRAY_ELEM_TYPE 1
#define JS_TYPEOBJ_ARRAY_SLOTS 2 // Maximum number
@ -34,7 +37,6 @@
#define JS_TYPEOBJ_SLOT_STRUCT_FIELD_TYPES 1
#define JS_TYPEOBJ_STRUCT_SLOTS 2 // Maximum number
///////////////////////////////////////////////////////////////////////////
// Slots for type representation objects
//
@ -52,7 +54,7 @@
// Slots on arrays:
#define JS_TYPEREPR_SLOT_LENGTH 3 // Length of the array
// Slots on scalars and references:
// Slots on scalars, references, and X4s:
#define JS_TYPEREPR_SLOT_TYPE 3 // One of the constants below
// Maximum number of slots for any type representation
@ -61,10 +63,11 @@
// These constants are for use exclusively in JS code. In C++ code,
// prefer TypeRepresentation::Scalar etc, which allows you to
// write a switch which will receive a warning if you omit a case.
#define JS_TYPEREPR_SCALAR_KIND 0
#define JS_TYPEREPR_SCALAR_KIND 0
#define JS_TYPEREPR_REFERENCE_KIND 1
#define JS_TYPEREPR_STRUCT_KIND 2
#define JS_TYPEREPR_ARRAY_KIND 3
#define JS_TYPEREPR_X4_KIND 2
#define JS_TYPEREPR_STRUCT_KIND 3
#define JS_TYPEREPR_ARRAY_KIND 4
// These constants are for use exclusively in JS code. In C++ code,
// prefer ScalarTypeRepresentation::TYPE_INT8 etc, which allows
@ -88,6 +91,13 @@
#define JS_REFERENCETYPEREPR_OBJECT 1
#define JS_REFERENCETYPEREPR_STRING 2
// These constants are for use exclusively in JS code. In C++ code,
// prefer X4TypeRepresentation::TYPE_INT32 etc, since that allows
// you to write a switch which will receive a warning if you omit a
// case.
#define JS_X4TYPEREPR_INT32 0
#define JS_X4TYPEREPR_FLOAT32 1
///////////////////////////////////////////////////////////////////////////
// Slots for typed objects (actually, any TypedContents objects)

View File

@ -6533,15 +6533,19 @@ IonBuilder::getElemTryTypedObject(bool *emitted, MDefinition *obj, MDefinition *
return true;
switch (elemTypeReprs.kind()) {
case TypeRepresentation::Struct:
case TypeRepresentation::Array:
case TypeRepresentation::X4:
// FIXME (bug 894104): load into a MIRType_float32x4 etc
return true;
case TypeRepresentation::Struct:
case TypeRepresentation::Array:
return getElemTryComplexElemOfTypedObject(emitted,
obj,
index,
objTypeReprs,
elemTypeReprs,
elemSize);
case TypeRepresentation::Scalar:
case TypeRepresentation::Scalar:
return getElemTryScalarElemOfTypedObject(emitted,
obj,
index,
@ -8208,6 +8212,10 @@ IonBuilder::getPropTryTypedObject(bool *emitted, PropertyName *name,
case TypeRepresentation::Reference:
return true;
case TypeRepresentation::X4:
// FIXME (bug 894104): load into a MIRType_float32x4 etc
return true;
case TypeRepresentation::Struct:
case TypeRepresentation::Array:
return getPropTryComplexPropOfTypedObject(emitted,
@ -8741,6 +8749,10 @@ IonBuilder::setPropTryTypedObject(bool *emitted, MDefinition *obj,
return true;
switch (fieldTypeReprs.kind()) {
case TypeRepresentation::X4:
// FIXME (bug 894104): store into a MIRType_float32x4 etc
return true;
case TypeRepresentation::Reference:
case TypeRepresentation::Struct:
case TypeRepresentation::Array:

View File

@ -3085,10 +3085,10 @@ DefineProperty(JSContext *cx, HandleObject obj, const char *name, const Value &v
RootedValue value(cx, value_);
AutoRooterGetterSetter gsRoot(cx, attrs, const_cast<JSPropertyOp *>(&getter.op),
const_cast<JSStrictPropertyOp *>(&setter.op));
RootedId id(cx);
RootedId id(cx);
if (attrs & JSPROP_INDEX) {
id = INT_TO_JSID(intptr_t(name));
id.set(INT_TO_JSID(intptr_t(name)));
attrs &= ~JSPROP_INDEX;
} else {
JSAtom *atom = Atomize(cx, name, strlen(name));
@ -3100,6 +3100,57 @@ DefineProperty(JSContext *cx, HandleObject obj, const char *name, const Value &v
return DefinePropertyById(cx, obj, id, value, getter, setter, attrs, flags, tinyid);
}
static bool
DefineSelfHostedProperty(JSContext *cx,
HandleObject obj,
const char *name,
const char *getterName,
const char *setterName,
unsigned attrs,
unsigned flags,
int tinyid)
{
RootedAtom nameAtom(cx, Atomize(cx, name, strlen(name)));
if (!nameAtom)
return false;
RootedAtom getterNameAtom(cx, Atomize(cx, getterName, strlen(getterName)));
if (!getterNameAtom)
return false;
RootedValue getterValue(cx);
if (!cx->global()->getSelfHostedFunction(cx, getterNameAtom, nameAtom,
0, &getterValue))
{
return false;
}
JS_ASSERT(getterValue.isObject() && getterValue.toObject().is<JSFunction>());
RootedFunction getterFunc(cx, &getterValue.toObject().as<JSFunction>());
JSPropertyOp getterOp = JS_DATA_TO_FUNC_PTR(PropertyOp, getterFunc.get());
RootedFunction setterFunc(cx);
if (setterName) {
RootedAtom setterNameAtom(cx, Atomize(cx, setterName, strlen(setterName)));
if (!setterNameAtom)
return false;
RootedValue setterValue(cx);
if (!cx->global()->getSelfHostedFunction(cx, setterNameAtom, nameAtom,
0, &setterValue))
{
return false;
}
JS_ASSERT(setterValue.isObject() && setterValue.toObject().is<JSFunction>());
setterFunc = &getterValue.toObject().as<JSFunction>();
}
JSStrictPropertyOp setterOp = JS_DATA_TO_FUNC_PTR(StrictPropertyOp, setterFunc.get());
return DefineProperty(cx, obj, name, UndefinedValue(),
GetterWrapper(getterOp), SetterWrapper(setterOp),
attrs, flags, tinyid);
}
JS_PUBLIC_API(bool)
JS_DefineProperty(JSContext *cx, JSObject *objArg, const char *name, jsval valueArg,
PropertyOp getter, JSStrictPropertyOp setter, unsigned attrs)
@ -3224,8 +3275,25 @@ JS_DefineProperties(JSContext *cx, JSObject *objArg, const JSPropertySpec *ps)
RootedObject obj(cx, objArg);
bool ok;
for (ok = true; ps->name; ps++) {
ok = DefineProperty(cx, obj, ps->name, UndefinedValue(), ps->getter, ps->setter,
ps->flags, Shape::HAS_SHORTID, ps->tinyid);
if (ps->selfHostedGetter) {
// If you have self-hosted getter/setter, you can't have a
// native one.
JS_ASSERT(!ps->getter.op && !ps->setter.op);
ok = DefineSelfHostedProperty(cx, obj, ps->name,
ps->selfHostedGetter,
ps->selfHostedSetter,
ps->flags, Shape::HAS_SHORTID,
ps->tinyid);
} else {
// If you do not have a self-hosted getter, you should
// have a native getter; and you should not have a
// self-hosted setter.
JS_ASSERT(ps->getter.op && !ps->selfHostedSetter);
ok = DefineProperty(cx, obj, ps->name, UndefinedValue(), ps->getter, ps->setter,
ps->flags, Shape::HAS_SHORTID, ps->tinyid);
}
if (!ok)
break;
}

View File

@ -2406,6 +2406,8 @@ struct JSPropertySpec {
uint8_t flags;
JSPropertyOpWrapper getter;
JSStrictPropertyOpWrapper setter;
const char *selfHostedGetter;
const char *selfHostedSetter;
};
namespace JS {
@ -2436,13 +2438,23 @@ inline int CheckIsNative(JSNative native);
{name, 0, \
uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | JSPROP_SHARED | JSPROP_NATIVE_ACCESSORS), \
JSOP_WRAPPER(JS_CAST_NATIVE_TO(getter, JSPropertyOp)), \
JSOP_NULLWRAPPER}
JSOP_NULLWRAPPER, nullptr, nullptr}
#define JS_PSGS(name, getter, setter, flags) \
{name, 0, \
uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | JSPROP_SHARED | JSPROP_NATIVE_ACCESSORS), \
JSOP_WRAPPER(JS_CAST_NATIVE_TO(getter, JSPropertyOp)), \
JSOP_WRAPPER(JS_CAST_NATIVE_TO(setter, JSStrictPropertyOp))}
#define JS_PS_END {0, 0, 0, JSOP_NULLWRAPPER, JSOP_NULLWRAPPER}
JSOP_WRAPPER(JS_CAST_NATIVE_TO(setter, JSStrictPropertyOp)), \
nullptr, nullptr}
#define JS_SELF_HOSTED_GET(name, getterName, flags) \
{name, 0, \
uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | JSPROP_SHARED | JSPROP_GETTER), \
JSOP_NULLWRAPPER, JSOP_NULLWRAPPER, getterName, nullptr}
#define JS_SELF_HOSTED_GETSET(name, getterName, setterName, flags) \
{name, 0, \
uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | JSPROP_SHARED | JSPROP_GETTER | JSPROP_SETTER), \
JSOP_NULLWRAPPER, JSOP_NULLWRAPPER, getterName, setterName}
#define JS_PS_END {0, 0, 0, JSOP_NULLWRAPPER, JSOP_NULLWRAPPER, \
nullptr, nullptr}
/*
* To define a native function, set call to a JSNativeWrapper. To define a

View File

@ -0,0 +1,30 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 938728;
var summary = 'float32x4 alignment';
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
*/
var StructType = TypedObject.StructType;
var uint8 = TypedObject.uint8;
var float32x4 = TypedObject.float32x4;
function test() {
print(BUGNUMBER + ": " + summary);
assertEq(float32x4.byteLength, 16);
assertEq(float32x4.byteAlignment, 16);
var Compound = new StructType({c: uint8, d: uint8, f: float32x4});
assertEq(Compound.fieldOffsets["c"], 0);
assertEq(Compound.fieldOffsets["d"], 1);
assertEq(Compound.fieldOffsets["f"], 16);
if (typeof reportCompare === "function")
reportCompare(true, true);
print("Tests complete");
}
test();

View File

@ -0,0 +1,51 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 938728;
var summary = 'float32x4 getters';
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
*/
var float32x4 = TypedObject.float32x4;
function test() {
print(BUGNUMBER + ": " + summary);
// Create a float32x4 and check that the getters work:
var f = float32x4(11, 22, 33, 44);
assertEq(f.x, 11);
assertEq(f.y, 22);
assertEq(f.z, 33);
assertEq(f.w, 44);
// Test that the getters work when called reflectively:
var g = f.__lookupGetter__("x");
assertEq(g.call(f), 11);
// Test that getters cannot be applied to various incorrect things:
assertThrowsInstanceOf(function() {
g.call({})
}, TypeError, "Getter applicable to random objects");
assertThrowsInstanceOf(function() {
g.call(0xDEADBEEF)
}, TypeError, "Getter applicable to integers");
assertThrowsInstanceOf(function() {
var T = new TypedObject.StructType({x: TypedObject.float32,
y: TypedObject.float32,
z: TypedObject.float32,
w: TypedObject.float32});
var v = new T({x: 11, y: 22, z: 33, w: 44});
g.call(v)
}, TypeError, "Getter applicable to structs");
assertThrowsInstanceOf(function() {
var t = new TypedObject.int32x4(1, 2, 3, 4);
g.call(t)
}, TypeError, "Getter applicable to int32x4");
if (typeof reportCompare === "function")
reportCompare(true, true);
print("Tests complete");
}
test();

View File

@ -0,0 +1,49 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 938728;
var summary = 'float32x4 handles';
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
*/
var ArrayType = TypedObject.ArrayType;
var float32x4 = TypedObject.float32x4;
var float32 = TypedObject.float32;
var Handle = TypedObject.Handle;
function test() {
print(BUGNUMBER + ": " + summary);
var Array = new ArrayType(float32x4, 3);
var array = new Array([float32x4(1, 2, 3, 4),
float32x4(5, 6, 7, 8),
float32x4(9, 10, 11, 12)]);
// Test that trying to create handle into the interior of a
// float32x4 fails.
assertThrowsInstanceOf(function() {
var h = float32.handle(array, 1, "w");
}, TypeError, "Creating a float32 handle to prop via ctor");
assertThrowsInstanceOf(function() {
var h = float32.handle();
Handle.move(h, array, 1, "w");
}, TypeError, "Creating a float32 handle to prop via move");
assertThrowsInstanceOf(function() {
var h = float32.handle(array, 1, 0);
}, TypeError, "Creating a float32 handle to elem via ctor");
assertThrowsInstanceOf(function() {
var h = float32.handle();
Handle.move(h, array, 1, 0);
}, TypeError, "Creating a float32 handle to elem via move");
if (typeof reportCompare === "function")
reportCompare(true, true);
print("Tests complete");
}
test();

View File

@ -0,0 +1,36 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 938728;
var summary = 'float32x4 reify';
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
*/
var ArrayType = TypedObject.ArrayType;
var float32x4 = TypedObject.float32x4;
function test() {
print(BUGNUMBER + ": " + summary);
var Array = new ArrayType(float32x4, 3);
var array = new Array([float32x4(1, 2, 3, 4),
float32x4(5, 6, 7, 8),
float32x4(9, 10, 11, 12)]);
// Test that reading array[1] produces a *copy* of float32x4, not an
// alias into the array.
var f = array[1];
assertEq(f.w, 8);
assertEq(array[1].w, 8);
array[1] = float32x4(15, 16, 17, 18);
assertEq(f.w, 8);
assertEq(array[1].w, 18);
if (typeof reportCompare === "function")
reportCompare(true, true);
print("Tests complete");
}
test();

View File

@ -0,0 +1,45 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 938728;
var summary = 'float32x4 setting';
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
*/
var ArrayType = TypedObject.ArrayType;
var float32x4 = TypedObject.float32x4;
function test() {
print(BUGNUMBER + ": " + summary);
var Array = new ArrayType(float32x4, 3);
var array = new Array([float32x4(1, 2, 3, 4),
float32x4(5, 6, 7, 8),
float32x4(9, 10, 11, 12)]);
assertEq(array[1].w, 8);
// Test that we are allowed to write float32x4 values into array,
// but not other things.
array[1] = float32x4(15, 16, 17, 18);
assertEq(array[1].w, 18);
assertThrowsInstanceOf(function() {
array[1] = {x: 15, y: 16, z: 17, w: 18};
}, TypeError, "Setting float32x4 from an object");
assertThrowsInstanceOf(function() {
array[1] = [15, 16, 17, 18];
}, TypeError, "Setting float32x4 from an array");
assertThrowsInstanceOf(function() {
array[1] = 22;
}, TypeError, "Setting float32x4 from a number");
if (typeof reportCompare === "function")
reportCompare(true, true);
print("Tests complete");
}
test();

View File

@ -0,0 +1,30 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 938728;
var summary = 'int32x4 alignment';
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
*/
var StructType = TypedObject.StructType;
var uint8 = TypedObject.uint8;
var int32x4 = TypedObject.int32x4;
function test() {
print(BUGNUMBER + ": " + summary);
assertEq(int32x4.byteLength, 16);
assertEq(int32x4.byteAlignment, 16);
var Compound = new StructType({c: uint8, d: uint8, f: int32x4});
assertEq(Compound.fieldOffsets["c"], 0);
assertEq(Compound.fieldOffsets["d"], 1);
assertEq(Compound.fieldOffsets["f"], 16);
if (typeof reportCompare === "function")
reportCompare(true, true);
print("Tests complete");
}
test();

View File

@ -0,0 +1,51 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 938728;
var summary = 'int32x4 getters';
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
*/
var int32x4 = TypedObject.int32x4;
function test() {
print(BUGNUMBER + ": " + summary);
// Create a int32x4 and check that the getters work:
var f = int32x4(11, 22, 33, 44);
assertEq(f.x, 11);
assertEq(f.y, 22);
assertEq(f.z, 33);
assertEq(f.w, 44);
// Test that the getters work when called reflectively:
var g = f.__lookupGetter__("x");
assertEq(g.call(f), 11);
// Test that getters cannot be applied to various incorrect things:
assertThrowsInstanceOf(function() {
g.call({})
}, TypeError, "Getter applicable to random objects");
assertThrowsInstanceOf(function() {
g.call(0xDEADBEEF)
}, TypeError, "Getter applicable to integers");
assertThrowsInstanceOf(function() {
var T = new TypedObject.StructType({x: TypedObject.int32,
y: TypedObject.int32,
z: TypedObject.int32,
w: TypedObject.int32});
var v = new T({x: 11, y: 22, z: 33, w: 44});
g.call(v)
}, TypeError, "Getter applicable to structs");
assertThrowsInstanceOf(function() {
var t = new TypedObject.float32x4(1, 2, 3, 4);
g.call(t)
}, TypeError, "Getter applicable to float32x4");
if (typeof reportCompare === "function")
reportCompare(true, true);
print("Tests complete");
}
test();

View File

@ -0,0 +1,49 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 938728;
var summary = 'int32x4 handles';
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
*/
var ArrayType = TypedObject.ArrayType;
var int32x4 = TypedObject.int32x4;
var int32 = TypedObject.int32;
var Handle = TypedObject.Handle;
function test() {
print(BUGNUMBER + ": " + summary);
var Array = new ArrayType(int32x4, 3);
var array = new Array([int32x4(1, 2, 3, 4),
int32x4(5, 6, 7, 8),
int32x4(9, 10, 11, 12)]);
// Test that trying to create handle into the interior of a
// int32x4 fails.
assertThrowsInstanceOf(function() {
var h = int32.handle(array, 1, "w");
}, TypeError, "Creating a int32 handle to prop via ctor");
assertThrowsInstanceOf(function() {
var h = int32.handle();
Handle.move(h, array, 1, "w");
}, TypeError, "Creating a int32 handle to prop via move");
assertThrowsInstanceOf(function() {
var h = int32.handle(array, 1, 0);
}, TypeError, "Creating a int32 handle to elem via ctor");
assertThrowsInstanceOf(function() {
var h = int32.handle();
Handle.move(h, array, 1, 0);
}, TypeError, "Creating a int32 handle to elem via move");
if (typeof reportCompare === "function")
reportCompare(true, true);
print("Tests complete");
}
test();

View File

@ -0,0 +1,36 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 938728;
var summary = 'int32x4 reify';
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
*/
var ArrayType = TypedObject.ArrayType;
var int32x4 = TypedObject.int32x4;
function test() {
print(BUGNUMBER + ": " + summary);
var Array = new ArrayType(int32x4, 3);
var array = new Array([int32x4(1, 2, 3, 4),
int32x4(5, 6, 7, 8),
int32x4(9, 10, 11, 12)]);
// Test that reading array[1] produces a *copy* of int32x4, not an
// alias into the array.
var f = array[1];
assertEq(f.w, 8);
assertEq(array[1].w, 8);
array[1] = int32x4(15, 16, 17, 18);
assertEq(f.w, 8);
assertEq(array[1].w, 18);
if (typeof reportCompare === "function")
reportCompare(true, true);
print("Tests complete");
}
test();

View File

@ -0,0 +1,45 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 938728;
var summary = 'int32x4 setting';
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
*/
var ArrayType = TypedObject.ArrayType;
var int32x4 = TypedObject.int32x4;
function test() {
print(BUGNUMBER + ": " + summary);
var Array = new ArrayType(int32x4, 3);
var array = new Array([int32x4(1, 2, 3, 4),
int32x4(5, 6, 7, 8),
int32x4(9, 10, 11, 12)]);
assertEq(array[1].w, 8);
// Test that we are allowed to write int32x4 values into array,
// but not other things.
array[1] = int32x4(15, 16, 17, 18);
assertEq(array[1].w, 18);
assertThrowsInstanceOf(function() {
array[1] = {x: 15, y: 16, z: 17, w: 18};
}, TypeError, "Setting int32x4 from an object");
assertThrowsInstanceOf(function() {
array[1] = [15, 16, 17, 18];
}, TypeError, "Setting int32x4 from an array");
assertThrowsInstanceOf(function() {
array[1] = 22;
}, TypeError, "Setting int32x4 from a number");
if (typeof reportCompare === "function")
reportCompare(true, true);
print("Tests complete");
}
test();

View File

@ -69,6 +69,7 @@
macro(FillTypedArrayWithValue, FillTypedArrayWithValue, "FillTypedArrayWithValue") \
macro(fix, fix, "fix") \
macro(float32, float32, "float32") \
macro(float32x4, float32x4, "float32x4") \
macro(float64, float64, "float64") \
macro(format, format, "format") \
macro(from, from, "from") \
@ -90,6 +91,7 @@
macro(InitializeNumberFormat, InitializeNumberFormat, "InitializeNumberFormat") \
macro(innermost, innermost, "innermost") \
macro(input, input, "input") \
macro(int32x4, int32x4, "int32x4") \
macro(isFinite, isFinite, "isFinite") \
macro(isNaN, isNaN, "isNaN") \
macro(isPrototypeOf, isPrototypeOf, "isPrototypeOf") \
@ -177,7 +179,11 @@
macro(void0, void0, "(void 0)") \
macro(watch, watch, "watch") \
macro(writable, writable, "writable") \
macro(w, w, "w") \
macro(x, x, "x") \
macro(y, y, "y") \
macro(yield, yield, "yield") \
macro(z, z, "z") \
/* Type names must be contiguous and ordered; see js::TypeName. */ \
macro(undefined, undefined, "undefined") \
macro(object, object, "object") \