Bug 898356 Part 1 -- Separate out simple type descriptors from the rest so that they can be referenced by TypedArray.h without pulling in everything else r=sfink

This commit is contained in:
Nicholas D. Matsakis 2014-02-03 10:55:40 -05:00
parent 7627deaf7d
commit e739d0bf2a
6 changed files with 430 additions and 387 deletions

View File

@ -174,207 +174,6 @@ GetPrototype(JSContext *cx, HandleObject obj)
return &prototypeVal.toObject();
}
/***************************************************************************
* Type descriptors
*/
TypeRepresentation *
TypeDescr::typeRepresentation() const {
return TypeRepresentation::fromOwnerObject(typeRepresentationOwnerObj());
}
TypeDescr::Kind
TypeDescr::kind() const {
return typeRepresentation()->kind();
}
/***************************************************************************
* Scalar type objects
*
* Scalar type objects like `uint8`, `uint16`, are all instances of
* the ScalarTypeDescr class. Like all type objects, they have a reserved
* slot pointing to a TypeRepresentation object, which is used to
* distinguish which scalar type object this actually is.
*/
const Class js::ScalarTypeDescr::class_ = {
"Scalar",
JSCLASS_HAS_RESERVED_SLOTS(JS_DESCR_SLOTS),
JS_PropertyStub, /* addProperty */
JS_DeletePropertyStub, /* delProperty */
JS_PropertyStub, /* getProperty */
JS_StrictPropertyStub, /* setProperty */
JS_EnumerateStub,
JS_ResolveStub,
JS_ConvertStub,
nullptr,
ScalarTypeDescr::call,
nullptr,
nullptr,
nullptr
};
const JSFunctionSpec js::ScalarTypeDescr::typeObjectMethods[] = {
JS_SELF_HOSTED_FN("toSource", "DescrToSourceMethod", 0, 0),
{"array", {nullptr, nullptr}, 1, 0, "ArrayShorthand"},
{"equivalent", {nullptr, nullptr}, 1, 0, "TypeDescrEquivalent"},
JS_FS_END
};
static size_t ScalarSizes[] = {
#define SCALAR_SIZE(_kind, _type, _name) \
sizeof(_type),
JS_FOR_EACH_SCALAR_TYPE_REPR(SCALAR_SIZE) 0
#undef SCALAR_SIZE
};
size_t
ScalarTypeDescr::size(Type t)
{
return ScalarSizes[t];
}
size_t
ScalarTypeDescr::alignment(Type t)
{
return ScalarSizes[t];
}
/*static*/ const char *
ScalarTypeDescr::typeName(Type type)
{
switch (type) {
#define NUMERIC_TYPE_TO_STRING(constant_, type_, name_) \
case constant_: return #name_;
JS_FOR_EACH_SCALAR_TYPE_REPR(NUMERIC_TYPE_TO_STRING)
}
MOZ_ASSUME_UNREACHABLE("Invalid type");
}
bool
ScalarTypeDescr::call(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
if (args.length() < 1) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_MORE_ARGS_NEEDED,
args.callee().getClass()->name, "0", "s");
return false;
}
ScalarTypeRepresentation *typeRepr =
args.callee().as<ScalarTypeDescr>().typeRepresentation()->asScalar();
ScalarTypeDescr::Type type = typeRepr->type();
double number;
if (!ToNumber(cx, args[0], &number))
return false;
if (type == ScalarTypeDescr::TYPE_UINT8_CLAMPED)
number = ClampDoubleToUint8(number);
switch (type) {
#define SCALARTYPE_CALL(constant_, type_, name_) \
case constant_: { \
type_ converted = ConvertScalar<type_>(number); \
args.rval().setNumber((double) converted); \
return true; \
}
JS_FOR_EACH_SCALAR_TYPE_REPR(SCALARTYPE_CALL)
#undef SCALARTYPE_CALL
}
return true;
}
/***************************************************************************
* Reference type objects
*
* Reference type objects like `Any` or `Object` basically work the
* same way that the scalar type objects do. There is one class with
* many instances, and each instance has a reserved slot with a
* TypeRepresentation object, which is used to distinguish which
* reference type object this actually is.
*/
const Class js::ReferenceTypeDescr::class_ = {
"Reference",
JSCLASS_HAS_RESERVED_SLOTS(JS_DESCR_SLOTS),
JS_PropertyStub, /* addProperty */
JS_DeletePropertyStub, /* delProperty */
JS_PropertyStub, /* getProperty */
JS_StrictPropertyStub, /* setProperty */
JS_EnumerateStub,
JS_ResolveStub,
JS_ConvertStub,
nullptr,
ReferenceTypeDescr::call,
nullptr,
nullptr,
nullptr
};
const JSFunctionSpec js::ReferenceTypeDescr::typeObjectMethods[] = {
JS_SELF_HOSTED_FN("toSource", "DescrToSourceMethod", 0, 0),
{"array", {nullptr, nullptr}, 1, 0, "ArrayShorthand"},
{"equivalent", {nullptr, nullptr}, 1, 0, "TypeDescrEquivalent"},
JS_FS_END
};
/*static*/ const char *
ReferenceTypeDescr::typeName(Type type)
{
switch (type) {
#define NUMERIC_TYPE_TO_STRING(constant_, type_, name_) \
case constant_: return #name_;
JS_FOR_EACH_REFERENCE_TYPE_REPR(NUMERIC_TYPE_TO_STRING)
}
MOZ_ASSUME_UNREACHABLE("Invalid type");
}
bool
js::ReferenceTypeDescr::call(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
JS_ASSERT(args.callee().is<ReferenceTypeDescr>());
ReferenceTypeRepresentation *typeRepr =
args.callee().as<ReferenceTypeDescr>().typeRepresentation()->asReference();
if (args.length() < 1) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr,
JSMSG_MORE_ARGS_NEEDED,
typeRepr->typeName(), "0", "s");
return false;
}
switch (typeRepr->type()) {
case ReferenceTypeDescr::TYPE_ANY:
args.rval().set(args[0]);
return true;
case ReferenceTypeDescr::TYPE_OBJECT:
{
RootedObject obj(cx, ToObject(cx, args[0]));
if (!obj)
return false;
args.rval().setObject(*obj);
return true;
}
case ReferenceTypeDescr::TYPE_STRING:
{
RootedString obj(cx, ToString<CanGC>(cx, args[0]));
if (!obj)
return false;
args.rval().setString(&*obj);
return true;
}
}
MOZ_ASSUME_UNREACHABLE("Unhandled Reference type");
}
/***************************************************************************
* ArrayMetaTypeDescr class
*/

View File

@ -10,6 +10,8 @@
#include "jsobj.h"
#include "builtin/TypedObjectConstants.h"
#include "builtin/TypedObjectSimple.h"
#include "vm/TypedArrayObject.h"
/*
* -------------
@ -95,57 +97,6 @@
namespace js {
class TypeRepresentation;
class ScalarTypeRepresentation;
class ReferenceTypeRepresentation;
class X4TypeRepresentation;
class StructTypeDescr;
/*
* Helper method for converting a double into other scalar
* types in the same way that JavaScript would. In particular,
* simple C casting from double to int32_t gets things wrong
* for values like 0xF0000000.
*/
template <typename T>
static T ConvertScalar(double d)
{
if (TypeIsFloatingPoint<T>()) {
return T(d);
} else if (TypeIsUnsigned<T>()) {
uint32_t n = ToUint32(d);
return T(n);
} else {
int32_t n = ToInt32(d);
return T(n);
}
}
class TypeDescr : public JSObject
{
public:
enum Kind {
Scalar = JS_TYPEREPR_SCALAR_KIND,
Reference = JS_TYPEREPR_REFERENCE_KIND,
X4 = JS_TYPEREPR_X4_KIND,
Struct = JS_TYPEREPR_STRUCT_KIND,
SizedArray = JS_TYPEREPR_SIZED_ARRAY_KIND,
UnsizedArray = JS_TYPEREPR_UNSIZED_ARRAY_KIND,
};
static bool isSized(Kind kind) {
return kind > JS_TYPEREPR_MAX_UNSIZED_KIND;
}
JSObject &typeRepresentationOwnerObj() const {
return getReservedSlot(JS_DESCR_SLOT_TYPE_REPR).toObject();
}
TypeRepresentation *typeRepresentation() const;
TypeDescr::Kind kind() const;
};
/*
* This object exists in order to encapsulate the typed object types
* somewhat, rather than sticking them all into the global object.
@ -167,142 +118,10 @@ class TypedObjectModuleObject : public JSObject {
MutableHandleObject proto);
};
typedef Handle<TypeDescr*> HandleTypeDescr;
bool InitializeCommonTypeDescriptorProperties(JSContext *cx,
HandleTypeDescr obj,
HandleObject typeReprOwnerObj);
class SizedTypeDescr : public TypeDescr
{
public:
size_t size() {
return getReservedSlot(JS_DESCR_SLOT_SIZE).toInt32();
}
};
typedef Handle<SizedTypeDescr*> HandleSizedTypeDescr;
class SimpleTypeDescr : public SizedTypeDescr
{
};
// Type for scalar type constructors like `uint8`. All such type
// constructors share a common js::Class and JSFunctionSpec. Scalar
// types are non-opaque (their storage is visible unless combined with
// an opaque reference type.)
class ScalarTypeDescr : public SimpleTypeDescr
{
public:
// Must match order of JS_FOR_EACH_SCALAR_TYPE_REPR below
enum Type {
TYPE_INT8 = JS_SCALARTYPEREPR_INT8,
TYPE_UINT8 = JS_SCALARTYPEREPR_UINT8,
TYPE_INT16 = JS_SCALARTYPEREPR_INT16,
TYPE_UINT16 = JS_SCALARTYPEREPR_UINT16,
TYPE_INT32 = JS_SCALARTYPEREPR_INT32,
TYPE_UINT32 = JS_SCALARTYPEREPR_UINT32,
TYPE_FLOAT32 = JS_SCALARTYPEREPR_FLOAT32,
TYPE_FLOAT64 = JS_SCALARTYPEREPR_FLOAT64,
/*
* Special type that's a uint8_t, but assignments are clamped to 0 .. 255.
* Treat the raw data type as a uint8_t.
*/
TYPE_UINT8_CLAMPED = JS_SCALARTYPEREPR_UINT8_CLAMPED,
};
static const int32_t TYPE_MAX = TYPE_UINT8_CLAMPED + 1;
static size_t size(Type t);
static size_t alignment(Type t);
static const char *typeName(Type type);
static const Class class_;
static const JSFunctionSpec typeObjectMethods[];
typedef ScalarTypeRepresentation TypeRepr;
ScalarTypeDescr::Type type() const {
return (ScalarTypeDescr::Type) getReservedSlot(JS_DESCR_SLOT_TYPE).toInt32();
}
static bool call(JSContext *cx, unsigned argc, Value *vp);
};
// Enumerates the cases of ScalarTypeDescr::Type which have
// unique C representation. In particular, omits Uint8Clamped since it
// is just a Uint8.
#define JS_FOR_EACH_UNIQUE_SCALAR_TYPE_REPR_CTYPE(macro_) \
macro_(ScalarTypeDescr::TYPE_INT8, int8_t, int8) \
macro_(ScalarTypeDescr::TYPE_UINT8, uint8_t, uint8) \
macro_(ScalarTypeDescr::TYPE_INT16, int16_t, int16) \
macro_(ScalarTypeDescr::TYPE_UINT16, uint16_t, uint16) \
macro_(ScalarTypeDescr::TYPE_INT32, int32_t, int32) \
macro_(ScalarTypeDescr::TYPE_UINT32, uint32_t, uint32) \
macro_(ScalarTypeDescr::TYPE_FLOAT32, float, float32) \
macro_(ScalarTypeDescr::TYPE_FLOAT64, double, float64)
// Must be in same order as the enum ScalarTypeDescr::Type:
#define JS_FOR_EACH_SCALAR_TYPE_REPR(macro_) \
JS_FOR_EACH_UNIQUE_SCALAR_TYPE_REPR_CTYPE(macro_) \
macro_(ScalarTypeDescr::TYPE_UINT8_CLAMPED, uint8_t, uint8Clamped)
// Type for reference type constructors like `Any`, `String`, and
// `Object`. All such type constructors share a common js::Class and
// JSFunctionSpec. All these types are opaque.
class ReferenceTypeDescr : public SimpleTypeDescr
{
public:
// Must match order of JS_FOR_EACH_REFERENCE_TYPE_REPR below
enum Type {
TYPE_ANY = JS_REFERENCETYPEREPR_ANY,
TYPE_OBJECT = JS_REFERENCETYPEREPR_OBJECT,
TYPE_STRING = JS_REFERENCETYPEREPR_STRING,
};
static const int32_t TYPE_MAX = TYPE_STRING + 1;
static const char *typeName(Type type);
static const Class class_;
static const JSFunctionSpec typeObjectMethods[];
typedef ReferenceTypeRepresentation TypeRepr;
ReferenceTypeDescr::Type type() const {
return (ReferenceTypeDescr::Type) getReservedSlot(JS_DESCR_SLOT_TYPE).toInt32();
}
static bool call(JSContext *cx, unsigned argc, Value *vp);
};
#define JS_FOR_EACH_REFERENCE_TYPE_REPR(macro_) \
macro_(ReferenceTypeDescr::TYPE_ANY, HeapValue, Any) \
macro_(ReferenceTypeDescr::TYPE_OBJECT, HeapPtrObject, Object) \
macro_(ReferenceTypeDescr::TYPE_STRING, HeapPtrString, string)
/*
* Type descriptors `float32x4` and `int32x4`
*/
class X4TypeDescr : public SizedTypeDescr
{
public:
enum Type {
TYPE_INT32 = JS_X4TYPEREPR_INT32,
TYPE_FLOAT32 = JS_X4TYPEREPR_FLOAT32,
};
static const Class class_;
typedef X4TypeRepresentation TypeRepr;
X4TypeDescr::Type type() const {
return (X4TypeDescr::Type) getReservedSlot(JS_DESCR_SLOT_TYPE).toInt32();
}
static bool call(JSContext *cx, unsigned argc, Value *vp);
static bool is(const Value &v);
};
#define JS_FOR_EACH_X4_TYPE_REPR(macro_) \
macro_(X4TypeDescr::TYPE_INT32, int32_t, int32) \
macro_(X4TypeDescr::TYPE_FLOAT32, float, float32)
/*
* Properties and methods of the `ArrayType` meta type object. There
* is no `class_` field because `ArrayType` is just a native
@ -752,7 +571,7 @@ bool GetTypedObjectModule(JSContext *cx, unsigned argc, Value *vp);
/*
* Usage: GetFloat32x4TypeDescr()
*
* Returns the float32x4 type object. SIMD pseudo-module must have
* Returns the float32x4 type object. SIMD pseudo-module must have
* been initialized for this to be safe.
*/
bool GetFloat32x4TypeDescr(JSContext *cx, unsigned argc, Value *vp);
@ -760,7 +579,7 @@ bool GetFloat32x4TypeDescr(JSContext *cx, unsigned argc, Value *vp);
/*
* Usage: GetInt32x4TypeDescr()
*
* Returns the int32x4 type object. SIMD pseudo-module must have
* Returns the int32x4 type object. SIMD pseudo-module must have
* been initialized for this to be safe.
*/
bool GetInt32x4TypeDescr(JSContext *cx, unsigned argc, Value *vp);

View File

@ -0,0 +1,212 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "builtin/TypedObjectSimple.h"
using mozilla::DebugOnly;
using namespace js;
/***************************************************************************
* Type descriptors
*/
TypeRepresentation *
TypeDescr::typeRepresentation() const {
return TypeRepresentation::fromOwnerObject(typeRepresentationOwnerObj());
}
TypeDescr::Kind
TypeDescr::kind() const {
return typeRepresentation()->kind();
}
/***************************************************************************
* Scalar type objects
*
* Scalar type objects like `uint8`, `uint16`, are all instances of
* the ScalarTypeDescr class. Like all type objects, they have a reserved
* slot pointing to a TypeRepresentation object, which is used to
* distinguish which scalar type object this actually is.
*/
const Class js::ScalarTypeDescr::class_ = {
"Scalar",
JSCLASS_HAS_RESERVED_SLOTS(JS_DESCR_SLOTS),
JS_PropertyStub, /* addProperty */
JS_DeletePropertyStub, /* delProperty */
JS_PropertyStub, /* getProperty */
JS_StrictPropertyStub, /* setProperty */
JS_EnumerateStub,
JS_ResolveStub,
JS_ConvertStub,
nullptr,
ScalarTypeDescr::call,
nullptr,
nullptr,
nullptr
};
const JSFunctionSpec js::ScalarTypeDescr::typeObjectMethods[] = {
JS_SELF_HOSTED_FN("toSource", "DescrToSourceMethod", 0, 0),
{"array", {nullptr, nullptr}, 1, 0, "ArrayShorthand"},
{"equivalent", {nullptr, nullptr}, 1, 0, "TypeDescrEquivalent"},
JS_FS_END
};
static size_t ScalarSizes[] = {
#define SCALAR_SIZE(_kind, _type, _name) \
sizeof(_type),
JS_FOR_EACH_SCALAR_TYPE_REPR(SCALAR_SIZE) 0
#undef SCALAR_SIZE
};
size_t
ScalarTypeDescr::size(Type t)
{
return ScalarSizes[t];
}
size_t
ScalarTypeDescr::alignment(Type t)
{
return ScalarSizes[t];
}
/*static*/ const char *
ScalarTypeDescr::typeName(Type type)
{
switch (type) {
#define NUMERIC_TYPE_TO_STRING(constant_, type_, name_) \
case constant_: return #name_;
JS_FOR_EACH_SCALAR_TYPE_REPR(NUMERIC_TYPE_TO_STRING)
}
MOZ_ASSUME_UNREACHABLE("Invalid type");
}
bool
ScalarTypeDescr::call(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
if (args.length() < 1) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_MORE_ARGS_NEEDED,
args.callee().getClass()->name, "0", "s");
return false;
}
ScalarTypeRepresentation *typeRepr =
args.callee().as<ScalarTypeDescr>().typeRepresentation()->asScalar();
ScalarTypeDescr::Type type = typeRepr->type();
double number;
if (!ToNumber(cx, args[0], &number))
return false;
if (type == ScalarTypeDescr::TYPE_UINT8_CLAMPED)
number = ClampDoubleToUint8(number);
switch (type) {
#define SCALARTYPE_CALL(constant_, type_, name_) \
case constant_: { \
type_ converted = ConvertScalar<type_>(number); \
args.rval().setNumber((double) converted); \
return true; \
}
JS_FOR_EACH_SCALAR_TYPE_REPR(SCALARTYPE_CALL)
#undef SCALARTYPE_CALL
}
return true;
}
/***************************************************************************
* Reference type objects
*
* Reference type objects like `Any` or `Object` basically work the
* same way that the scalar type objects do. There is one class with
* many instances, and each instance has a reserved slot with a
* TypeRepresentation object, which is used to distinguish which
* reference type object this actually is.
*/
const Class js::ReferenceTypeDescr::class_ = {
"Reference",
JSCLASS_HAS_RESERVED_SLOTS(JS_DESCR_SLOTS),
JS_PropertyStub, /* addProperty */
JS_DeletePropertyStub, /* delProperty */
JS_PropertyStub, /* getProperty */
JS_StrictPropertyStub, /* setProperty */
JS_EnumerateStub,
JS_ResolveStub,
JS_ConvertStub,
nullptr,
ReferenceTypeDescr::call,
nullptr,
nullptr,
nullptr
};
const JSFunctionSpec js::ReferenceTypeDescr::typeObjectMethods[] = {
JS_SELF_HOSTED_FN("toSource", "DescrToSourceMethod", 0, 0),
{"array", {nullptr, nullptr}, 1, 0, "ArrayShorthand"},
{"equivalent", {nullptr, nullptr}, 1, 0, "TypeDescrEquivalent"},
JS_FS_END
};
/*static*/ const char *
ReferenceTypeDescr::typeName(Type type)
{
switch (type) {
#define NUMERIC_TYPE_TO_STRING(constant_, type_, name_) \
case constant_: return #name_;
JS_FOR_EACH_REFERENCE_TYPE_REPR(NUMERIC_TYPE_TO_STRING)
}
MOZ_ASSUME_UNREACHABLE("Invalid type");
}
bool
js::ReferenceTypeDescr::call(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
JS_ASSERT(args.callee().is<ReferenceTypeDescr>());
ReferenceTypeRepresentation *typeRepr =
args.callee().as<ReferenceTypeDescr>().typeRepresentation()->asReference();
if (args.length() < 1) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr,
JSMSG_MORE_ARGS_NEEDED,
typeRepr->typeName(), "0", "s");
return false;
}
switch (typeRepr->type()) {
case ReferenceTypeDescr::TYPE_ANY:
args.rval().set(args[0]);
return true;
case ReferenceTypeDescr::TYPE_OBJECT:
{
RootedObject obj(cx, ToObject(cx, args[0]));
if (!obj)
return false;
args.rval().setObject(*obj);
return true;
}
case ReferenceTypeDescr::TYPE_STRING:
{
RootedString obj(cx, ToString<CanGC>(cx, args[0]));
if (!obj)
return false;
args.rval().setString(&*obj);
return true;
}
}
MOZ_ASSUME_UNREACHABLE("Unhandled Reference type");
}

