Remove "All rights reserved" line from license headers.
[profile/ivi/qtdeclarative.git] / src / declarative / qml / v8 / qjsengine.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtScript module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL-ONLY$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser
11 ** General Public License version 2.1 as published by the Free Software
12 ** Foundation and appearing in the file LICENSE.LGPL included in the
13 ** packaging of this file.  Please review the following information to
14 ** ensure the GNU Lesser General Public License version 2.1 requirements
15 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** If you have questions regarding the use of this file, please contact
18 ** us via http://www.qt-project.org/.
19 **
20 ** $QT_END_LICENSE$
21 **
22 ****************************************************************************/
23
24 #include "qjsengine.h"
25 #include "qjsengine_p.h"
26 #include "qjsvalue.h"
27 #include "qjsvalue_p.h"
28 #include "qscriptisolate_p.h"
29 #include "qscript_impl_p.h"
30 #include "qv8engine_p.h"
31
32 #include <QtCore/qdatetime.h>
33 #include <QtCore/qmetaobject.h>
34 #include <QtCore/qstringlist.h>
35 #include <QtCore/qvariant.h>
36 #include <QtCore/qdatetime.h>
37
38 #include <QtCore/qcoreapplication.h>
39 #include <QtCore/qdir.h>
40 #include <QtCore/qfile.h>
41 #include <QtCore/qfileinfo.h>
42 #include <QtCore/qpluginloader.h>
43 #include <qthread.h>
44 #include <qmutex.h>
45 #include <qwaitcondition.h>
46
47 #undef Q_D
48 #undef Q_Q
49 #define Q_D(blah)
50 #define Q_Q(blah)
51
52 Q_DECLARE_METATYPE(QJSValue)
53 Q_DECLARE_METATYPE(QObjectList)
54 Q_DECLARE_METATYPE(QList<int>)
55
56 /*!
57   \since 5.0
58   \class QJSEngine
59
60   \brief The QJSEngine class provides an environment for evaluating JavaScript code.
61
62   \ingroup qtjavascript
63   \mainclass
64
65   \section1 Evaluating Scripts
66
67   Use evaluate() to evaluate script code.
68
69   \snippet doc/src/snippets/code/src_script_qjsengine.cpp 0
70
71   evaluate() returns a QJSValue that holds the result of the
72   evaluation. The QJSValue class provides functions for converting
73   the result to various C++ types (e.g. QJSValue::toString()
74   and QJSValue::toNumber()).
75
76   The following code snippet shows how a script function can be
77   defined and then invoked from C++ using QJSValue::call():
78
79   \snippet doc/src/snippets/code/src_script_qjsengine.cpp 1
80
81   As can be seen from the above snippets, a script is provided to the
82   engine in the form of a string. One common way of loading scripts is
83   by reading the contents of a file and passing it to evaluate():
84
85   \snippet doc/src/snippets/code/src_script_qjsengine.cpp 2
86
87   Here we pass the name of the file as the second argument to
88   evaluate().  This does not affect evaluation in any way; the second
89   argument is a general-purpose string that is used to identify the
90   script for debugging purposes (for example, our filename will now
91   show up in any uncaughtExceptionBacktrace() involving the script).
92
93   \section1 Engine Configuration
94
95   The globalObject() function returns the \bold {Global Object}
96   associated with the script engine. Properties of the Global Object
97   are accessible from any script code (i.e. they are global
98   variables). Typically, before evaluating "user" scripts, you will
99   want to configure a script engine by adding one or more properties
100   to the Global Object:
101
102   \snippet doc/src/snippets/code/src_script_qjsengine.cpp 3
103
104   Adding custom properties to the scripting environment is one of the
105   standard means of providing a scripting API that is specific to your
106   application. Usually these custom properties are objects created by
107   the newQObject() or newObject() functions.
108
109   \section1 Script Exceptions
110
111   evaluate() can throw a script exception (e.g. due to a syntax
112   error); in that case, the return value is the value that was thrown
113   (typically an \c{Error} object). You can check whether the
114   evaluation caused an exception by calling hasUncaughtException(). In
115   that case, you can call toString() on the error object to obtain an
116   error message. The current uncaught exception is also available
117   through uncaughtException().
118   Calling clearExceptions() will cause any uncaught exceptions to be
119   cleared.
120
121   \snippet doc/src/snippets/code/src_script_qjsengine.cpp 4
122
123   \section1 Script Object Creation
124
125   Use newObject() to create a JavaScript object; this is the
126   C++ equivalent of the script statement \c{new Object()}. You can use
127   the object-specific functionality in QJSValue to manipulate the
128   script object (e.g. QJSValue::setProperty()). Similarly, use
129   newArray() to create a JavaScript array object. Use newDate() to
130   create a \c{Date} object, and newRegExp() to create a \c{RegExp}
131   object.
132
133   \section1 QObject Integration
134
135   Use newQObject() to wrap a QObject (or subclass)
136   pointer. newQObject() returns a proxy script object; properties,
137   children, and signals and slots of the QObject are available as
138   properties of the proxy object. No binding code is needed because it
139   is done dynamically using the Qt meta object system.
140
141   \snippet doc/src/snippets/code/src_script_qjsengine.cpp 5
142
143   \sa QJSValue, {Making Applications Scriptable}
144
145 */
146
147 QT_BEGIN_NAMESPACE
148
149
150 /*!
151     Constructs a QJSEngine object.
152
153     The globalObject() is initialized to have properties as described in
154     \l{ECMA-262}, Section 15.1.
155 */
156 QJSEngine::QJSEngine()
157     : d(new QV8Engine(this))
158 {
159 }
160
161 #ifdef QT_DEPRECATED
162
163 /*!
164     \internal
165 */
166 QJSEngine::QJSEngine(QJSEngine::ContextOwnership ownership)
167     : d(new QV8Engine(this, ownership))
168 {
169 }
170
171 #endif // QT_DEPRECATED
172
173 /*!
174     Constructs a QJSEngine object with the given \a parent.
175
176     The globalObject() is initialized to have properties as described in
177     \l{ECMA-262}, Section 15.1.
178 */
179
180 QJSEngine::QJSEngine(QObject *parent)
181     : QObject(parent)
182     , d(new QV8Engine(this))
183 {
184 }
185
186 QJSEngine::QJSEngine(QJSEnginePrivate &dd, QObject *parent)
187     : QObject(dd, parent)
188     , d(new QV8Engine(this))
189 {
190 }
191
192 /*!
193     Destroys this QJSEngine.
194 */
195 QJSEngine::~QJSEngine()
196 {
197     delete d;
198 }
199
200 /*!
201     \fn QV8Engine *QJSEngine::handle() const
202     \internal
203 */
204
205 #ifdef QT_DEPRECATED
206
207 /*!
208     \obsolete
209
210     Returns true if the last script evaluation resulted in an uncaught
211     exception; otherwise returns false.
212
213     The exception state is cleared when evaluate() is called.
214
215     \sa uncaughtException(), uncaughtExceptionLineNumber(),
216       uncaughtExceptionBacktrace()
217 */
218 bool QJSEngine::hasUncaughtException() const
219 {
220     Q_D(const QJSEngine);
221     QScriptIsolate api(d);
222     return d->hasUncaughtException();
223 }
224
225 /*!
226     \obsolete
227
228     Returns the current uncaught exception, or an invalid QJSValue
229     if there is no uncaught exception.
230
231     The exception value is typically an \c{Error} object; in that case,
232     you can call toString() on the return value to obtain an error
233     message.
234
235     \sa hasUncaughtException(), uncaughtExceptionLineNumber(),
236       uncaughtExceptionBacktrace()
237 */
238 QJSValue QJSEngine::uncaughtException() const
239 {
240     Q_D(const QJSEngine);
241     QScriptIsolate api(d);
242     return d->scriptValueFromInternal(d->uncaughtException());
243 }
244
245 /*!
246     \obsolete
247
248     Clears any uncaught exceptions in this engine.
249
250     \sa hasUncaughtException()
251 */
252 void QJSEngine::clearExceptions()
253 {
254     Q_D(QJSEngine);
255     QScriptIsolate api(d);
256     d->clearExceptions();
257 }
258
259 #endif // QT_DEPRECATED
260
261 /*!
262     Runs the garbage collector.
263
264     The garbage collector will attempt to reclaim memory by locating and disposing of objects that are
265     no longer reachable in the script environment.
266
267     Normally you don't need to call this function; the garbage collector will automatically be invoked
268     when the QJSEngine decides that it's wise to do so (i.e. when a certain number of new objects
269     have been created). However, you can call this function to explicitly request that garbage
270     collection should be performed as soon as possible.
271
272     \sa reportAdditionalMemoryCost()
273 */
274 void QJSEngine::collectGarbage()
275 {
276     Q_D(QJSEngine);
277     QScriptIsolate api(d);
278     d->collectGarbage();
279 }
280
281 /*!
282     Evaluates \a program, using \a lineNumber as the base line number,
283     and returns the result of the evaluation.
284
285     The script code will be evaluated in the current context.
286
287     The evaluation of \a program can cause an exception in the
288     engine; in this case the return value will be the exception
289     that was thrown (typically an \c{Error} object). You can call
290     hasUncaughtException() to determine if an exception occurred in
291     the last call to evaluate().
292
293     \a lineNumber is used to specify a starting line number for \a
294     program; line number information reported by the engine that pertain
295     to this evaluation (e.g. uncaughtExceptionLineNumber()) will be
296     based on this argument. For example, if \a program consists of two
297     lines of code, and the statement on the second line causes a script
298     exception, uncaughtExceptionLineNumber() would return the given \a
299     lineNumber plus one. When no starting line number is specified, line
300     numbers will be 1-based.
301
302     \a fileName is used for error reporting. For example in error objects
303     the file name is accessible through the "fileName" property if it's
304     provided with this function.
305 */
306 QJSValue QJSEngine::evaluate(const QString& program, const QString& fileName, int lineNumber)
307 {
308     Q_D(QJSEngine);
309     QScriptIsolate api(d, QScriptIsolate::NotNullEngine);
310     v8::HandleScope handleScope;
311     return QJSValuePrivate::get(d->evaluate(program, fileName, lineNumber));
312 }
313
314 #ifdef QT_DEPRECATED
315
316 /*!
317   \obsolete
318
319   Returns a QJSValue of the primitive type Null.
320
321   \sa nullValue()
322 */
323 QJSValue QJSEngine::nullValue()
324 {
325     Q_D(QJSEngine);
326     QScriptIsolate api(d, QScriptIsolate::NotNullEngine);
327     v8::HandleScope handleScope;
328     return QJSValuePrivate::get(new QJSValuePrivate(d, v8::Null()));
329 }
330
331 /*!
332   \obsolete
333
334   Returns a QJSValue of the primitive type Undefined.
335
336   \sa nullValue()
337 */
338 QJSValue QJSEngine::undefinedValue()
339 {
340     Q_D(QJSEngine);
341     QScriptIsolate api(d, QScriptIsolate::NotNullEngine);
342     v8::HandleScope handleScope;
343     return QJSValuePrivate::get(new QJSValuePrivate(d, v8::Undefined()));
344 }
345
346 #endif // QT_DEPRECATED
347
348 /*!
349   Creates a JavaScript object of class Object.
350
351   The prototype of the created object will be the Object
352   prototype object.
353
354   \sa newArray(), QJSValue::setProperty()
355 */
356 QJSValue QJSEngine::newObject()
357 {
358     Q_D(QJSEngine);
359     QScriptIsolate api(d, QScriptIsolate::NotNullEngine);
360     v8::HandleScope handleScope;
361     return QJSValuePrivate::get(new QJSValuePrivate(d, v8::Object::New()));
362 }
363
364 /*!
365   Creates a JavaScript object of class Array with the given \a length.
366
367   \sa newObject()
368 */
369 QJSValue QJSEngine::newArray(uint length)
370 {
371     Q_D(QJSEngine);
372     QScriptIsolate api(d, QScriptIsolate::NotNullEngine);
373     v8::HandleScope handleScope;
374     return QJSValuePrivate::get(d->newArray(length));
375 }
376
377 /*!
378   Creates a JavaScript object that wraps the given QObject \a
379   object, using the given \a ownership. The given \a options control
380   various aspects of the interaction with the resulting script object.
381
382   Signals and slots, properties and children of \a object are
383   available as properties of the created QJSValue.
384
385   If \a object is a null pointer, this function returns nullValue().
386
387   If a default prototype has been registered for the \a object's class
388   (or its superclass, recursively), the prototype of the new script
389   object will be set to be that default prototype.
390
391   If the given \a object is deleted outside of the engine's control, any
392   attempt to access the deleted QObject's members through the JavaScript
393   wrapper object (either by script code or C++) will result in a
394   script exception.
395
396   \sa QJSValue::toQObject(), reportAdditionalMemoryCost()
397 */
398 QJSValue QJSEngine::newQObject(QObject *object)
399 {
400     Q_D(QJSEngine);
401     QScriptIsolate api(d, QScriptIsolate::NotNullEngine);
402     v8::HandleScope handleScope;
403     return d->scriptValueFromInternal(d->newQObject(object, QV8Engine::JavaScriptOwnership));
404 }
405
406 #ifdef QT_DEPRECATED
407
408 /*!
409   \obsolete
410
411   Creates a JavaScript object holding the given variant \a value.
412
413   If a default prototype has been registered with the meta type id of
414   \a value, then the prototype of the created object will be that
415   prototype; otherwise, the prototype will be the Object prototype
416   object.
417
418   \sa setDefaultPrototype(), QJSValue::toVariant(), reportAdditionalMemoryCost()
419 */
420 QJSValue QJSEngine::newVariant(const QVariant &value)
421 {
422     Q_D(QJSEngine);
423     QScriptIsolate api(d, QScriptIsolate::NotNullEngine);
424     v8::HandleScope handleScope;
425     return d->scriptValueFromInternal(d->newVariant(value));
426 }
427
428 #endif // QT_DEPRECATED
429
430 /*!
431   Returns this engine's Global Object.
432
433   By default, the Global Object contains the built-in objects that are
434   part of \l{ECMA-262}, such as Math, Date and String. Additionally,
435   you can set properties of the Global Object to make your own
436   extensions available to all script code. Non-local variables in
437   script code will be created as properties of the Global Object, as
438   well as local variables in global code.
439 */
440 QJSValue QJSEngine::globalObject() const
441 {
442     Q_D(const QJSEngine);
443     QScriptIsolate api(d, QScriptIsolate::NotNullEngine);
444     v8::HandleScope handleScope;
445     return d->scriptValueFromInternal(d->global());
446 }
447
448 #ifdef QT_DEPRECATED
449
450 /*!
451   \obsolete
452
453   Converts the given \a value to an object, if such a conversion is
454   possible; otherwise returns an invalid QJSValue. The conversion
455   is performed according to the following table:
456
457     \table
458     \header \o Input Type \o Result
459     \row    \o Undefined  \o An invalid QJSValue.
460     \row    \o Null       \o An invalid QJSValue.
461     \row    \o Boolean    \o A new Boolean object whose internal value is set to the value of the boolean.
462     \row    \o Number     \o A new Number object whose internal value is set to the value of the number.
463     \row    \o String     \o A new String object whose internal value is set to the value of the string.
464     \row    \o Object     \o The result is the object itself (no conversion).
465     \endtable
466
467     \sa newObject()
468 */
469 QJSValue QJSEngine::toObject(const QJSValue& value)
470 {
471     Q_D(QJSEngine);
472     QScriptIsolate api(d, QScriptIsolate::NotNullEngine);
473     v8::HandleScope handleScope;
474     return QJSValuePrivate::get(QJSValuePrivate::get(value)->toObject(d));
475 }
476
477 /*!
478   \obsolete
479
480   Creates a JavaScript object of class Date from the given \a value.
481
482   \sa QJSValue::toDateTime()
483 */
484 QJSValue QJSEngine::newDate(const QDateTime &dt)
485 {
486     Q_D(QJSEngine);
487     QScriptIsolate api(d, QScriptIsolate::NotNullEngine);
488     v8::HandleScope handleScope;
489     return d->scriptValueFromInternal(QJSConverter::toDateTime(dt));
490 }
491
492 /*!
493   \obsolete
494
495   Creates a JavaScript object of class Date with the given
496   \a value (the number of milliseconds since 01 January 1970,
497   UTC).
498 */
499 QJSValue QJSEngine::newDate(double date)
500 {
501     Q_D(QJSEngine);
502     QScriptIsolate api(d, QScriptIsolate::NotNullEngine);
503     v8::HandleScope handleScope;
504     return d->scriptValueFromInternal(v8::Handle<v8::Value>(v8::Date::New(date)));
505 }
506
507 /*!
508   \obsolete
509
510   Creates a JavaScript object of class RegExp with the given
511   \a regexp.
512
513   \sa QJSValue::toRegExp()
514 */
515 QJSValue QJSEngine::newRegExp(const QRegExp &regexp)
516 {
517     Q_D(QJSEngine);
518     QScriptIsolate api(d, QScriptIsolate::NotNullEngine);
519     v8::HandleScope handleScope;
520     return QJSValuePrivate::get(d->newRegExp(regexp));
521 }
522
523 /*!
524   \obsolete
525
526   Creates a JavaScript object of class RegExp with the given
527   \a pattern and \a flags.
528
529   The legal flags are 'g' (global), 'i' (ignore case), and 'm'
530   (multiline).
531 */
532 QJSValue QJSEngine::newRegExp(const QString &pattern, const QString &flags)
533 {
534     Q_D(QJSEngine);
535     QScriptIsolate api(d, QScriptIsolate::NotNullEngine);
536     v8::HandleScope handleScope;
537     return QJSValuePrivate::get(d->newRegExp(pattern, flags));
538 }
539
540 #endif // QT_DEPRECATED
541
542 /*!
543  *  \internal
544  * used by QJSEngine::toScriptValue
545  */
546 QJSValue QJSEngine::create(int type, const void *ptr)
547 {
548     Q_D(QJSEngine);
549     QScriptIsolate api(d, QScriptIsolate::NotNullEngine);
550     v8::HandleScope handleScope;
551     return d->scriptValueFromInternal(d->metaTypeToJS(type, ptr));
552 }
553
554 /*!
555     \internal
556     \since 4.5
557     convert \a value to \a type, store the result in \a ptr
558 */
559 bool QJSEngine::convertV2(const QJSValue &value, int type, void *ptr)
560 {
561     QJSValuePrivate *vp = QJSValuePrivate::get(value);
562     QV8Engine *engine = vp->engine();
563     if (engine) {
564         QScriptIsolate api(engine, QScriptIsolate::NotNullEngine);
565         v8::HandleScope handleScope;
566         return engine->metaTypeFromJS(*vp, type, ptr);
567     } else {
568         switch (type) {
569             case QMetaType::Bool:
570                 *reinterpret_cast<bool*>(ptr) = vp->toBool();
571                 return true;
572             case QMetaType::Int:
573                 *reinterpret_cast<int*>(ptr) = vp->toInt32();
574                 return true;
575             case QMetaType::UInt:
576                 *reinterpret_cast<uint*>(ptr) = vp->toUInt32();
577                 return true;
578             case QMetaType::LongLong:
579                 *reinterpret_cast<qlonglong*>(ptr) = vp->toInteger();
580                 return true;
581             case QMetaType::ULongLong:
582                 *reinterpret_cast<qulonglong*>(ptr) = vp->toInteger();
583                 return true;
584             case QMetaType::Double:
585                 *reinterpret_cast<double*>(ptr) = vp->toNumber();
586                 return true;
587             case QMetaType::QString:
588                 *reinterpret_cast<QString*>(ptr) = vp->toString();
589                 return true;
590             case QMetaType::Float:
591                 *reinterpret_cast<float*>(ptr) = vp->toNumber();
592                 return true;
593             case QMetaType::Short:
594                 *reinterpret_cast<short*>(ptr) = vp->toInt32();
595                 return true;
596             case QMetaType::UShort:
597                 *reinterpret_cast<unsigned short*>(ptr) = vp->toUInt16();
598                 return true;
599             case QMetaType::Char:
600                 *reinterpret_cast<char*>(ptr) = vp->toInt32();
601                 return true;
602             case QMetaType::UChar:
603                 *reinterpret_cast<unsigned char*>(ptr) = vp->toUInt16();
604                 return true;
605             case QMetaType::QChar:
606                 *reinterpret_cast<QChar*>(ptr) = vp->toUInt16();
607                 return true;
608             default:
609                 return false;
610         }
611     }
612 }
613
614 /*! \fn QJSValue QJSEngine::toScriptValue(const T &value)
615
616     Creates a QJSValue with the given \a value.
617
618     \sa fromScriptValue()
619 */
620
621 /*! \fn T QJSEngine::fromScriptValue(const QJSValue &value)
622
623     Returns the given \a value converted to the template type \c{T}.
624
625     \sa toScriptValue()
626 */
627
628 QT_END_NAMESPACE
629
630 #include "moc_qjsengine.cpp"