Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qv4errorobject.cpp
Go to the documentation of this file.
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// Qt-Security score:significant
4
5
7#include <QtCore/qnumeric.h>
8#include <QtCore/qmath.h>
9#include <QtCore/QDateTime>
10#include <QtCore/QStringList>
11#include <QtCore/QDebug>
12
13#include <private/qv4mm_p.h>
14#include <private/qv4codegen_p.h>
15
16#ifndef Q_OS_WIN
17# include <time.h>
18# ifndef Q_OS_VXWORKS
19# include <sys/time.h>
20# else
21# include "qplatformdefs.h"
22# endif
23#else
24# include <qt_windows.h>
25#endif
26
27using namespace QV4;
28
29void Heap::ErrorObject::init()
30{
31 Object::init();
32 stackTrace = nullptr;
33
34 Scope scope(internalClass->engine);
35 Scoped<QV4::ErrorObject> e(scope, this);
36
37 if (internalClass == scope.engine->internalClasses(EngineBase::Class_ErrorProto))
38 return;
39
40 setProperty(scope.engine, QV4::ErrorObject::Index_Stack, scope.engine->getStackFunction()->d());
41 setProperty(scope.engine, QV4::ErrorObject::Index_StackSetter, Value::undefinedValue());
42 setProperty(scope.engine, QV4::ErrorObject::Index_FileName, Value::undefinedValue());
43 setProperty(scope.engine, QV4::ErrorObject::Index_LineNumber, Value::undefinedValue());
44}
45
46void Heap::ErrorObject::init(const Value &message, ErrorType t)
47{
48 Object::init();
49 errorType = t;
50
51 Scope scope(internalClass->engine);
52 Scoped<QV4::ErrorObject> e(scope, this);
53
54 setProperty(scope.engine, QV4::ErrorObject::Index_Stack, scope.engine->getStackFunction()->d());
55 setProperty(scope.engine, QV4::ErrorObject::Index_StackSetter, Value::undefinedValue());
56
57 e->d()->stackTrace = new StackTrace(scope.engine->stackTrace());
58 if (!e->d()->stackTrace->isEmpty()) {
59 setProperty(scope.engine, QV4::ErrorObject::Index_FileName, scope.engine->newString(e->d()->stackTrace->at(0).source));
60 setProperty(scope.engine, QV4::ErrorObject::Index_LineNumber, Value::fromInt32(qAbs(e->d()->stackTrace->at(0).line)));
61 }
62
63 if (!message.isUndefined())
64 setProperty(scope.engine, QV4::ErrorObject::Index_Message, message);
65}
66
67void Heap::ErrorObject::init(const Value &message, const QString &fileName, int line, int column, ErrorObject::ErrorType t)
68{
69 Q_UNUSED(fileName); // ####
70 Object::init();
71 errorType = t;
72
73 Scope scope(internalClass->engine);
74 Scoped<QV4::ErrorObject> e(scope, this);
75
76 setProperty(scope.engine, QV4::ErrorObject::Index_Stack, scope.engine->getStackFunction()->d());
77 setProperty(scope.engine, QV4::ErrorObject::Index_StackSetter, Value::undefinedValue());
78
79 e->d()->stackTrace = new StackTrace(scope.engine->stackTrace());
80 StackFrame frame;
81 frame.source = fileName;
82 frame.line = line;
83 frame.column = column;
84 e->d()->stackTrace->prepend(frame);
85
86 Q_ASSERT(!e->d()->stackTrace->isEmpty());
87 setProperty(scope.engine, QV4::ErrorObject::Index_FileName, scope.engine->newString(e->d()->stackTrace->at(0).source));
88 setProperty(scope.engine, QV4::ErrorObject::Index_LineNumber, Value::fromInt32(qAbs(e->d()->stackTrace->at(0).line)));
89
90 if (!message.isUndefined())
91 setProperty(scope.engine, QV4::ErrorObject::Index_Message, message);
92}
93
94const char *ErrorObject::className(Heap::ErrorObject::ErrorType t)
95{
96 switch (t) {
97 case Heap::ErrorObject::Error:
98 return "Error";
99 case Heap::ErrorObject::EvalError:
100 return "EvalError";
101 case Heap::ErrorObject::RangeError:
102 return "RangeError";
103 case Heap::ErrorObject::ReferenceError:
104 return "ReferenceError";
105 case Heap::ErrorObject::SyntaxError:
106 return "SyntaxError";
107 case Heap::ErrorObject::TypeError:
108 return "TypeError";
109 case Heap::ErrorObject::URIError:
110 return "URIError";
111 }
112 Q_UNREACHABLE();
113}
114
115ReturnedValue ErrorObject::method_get_stack(const FunctionObject *b, const Value *thisObject, const Value *, int)
116{
117 ExecutionEngine *v4 = b->engine();
118 const ErrorObject *This = thisObject->as<ErrorObject>();
119 if (!This)
120 return v4->throwTypeError();
121 if (!This->d()->stack) {
122 QString trace;
123 for (int i = 0; i < This->d()->stackTrace->size(); ++i) {
124 if (i > 0)
125 trace += QLatin1Char('\n');
126 const StackFrame &frame = This->d()->stackTrace->at(i);
127 trace += frame.function + QLatin1Char('@') + frame.source;
128 if (frame.line >= 0)
129 trace += QLatin1Char(':') + QString::number(frame.line);
130 }
131 This->d()->stack.set(v4, v4->newString(trace));
132 }
133 return This->d()->stack->asReturnedValue();
134}
135
137
138void Heap::SyntaxErrorObject::init(const Value &msg)
139{
140 Heap::ErrorObject::init(msg, SyntaxError);
141}
142
143void Heap::SyntaxErrorObject::init(const Value &msg, const QString &fileName, int lineNumber, int columnNumber)
144{
145 Heap::ErrorObject::init(msg, fileName, lineNumber, columnNumber, SyntaxError);
146}
147
148void Heap::EvalErrorObject::init(const Value &message)
149{
150 Heap::ErrorObject::init(message, EvalError);
151}
152
153void Heap::RangeErrorObject::init(const Value &message)
154{
155 Heap::ErrorObject::init(message, RangeError);
156}
157
158void Heap::ReferenceErrorObject::init(const Value &message)
159{
160 Heap::ErrorObject::init(message, ReferenceError);
161}
162
163void Heap::ReferenceErrorObject::init(const Value &msg, const QString &fileName, int lineNumber, int columnNumber)
164{
165 Heap::ErrorObject::init(msg, fileName, lineNumber, columnNumber, ReferenceError);
166}
167
168void Heap::TypeErrorObject::init(const Value &message)
169{
170 Heap::ErrorObject::init(message, TypeError);
171}
172
173void Heap::URIErrorObject::init(const Value &message)
174{
175 Heap::ErrorObject::init(message, URIError);
176}
177
185
186void Heap::ErrorCtor::init(QV4::ExecutionEngine *engine)
187{
188 Heap::FunctionObject::init(engine, QStringLiteral("Error"));
189}
190
191void Heap::ErrorCtor::init(QV4::ExecutionEngine *engine, const QString &name)
192{
193 Heap::FunctionObject::init(engine, name);
194}
195
196ReturnedValue ErrorCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *newTarget)
197{
198 Value v = argc ? *argv : Value::undefinedValue();
199 return ErrorObject::create<ErrorObject>(f->engine(), v, newTarget)->asReturnedValue();
200}
201
202ReturnedValue ErrorCtor::virtualCall(const FunctionObject *f, const Value *, const Value *argv, int argc)
203{
204 return f->callAsConstructor(argv, argc);
205}
206
207void Heap::EvalErrorCtor::init(QV4::ExecutionEngine *engine)
208{
209 Heap::FunctionObject::init(engine, QStringLiteral("EvalError"));
210}
211
212ReturnedValue EvalErrorCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *newTarget)
213{
214 Value v = argc ? *argv : Value::undefinedValue();
215 return ErrorObject::create<EvalErrorObject>(f->engine(), v, newTarget)->asReturnedValue();
216}
217
218void Heap::RangeErrorCtor::init(QV4::ExecutionEngine *engine)
219{
220 Heap::FunctionObject::init(engine, QStringLiteral("RangeError"));
221}
222
223ReturnedValue RangeErrorCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *newTarget)
224{
225 Value v = argc ? *argv : Value::undefinedValue();
226 return ErrorObject::create<RangeErrorObject>(f->engine(), v, newTarget)->asReturnedValue();
227}
228
229void Heap::ReferenceErrorCtor::init(QV4::ExecutionEngine *engine)
230{
231 Heap::FunctionObject::init(engine, QStringLiteral("ReferenceError"));
232}
233
234ReturnedValue ReferenceErrorCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *newTarget)
235{
236 Value v = argc ? *argv : Value::undefinedValue();
237 return ErrorObject::create<ReferenceErrorObject>(f->engine(), v, newTarget)->asReturnedValue();
238}
239
240void Heap::SyntaxErrorCtor::init(QV4::ExecutionEngine *engine)
241{
242 Heap::FunctionObject::init(engine, QStringLiteral("SyntaxError"));
243}
244
245ReturnedValue SyntaxErrorCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *newTarget)
246{
247 Value v = argc ? *argv : Value::undefinedValue();
248 return ErrorObject::create<SyntaxErrorObject>(f->engine(), v, newTarget)->asReturnedValue();
249}
250
251void Heap::TypeErrorCtor::init(QV4::ExecutionEngine *engine)
252{
253 Heap::FunctionObject::init(engine, QStringLiteral("TypeError"));
254}
255
256ReturnedValue TypeErrorCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *newTarget)
257{
258 Value v = argc ? *argv : Value::undefinedValue();
259 return ErrorObject::create<TypeErrorObject>(f->engine(), v, newTarget)->asReturnedValue();
260}
261
262void Heap::URIErrorCtor::init(QV4::ExecutionEngine *engine)
263{
264 Heap::FunctionObject::init(engine, QStringLiteral("URIError"));
265}
266
267ReturnedValue URIErrorCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *newTarget)
268{
269 Value v = argc ? *argv : Value::undefinedValue();
270 return ErrorObject::create<URIErrorObject>(f->engine(), v, newTarget)->asReturnedValue();
271}
272
273void ErrorPrototype::init(ExecutionEngine *engine, Object *ctor, Object *obj, Heap::ErrorObject::ErrorType t)
274{
275 Scope scope(engine);
276 ScopedString s(scope);
277 ScopedObject o(scope);
278 ctor->defineReadonlyProperty(engine->id_prototype(), (o = obj));
279 ctor->defineReadonlyConfigurableProperty(engine->id_length(), Value::fromInt32(1));
280 obj->setProperty(Index_Constructor, ctor->d());
281 obj->setProperty(Index_Message, engine->id_empty()->d());
282 obj->setProperty(Index_Name, engine->newString(QString::fromLatin1(ErrorObject::className(t))));
283 obj->defineDefaultProperty(engine->id_toString(), method_toString, 0);
284}
285
286ReturnedValue ErrorPrototype::method_toString(const FunctionObject *b, const Value *thisObject, const Value *, int)
287{
288 ExecutionEngine *v4 = b->engine();
289 const Object *o = thisObject->as<Object>();
290 if (!o)
291 return v4->throwTypeError();
292
293 Scope scope(v4);
294 ScopedValue name(scope, o->get(scope.engine->id_name()));
295 QString qname;
296 if (name->isUndefined())
297 qname = QStringLiteral("Error");
298 else
299 qname = name->toQString();
300
301 ScopedString s(scope, scope.engine->newString(QStringLiteral("message")));
302 ScopedValue message(scope, o->get(s));
303 QString qmessage;
304 if (!message->isUndefined())
305 qmessage = message->toQString();
306
307 QString str;
308 if (qname.isEmpty()) {
309 str = qmessage;
310 } else if (qmessage.isEmpty()) {
311 str = qname;
312 } else {
313 str = qname + QLatin1String(": ") + qmessage;
314 }
315
316 return scope.engine->newString(str)->asReturnedValue();
317}
Definition qjsvalue.h:23
Scoped< Object > ScopedObject
Scoped< String > ScopedString
DEFINE_OBJECT_VTABLE(EvalErrorCtor)
DEFINE_OBJECT_VTABLE(URIErrorCtor)
DEFINE_OBJECT_VTABLE(ErrorCtor)
DEFINE_OBJECT_VTABLE(SyntaxErrorCtor)
DEFINE_OBJECT_VTABLE(RangeErrorCtor)
DEFINE_OBJECT_VTABLE(TypeErrorCtor)
DEFINE_OBJECT_VTABLE(ErrorObject)
DEFINE_OBJECT_VTABLE(ReferenceErrorCtor)
Scope(ExecutionEngine *e)