Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qv4arraybuffer.cpp
Go to the documentation of this file.
1// Copyright (C) 2018 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3#include "qv4arraybuffer_p.h"
4#include "qv4typedarray_p.h"
5#include "qv4dataview_p.h"
6#include "qv4symbol_p.h"
7
8using namespace QV4;
9
14
16{
17 Heap::FunctionObject::init(engine, QStringLiteral("SharedArrayBuffer"));
18}
19
21{
22 Heap::FunctionObject::init(engine, QStringLiteral("ArrayBuffer"));
23}
24
26{
27 Scope scope(f);
28 if (newTarget->isUndefined())
29 return scope.engine->throwTypeError();
30
31 const double len = argc ? argv[0].toInteger() : 0;
32 if (scope.hasException())
33 return Encode::undefined();
34 if (len < 0 || len >= std::numeric_limits<int>::max())
35 return scope.engine->throwRangeError(QStringLiteral("SharedArrayBuffer: Invalid length."));
36
37 Scoped<SharedArrayBuffer> a(
38 scope, scope.engine->memoryManager->allocate<SharedArrayBuffer>(size_t(len)));
39 if (scope.hasException())
40 return Encode::undefined();
41
42 return a->asReturnedValue();
43}
44
46{
47 return f->engine()->throwTypeError();
48}
49
50
52{
53 ExecutionEngine *v4 = f->engine();
54 Scope scope(v4);
55
56 ScopedValue l(scope, argc ? argv[0] : Value::undefinedValue());
57 double dl = l->toInteger();
58 if (v4->hasException)
59 return Encode::undefined();
60 uint len = (uint)qBound(0., dl, (double)UINT_MAX);
61 if (len != dl)
62 return v4->throwRangeError(QLatin1String("ArrayBuffer constructor: invalid length"));
63
64 Scoped<ArrayBuffer> a(scope, v4->newArrayBuffer(len));
65 if (newTarget->heapObject() != f->heapObject() && newTarget->isFunctionObject()) {
66 const FunctionObject *nt = static_cast<const FunctionObject *>(newTarget);
67 ScopedObject o(scope, nt->protoProperty());
68 if (o)
69 a->setPrototypeOf(o);
70 }
71 if (scope.hasException())
72 return Encode::undefined();
73
74 return a->asReturnedValue();
75}
76
78{
79 if (argc < 1)
80 return Encode(false);
81
82 if (argv[0].as<TypedArray>() ||
83 argv[0].as<DataView>())
84 return Encode(true);
85
86 return Encode(false);
87}
88
89
91{
92 Object::init();
93 QPair<QTypedArrayData<char> *, char *> pair;
94 if (length < UINT_MAX)
96 if (!pair.first) {
97 new (&arrayDataPointerStorage) QArrayDataPointer<char>();
98 internalClass->engine->throwRangeError(QStringLiteral("ArrayBuffer: out of memory"));
99 return;
100 }
101 auto data = new (&arrayDataPointerStorage) QArrayDataPointer<char>{
102 pair.first, pair.second, qsizetype(length) };
103
104 // can't use appendInitialize() because we want to set the terminating '\0'
105 memset(data->data(), 0, length + 1);
106 isShared = true;
107}
108
110{
111 Object::init();
112 new (&arrayDataPointerStorage) QArrayDataPointer<char>(*const_cast<QByteArray &>(array).data_ptr());
113 isShared = true;
114}
115
117{
118 arrayDataPointer().~QArrayDataPointer();
119 Object::destroy();
120}
121
126
128{
130}
131
132
134{
135 Scope scope(engine);
136 ScopedObject o(scope);
137 ctor->defineReadonlyConfigurableProperty(engine->id_length(), Value::fromInt32(1));
138 ctor->defineReadonlyProperty(engine->id_prototype(), (o = this));
139 ctor->addSymbolSpecies();
140
141 defineDefaultProperty(engine->id_constructor(), (o = ctor));
142 defineAccessorProperty(QStringLiteral("byteLength"), method_get_byteLength, nullptr);
143 defineDefaultProperty(QStringLiteral("slice"), method_slice, 2);
144 ScopedString name(scope, engine->newString(QStringLiteral("SharedArrayBuffer")));
145 defineReadonlyConfigurableProperty(scope.engine->symbol_toStringTag(), name);
146}
147
149{
150 const SharedArrayBuffer *a = thisObject->as<SharedArrayBuffer>();
151 if (!a || a->hasDetachedArrayData() || !a->isSharedArrayBuffer())
152 return b->engine()->throwTypeError();
153
154 return Encode(a->arrayDataLength());
155}
156
157ReturnedValue SharedArrayBufferPrototype::method_slice(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
158{
159 return slice(b, thisObject, argv, argc, true);
160}
161
162ReturnedValue SharedArrayBufferPrototype::slice(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc, bool shared)
163{
164 Scope scope(b);
165 const SharedArrayBuffer *a = thisObject->as<SharedArrayBuffer>();
166 if (!a || a->hasDetachedArrayData() || (a->isSharedArrayBuffer() != shared))
167 return scope.engine->throwTypeError();
168
169 const uint aDataLength = a->arrayDataLength();
170
171 double start = argc > 0 ? argv[0].toInteger() : 0;
172 double end = (argc < 2 || argv[1].isUndefined()) ? aDataLength : argv[1].toInteger();
173 if (scope.hasException())
174 return QV4::Encode::undefined();
175
176 double first = (start < 0) ? qMax(aDataLength + start, 0.) : qMin(start, double(aDataLength));
177 double final = (end < 0) ? qMax(aDataLength + end, 0.) : qMin(end, double(aDataLength));
178
179 const FunctionObject *constructor = a->speciesConstructor(scope, shared ? scope.engine->sharedArrayBufferCtor() : scope.engine->arrayBufferCtor());
180 if (!constructor)
181 return scope.engine->throwTypeError();
182
183 double newLen = qMax(final - first, 0.);
184 ScopedValue argument(scope, QV4::Encode(newLen));
185 QV4::Scoped<SharedArrayBuffer> newBuffer(scope, constructor->callAsConstructor(argument, 1));
186 if (!newBuffer || newBuffer->arrayDataLength() < newLen ||
187 newBuffer->hasDetachedArrayData() || (newBuffer->isSharedArrayBuffer() != shared) ||
188 newBuffer->sameValue(*a) ||
189 a->hasDetachedArrayData())
190 return scope.engine->throwTypeError();
191
192 memcpy(newBuffer->arrayData(), a->constArrayData() + (uint)first, newLen);
193 return newBuffer->asReturnedValue();
194}
195
196
198{
199 Scope scope(engine);
200 ScopedObject o(scope);
201 ctor->defineReadonlyConfigurableProperty(engine->id_length(), Value::fromInt32(1));
202 ctor->defineReadonlyProperty(engine->id_prototype(), (o = this));
203 ctor->defineDefaultProperty(QStringLiteral("isView"), ArrayBufferCtor::method_isView, 1);
204 ctor->addSymbolSpecies();
205
206 defineDefaultProperty(engine->id_constructor(), (o = ctor));
207 defineAccessorProperty(QStringLiteral("byteLength"), method_get_byteLength, nullptr);
208 defineDefaultProperty(QStringLiteral("slice"), method_slice, 2);
209 defineDefaultProperty(QStringLiteral("toString"), method_toString, 0);
210 ScopedString name(scope, engine->newString(QStringLiteral("ArrayBuffer")));
211 defineReadonlyConfigurableProperty(scope.engine->symbol_toStringTag(), name);
212}
213
215{
216 const ArrayBuffer *a = thisObject->as<ArrayBuffer>();
217 if (!a || a->isSharedArrayBuffer())
218 return f->engine()->throwTypeError();
219
220 if (a->hasDetachedArrayData())
221 return Encode(0);
222
223 return Encode(a->arrayDataLength());
224}
225
226ReturnedValue ArrayBufferPrototype::method_slice(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
227{
228 return slice(b, thisObject, argv, argc, false);
229}
230
232{
233 ExecutionEngine *v4 = b->engine();
234 const ArrayBuffer *a = thisObject->as<ArrayBuffer>();
235 if (!a)
237 return Encode(v4->newString(QString::fromUtf8(a->asByteArray())));
238}
\inmodule QtCore
Definition qbytearray.h:57
const DataPointer & data_ptr() const
Definition qbytearray.h:503
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:6018
ObjectType::Data * allocate(Args &&... args)
Definition qv4mm_p.h:298
quint64 ReturnedValue
Scoped< String > ScopedString
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
constexpr const T & qBound(const T &min, const T &val, const T &max)
Definition qminmax.h:44
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
GLboolean GLboolean GLboolean b
GLboolean GLboolean GLboolean GLboolean a
[7]
GLuint GLuint end
GLenum GLuint GLenum GLsizei length
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLfloat GLfloat f
GLuint start
GLuint name
GLint first
GLenum array
GLenum GLsizei len
QLatin1StringView QLatin1String
Definition qstringfwd.h:31
#define QStringLiteral(str)
ptrdiff_t qsizetype
Definition qtypes.h:165
unsigned int uint
Definition qtypes.h:34
#define RETURN_UNDEFINED()
#define DEFINE_OBJECT_VTABLE(classname)
QDBusArgument argument
QJSEngine engine
[0]
static std::pair< QTypedArrayData *, T * > allocate(qsizetype capacity, AllocationOption option=QArrayData::KeepSize)
Definition qarraydata.h:129
static ReturnedValue method_isView(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_get_byteLength(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_toString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_slice(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
void init(ExecutionEngine *engine, Object *ctor)
V4_NEEDS_DESTROY QByteArray asByteArray() const
static constexpr ReturnedValue undefined()
MemoryManager * memoryManager
ReturnedValue throwRangeError(const Value &value)
Symbol * symbol_toStringTag() const
FunctionObject * arrayBufferCtor() const
Heap::String * newString(char16_t c)
Heap::ArrayBuffer * newArrayBuffer(const QByteArray &array)
ReturnedValue throwTypeError()
FunctionObject * sharedArrayBufferCtor() const
ReturnedValue protoProperty() const
ReturnedValue callAsConstructor(const Value *argv, int argc, const Value *newTarget=nullptr) const
void init(QV4::ExecutionEngine *engine)
void init(QV4::ExecutionEngine *engine)
uint arrayDataLength() const noexcept
const char * constArrayData() const noexcept
ExecutionEngine * engine() const
const FunctionObject * speciesConstructor(Scope &scope, const FunctionObject *defaultConstructor) const
bool hasException() const
ExecutionEngine * engine
void init(ExecutionEngine *engine, Object *ctor)
static ReturnedValue method_get_byteLength(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_slice(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue slice(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc, bool shared)
bool isUndefined() const
static constexpr VTable::CallAsConstructor virtualCallAsConstructor
static constexpr VTable::Call virtualCall
static constexpr Value fromInt32(int i)
Definition qv4value_p.h:187
bool isFunctionObject() const
Definition qv4value_p.h:309
static constexpr Value undefinedValue()
Definition qv4value_p.h:191
const T * as() const
Definition qv4value_p.h:132
QML_NEARLY_ALWAYS_INLINE Value::HeapBasePtr heapObject() const
Definition qv4value_p.h:80
double toInteger() const
Definition qv4value_p.h:394