]> git.saurik.com Git - apple/javascriptcore.git/blame - qt/api/qscriptengine.cpp
JavaScriptCore-903.5.tar.gz
[apple/javascriptcore.git] / qt / api / qscriptengine.cpp
CommitLineData
f9bf01c6
A
1/*
2 Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
18*/
19
20#include "config.h"
21
22#include "qscriptengine.h"
23
24#include "qscriptengine_p.h"
4e4e5a6f
A
25#include "qscriptprogram_p.h"
26#include "qscriptsyntaxcheckresult_p.h"
f9bf01c6 27#include "qscriptvalue_p.h"
14957cd0
A
28#include <QtCore/qdatetime.h>
29#include <QtCore/qnumeric.h>
f9bf01c6
A
30
31/*!
32 Constructs a QScriptEngine object.
33
34 The globalObject() is initialized to have properties as described in ECMA-262, Section 15.1.
35*/
36QScriptEngine::QScriptEngine()
37 : d_ptr(new QScriptEnginePrivate(this))
38{
39}
40
41/*!
42 Destroys this QScriptEngine.
43*/
44QScriptEngine::~QScriptEngine()
45{
46}
47
4e4e5a6f
A
48/*!
49 Checks the syntax of the given \a program. Returns a
50 QScriptSyntaxCheckResult object that contains the result of the check.
51*/
52QScriptSyntaxCheckResult QScriptEngine::checkSyntax(const QString &program)
53{
54 // FIXME This is not optimal.
55 // The JSC C API needs a context to perform a syntax check, it means that a QScriptEnginePrivate
56 // had to be created. This function is static so we have to create QScriptEnginePrivate for each
57 // call. We can't remove the "static" for compatibility reason, at least up to Qt5.
58 // QScriptSyntaxCheckResultPrivate takes ownership of newly created engine. The engine will be
59 // kept as long as it is needed for lazy evaluation of properties of
60 // the QScriptSyntaxCheckResultPrivate.
61 QScriptEnginePrivate* engine = new QScriptEnginePrivate(/* q_ptr */ 0);
62 return QScriptSyntaxCheckResultPrivate::get(engine->checkSyntax(program));
63}
64
f9bf01c6
A
65/*!
66 Evaluates \a program, using \a lineNumber as the base line number,
67 and returns the result of the evaluation.
68
69 The script code will be evaluated in the current context.
70
71 The evaluation of \a program can cause an exception in the
72 engine; in this case the return value will be the exception
73 that was thrown (typically an \c{Error} object). You can call
74 hasUncaughtException() to determine if an exception occurred in
75 the last call to evaluate().
76
77 \a lineNumber is used to specify a starting line number for \a
78 program; line number information reported by the engine that pertain
79 to this evaluation (e.g. uncaughtExceptionLineNumber()) will be
80 based on this argument. For example, if \a program consists of two
81 lines of code, and the statement on the second line causes a script
82 exception, uncaughtExceptionLineNumber() would return the given \a
83 lineNumber plus one. When no starting line number is specified, line
84 numbers will be 1-based.
85
86 \a fileName is used for error reporting. For example in error objects
87 the file name is accessible through the "fileName" property if it's
88 provided with this function.
89*/
90QScriptValue QScriptEngine::evaluate(const QString& program, const QString& fileName, int lineNumber)
91{
92 return QScriptValuePrivate::get(d_ptr->evaluate(program, fileName, lineNumber));
93}
94
4e4e5a6f
A
95QScriptValue QScriptEngine::evaluate(const QScriptProgram& program)
96{
97 return QScriptValuePrivate::get(d_ptr->evaluate(QScriptProgramPrivate::get(program)));
98}
99
14957cd0
A
100/*!
101 Returns true if the last script evaluation resulted in an uncaught
102 exception; otherwise returns false.
103
104 The exception state is cleared when evaluate() is called.
105
106 \sa uncaughtException(), uncaughtExceptionLineNumber(),
107 uncaughtExceptionBacktrace()
108*/
109bool QScriptEngine::hasUncaughtException() const
110{
111 return d_ptr->hasUncaughtException();
112}
113
114/*!
115 Returns the current uncaught exception, or an invalid QScriptValue
116 if there is no uncaught exception.
117
118 The exception value is typically an \c{Error} object; in that case,
119 you can call toString() on the return value to obtain an error
120 message.
121
122 \sa hasUncaughtException(), uncaughtExceptionLineNumber(),
123 uncaughtExceptionBacktrace()
124*/
125QScriptValue QScriptEngine::uncaughtException() const
126{
127 return QScriptValuePrivate::get(d_ptr->uncaughtException());
128}
129
130/*!
131 Clears any uncaught exceptions in this engine.
132
133 \sa hasUncaughtException()
134*/
135void QScriptEngine::clearExceptions()
136{
137 d_ptr->clearExceptions();
138}
139
140/*!
141 Returns the line number where the last uncaught exception occurred.
142
143 Line numbers are 1-based, unless a different base was specified as
144 the second argument to evaluate().
145
146 \sa hasUncaughtException(), uncaughtExceptionBacktrace()
147*/
148int QScriptEngine::uncaughtExceptionLineNumber() const
149{
150 return d_ptr->uncaughtExceptionLineNumber();
151}
152
153/*!
154 Returns a human-readable backtrace of the last uncaught exception.
155
156 Each line is of the form \c{<function-name>(<arguments>)@<file-name>:<line-number>}.
157
158 \sa uncaughtException()
159*/
160QStringList QScriptEngine::uncaughtExceptionBacktrace() const
161{
162 return d_ptr->uncaughtExceptionBacktrace();
163}
164
f9bf01c6
A
165/*!
166 Runs the garbage collector.
167
168 The garbage collector will attempt to reclaim memory by locating and disposing of objects that are
169 no longer reachable in the script environment.
170
171 Normally you don't need to call this function; the garbage collector will automatically be invoked
172 when the QScriptEngine decides that it's wise to do so (i.e. when a certain number of new objects
173 have been created). However, you can call this function to explicitly request that garbage
174 collection should be performed as soon as possible.
4e4e5a6f
A
175
176 \sa reportAdditionalMemoryCost()
f9bf01c6
A
177*/
178void QScriptEngine::collectGarbage()
179{
180 d_ptr->collectGarbage();
181}
4e4e5a6f
A
182
183/*!
184 Reports an additional memory cost of the given \a size, measured in
185 bytes, to the garbage collector.
186
187 This function can be called to indicate that a JavaScript object has
188 memory associated with it that isn't managed by Qt Script itself.
189 Reporting the additional cost makes it more likely that the garbage
190 collector will be triggered.
191
192 Note that if the additional memory is shared with objects outside
193 the scripting environment, the cost should not be reported, since
194 collecting the JavaScript object would not cause the memory to be
195 freed anyway.
196
197 Negative \a size values are ignored, i.e. this function can't be
198 used to report that the additional memory has been deallocated.
199
200 \sa collectGarbage()
201*/
202void QScriptEngine::reportAdditionalMemoryCost(int cost)
203{
204 d_ptr->reportAdditionalMemoryCost(cost);
205}
206
207/*!
208 Returns a handle that represents the given string, \a str.
209
210 QScriptString can be used to quickly look up properties, and
211 compare property names, of script objects.
212
213 \sa QScriptValue::property()
214*/
215QScriptString QScriptEngine::toStringHandle(const QString& str)
216{
217 return QScriptStringPrivate::get(d_ptr->toStringHandle(str));
218}
219
14957cd0
A
220/*!
221 Converts the given \a value to an object, if such a conversion is
222 possible; otherwise returns an invalid QScriptValue. The conversion
223 is performed according to the following table:
224
225 \table
226 \header \o Input Type \o Result
227 \row \o Undefined \o An invalid QScriptValue.
228 \row \o Null \o An invalid QScriptValue.
229 \row \o Boolean \o A new Boolean object whose internal value is set to the value of the boolean.
230 \row \o Number \o A new Number object whose internal value is set to the value of the number.
231 \row \o String \o A new String object whose internal value is set to the value of the string.
232 \row \o Object \o The result is the object itself (no conversion).
233 \endtable
234
235 \sa newObject()
236*/
237QScriptValue QScriptEngine::toObject(const QScriptValue& value)
238{
239 return QScriptValuePrivate::get(QScriptValuePrivate::get(value)->toObject(d_ptr.data()));
240}
241
4e4e5a6f
A
242/*!
243 Returns a QScriptValue of the primitive type Null.
244
245 \sa undefinedValue()
246*/
247QScriptValue QScriptEngine::nullValue()
248{
249 return QScriptValue(this, QScriptValue::NullValue);
250}
251
252/*!
253 Returns a QScriptValue of the primitive type Undefined.
254
255 \sa nullValue()
256*/
257QScriptValue QScriptEngine::undefinedValue()
258{
259 return QScriptValue(this, QScriptValue::UndefinedValue);
260}
261
14957cd0
A
262/*!
263 Creates a QScriptValue that wraps a native (C++) function. \a fun
264 must be a C++ function with signature QScriptEngine::FunctionSignature.
265 \a length is the number of arguments that \a fun expects; this becomes
266 the \c{length} property of the created QScriptValue.
267
268 Note that \a length only gives an indication of the number of
269 arguments that the function expects; an actual invocation of a
270 function can include any number of arguments. You can check the
271 \l{QScriptContext::argumentCount()}{argumentCount()} of the
272 QScriptContext associated with the invocation to determine the
273 actual number of arguments passed.
274
275 A \c{prototype} property is automatically created for the resulting
276 function object, to provide for the possibility that the function
277 will be used as a constructor.
278
279 By combining newFunction() and the property flags
280 QScriptValue::PropertyGetter and QScriptValue::PropertySetter, you
281 can create script object properties that behave like normal
282 properties in script code, but are in fact accessed through
283 functions (analogous to how properties work in \l{Qt's Property
284 System}). Example:
285
286 \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 11
287
288 When the property \c{foo} of the script object is subsequently
289 accessed in script code, \c{getSetFoo()} will be invoked to handle
290 the access. In this particular case, we chose to store the "real"
291 value of \c{foo} as a property of the accessor function itself; you
292 are of course free to do whatever you like in this function.
293
294 In the above example, a single native function was used to handle
295 both reads and writes to the property; the argument count is used to
296 determine if we are handling a read or write. You can also use two
297 separate functions; just specify the relevant flag
298 (QScriptValue::PropertyGetter or QScriptValue::PropertySetter) when
299 setting the property, e.g.:
300
301 \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 12
302
303 \sa QScriptValue::call()
304*/
305QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionSignature fun, int length)
306{
307 return QScriptValuePrivate::get(d_ptr->newFunction(fun, 0, length));
308}
309
310/*!
311 Creates a constructor function from \a fun, with the given \a length.
312 The \c{prototype} property of the resulting function is set to be the
313 given \a prototype. The \c{constructor} property of \a prototype is
314 set to be the resulting function.
315
316 When a function is called as a constructor (e.g. \c{new Foo()}), the
317 `this' object associated with the function call is the new object
318 that the function is expected to initialize; the prototype of this
319 default constructed object will be the function's public
320 \c{prototype} property. If you always want the function to behave as
321 a constructor (e.g. \c{Foo()} should also create a new object), or
322 if you need to create your own object rather than using the default
323 `this' object, you should make sure that the prototype of your
324 object is set correctly; either by setting it manually, or, when
325 wrapping a custom type, by having registered the defaultPrototype()
326 of that type. Example:
327
328 \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 9
329
330 To wrap a custom type and provide a constructor for it, you'd typically
331 do something like this:
332
333 \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 10
334*/
335QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionSignature fun, const QScriptValue& prototype, int length)
336{
337 return QScriptValuePrivate::get(d_ptr->newFunction(fun, QScriptValuePrivate::get(prototype), length));
338}
339
340/*!
341 \internal
342 \since 4.4
343*/
344QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionWithArgSignature fun, void* arg)
345{
346 return QScriptValuePrivate::get(d_ptr->newFunction(fun, arg));
347}
348
349/*!
350 Creates a QtScript object of class Object.
351
352 The prototype of the created object will be the Object
353 prototype object.
354
355 \sa newArray(), QScriptValue::setProperty()
356*/
357QScriptValue QScriptEngine::newObject()
358{
359 return QScriptValuePrivate::get(d_ptr->newObject());
360}
361
362/*!
363 Creates a QtScript object of class Array with the given \a length.
364
365 \sa newObject()
366*/
367QScriptValue QScriptEngine::newArray(uint length)
368{
369 return QScriptValuePrivate::get(d_ptr->newArray(length));
370}
371
372/*!
373 Creates a QtScript object of class Date with the given \a value
374 (the number of milliseconds since 01 January 1970, UTC).
375*/
376QScriptValue QScriptEngine::newDate(qsreal value)
377{
378 return QScriptValuePrivate::get(d_ptr->newDate(value));
379}
380
381/*!
382 Creates a QtScript object of class Date from the given \a value.
383
384 \sa QScriptValue::toDateTime()
385*/
386QScriptValue QScriptEngine::newDate(const QDateTime& value)
387{
388 if (value.isValid())
389 return QScriptValuePrivate::get(d_ptr->newDate(qsreal(value.toMSecsSinceEpoch())));
390 return QScriptValuePrivate::get(d_ptr->newDate(qSNaN()));
391}
392
4e4e5a6f
A
393/*!
394 Returns this engine's Global Object.
395
396 By default, the Global Object contains the built-in objects that are
397 part of \l{ECMA-262}, such as Math, Date and String. Additionally,
398 you can set properties of the Global Object to make your own
399 extensions available to all script code. Non-local variables in
400 script code will be created as properties of the Global Object, as
401 well as local variables in global code.
402*/
403QScriptValue QScriptEngine::globalObject() const
404{
405 return QScriptValuePrivate::get(d_ptr->globalObject());
406}
14957cd0
A
407
408/*!
409 \typedef QScriptEngine::FunctionSignature
410 \relates QScriptEngine
411
412 The function signature \c{QScriptValue f(QScriptContext *, QScriptEngine *)}.
413
414 A function with such a signature can be passed to
415 QScriptEngine::newFunction() to wrap the function.
416*/
417
418/*!
419 \typedef QScriptEngine::FunctionWithArgSignature
420 \relates QScriptEngine
421
422 The function signature \c{QScriptValue f(QScriptContext *, QScriptEngine *, void *)}.
423
424 A function with such a signature can be passed to
425 QScriptEngine::newFunction() to wrap the function.
426*/