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" 25#include "qscriptprogram_p.h" 26#include "qscriptsyntaxcheckresult_p.h" 27#include "qscriptvalue_p.h" 28#include <QtCore/qdatetime.h> 29#include <QtCore/qnumeric.h> 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 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 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 95QScriptValue QScriptEngine::evaluate(const QScriptProgram& program) 96{ 97 return QScriptValuePrivate::get(d_ptr->evaluate(QScriptProgramPrivate::get(program))); 98} 99 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 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. 175 176 \sa reportAdditionalMemoryCost() 177*/ 178void QScriptEngine::collectGarbage() 179{ 180 d_ptr->collectGarbage(); 181} 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 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 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 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 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} 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*/ 427