mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 938728 - Add float32x4 and int32x4 data constructors r=till
This commit is contained in:
parent
4f0894ce81
commit
f99c3f2826
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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(...)`
|
||||
*/
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
30
js/src/tests/ecma_6/TypedObject/simd/float32x4alignment.js
Normal file
30
js/src/tests/ecma_6/TypedObject/simd/float32x4alignment.js
Normal 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();
|
51
js/src/tests/ecma_6/TypedObject/simd/float32x4getters.js
Normal file
51
js/src/tests/ecma_6/TypedObject/simd/float32x4getters.js
Normal 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();
|
49
js/src/tests/ecma_6/TypedObject/simd/float32x4handle.js
Normal file
49
js/src/tests/ecma_6/TypedObject/simd/float32x4handle.js
Normal 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();
|
36
js/src/tests/ecma_6/TypedObject/simd/float32x4reify.js
Normal file
36
js/src/tests/ecma_6/TypedObject/simd/float32x4reify.js
Normal 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();
|
45
js/src/tests/ecma_6/TypedObject/simd/float32x4setter.js
Normal file
45
js/src/tests/ecma_6/TypedObject/simd/float32x4setter.js
Normal 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();
|
30
js/src/tests/ecma_6/TypedObject/simd/int32x4alignment.js
Normal file
30
js/src/tests/ecma_6/TypedObject/simd/int32x4alignment.js
Normal 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();
|
51
js/src/tests/ecma_6/TypedObject/simd/int32x4getters.js
Normal file
51
js/src/tests/ecma_6/TypedObject/simd/int32x4getters.js
Normal 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();
|
49
js/src/tests/ecma_6/TypedObject/simd/int32x4handle.js
Normal file
49
js/src/tests/ecma_6/TypedObject/simd/int32x4handle.js
Normal 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();
|
36
js/src/tests/ecma_6/TypedObject/simd/int32x4reify.js
Normal file
36
js/src/tests/ecma_6/TypedObject/simd/int32x4reify.js
Normal 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();
|
45
js/src/tests/ecma_6/TypedObject/simd/int32x4setter.js
Normal file
45
js/src/tests/ecma_6/TypedObject/simd/int32x4setter.js
Normal 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();
|
0
js/src/tests/ecma_6/TypedObject/simd/shell.js
Normal file
0
js/src/tests/ecma_6/TypedObject/simd/shell.js
Normal 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") \
|
||||
|
Loading…
Reference in New Issue
Block a user