38ReturnedValue DataViewCtor::virtualCallAsConstructor(
const FunctionObject *f,
const Value *argv,
int argc,
const Value *newTarget)
40 Scope scope(f->engine());
41 Scoped<SharedArrayBuffer> buffer(scope, argc ? argv[0] : Value::undefinedValue());
42 if (!newTarget || !buffer)
43 return scope.engine->throwTypeError();
45 uint offset = ::toIndex(scope.engine, argc > 1 ? argv[1] : Value::undefinedValue());
46 if (scope.hasException())
47 return Encode::undefined();
48 if (buffer->hasDetachedArrayData())
49 return scope.engine->throwTypeError();
51 uint bufferLength = buffer->arrayDataLength();
52 if (offset > bufferLength)
53 return scope.engine->throwRangeError(QStringLiteral(
"DataView: constructor arguments out of range"));
55 uint byteLength = (argc < 3 || argv[2].isUndefined()) ? (bufferLength - offset) : ::toIndex(scope.engine, argv[2]);
56 if (scope.hasException())
57 return Encode::undefined();
58 if (offset > bufferLength || byteLength > bufferLength - offset)
59 return scope.engine->throwRangeError(QStringLiteral(
"DataView: constructor arguments out of range"));
61 Scoped<DataView> a(scope, scope.engine->memoryManager->allocate<DataView>());
62 a->d()->buffer.set(scope.engine, buffer->d());
63 a->d()->byteLength = byteLength;
64 a->d()->byteOffset = offset;
65 return a.asReturnedValue();
73void DataViewPrototype::init(ExecutionEngine *engine, Object *ctor)
76 ScopedObject o(scope);
77 ctor->defineReadonlyConfigurableProperty(engine->id_length(), Value::fromInt32(1));
78 ctor->defineReadonlyProperty(engine->id_prototype(), (o =
this));
79 defineDefaultProperty(engine->id_constructor(), (o = ctor));
80 defineAccessorProperty(QStringLiteral(
"buffer"), method_get_buffer,
nullptr);
81 defineAccessorProperty(QStringLiteral(
"byteLength"), method_get_byteLength,
nullptr);
82 defineAccessorProperty(QStringLiteral(
"byteOffset"), method_get_byteOffset,
nullptr);
84 defineDefaultProperty(QStringLiteral(
"getInt8"), method_getChar<
signed char>, 1);
85 defineDefaultProperty(QStringLiteral(
"getUint8"), method_getChar<
unsigned char>, 1);
86 defineDefaultProperty(QStringLiteral(
"getInt16"), method_get<
short>, 1);
87 defineDefaultProperty(QStringLiteral(
"getUint16"), method_get<
unsigned short>, 1);
88 defineDefaultProperty(QStringLiteral(
"getInt32"), method_get<
int>, 1);
89 defineDefaultProperty(QStringLiteral(
"getUint32"), method_get<
unsigned int>, 1);
90 defineDefaultProperty(QStringLiteral(
"getFloat32"), method_getFloat<
float>, 1);
91 defineDefaultProperty(QStringLiteral(
"getFloat64"), method_getFloat<
double>, 1);
93 defineDefaultProperty(QStringLiteral(
"setInt8"), method_setChar<
signed char>, 2);
94 defineDefaultProperty(QStringLiteral(
"setUint8"), method_setChar<
unsigned char>, 2);
95 defineDefaultProperty(QStringLiteral(
"setInt16"), method_set<
short>, 2);
96 defineDefaultProperty(QStringLiteral(
"setUint16"), method_set<
unsigned short>, 2);
97 defineDefaultProperty(QStringLiteral(
"setInt32"), method_set<
int>, 2);
98 defineDefaultProperty(QStringLiteral(
"setUint32"), method_set<
unsigned int>, 2);
99 defineDefaultProperty(QStringLiteral(
"setFloat32"), method_setFloat<
float>, 2);
100 defineDefaultProperty(QStringLiteral(
"setFloat64"), method_setFloat<
double>, 2);
102 ScopedString name(scope, engine->newString(QStringLiteral(
"DataView")));
103 defineReadonlyConfigurableProperty(scope.engine->symbol_toStringTag(), name);
106 defineDefaultProperty(QStringLiteral(
"getUInt8"), method_getChar<
unsigned char>, 1);
107 defineDefaultProperty(QStringLiteral(
"getUInt16"), method_get<
unsigned short>, 1);
108 defineDefaultProperty(QStringLiteral(
"getUInt32"), method_get<
unsigned int>, 1);
109 defineDefaultProperty(QStringLiteral(
"setUInt8"), method_setChar<
unsigned char>, 1);
110 defineDefaultProperty(QStringLiteral(
"setUInt16"), method_set<
unsigned short>, 1);
111 defineDefaultProperty(QStringLiteral(
"setUInt32"), method_set<
unsigned int>, 1);
123ReturnedValue DataViewPrototype::method_get_byteLength(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
125 const DataView *v = thisObject->as<DataView>();
127 return b->engine()->throwTypeError();
129 if (v->d()->buffer->hasDetachedArrayData())
130 return b->engine()->throwTypeError();
132 return Encode(v->d()->byteLength);
135ReturnedValue DataViewPrototype::method_get_byteOffset(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
137 const DataView *v = thisObject->as<DataView>();
139 return b->engine()->throwTypeError();
141 if (v->d()->buffer->hasDetachedArrayData())
142 return b->engine()->throwTypeError();
144 return Encode(v->d()->byteOffset);
148ReturnedValue DataViewPrototype::method_getChar(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
150 ExecutionEngine *e = b->engine();
151 const DataView *v = thisObject->as<DataView>();
153 return e->throwTypeError();
154 uint idx = ::toIndex(e, argc ? argv[0] : Value::undefinedValue());
156 return Encode::undefined();
157 if (v->d()->buffer->hasDetachedArrayData())
158 return e->throwTypeError();
159 if (idx +
sizeof(T) > v->d()->byteLength)
160 return e->throwRangeError(QStringLiteral(
"index out of range"));
161 idx += v->d()->byteOffset;
163 T t = T(v->d()->buffer->constArrayData()[idx]);
165 return Encode((
int)t);
169ReturnedValue DataViewPrototype::method_get(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
171 ExecutionEngine *e = b->engine();
172 const DataView *v = thisObject->as<DataView>();
174 return e->throwTypeError();
175 uint idx = ::toIndex(e, argc ? argv[0] : Value::undefinedValue());
177 return Encode::undefined();
178 if (v->d()->buffer->hasDetachedArrayData())
179 return e->throwTypeError();
180 if (idx +
sizeof(T) > v->d()->byteLength)
181 return e->throwRangeError(QStringLiteral(
"index out of range"));
182 idx += v->d()->byteOffset;
184 bool littleEndian = argc < 2 ?
false : argv[1].toBoolean();
187 ? qFromLittleEndian<T>((
const uchar *)v->d()->buffer->constArrayData() + idx)
188 : qFromBigEndian<T>((
const uchar *)v->d()->buffer->constArrayData() + idx);
194ReturnedValue DataViewPrototype::method_getFloat(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
196 ExecutionEngine *e = b->engine();
197 const DataView *v = thisObject->as<DataView>();
199 return e->throwTypeError();
200 uint idx = ::toIndex(e, argc ? argv[0] : Value::undefinedValue());
202 return Encode::undefined();
203 if (v->d()->buffer->hasDetachedArrayData())
204 return e->throwTypeError();
205 if (idx +
sizeof(T) > v->d()->byteLength)
206 return e->throwRangeError(QStringLiteral(
"index out of range"));
207 idx += v->d()->byteOffset;
209 bool littleEndian = argc < 2 ?
false : argv[1].toBoolean();
211 if (
sizeof(T) == 4) {
218 ? qFromLittleEndian<uint>((
const uchar *)v->d()->buffer->constArrayData() + idx)
219 : qFromBigEndian<uint>((
const uchar *)v->d()->buffer->constArrayData() + idx);
222 Q_ASSERT(
sizeof(T) == 8);
228 ? qFromLittleEndian<quint64>((
const uchar *)v->d()->buffer->constArrayData() + idx)
229 : qFromBigEndian<quint64>((
const uchar *)v->d()->buffer->constArrayData() + idx);
235ReturnedValue DataViewPrototype::method_setChar(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
237 ExecutionEngine *e = b->engine();
238 const DataView *v = thisObject->as<DataView>();
240 return e->throwTypeError();
241 uint idx = ::toIndex(e, argc ? argv[0] : Value::undefinedValue());
243 return Encode::undefined();
245 int val = argc >= 2 ? argv[1].toInt32() : 0;
247 if (v->d()->buffer->hasDetachedArrayData())
248 return e->throwTypeError();
250 if (idx +
sizeof(T) > v->d()->byteLength)
251 return e->throwRangeError(QStringLiteral(
"index out of range"));
252 idx += v->d()->byteOffset;
254 v->d()->buffer->arrayData()[idx] = (
char)val;
260ReturnedValue DataViewPrototype::method_set(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
262 ExecutionEngine *e = b->engine();
263 const DataView *v = thisObject->as<DataView>();
265 return e->throwTypeError();
266 uint idx = ::toIndex(e, argc ? argv[0] : Value::undefinedValue());
268 return Encode::undefined();
270 int val = argc >= 2 ? argv[1].toInt32() : 0;
271 bool littleEndian = argc < 3 ?
false : argv[2].toBoolean();
273 if (v->d()->buffer->hasDetachedArrayData())
274 return e->throwTypeError();
276 if (idx +
sizeof(T) > v->d()->byteLength)
277 return e->throwRangeError(QStringLiteral(
"index out of range"));
278 idx += v->d()->byteOffset;
282 qToLittleEndian<T>(val, (uchar *)v->d()->buffer->arrayData() + idx);
284 qToBigEndian<T>(val, (uchar *)v->d()->buffer->arrayData() + idx);
290ReturnedValue DataViewPrototype::method_setFloat(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
292 ExecutionEngine *e = b->engine();
293 const DataView *v = thisObject->as<DataView>();
295 return e->throwTypeError();
296 uint idx = ::toIndex(e, argc ? argv[0] : Value::undefinedValue());
298 return Encode::undefined();
300 double val = argc >= 2 ? argv[1].toNumber() : qt_qnan();
301 bool littleEndian = argc < 3 ?
false : argv[2].toBoolean();
303 if (v->d()->buffer->hasDetachedArrayData())
304 return e->throwTypeError();
306 if (idx +
sizeof(T) > v->d()->byteLength)
307 return e->throwRangeError(QStringLiteral(
"index out of range"));
308 idx += v->d()->byteOffset;
310 if (
sizeof(T) == 4) {
318 qToLittleEndian(u.i, (uchar *)v->d()->buffer->arrayData() + idx);
320 qToBigEndian(u.i, (uchar *)v->d()->buffer->arrayData() + idx);
322 Q_ASSERT(
sizeof(T) == 8);
329 qToLittleEndian(u.i, (uchar *)v->d()->buffer->arrayData() + idx);
331 qToBigEndian(u.i, (uchar *)v->d()->buffer->arrayData() + idx);