Clean up the code handling reads and writes into typed arrays
This is a preparation for supporting atomic operations on Typed arrays. Change-Id: I91d00f3aee3f35fc22e74ee010ed2cbec2d46aae Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
This commit is contained in:
parent
860807b22a
commit
7bdb46c5aa
|
@ -513,7 +513,7 @@ ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine)
|
||||||
static_cast<IntrinsicTypedArrayPrototype *>(intrinsicTypedArrayPrototype())
|
static_cast<IntrinsicTypedArrayPrototype *>(intrinsicTypedArrayPrototype())
|
||||||
->init(this, static_cast<IntrinsicTypedArrayCtor *>(intrinsicTypedArrayCtor()));
|
->init(this, static_cast<IntrinsicTypedArrayCtor *>(intrinsicTypedArrayCtor()));
|
||||||
|
|
||||||
for (int i = 0; i < Heap::TypedArray::NTypes; ++i) {
|
for (int i = 0; i < NTypedArrayTypes; ++i) {
|
||||||
static_cast<Value &>(typedArrayCtors[i]) = memoryManager->allocate<TypedArrayCtor>(global, Heap::TypedArray::Type(i));
|
static_cast<Value &>(typedArrayCtors[i]) = memoryManager->allocate<TypedArrayCtor>(global, Heap::TypedArray::Type(i));
|
||||||
static_cast<Value &>(typedArrayPrototype[i]) = memoryManager->allocate<TypedArrayPrototype>(Heap::TypedArray::Type(i));
|
static_cast<Value &>(typedArrayPrototype[i]) = memoryManager->allocate<TypedArrayPrototype>(Heap::TypedArray::Type(i));
|
||||||
typedArrayPrototype[i].as<TypedArrayPrototype>()->init(this, static_cast<TypedArrayCtor *>(typedArrayCtors[i].as<Object>()));
|
typedArrayPrototype[i].as<TypedArrayPrototype>()->init(this, static_cast<TypedArrayCtor *>(typedArrayCtors[i].as<Object>()));
|
||||||
|
@ -549,8 +549,8 @@ ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine)
|
||||||
globalObject->defineDefaultProperty(QStringLiteral("Set"), *setCtor());
|
globalObject->defineDefaultProperty(QStringLiteral("Set"), *setCtor());
|
||||||
globalObject->defineDefaultProperty(QStringLiteral("Map"), *mapCtor());
|
globalObject->defineDefaultProperty(QStringLiteral("Map"), *mapCtor());
|
||||||
|
|
||||||
for (int i = 0; i < Heap::TypedArray::NTypes; ++i)
|
for (int i = 0; i < NTypedArrayTypes; ++i)
|
||||||
globalObject->defineDefaultProperty((str = typedArrayCtors[i].as<FunctionObject>()->name())->toQString(), typedArrayCtors[i]);
|
globalObject->defineDefaultProperty((str = typedArrayCtors[i].as<FunctionObject>()->name()), typedArrayCtors[i]);
|
||||||
ScopedObject o(scope);
|
ScopedObject o(scope);
|
||||||
globalObject->defineDefaultProperty(QStringLiteral("Math"), (o = memoryManager->allocate<MathObject>()));
|
globalObject->defineDefaultProperty(QStringLiteral("Math"), (o = memoryManager->allocate<MathObject>()));
|
||||||
globalObject->defineDefaultProperty(QStringLiteral("JSON"), (o = memoryManager->allocate<JsonObject>()));
|
globalObject->defineDefaultProperty(QStringLiteral("JSON"), (o = memoryManager->allocate<JsonObject>()));
|
||||||
|
|
|
@ -55,7 +55,7 @@ DEFINE_OBJECT_VTABLE(TypedArrayCtor);
|
||||||
DEFINE_OBJECT_VTABLE(TypedArrayPrototype);
|
DEFINE_OBJECT_VTABLE(TypedArrayPrototype);
|
||||||
DEFINE_OBJECT_VTABLE(TypedArray);
|
DEFINE_OBJECT_VTABLE(TypedArray);
|
||||||
|
|
||||||
Q_STATIC_ASSERT((int)ExecutionEngine::NTypedArrayTypes == (int)Heap::TypedArray::NTypes);
|
Q_STATIC_ASSERT((int)ExecutionEngine::NTypedArrayTypes == (int)NTypedArrayTypes);
|
||||||
|
|
||||||
static inline int toInt32(Value v)
|
static inline int toInt32(Value v)
|
||||||
{
|
{
|
||||||
|
@ -73,144 +73,97 @@ static inline double toDouble(Value v)
|
||||||
return v.doubleValue();
|
return v.doubleValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnedValue Int8ArrayRead(const char *data, int index)
|
struct ClampedUInt8 {
|
||||||
{
|
quint8 c;
|
||||||
return Encode((int)(signed char)data[index]);
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
ReturnedValue typeToValue(T t) {
|
||||||
|
return Encode(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Int8ArrayWrite(char *data, int index, const Value &value)
|
template <>
|
||||||
{
|
ReturnedValue typeToValue(ClampedUInt8 t) {
|
||||||
int n = toInt32(value);
|
return Encode(t.c);
|
||||||
signed char v = static_cast<signed char>(n);
|
|
||||||
data[index] = v;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnedValue UInt8ArrayRead(const char *data, int index)
|
template <typename T>
|
||||||
{
|
T valueToType(Value value)
|
||||||
return Encode((int)(unsigned char)data[index]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UInt8ArrayWrite(char *data, int index, const Value &value)
|
|
||||||
{
|
|
||||||
int n = toInt32(value);
|
|
||||||
unsigned char v = static_cast<unsigned char>(uint(n));
|
|
||||||
data[index] = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
void UInt8ClampedArrayWrite(char *data, int index, const Value &value)
|
|
||||||
{
|
{
|
||||||
Q_ASSERT(value.isNumber());
|
Q_ASSERT(value.isNumber());
|
||||||
if (value.isInteger()) {
|
int n = toInt32(value);
|
||||||
data[index] = (char)(unsigned char)qBound(0, value.integerValue(), 255);
|
return static_cast<T>(n);
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
template <>
|
||||||
|
ClampedUInt8 valueToType(Value value)
|
||||||
|
{
|
||||||
|
Q_ASSERT(value.isNumber());
|
||||||
|
if (value.isInteger())
|
||||||
|
return { static_cast<quint8>(qBound(0, value.integerValue(), 255)) };
|
||||||
Q_ASSERT(value.isDouble());
|
Q_ASSERT(value.isDouble());
|
||||||
double d = value.doubleValue();
|
double d = value.doubleValue();
|
||||||
// ### is there a way to optimise this?
|
// ### is there a way to optimise this?
|
||||||
if (d <= 0 || std::isnan(d)) {
|
if (d <= 0 || std::isnan(d))
|
||||||
data[index] = 0;
|
return { 0 };
|
||||||
return;
|
if (d >= 255)
|
||||||
}
|
return { 255 };
|
||||||
if (d >= 255) {
|
|
||||||
data[index] = (char)(255);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
double f = std::floor(d);
|
double f = std::floor(d);
|
||||||
if (f + 0.5 < d) {
|
if (f + 0.5 < d)
|
||||||
data[index] = (unsigned char)(f + 1);
|
return { (quint8)(f + 1) };
|
||||||
return;
|
if (d < f + 0.5)
|
||||||
}
|
return { (quint8)(f) };
|
||||||
if (d < f + 0.5) {
|
if (int(f) % 2)
|
||||||
data[index] = (unsigned char)(f);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (int(f) % 2) {
|
|
||||||
// odd number
|
// odd number
|
||||||
data[index] = (unsigned char)(f + 1);
|
return { (quint8)(f + 1) };
|
||||||
return;
|
return { (quint8)(f) };
|
||||||
}
|
|
||||||
data[index] = (unsigned char)(f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnedValue Int16ArrayRead(const char *data, int index)
|
template <>
|
||||||
|
float valueToType(Value value)
|
||||||
{
|
{
|
||||||
return Encode((int)*(const short *)(data + index));
|
Q_ASSERT(value.isNumber());
|
||||||
|
double d = toDouble(value);
|
||||||
|
return static_cast<float>(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Int16ArrayWrite(char *data, int index, const Value &value)
|
template <>
|
||||||
|
double valueToType(Value value)
|
||||||
{
|
{
|
||||||
int n = toInt32(value);
|
Q_ASSERT(value.isNumber());
|
||||||
short v = static_cast<short>(n);
|
return toDouble(value);
|
||||||
*(short *)(data + index) = v;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnedValue UInt16ArrayRead(const char *data, int index)
|
template <typename T>
|
||||||
|
ReturnedValue read(const char *data) {
|
||||||
|
return typeToValue(*reinterpret_cast<const T *>(data));
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
void write(char *data, Value value)
|
||||||
{
|
{
|
||||||
return Encode((int)*(const unsigned short *)(data + index));
|
*reinterpret_cast<T *>(data) = valueToType<T>(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UInt16ArrayWrite(char *data, int index, const Value &value)
|
template<typename T>
|
||||||
|
constexpr TypedArrayOperations TypedArrayOperations::create(const char *name)
|
||||||
{
|
{
|
||||||
int n = toInt32(value);
|
return { sizeof(T),
|
||||||
unsigned short v = static_cast<unsigned short>(n);
|
name,
|
||||||
*(unsigned short *)(data + index) = v;
|
::read<T>,
|
||||||
|
::write<T>
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnedValue Int32ArrayRead(const char *data, int index)
|
const TypedArrayOperations operations[NTypedArrayTypes] = {
|
||||||
{
|
TypedArrayOperations::create<qint8>("Int8Array"),
|
||||||
return Encode(*(const int *)(data + index));
|
TypedArrayOperations::create<quint8>("Uint8Array"),
|
||||||
}
|
TypedArrayOperations::create<ClampedUInt8>("Uint8ClampedArray"),
|
||||||
|
TypedArrayOperations::create<qint16>("Int16Array"),
|
||||||
void Int32ArrayWrite(char *data, int index, const Value &value)
|
TypedArrayOperations::create<quint16>("Uint16Array"),
|
||||||
{
|
TypedArrayOperations::create<qint32>("Int32Array"),
|
||||||
int v = toInt32(value);
|
TypedArrayOperations::create<quint32>("Uint32Array"),
|
||||||
*(int *)(data + index) = v;
|
TypedArrayOperations::create<float>("Float32Array"),
|
||||||
}
|
TypedArrayOperations::create<double>("Float64Array")
|
||||||
|
|
||||||
ReturnedValue UInt32ArrayRead(const char *data, int index)
|
|
||||||
{
|
|
||||||
return Encode(*(const unsigned int *)(data + index));
|
|
||||||
}
|
|
||||||
|
|
||||||
void UInt32ArrayWrite(char *data, int index, const Value &value)
|
|
||||||
{
|
|
||||||
int n = toInt32(value);
|
|
||||||
unsigned v = static_cast<unsigned>(n);
|
|
||||||
*(unsigned int *)(data + index) = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnedValue Float32ArrayRead(const char *data, int index)
|
|
||||||
{
|
|
||||||
return Encode(*(const float *)(data + index));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Float32ArrayWrite(char *data, int index, const Value &value)
|
|
||||||
{
|
|
||||||
float v = toDouble(value);
|
|
||||||
*(float *)(data + index) = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnedValue Float64ArrayRead(const char *data, int index)
|
|
||||||
{
|
|
||||||
return Encode(*(const double *)(data + index));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Float64ArrayWrite(char *data, int index, const Value &value)
|
|
||||||
{
|
|
||||||
double v = toDouble(value);
|
|
||||||
*(double *)(data + index) = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
const TypedArrayOperations operations[Heap::TypedArray::NTypes] = {
|
|
||||||
{ 1, "Int8Array", Int8ArrayRead, Int8ArrayWrite },
|
|
||||||
{ 1, "Uint8Array", UInt8ArrayRead, UInt8ArrayWrite },
|
|
||||||
{ 1, "Uint8ClampedArray", UInt8ArrayRead, UInt8ClampedArrayWrite },
|
|
||||||
{ 2, "Int16Array", Int16ArrayRead, Int16ArrayWrite },
|
|
||||||
{ 2, "Uint16Array", UInt16ArrayRead, UInt16ArrayWrite },
|
|
||||||
{ 4, "Int32Array", Int32ArrayRead, Int32ArrayWrite },
|
|
||||||
{ 4, "Uint32Array", UInt32ArrayRead, UInt32ArrayWrite },
|
|
||||||
{ 4, "Float32Array", Float32ArrayRead, Float32ArrayWrite },
|
|
||||||
{ 8, "Float64Array", Float64ArrayRead, Float64ArrayWrite },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -281,8 +234,8 @@ ReturnedValue TypedArrayCtor::virtualCallAsConstructor(const FunctionObject *f,
|
||||||
TypedArrayWrite write =array->d()->type->write;
|
TypedArrayWrite write =array->d()->type->write;
|
||||||
for (uint i = 0; i < l; ++i) {
|
for (uint i = 0; i < l; ++i) {
|
||||||
Primitive val;
|
Primitive val;
|
||||||
val.setRawValue(read(src, i*srcElementSize));
|
val.setRawValue(read(src + i*srcElementSize));
|
||||||
write(dest, i*destElementSize, val);
|
write(dest + i*destElementSize, val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -354,7 +307,7 @@ ReturnedValue TypedArrayCtor::virtualCallAsConstructor(const FunctionObject *f,
|
||||||
val = val->convertedToNumber();
|
val = val->convertedToNumber();
|
||||||
if (scope.engine->hasException)
|
if (scope.engine->hasException)
|
||||||
return Encode::undefined();
|
return Encode::undefined();
|
||||||
array->d()->type->write(b, 0, val);
|
array->d()->type->write(b, val);
|
||||||
if (scope.engine->hasException)
|
if (scope.engine->hasException)
|
||||||
return Encode::undefined();
|
return Encode::undefined();
|
||||||
++idx;
|
++idx;
|
||||||
|
@ -373,14 +326,14 @@ ReturnedValue TypedArrayCtor::virtualCall(const FunctionObject *f, const Value *
|
||||||
void Heap::TypedArray::init(Type t)
|
void Heap::TypedArray::init(Type t)
|
||||||
{
|
{
|
||||||
Object::init();
|
Object::init();
|
||||||
type = operations + t;
|
type = operations + static_cast<int>(t);
|
||||||
arrayType = t;
|
arrayType = static_cast<int>(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
Heap::TypedArray *TypedArray::create(ExecutionEngine *e, Heap::TypedArray::Type t)
|
Heap::TypedArray *TypedArray::create(ExecutionEngine *e, Heap::TypedArray::Type t)
|
||||||
{
|
{
|
||||||
Scope scope(e);
|
Scope scope(e);
|
||||||
Scoped<InternalClass> ic(scope, e->newInternalClass(staticVTable(), e->typedArrayPrototype + t));
|
Scoped<InternalClass> ic(scope, e->newInternalClass(staticVTable(), e->typedArrayPrototype + static_cast<int>(t)));
|
||||||
return e->memoryManager->allocObject<TypedArray>(ic->d(), t);
|
return e->memoryManager->allocObject<TypedArray>(ic->d(), t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -404,7 +357,7 @@ ReturnedValue TypedArray::virtualGet(const Managed *m, PropertyKey id, const Val
|
||||||
}
|
}
|
||||||
if (hasProperty)
|
if (hasProperty)
|
||||||
*hasProperty = true;
|
*hasProperty = true;
|
||||||
return a->d()->type->read(a->d()->buffer->data->data(), byteOffset);
|
return a->d()->type->read(a->d()->buffer->data->data() + byteOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TypedArray::virtualPut(Managed *m, PropertyKey id, const Value &value, Value *receiver)
|
bool TypedArray::virtualPut(Managed *m, PropertyKey id, const Value &value, Value *receiver)
|
||||||
|
@ -430,7 +383,7 @@ bool TypedArray::virtualPut(Managed *m, PropertyKey id, const Value &value, Valu
|
||||||
Value v = Primitive::fromReturnedValue(value.convertedToNumber());
|
Value v = Primitive::fromReturnedValue(value.convertedToNumber());
|
||||||
if (scope.hasException() || a->d()->buffer->isDetachedBuffer())
|
if (scope.hasException() || a->d()->buffer->isDetachedBuffer())
|
||||||
return scope.engine->throwTypeError();
|
return scope.engine->throwTypeError();
|
||||||
a->d()->type->write(a->d()->buffer->data->data(), byteOffset, v);
|
a->d()->type->write(a->d()->buffer->data->data() + byteOffset, v);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -441,12 +394,12 @@ void TypedArrayPrototype::init(ExecutionEngine *engine, TypedArrayCtor *ctor)
|
||||||
|
|
||||||
ctor->defineReadonlyConfigurableProperty(engine->id_length(), Primitive::fromInt32(3));
|
ctor->defineReadonlyConfigurableProperty(engine->id_length(), Primitive::fromInt32(3));
|
||||||
ctor->defineReadonlyProperty(engine->id_prototype(), *this);
|
ctor->defineReadonlyProperty(engine->id_prototype(), *this);
|
||||||
ctor->defineReadonlyProperty(QStringLiteral("BYTES_PER_ELEMENT"), Primitive::fromInt32(operations[ctor->d()->type].bytesPerElement));
|
ctor->defineReadonlyProperty(QStringLiteral("BYTES_PER_ELEMENT"), Primitive::fromInt32(operations[static_cast<int>(ctor->d()->type)].bytesPerElement));
|
||||||
ctor->setPrototypeOf(engine->intrinsicTypedArrayCtor());
|
ctor->setPrototypeOf(engine->intrinsicTypedArrayCtor());
|
||||||
|
|
||||||
setPrototypeOf(engine->intrinsicTypedArrayPrototype());
|
setPrototypeOf(engine->intrinsicTypedArrayPrototype());
|
||||||
defineDefaultProperty(engine->id_constructor(), (o = ctor));
|
defineDefaultProperty(engine->id_constructor(), (o = ctor));
|
||||||
defineReadonlyProperty(QStringLiteral("BYTES_PER_ELEMENT"), Primitive::fromInt32(operations[ctor->d()->type].bytesPerElement));
|
defineReadonlyProperty(QStringLiteral("BYTES_PER_ELEMENT"), Primitive::fromInt32(operations[static_cast<int>(ctor->d()->type)].bytesPerElement));
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnedValue IntrinsicTypedArrayPrototype::method_get_buffer(const FunctionObject *b, const Value *thisObject, const Value *, int)
|
ReturnedValue IntrinsicTypedArrayPrototype::method_get_buffer(const FunctionObject *b, const Value *thisObject, const Value *, int)
|
||||||
|
@ -586,7 +539,7 @@ ReturnedValue IntrinsicTypedArrayPrototype::method_every(const FunctionObject *b
|
||||||
if (v->d()->buffer->isDetachedBuffer())
|
if (v->d()->buffer->isDetachedBuffer())
|
||||||
return scope.engine->throwTypeError();
|
return scope.engine->throwTypeError();
|
||||||
|
|
||||||
arguments[0] = v->d()->type->read(data, byteOffset + k * bytesPerElement);
|
arguments[0] = v->d()->type->read(data + byteOffset + k * bytesPerElement);
|
||||||
|
|
||||||
arguments[1] = Primitive::fromDouble(k);
|
arguments[1] = Primitive::fromDouble(k);
|
||||||
arguments[2] = v;
|
arguments[2] = v;
|
||||||
|
@ -635,7 +588,7 @@ ReturnedValue IntrinsicTypedArrayPrototype::method_fill(const FunctionObject *b,
|
||||||
uint byteOffset = v->d()->byteOffset;
|
uint byteOffset = v->d()->byteOffset;
|
||||||
|
|
||||||
while (k < fin) {
|
while (k < fin) {
|
||||||
v->d()->type->write(data, byteOffset + k * bytesPerElement, value);
|
v->d()->type->write(data + byteOffset + k * bytesPerElement, value);
|
||||||
k++;
|
k++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1259,7 +1212,7 @@ ReturnedValue IntrinsicTypedArrayPrototype::method_set(const FunctionObject *b,
|
||||||
val = val->convertedToNumber();
|
val = val->convertedToNumber();
|
||||||
if (scope.hasException() || buffer->isDetachedBuffer())
|
if (scope.hasException() || buffer->isDetachedBuffer())
|
||||||
return scope.engine->throwTypeError();
|
return scope.engine->throwTypeError();
|
||||||
a->d()->type->write(b, 0, val);
|
a->d()->type->write(b, val);
|
||||||
if (scope.engine->hasException)
|
if (scope.engine->hasException)
|
||||||
RETURN_UNDEFINED();
|
RETURN_UNDEFINED();
|
||||||
++idx;
|
++idx;
|
||||||
|
@ -1299,8 +1252,8 @@ ReturnedValue IntrinsicTypedArrayPrototype::method_set(const FunctionObject *b,
|
||||||
TypedArrayWrite write = a->d()->type->write;
|
TypedArrayWrite write = a->d()->type->write;
|
||||||
for (uint i = 0; i < l; ++i) {
|
for (uint i = 0; i < l; ++i) {
|
||||||
Primitive val;
|
Primitive val;
|
||||||
val.setRawValue(read(src, i*srcElementSize));
|
val.setRawValue(read(src + i*srcElementSize));
|
||||||
write(dest, i*elementSize, val);
|
write(dest + i*elementSize, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (srcCopy)
|
if (srcCopy)
|
||||||
|
|
|
@ -60,10 +60,26 @@ namespace QV4 {
|
||||||
|
|
||||||
struct ArrayBuffer;
|
struct ArrayBuffer;
|
||||||
|
|
||||||
typedef ReturnedValue (*TypedArrayRead)(const char *data, int index);
|
typedef ReturnedValue (*TypedArrayRead)(const char *data);
|
||||||
typedef void (*TypedArrayWrite)(char *data, int index, const Value &value);
|
typedef void (*TypedArrayWrite)(char *data, Value value);
|
||||||
|
|
||||||
|
enum TypedArrayType {
|
||||||
|
Int8Array,
|
||||||
|
UInt8Array,
|
||||||
|
UInt8ClampedArray,
|
||||||
|
Int16Array,
|
||||||
|
UInt16Array,
|
||||||
|
Int32Array,
|
||||||
|
UInt32Array,
|
||||||
|
Float32Array,
|
||||||
|
Float64Array,
|
||||||
|
NTypedArrayTypes
|
||||||
|
};
|
||||||
|
|
||||||
struct TypedArrayOperations {
|
struct TypedArrayOperations {
|
||||||
|
template<typename T>
|
||||||
|
static constexpr TypedArrayOperations create(const char *name);
|
||||||
|
|
||||||
int bytesPerElement;
|
int bytesPerElement;
|
||||||
const char *name;
|
const char *name;
|
||||||
TypedArrayRead read;
|
TypedArrayRead read;
|
||||||
|
@ -81,18 +97,7 @@ namespace Heap {
|
||||||
|
|
||||||
DECLARE_HEAP_OBJECT(TypedArray, Object) {
|
DECLARE_HEAP_OBJECT(TypedArray, Object) {
|
||||||
DECLARE_MARKOBJECTS(TypedArray);
|
DECLARE_MARKOBJECTS(TypedArray);
|
||||||
enum Type {
|
using Type = TypedArrayType;
|
||||||
Int8Array,
|
|
||||||
UInt8Array,
|
|
||||||
UInt8ClampedArray,
|
|
||||||
Int16Array,
|
|
||||||
UInt16Array,
|
|
||||||
Int32Array,
|
|
||||||
UInt32Array,
|
|
||||||
Float32Array,
|
|
||||||
Float64Array,
|
|
||||||
NTypes
|
|
||||||
};
|
|
||||||
|
|
||||||
void init(Type t);
|
void init(Type t);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue