source: trunk/src/script/qscriptecmaerror.cpp@ 318

Last change on this file since 318 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 13.1 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtScript module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qscriptecmaerror_p.h"
43
44#ifndef QT_NO_SCRIPT
45
46#include "qscriptengine_p.h"
47#include "qscriptvalueimpl_p.h"
48#include "qscriptcontext_p.h"
49#include "qscriptmember_p.h"
50#include "qscriptobject_p.h"
51
52#include <QtCore/QtDebug>
53
54QT_BEGIN_NAMESPACE
55
56namespace QScript { namespace Ecma {
57
58static QString getMessage(QScriptContextPrivate *context)
59{
60 if (context->argumentCount() > 0)
61 return context->argument(0).toString();
62 return QString();
63}
64
65static void setDebugInformation(QScriptValueImpl *error, QScriptContextPrivate *context)
66{
67 Q_ASSERT(context->previous);
68 context->previous->setDebugInformation(error);
69}
70
71static QScriptValueImpl method_EvalError(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *)
72{
73 QScriptValueImpl result;
74 if (context->isCalledAsConstructor())
75 result = context->thisObject();
76 eng->errorConstructor->newEvalError(&result, getMessage(context));
77 setDebugInformation(&result, context);
78 return result;
79}
80
81static QScriptValueImpl method_RangeError(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *)
82{
83 QScriptValueImpl result;
84 if (context->isCalledAsConstructor())
85 result = context->thisObject();
86 eng->errorConstructor->newRangeError(&result, getMessage(context));
87 setDebugInformation(&result, context);
88 return result;
89}
90
91static QScriptValueImpl method_ReferenceError(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *)
92{
93 QScriptValueImpl result;
94 if (context->isCalledAsConstructor())
95 result = context->thisObject();
96 eng->errorConstructor->newReferenceError(&result, getMessage(context));
97 setDebugInformation(&result, context);
98 return result;
99}
100
101static QScriptValueImpl method_SyntaxError(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *)
102{
103 QScriptValueImpl result;
104 if (context->isCalledAsConstructor())
105 result = context->thisObject();
106 eng->errorConstructor->newSyntaxError(&result, getMessage(context));
107 setDebugInformation(&result, context);
108 return result;
109}
110
111static QScriptValueImpl method_TypeError(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *)
112{
113 QScriptValueImpl result;
114 if (context->isCalledAsConstructor())
115 result = context->thisObject();
116 eng->errorConstructor->newTypeError(&result, getMessage(context));
117 setDebugInformation(&result, context);
118 return result;
119}
120
121static QScriptValueImpl method_UriError(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *)
122{
123 QScriptValueImpl result;
124 if (context->isCalledAsConstructor())
125 result = context->thisObject();
126 eng->errorConstructor->newURIError(&result, getMessage(context));
127 setDebugInformation(&result, context);
128 return result;
129}
130
131Error::Error(QScriptEnginePrivate *eng):
132 Core(eng, QLatin1String("Error"), QScriptClassInfo::ErrorType)
133{
134 eng->newFunction(&ctor, this);
135 newErrorPrototype(&publicPrototype, QScriptValueImpl(), ctor, QLatin1String("Error"));
136 addPrototypeFunction(QLatin1String("backtrace"), method_backtrace, 0);
137 addPrototypeFunction(QLatin1String("toString"), method_toString, 0);
138
139 // native errors
140
141 evalErrorCtor = eng->createFunction(method_EvalError, 3,
142 classInfo(), QLatin1String("EvalError"));
143 rangeErrorCtor = eng->createFunction(method_RangeError, 3,
144 classInfo(), QLatin1String("RangeError"));
145 referenceErrorCtor = eng->createFunction(method_ReferenceError, 3,
146 classInfo(), QLatin1String("ReferenceError"));
147 syntaxErrorCtor = eng->createFunction(method_SyntaxError, 3,
148 classInfo(), QLatin1String("SyntaxError"));
149 typeErrorCtor = eng->createFunction(method_TypeError, 3,
150 classInfo(), QLatin1String("TypeError"));
151 uriErrorCtor = eng->createFunction(method_UriError, 3,
152 classInfo(), QLatin1String("URIError"));
153
154 newErrorPrototype(&evalErrorPrototype, publicPrototype,
155 evalErrorCtor, QLatin1String("EvalError"));
156 newErrorPrototype(&rangeErrorPrototype, publicPrototype,
157 rangeErrorCtor, QLatin1String("RangeError"));
158 newErrorPrototype(&referenceErrorPrototype, publicPrototype,
159 referenceErrorCtor, QLatin1String("ReferenceError"));
160 newErrorPrototype(&syntaxErrorPrototype, publicPrototype,
161 syntaxErrorCtor, QLatin1String("SyntaxError"));
162 newErrorPrototype(&typeErrorPrototype, publicPrototype,
163 typeErrorCtor, QLatin1String("TypeError"));
164 newErrorPrototype(&uriErrorPrototype, publicPrototype,
165 uriErrorCtor, QLatin1String("URIError"));
166}
167
168Error::~Error()
169{
170}
171
172void Error::execute(QScriptContextPrivate *context)
173{
174#ifndef Q_SCRIPT_NO_EVENT_NOTIFY
175 engine()->notifyFunctionEntry(context);
176#endif
177 QString message = QString();
178
179 if (context->argumentCount() > 0)
180 message = context->argument(0).toString();
181
182 QScriptValueImpl result;
183 newError(&result, publicPrototype, message);
184
185 setDebugInformation(&result, context);
186
187 context->setReturnValue(result);
188#ifndef Q_SCRIPT_NO_EVENT_NOTIFY
189 engine()->notifyFunctionExit(context);
190#endif
191}
192
193void Error::mark(QScriptEnginePrivate *eng, int generation)
194{
195 Core::mark(eng, generation);
196
197 eng->markObject(evalErrorCtor, generation);
198 eng->markObject(rangeErrorCtor, generation);
199 eng->markObject(referenceErrorCtor, generation);
200 eng->markObject(syntaxErrorCtor, generation);
201 eng->markObject(typeErrorCtor, generation);
202 eng->markObject(uriErrorCtor, generation);
203
204 eng->markObject(evalErrorPrototype, generation);
205 eng->markObject(rangeErrorPrototype, generation);
206 eng->markObject(referenceErrorPrototype, generation);
207 eng->markObject(syntaxErrorPrototype, generation);
208 eng->markObject(typeErrorPrototype, generation);
209 eng->markObject(uriErrorPrototype, generation);
210}
211
212void Error::newError(QScriptValueImpl *result, const QString &message)
213{
214 newError(result, publicPrototype, message);
215}
216
217void Error::newEvalError(QScriptValueImpl *result, const QString &message)
218{
219 newError(result, evalErrorPrototype, message);
220}
221
222void Error::newRangeError(QScriptValueImpl *result, const QString &message)
223{
224 newError(result, rangeErrorPrototype, message);
225}
226
227void Error::newReferenceError(QScriptValueImpl *result, const QString &message)
228{
229 newError(result, referenceErrorPrototype, message);
230}
231
232void Error::newSyntaxError(QScriptValueImpl *result, const QString &message)
233{
234 newError(result, syntaxErrorPrototype, message);
235}
236
237void Error::newTypeError(QScriptValueImpl *result, const QString &message)
238{
239 newError(result, typeErrorPrototype, message);
240}
241
242void Error::newURIError(QScriptValueImpl *result, const QString &message)
243{
244 newError(result, uriErrorPrototype, message);
245}
246
247void Error::newError(QScriptValueImpl *result, const QScriptValueImpl &proto,
248 const QString &message)
249{
250 QScriptEnginePrivate *eng_p = engine();
251
252 if (!result->isValid())
253 eng_p->newObject(result, proto, classInfo());
254 else
255 result->setClassInfo(classInfo());
256 result->setProperty(QLatin1String("message"), QScriptValueImpl(eng_p, message));
257}
258
259void Error::newErrorPrototype(QScriptValueImpl *result, const QScriptValueImpl &proto,
260 QScriptValueImpl &ztor, const QString &name)
261{
262 newError(result, proto);
263 result->setProperty(QLatin1String("name"), QScriptValueImpl(engine(), name));
264 result->setProperty(QLatin1String("constructor"), ztor,
265 QScriptValue::Undeletable
266 | QScriptValue::SkipInEnumeration);
267 ztor.setProperty(QLatin1String("prototype"), *result,
268 QScriptValue::Undeletable
269 | QScriptValue::ReadOnly
270 | QScriptValue::SkipInEnumeration);
271}
272
273bool Error::isEvalError(const QScriptValueImpl &value) const
274{
275 return value.instanceOf(evalErrorPrototype);
276}
277
278bool Error::isRangeError(const QScriptValueImpl &value) const
279{
280 return value.instanceOf(rangeErrorPrototype);
281}
282
283bool Error::isReferenceError(const QScriptValueImpl &value) const
284{
285 return value.instanceOf(referenceErrorPrototype);
286}
287
288bool Error::isSyntaxError(const QScriptValueImpl &value) const
289{
290 return value.instanceOf(syntaxErrorPrototype);
291}
292
293bool Error::isTypeError(const QScriptValueImpl &value) const
294{
295 return value.instanceOf(typeErrorPrototype);
296}
297
298bool Error::isURIError(const QScriptValueImpl &value) const
299{
300 return value.instanceOf(uriErrorPrototype);
301}
302
303QStringList Error::backtrace(const QScriptValueImpl &error)
304{
305 QStringList result;
306 QScriptValueImpl stack = error.property(QLatin1String("stack"));
307 int frameCount = stack.property(QLatin1String("length")).toInt32();
308 for (int i = 0; i < frameCount; ++i) {
309 QScriptValueImpl o = stack.property(i);
310 QScriptValueImpl frame = o.property(QLatin1String("frame"));
311 QString s;
312 QString functionName = o.property(QLatin1String("functionName")).toString();
313 if (functionName.isEmpty()) {
314 if (i == frameCount-1)
315 s += QLatin1String("<global>");
316 else
317 s += QLatin1String("<anonymous>");
318 } else {
319 s += functionName;
320 }
321 s += QLatin1String("(");
322 QScriptValueImpl arguments = frame.property(QLatin1String("arguments"));
323 if (arguments.isObject()) {
324 int argCount = arguments.property(QLatin1String("length")).toInt32();
325 for (int j = 0; j < argCount; ++j) {
326 if (j > 0)
327 s += QLatin1String(",");
328 s += arguments.property(j).toString();
329 }
330 }
331 s += QLatin1String(")@") + o.property(QLatin1String("fileName")).toString()
332 + QLatin1String(":") + o.property(QLatin1String("lineNumber")).toString();
333 result.append(s);
334 }
335 return result;
336}
337
338QScriptValueImpl Error::method_toString(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *)
339{
340 QScriptValueImpl name = context->thisObject().property(QLatin1String("name"),
341 QScriptValue::ResolvePrototype);
342 QScriptValueImpl message = context->thisObject().property(QLatin1String("message"),
343 QScriptValue::ResolvePrototype);
344 QString result = QLatin1String("");
345 if (name.isValid())
346 result = name.toString();
347 if (message.isValid()) {
348 QString str = message.toString();
349 if (!str.isEmpty()) {
350 if (!result.isEmpty())
351 result += QLatin1String(": ");
352 result += str;
353 }
354 }
355 return (QScriptValueImpl(eng, result));
356}
357
358QScriptValueImpl Error::method_backtrace(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *)
359{
360 QScriptValueImpl self = context->thisObject();
361 return eng->arrayFromStringList(backtrace(self));
362}
363
364} } // namespace QSA::Ecma
365
366QT_END_NAMESPACE
367
368#endif // QT_NO_SCRIPT
Note: See TracBrowser for help on using the repository browser.