39ReturnedValue DataViewCtor::virtualCallAsConstructor(
const FunctionObject *f,
const Value *argv,
int argc,
const Value *newTarget)
41 Scope scope(f->engine());
42 Scoped<SharedArrayBuffer> buffer(scope, argc ? argv[0] : Value::undefinedValue());
43 if (!newTarget || !buffer)
44 return scope.engine->throwTypeError();
46 uint offset = ::toIndex(scope.engine, argc > 1 ? argv[1] : Value::undefinedValue());
47 if (scope.hasException())
48 return Encode::undefined();
49 if (buffer->hasDetachedArrayData())
50 return scope.engine->throwTypeError();
52 uint bufferLength = buffer->arrayDataLength();
53 if (offset > bufferLength)
54 return scope.engine->throwRangeError(QStringLiteral(
"DataView: constructor arguments out of range"));
56 uint byteLength = (argc < 3 || argv[2].isUndefined()) ? (bufferLength - offset) : ::toIndex(scope.engine, argv[2]);
57 if (scope.hasException())
58 return Encode::undefined();
59 if (offset > bufferLength || byteLength > bufferLength - offset)
60 return scope.engine->throwRangeError(QStringLiteral(
"DataView: constructor arguments out of range"));
62 Scoped<DataView> a(scope, scope.engine->memoryManager->allocate<DataView>());
63 a->d()->buffer.set(scope.engine, buffer->d());
64 a->d()->byteLength = byteLength;
65 a->d()->byteOffset = offset;
66 return a.asReturnedValue();
74void DataViewPrototype::init(ExecutionEngine *engine, Object *ctor)
77 ScopedObject o(scope);
78 ctor->defineReadonlyConfigurableProperty(engine->id_length(), Value::fromInt32(1));
79 ctor->defineReadonlyProperty(engine->id_prototype(), (o =
this));
80 defineDefaultProperty(engine->id_constructor(), (o = ctor));
81 defineAccessorProperty(QStringLiteral(
"buffer"), method_get_buffer,
nullptr);
82 defineAccessorProperty(QStringLiteral(
"byteLength"), method_get_byteLength,
nullptr);
83 defineAccessorProperty(QStringLiteral(
"byteOffset"), method_get_byteOffset,
nullptr);
85 defineDefaultProperty(QStringLiteral(
"getInt8"), method_getChar<
signed char>, 1);
86 defineDefaultProperty(QStringLiteral(
"getUint8"), method_getChar<
unsigned char>, 1);
87 defineDefaultProperty(QStringLiteral(
"getInt16"), method_get<
short>, 1);
88 defineDefaultProperty(QStringLiteral(
"getUint16"), method_get<
unsigned short>, 1);
89 defineDefaultProperty(QStringLiteral(
"getInt32"), method_get<
int>, 1);
90 defineDefaultProperty(QStringLiteral(
"getUint32"), method_get<
unsigned int>, 1);
91 defineDefaultProperty(QStringLiteral(
"getFloat32"), method_getFloat<
float>, 1);
92 defineDefaultProperty(QStringLiteral(
"getFloat64"), method_getFloat<
double>, 1);
94 defineDefaultProperty(QStringLiteral(
"setInt8"), method_setChar<
signed char>, 2);
95 defineDefaultProperty(QStringLiteral(
"setUint8"), method_setChar<
unsigned char>, 2);
96 defineDefaultProperty(QStringLiteral(
"setInt16"), method_set<
short>, 2);
97 defineDefaultProperty(QStringLiteral(
"setUint16"), method_set<
unsigned short>, 2);
98 defineDefaultProperty(QStringLiteral(
"setInt32"), method_set<
int>, 2);
99 defineDefaultProperty(QStringLiteral(
"setUint32"), method_set<
unsigned int>, 2);
100 defineDefaultProperty(QStringLiteral(
"setFloat32"), method_setFloat<
float>, 2);
101 defineDefaultProperty(QStringLiteral(
"setFloat64"), method_setFloat<
double>, 2);
103 ScopedString name(scope, engine->newString(QStringLiteral(
"DataView")));
104 defineReadonlyConfigurableProperty(scope.engine->symbol_toStringTag(), name);
107 defineDefaultProperty(QStringLiteral(
"getUInt8"), method_getChar<
unsigned char>, 1);
108 defineDefaultProperty(QStringLiteral(
"getUInt16"), method_get<
unsigned short>, 1);
109 defineDefaultProperty(QStringLiteral(
"getUInt32"), method_get<
unsigned int>, 1);
110 defineDefaultProperty(QStringLiteral(
"setUInt8"), method_setChar<
unsigned char>, 1);
111 defineDefaultProperty(QStringLiteral(
"setUInt16"), method_set<
unsigned short>, 1);
112 defineDefaultProperty(QStringLiteral(
"setUInt32"), method_set<
unsigned int>, 1);
124ReturnedValue DataViewPrototype::method_get_byteLength(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
126 const DataView *v = thisObject->as<DataView>();
128 return b->engine()->throwTypeError();
130 if (v->d()->buffer->hasDetachedArrayData())
131 return b->engine()->throwTypeError();
133 return Encode(v->d()->byteLength);
136ReturnedValue DataViewPrototype::method_get_byteOffset(
const FunctionObject *b,
const Value *thisObject,
const Value *,
int)
138 const DataView *v = thisObject->as<DataView>();
140 return b->engine()->throwTypeError();
142 if (v->d()->buffer->hasDetachedArrayData())
143 return b->engine()->throwTypeError();
145 return Encode(v->d()->byteOffset);
149ReturnedValue DataViewPrototype::method_getChar(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
151 ExecutionEngine *e = b->engine();
152 const DataView *v = thisObject->as<DataView>();
154 return e->throwTypeError();
155 uint idx = ::toIndex(e, argc ? argv[0] : Value::undefinedValue());
157 return Encode::undefined();
158 if (v->d()->buffer->hasDetachedArrayData())
159 return e->throwTypeError();
160 if (idx +
sizeof(T) > v->d()->byteLength)
161 return e->throwRangeError(QStringLiteral(
"index out of range"));
162 idx += v->d()->byteOffset;
164 T t = T(v->d()->buffer->constArrayData()[idx]);
166 return Encode((
int)t);
170ReturnedValue DataViewPrototype::method_get(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
172 ExecutionEngine *e = b->engine();
173 const DataView *v = thisObject->as<DataView>();
175 return e->throwTypeError();
176 uint idx = ::toIndex(e, argc ? argv[0] : Value::undefinedValue());
178 return Encode::undefined();
179 if (v->d()->buffer->hasDetachedArrayData())
180 return e->throwTypeError();
181 if (idx +
sizeof(T) > v->d()->byteLength)
182 return e->throwRangeError(QStringLiteral(
"index out of range"));
183 idx += v->d()->byteOffset;
185 bool littleEndian = argc < 2 ?
false : argv[1].toBoolean();
188 ? qFromLittleEndian<T>((
const uchar *)v->d()->buffer->constArrayData() + idx)
189 : qFromBigEndian<T>((
const uchar *)v->d()->buffer->constArrayData() + idx);
195ReturnedValue DataViewPrototype::method_getFloat(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
197 ExecutionEngine *e = b->engine();
198 const DataView *v = thisObject->as<DataView>();
200 return e->throwTypeError();
201 uint idx = ::toIndex(e, argc ? argv[0] : Value::undefinedValue());
203 return Encode::undefined();
204 if (v->d()->buffer->hasDetachedArrayData())
205 return e->throwTypeError();
206 if (idx +
sizeof(T) > v->d()->byteLength)
207 return e->throwRangeError(QStringLiteral(
"index out of range"));
208 idx += v->d()->byteOffset;
210 bool littleEndian = argc < 2 ?
false : argv[1].toBoolean();
212 if (
sizeof(T) == 4) {
219 ? qFromLittleEndian<uint>((
const uchar *)v->d()->buffer->constArrayData() + idx)
220 : qFromBigEndian<uint>((
const uchar *)v->d()->buffer->constArrayData() + idx);
223 Q_ASSERT(
sizeof(T) == 8);
229 ? qFromLittleEndian<quint64>((
const uchar *)v->d()->buffer->constArrayData() + idx)
230 : qFromBigEndian<quint64>((
const uchar *)v->d()->buffer->constArrayData() + idx);
236ReturnedValue DataViewPrototype::method_setChar(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
238 ExecutionEngine *e = b->engine();
239 const DataView *v = thisObject->as<DataView>();
241 return e->throwTypeError();
242 uint idx = ::toIndex(e, argc ? argv[0] : Value::undefinedValue());
244 return Encode::undefined();
246 int val = argc >= 2 ? argv[1].toInt32() : 0;
248 if (v->d()->buffer->hasDetachedArrayData())
249 return e->throwTypeError();
251 if (idx +
sizeof(T) > v->d()->byteLength)
252 return e->throwRangeError(QStringLiteral(
"index out of range"));
253 idx += v->d()->byteOffset;
255 v->d()->buffer->arrayData()[idx] = (
char)val;
261ReturnedValue DataViewPrototype::method_set(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
263 ExecutionEngine *e = b->engine();
264 const DataView *v = thisObject->as<DataView>();
266 return e->throwTypeError();
267 uint idx = ::toIndex(e, argc ? argv[0] : Value::undefinedValue());
269 return Encode::undefined();
271 int val = argc >= 2 ? argv[1].toInt32() : 0;
272 bool littleEndian = argc < 3 ?
false : argv[2].toBoolean();
274 if (v->d()->buffer->hasDetachedArrayData())
275 return e->throwTypeError();
277 if (idx +
sizeof(T) > v->d()->byteLength)
278 return e->throwRangeError(QStringLiteral(
"index out of range"));
279 idx += v->d()->byteOffset;
283 qToLittleEndian<T>(val, (uchar *)v->d()->buffer->arrayData() + idx);
285 qToBigEndian<T>(val, (uchar *)v->d()->buffer->arrayData() + idx);
291ReturnedValue DataViewPrototype::method_setFloat(
const FunctionObject *b,
const Value *thisObject,
const Value *argv,
int argc)
293 ExecutionEngine *e = b->engine();
294 const DataView *v = thisObject->as<DataView>();
296 return e->throwTypeError();
297 uint idx = ::toIndex(e, argc ? argv[0] : Value::undefinedValue());
299 return Encode::undefined();
301 double val = argc >= 2 ? argv[1].toNumber() : qt_qnan();
302 bool littleEndian = argc < 3 ?
false : argv[2].toBoolean();
304 if (v->d()->buffer->hasDetachedArrayData())
305 return e->throwTypeError();
307 if (idx +
sizeof(T) > v->d()->byteLength)
308 return e->throwRangeError(QStringLiteral(
"index out of range"));
309 idx += v->d()->byteOffset;
311 if (
sizeof(T) == 4) {
319 qToLittleEndian(u.i, (uchar *)v->d()->buffer->arrayData() + idx);
321 qToBigEndian(u.i, (uchar *)v->d()->buffer->arrayData() + idx);
323 Q_ASSERT(
sizeof(T) == 8);
330 qToLittleEndian(u.i, (uchar *)v->d()->buffer->arrayData() + idx);
332 qToBigEndian(u.i, (uchar *)v->d()->buffer->arrayData() + idx);