1// Copyright (C) 2016 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#ifndef QV4ERROROBJECT_H
4#define QV4ERROROBJECT_H
5
6//
7// W A R N I N G
8// -------------
9//
10// This file is not part of the Qt API. It exists purely as an
11// implementation detail. This header file may change from version to
12// version without notice, or even be removed.
13//
14// We mean it.
15//
16
17#include "qv4object_p.h"
18#include "qv4functionobject_p.h"
19
20QT_BEGIN_NAMESPACE
21
22namespace QV4 {
23
24struct SyntaxErrorObject;
25
26namespace Heap {
27
28
29#define ErrorObjectMembers(class, Member) \
30 Member(class, Pointer, String *, stack)
31
32DECLARE_HEAP_OBJECT(ErrorObject, Object) {
33 DECLARE_MARKOBJECTS(ErrorObject)
34 enum ErrorType {
35 Error,
36 EvalError,
37 RangeError,
38 ReferenceError,
39 SyntaxError,
40 TypeError,
41 URIError
42 };
43 StackTrace *stackTrace;
44 ErrorType errorType;
45
46 void init();
47 void init(const Value &message, ErrorType t = Error);
48 void init(const Value &message, const QString &fileName, int line, int column, ErrorType t = Error);
49 void destroy() {
50 delete stackTrace;
51 Object::destroy();
52 }
53};
54
55struct EvalErrorObject : ErrorObject {
56 void init(const Value &message);
57};
58
59struct RangeErrorObject : ErrorObject {
60 void init(const Value &message);
61};
62
63struct ReferenceErrorObject : ErrorObject {
64 void init(const Value &message);
65 void init(const Value &msg, const QString &fileName, int lineNumber, int columnNumber);
66};
67
68struct SyntaxErrorObject : ErrorObject {
69 void init(const Value &message);
70 void init(const Value &msg, const QString &fileName, int lineNumber, int columnNumber);
71};
72
73struct TypeErrorObject : ErrorObject {
74 void init(const Value &message);
75};
76
77struct URIErrorObject : ErrorObject {
78 void init(const Value &message);
79};
80
81struct ErrorCtor : FunctionObject {
82 void init(QV4::ExecutionContext *scope);
83 void init(QV4::ExecutionContext *scope, const QString &name);
84};
85
86struct EvalErrorCtor : ErrorCtor {
87 void init(QV4::ExecutionContext *scope);
88};
89
90struct RangeErrorCtor : ErrorCtor {
91 void init(QV4::ExecutionContext *scope);
92};
93
94struct ReferenceErrorCtor : ErrorCtor {
95 void init(QV4::ExecutionContext *scope);
96};
97
98struct SyntaxErrorCtor : ErrorCtor {
99 void init(QV4::ExecutionContext *scope);
100};
101
102struct TypeErrorCtor : ErrorCtor {
103 void init(QV4::ExecutionContext *scope);
104};
105
106struct URIErrorCtor : ErrorCtor {
107 void init(QV4::ExecutionContext *scope);
108};
109
110}
111
112struct ErrorObject: Object {
113 enum {
114 IsErrorObject = true
115 };
116
117 enum {
118 Index_Stack = 0, // Accessor Property
119 Index_StackSetter = 1, // Accessor Property
120 Index_FileName = 2,
121 Index_LineNumber = 3,
122 Index_Message = 4
123 };
124
125 V4_OBJECT2(ErrorObject, Object)
126 Q_MANAGED_TYPE(ErrorObject)
127 V4_INTERNALCLASS(ErrorObject)
128 V4_PROTOTYPE(errorPrototype)
129 V4_NEEDS_DESTROY
130
131 template <typename T>
132 static Heap::Object *create(ExecutionEngine *e, const Value &message, const Value *newTarget);
133 template <typename T>
134 static Heap::Object *create(ExecutionEngine *e, const QString &message);
135 template <typename T>
136 static Heap::Object *create(ExecutionEngine *e, const QString &message, const QString &filename, int line, int column);
137
138 SyntaxErrorObject *asSyntaxError();
139
140 static const char *className(Heap::ErrorObject::ErrorType t);
141
142 static ReturnedValue method_get_stack(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
143};
144
145template<>
146inline const ErrorObject *Value::as() const {
147 return isManaged() && m()->internalClass->vtable->isErrorObject ? reinterpret_cast<const ErrorObject *>(this) : nullptr;
148}
149
150struct EvalErrorObject: ErrorObject {
151 typedef Heap::EvalErrorObject Data;
152 V4_PROTOTYPE(evalErrorPrototype)
153 const Data *d() const { return static_cast<const Data *>(ErrorObject::d()); }
154 Data *d() { return static_cast<Data *>(ErrorObject::d()); }
155};
156
157struct RangeErrorObject: ErrorObject {
158 typedef Heap::RangeErrorObject Data;
159 V4_PROTOTYPE(rangeErrorPrototype)
160 const Data *d() const { return static_cast<const Data *>(ErrorObject::d()); }
161 Data *d() { return static_cast<Data *>(ErrorObject::d()); }
162};
163
164struct ReferenceErrorObject: ErrorObject {
165 typedef Heap::ReferenceErrorObject Data;
166 V4_PROTOTYPE(referenceErrorPrototype)
167 const Data *d() const { return static_cast<const Data *>(ErrorObject::d()); }
168 Data *d() { return static_cast<Data *>(ErrorObject::d()); }
169};
170
171struct SyntaxErrorObject: ErrorObject {
172 typedef Heap::SyntaxErrorObject Data;
173 V4_PROTOTYPE(syntaxErrorPrototype)
174 const Data *d() const { return static_cast<const Data *>(ErrorObject::d()); }
175 Data *d() { return static_cast<Data *>(ErrorObject::d()); }
176};
177
178struct TypeErrorObject: ErrorObject {
179 typedef Heap::TypeErrorObject Data;
180 V4_PROTOTYPE(typeErrorPrototype)
181 const Data *d() const { return static_cast<const Data *>(ErrorObject::d()); }
182 Data *d() { return static_cast<Data *>(ErrorObject::d()); }
183};
184
185struct URIErrorObject: ErrorObject {
186 typedef Heap::URIErrorObject Data;
187 V4_PROTOTYPE(uRIErrorPrototype)
188 const Data *d() const { return static_cast<const Data *>(ErrorObject::d()); }
189 Data *d() { return static_cast<Data *>(ErrorObject::d()); }
190};
191
192struct ErrorCtor: FunctionObject
193{
194 V4_OBJECT2(ErrorCtor, FunctionObject)
195
196 static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *);
197 static ReturnedValue virtualCall(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc);
198};
199
200struct EvalErrorCtor: ErrorCtor
201{
202 V4_OBJECT2(EvalErrorCtor, FunctionObject)
203 V4_PROTOTYPE(errorCtor)
204
205 static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *);
206};
207
208struct RangeErrorCtor: ErrorCtor
209{
210 V4_OBJECT2(RangeErrorCtor, FunctionObject)
211 V4_PROTOTYPE(errorCtor)
212
213 static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *);
214};
215
216struct ReferenceErrorCtor: ErrorCtor
217{
218 V4_OBJECT2(ReferenceErrorCtor, FunctionObject)
219 V4_PROTOTYPE(errorCtor)
220
221 static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *);
222};
223
224struct SyntaxErrorCtor: ErrorCtor
225{
226 V4_OBJECT2(SyntaxErrorCtor, FunctionObject)
227 V4_PROTOTYPE(errorCtor)
228
229 static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *);
230};
231
232struct TypeErrorCtor: ErrorCtor
233{
234 V4_OBJECT2(TypeErrorCtor, FunctionObject)
235 V4_PROTOTYPE(errorCtor)
236
237 static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *);
238};
239
240struct URIErrorCtor: ErrorCtor
241{
242 V4_OBJECT2(URIErrorCtor, FunctionObject)
243 V4_PROTOTYPE(errorCtor)
244
245 static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *);
246};
247
248
249struct ErrorPrototype : Object
250{
251 enum {
252 Index_Constructor = 0,
253 Index_Message = 1,
254 Index_Name = 2
255 };
256 void init(ExecutionEngine *engine, Object *ctor) { init(engine, ctor, obj: this, t: Heap::ErrorObject::Error); }
257
258 static void init(ExecutionEngine *engine, Object *ctor, Object *obj, Heap::ErrorObject::ErrorType t);
259 static ReturnedValue method_toString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
260};
261
262struct EvalErrorPrototype : Object
263{
264 void init(ExecutionEngine *engine, Object *ctor) { ErrorPrototype::init(engine, ctor, obj: this, t: Heap::ErrorObject::EvalError); }
265};
266
267struct RangeErrorPrototype : Object
268{
269 void init(ExecutionEngine *engine, Object *ctor) { ErrorPrototype::init(engine, ctor, obj: this, t: Heap::ErrorObject::RangeError); }
270};
271
272struct ReferenceErrorPrototype : Object
273{
274 void init(ExecutionEngine *engine, Object *ctor) { ErrorPrototype::init(engine, ctor, obj: this, t: Heap::ErrorObject::ReferenceError); }
275};
276
277struct SyntaxErrorPrototype : Object
278{
279 void init(ExecutionEngine *engine, Object *ctor) { ErrorPrototype::init(engine, ctor, obj: this, t: Heap::ErrorObject::SyntaxError); }
280};
281
282struct TypeErrorPrototype : Object
283{
284 void init(ExecutionEngine *engine, Object *ctor) { ErrorPrototype::init(engine, ctor, obj: this, t: Heap::ErrorObject::TypeError); }
285};
286
287struct URIErrorPrototype : Object
288{
289 void init(ExecutionEngine *engine, Object *ctor) { ErrorPrototype::init(engine, ctor, obj: this, t: Heap::ErrorObject::URIError); }
290};
291
292
293inline SyntaxErrorObject *ErrorObject::asSyntaxError()
294{
295 return d()->errorType == QV4::Heap::ErrorObject::SyntaxError ? static_cast<SyntaxErrorObject *>(this) : nullptr;
296}
297
298
299template <typename T>
300Heap::Object *ErrorObject::create(ExecutionEngine *e, const Value &message, const Value *newTarget) {
301 EngineBase::InternalClassType klass = message.isUndefined() ? EngineBase::Class_ErrorObject : EngineBase::Class_ErrorObjectWithMessage;
302 Scope scope(e);
303 ScopedObject proto(scope, static_cast<const Object *>(newTarget)->get(name: scope.engine->id_prototype()));
304 Scoped<InternalClass> ic(scope, e->internalClasses(icType: klass)->changePrototype(proto: proto->d()));
305 return e->memoryManager->allocObject<T>(ic->d(), message);
306}
307template <typename T>
308Heap::Object *ErrorObject::create(ExecutionEngine *e, const QString &message) {
309 Scope scope(e);
310 ScopedValue v(scope, message.isEmpty() ? Encode::undefined() : e->newString(s: message)->asReturnedValue());
311 EngineBase::InternalClassType klass = v->isUndefined() ? EngineBase::Class_ErrorObject : EngineBase::Class_ErrorObjectWithMessage;
312 Scoped<InternalClass> ic(scope, e->internalClasses(icType: klass)->changePrototype(proto: T::defaultPrototype(e)->d()));
313 return e->memoryManager->allocObject<T>(ic->d(), v);
314}
315template <typename T>
316Heap::Object *ErrorObject::create(ExecutionEngine *e, const QString &message, const QString &filename, int line, int column) {
317 Scope scope(e);
318 ScopedValue v(scope, message.isEmpty() ? Encode::undefined() : e->newString(s: message)->asReturnedValue());
319 EngineBase::InternalClassType klass = v->isUndefined() ? EngineBase::Class_ErrorObject : EngineBase::Class_ErrorObjectWithMessage;
320 Scoped<InternalClass> ic(scope, e->internalClasses(icType: klass)->changePrototype(proto: T::defaultPrototype(e)->d()));
321 return e->memoryManager->allocObject<T>(ic->d(), v, filename, line, column);
322}
323
324
325}
326
327QT_END_NAMESPACE
328
329#endif // QV4ECMAOBJECTS_P_H
330

source code of qtdeclarative/src/qml/jsruntime/qv4errorobject_p.h