View File

@ -0,0 +1,212 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef builtin_TypedObjectSimple_h
#define builtin_TypedObjectSimple_h
#include "jsobj.h"
#include "builtin/TypedObjectConstants.h"
/*
* Simple Typed Objects
* --------------------
*
* Contains definitions for the "simple" type descriptors like scalar
* and reference types. These are pulled apart from the rest of the
* typed object primarily so that this file can be included from
* TypedArrayObject.h, but it also helps to reduce the monolithic
* nature of TypedObject.h.
*/
namespace js {
class TypeRepresentation;
class ScalarTypeRepresentation;
class ReferenceTypeRepresentation;
class X4TypeRepresentation;
class StructTypeDescr;
/*
* Helper method for converting a double into other scalar
* types in the same way that JavaScript would. In particular,
* simple C casting from double to int32_t gets things wrong
* for values like 0xF0000000.
*/
template <typename T>
static T ConvertScalar(double d)
{
if (TypeIsFloatingPoint<T>()) {
return T(d);
} else if (TypeIsUnsigned<T>()) {
uint32_t n = ToUint32(d);
return T(n);
} else {
int32_t n = ToInt32(d);
return T(n);
}
}
class TypeDescr : public JSObject
{
public:
enum Kind {
Scalar = JS_TYPEREPR_SCALAR_KIND,
Reference = JS_TYPEREPR_REFERENCE_KIND,
X4 = JS_TYPEREPR_X4_KIND,
Struct = JS_TYPEREPR_STRUCT_KIND,
SizedArray = JS_TYPEREPR_SIZED_ARRAY_KIND,
UnsizedArray = JS_TYPEREPR_UNSIZED_ARRAY_KIND,
};
static bool isSized(Kind kind) {
return kind > JS_TYPEREPR_MAX_UNSIZED_KIND;
}
JSObject &typeRepresentationOwnerObj() const {
return getReservedSlot(JS_DESCR_SLOT_TYPE_REPR).toObject();
}
TypeRepresentation *typeRepresentation() const;
TypeDescr::Kind kind() const;
};
typedef Handle<TypeDescr*> HandleTypeDescr;
class SizedTypeDescr : public TypeDescr
{
public:
size_t size() {
return getReservedSlot(JS_DESCR_SLOT_SIZE).toInt32();
}
};
typedef Handle<SizedTypeDescr*> HandleSizedTypeDescr;
class SimpleTypeDescr : public SizedTypeDescr
{
};
// Type for scalar type constructors like `uint8`. All such type
// constructors share a common js::Class and JSFunctionSpec. Scalar
// types are non-opaque (their storage is visible unless combined with
// an opaque reference type.)
class ScalarTypeDescr : public SimpleTypeDescr
{
public:
// Must match order of JS_FOR_EACH_SCALAR_TYPE_REPR below
enum Type {
TYPE_INT8 = JS_SCALARTYPEREPR_INT8,
TYPE_UINT8 = JS_SCALARTYPEREPR_UINT8,
TYPE_INT16 = JS_SCALARTYPEREPR_INT16,
TYPE_UINT16 = JS_SCALARTYPEREPR_UINT16,
TYPE_INT32 = JS_SCALARTYPEREPR_INT32,
TYPE_UINT32 = JS_SCALARTYPEREPR_UINT32,
TYPE_FLOAT32 = JS_SCALARTYPEREPR_FLOAT32,
TYPE_FLOAT64 = JS_SCALARTYPEREPR_FLOAT64,
/*
* Special type that's a uint8_t, but assignments are clamped to 0 .. 255.
* Treat the raw data type as a uint8_t.
*/
TYPE_UINT8_CLAMPED = JS_SCALARTYPEREPR_UINT8_CLAMPED,
};
static const int32_t TYPE_MAX = TYPE_UINT8_CLAMPED + 1;
static size_t size(Type t);
static size_t alignment(Type t);
static const char *typeName(Type type);
static const Class class_;
static const JSFunctionSpec typeObjectMethods[];
typedef ScalarTypeRepresentation TypeRepr;
ScalarTypeDescr::Type type() const {
return (ScalarTypeDescr::Type) getReservedSlot(JS_DESCR_SLOT_TYPE).toInt32();
}
static bool call(JSContext *cx, unsigned argc, Value *vp);
};
// Enumerates the cases of ScalarTypeDescr::Type which have
// unique C representation. In particular, omits Uint8Clamped since it
// is just a Uint8.
#define JS_FOR_EACH_UNIQUE_SCALAR_TYPE_REPR_CTYPE(macro_) \
macro_(ScalarTypeDescr::TYPE_INT8, int8_t, int8) \
macro_(ScalarTypeDescr::TYPE_UINT8, uint8_t, uint8) \
macro_(ScalarTypeDescr::TYPE_INT16, int16_t, int16) \
macro_(ScalarTypeDescr::TYPE_UINT16, uint16_t, uint16) \
macro_(ScalarTypeDescr::TYPE_INT32, int32_t, int32) \
macro_(ScalarTypeDescr::TYPE_UINT32, uint32_t, uint32) \
macro_(ScalarTypeDescr::TYPE_FLOAT32, float, float32) \
macro_(ScalarTypeDescr::TYPE_FLOAT64, double, float64)
// Must be in same order as the enum ScalarTypeDescr::Type:
#define JS_FOR_EACH_SCALAR_TYPE_REPR(macro_) \
JS_FOR_EACH_UNIQUE_SCALAR_TYPE_REPR_CTYPE(macro_) \
macro_(ScalarTypeDescr::TYPE_UINT8_CLAMPED, uint8_t, uint8Clamped)
// Type for reference type constructors like `Any`, `String`, and
// `Object`. All such type constructors share a common js::Class and
// JSFunctionSpec. All these types are opaque.
class ReferenceTypeDescr : public SimpleTypeDescr
{
public:
// Must match order of JS_FOR_EACH_REFERENCE_TYPE_REPR below
enum Type {
TYPE_ANY = JS_REFERENCETYPEREPR_ANY,
TYPE_OBJECT = JS_REFERENCETYPEREPR_OBJECT,
TYPE_STRING = JS_REFERENCETYPEREPR_STRING,
};
static const int32_t TYPE_MAX = TYPE_STRING + 1;
static const char *typeName(Type type);
static const Class class_;
static const JSFunctionSpec typeObjectMethods[];
typedef ReferenceTypeRepresentation TypeRepr;
ReferenceTypeDescr::Type type() const {
return (ReferenceTypeDescr::Type) getReservedSlot(JS_DESCR_SLOT_TYPE).toInt32();
}
static bool call(JSContext *cx, unsigned argc, Value *vp);
};
#define JS_FOR_EACH_REFERENCE_TYPE_REPR(macro_) \
macro_(ReferenceTypeDescr::TYPE_ANY, HeapValue, Any) \
macro_(ReferenceTypeDescr::TYPE_OBJECT, HeapPtrObject, Object) \
macro_(ReferenceTypeDescr::TYPE_STRING, HeapPtrString, string)
/*
* Type descriptors `float32x4` and `int32x4`
*/
class X4TypeDescr : public SizedTypeDescr
{
public:
enum Type {
TYPE_INT32 = JS_X4TYPEREPR_INT32,
TYPE_FLOAT32 = JS_X4TYPEREPR_FLOAT32,
};
static const Class class_;
typedef X4TypeRepresentation TypeRepr;
X4TypeDescr::Type type() const {
return (X4TypeDescr::Type) getReservedSlot(JS_DESCR_SLOT_TYPE).toInt32();
}
static bool call(JSContext *cx, unsigned argc, Value *vp);
static bool is(const Value &v);
};
#define JS_FOR_EACH_X4_TYPE_REPR(macro_) \
macro_(X4TypeDescr::TYPE_INT32, int32_t, int32) \
macro_(X4TypeDescr::TYPE_FLOAT32, float, float32)
} // namespace js
#endif

View File

@ -100,6 +100,7 @@ UNIFIED_SOURCES += [
'builtin/SIMD.cpp',
'builtin/TestingFunctions.cpp',
'builtin/TypedObject.cpp',
'builtin/TypedObjectSimple.cpp',
'builtin/TypeRepresentation.cpp',
'devtools/sharkctl.cpp',
'ds/LifoAlloc.cpp',

View File

@ -9,7 +9,7 @@
#include "jsobj.h"
#include "builtin/TypedObject.h"
#include "builtin/TypedObjectSimple.h"
#include "gc/Barrier.h"
#include "js/Class.h"