src/script/api/qscriptengine.cpp
branchGCC_SURGE
changeset 31 5daf16870df6
parent 30 5dc02b23752f
child 33 3e2da88830cd
equal deleted inserted replaced
27:93b982ccede2 31:5daf16870df6
    22 ****************************************************************************/
    22 ****************************************************************************/
    23 
    23 
    24 #include "config.h"
    24 #include "config.h"
    25 #include "qscriptengine.h"
    25 #include "qscriptengine.h"
    26 #include "qscriptsyntaxchecker_p.h"
    26 #include "qscriptsyntaxchecker_p.h"
    27 #include "qnumeric.h"
       
    28 
    27 
    29 #include "qscriptengine_p.h"
    28 #include "qscriptengine_p.h"
    30 #include "qscriptengineagent_p.h"
    29 #include "qscriptengineagent_p.h"
    31 #include "qscriptcontext_p.h"
    30 #include "qscriptcontext_p.h"
    32 #include "qscriptstring_p.h"
    31 #include "qscriptstring_p.h"
    39 #include "qdebug.h"
    38 #include "qdebug.h"
    40 
    39 
    41 #include <QtCore/qstringlist.h>
    40 #include <QtCore/qstringlist.h>
    42 #include <QtCore/qmetaobject.h>
    41 #include <QtCore/qmetaobject.h>
    43 
    42 
       
    43 #include <math.h>
       
    44 
    44 #include "CodeBlock.h"
    45 #include "CodeBlock.h"
    45 #include "Error.h"
    46 #include "Error.h"
    46 #include "JSArray.h"
       
    47 #include "JSLock.h"
    47 #include "JSLock.h"
    48 #include "Interpreter.h"
    48 #include "Interpreter.h"
    49 #include "DateConstructor.h"
       
    50 #include "RegExpConstructor.h"
       
    51 
    49 
    52 #include "PrototypeFunction.h"
    50 #include "PrototypeFunction.h"
    53 #include "InitializeThreading.h"
    51 #include "InitializeThreading.h"
    54 #include "ObjectPrototype.h"
    52 #include "ObjectPrototype.h"
    55 #include "SourceCode.h"
    53 #include "SourceCode.h"
    56 #include "FunctionPrototype.h"
    54 #include "FunctionPrototype.h"
    57 #include "TimeoutChecker.h"
    55 #include "TimeoutChecker.h"
    58 #include "JSFunction.h"
    56 #include "JSFunction.h"
    59 #include "Parser.h"
    57 #include "Parser.h"
       
    58 #include "PropertyNameArray.h"
    60 #include "Operations.h"
    59 #include "Operations.h"
    61 
    60 
    62 #include "utils/qscriptdate_p.h"
       
    63 #include "bridge/qscriptfunction_p.h"
    61 #include "bridge/qscriptfunction_p.h"
    64 #include "bridge/qscriptobject_p.h"
       
    65 #include "bridge/qscriptclassobject_p.h"
    62 #include "bridge/qscriptclassobject_p.h"
    66 #include "bridge/qscriptvariant_p.h"
    63 #include "bridge/qscriptvariant_p.h"
    67 #include "bridge/qscriptqobject_p.h"
    64 #include "bridge/qscriptqobject_p.h"
    68 #include "bridge/qscriptglobalobject_p.h"
    65 #include "bridge/qscriptglobalobject_p.h"
    69 #include "bridge/qscriptactivationobject_p.h"
    66 #include "bridge/qscriptactivationobject_p.h"
   262   make sure that the GUI stays responsive. You can abort a currently
   259   make sure that the GUI stays responsive. You can abort a currently
   263   running script by calling abortEvaluation(). You can determine
   260   running script by calling abortEvaluation(). You can determine
   264   whether an engine is currently running a script by calling
   261   whether an engine is currently running a script by calling
   265   isEvaluating().
   262   isEvaluating().
   266 
   263 
       
   264   \section1 Garbage Collection
       
   265 
       
   266   Qt Script objects may be garbage collected when they are no longer
       
   267   referenced. There is no guarantee as to when automatic garbage
       
   268   collection will take place.
       
   269 
       
   270   The collectGarbage() function can be called to explicitly request
       
   271   garbage collection.
       
   272 
       
   273   The reportAdditionalMemoryCost() function can be called to indicate
       
   274   that a Qt Script object occupies memory that isn't managed by the
       
   275   scripting environment. Reporting the additional cost makes it more
       
   276   likely that the garbage collector will be triggered. This can be
       
   277   useful, for example, when many custom, native Qt Script objects are
       
   278   allocated.
       
   279 
   267   \section1 Core Debugging/Tracing Facilities
   280   \section1 Core Debugging/Tracing Facilities
   268 
   281 
   269   Since Qt 4.4, you can be notified of events pertaining to script
   282   Since Qt 4.4, you can be notified of events pertaining to script
   270   execution (e.g. script function calls and statement execution)
   283   execution (e.g. script function calls and statement execution)
   271   through the QScriptEngineAgent interface; see the setAgent()
   284   through the QScriptEngineAgent interface; see the setAgent()
   279 /*!
   292 /*!
   280     \enum QScriptEngine::ValueOwnership
   293     \enum QScriptEngine::ValueOwnership
   281 
   294 
   282     This enum specifies the ownership when wrapping a C++ value, e.g. by using newQObject().
   295     This enum specifies the ownership when wrapping a C++ value, e.g. by using newQObject().
   283 
   296 
   284     \value QtOwnership The standard Qt ownership rules apply, i.e. the associated object will never be explicitly deleted by the script engine. This is the default. (QObject ownership is explained in \l{Object Trees and Object Ownership}.)
   297     \value QtOwnership The standard Qt ownership rules apply, i.e. the
   285     \value ScriptOwnership The value is owned by the script environment. The associated data will be deleted when appropriate (i.e. after the garbage collector has discovered that there are no more live references to the value).
   298     associated object will never be explicitly deleted by the script
   286     \value AutoOwnership If the associated object has a parent, the Qt ownership rules apply (QtOwnership); otherwise, the object is owned by the script environment (ScriptOwnership).
   299     engine. This is the default. (QObject ownership is explained in
       
   300     \l{Object Trees & Ownership}.)
       
   301 
       
   302     \value ScriptOwnership The value is owned by the script
       
   303     environment. The associated data will be deleted when appropriate
       
   304     (i.e. after the garbage collector has discovered that there are no
       
   305     more live references to the value).
       
   306 
       
   307     \value AutoOwnership If the associated object has a parent, the Qt
       
   308     ownership rules apply (QtOwnership); otherwise, the object is
       
   309     owned by the script environment (ScriptOwnership).
       
   310 
   287 */
   311 */
   288 
   312 
   289 /*!
   313 /*!
   290     \enum  QScriptEngine::QObjectWrapOption
   314     \enum  QScriptEngine::QObjectWrapOption
   291 
   315 
   294     \value ExcludeChildObjects The script object will not expose child objects as properties.
   318     \value ExcludeChildObjects The script object will not expose child objects as properties.
   295     \value ExcludeSuperClassMethods The script object will not expose signals and slots inherited from the superclass.
   319     \value ExcludeSuperClassMethods The script object will not expose signals and slots inherited from the superclass.
   296     \value ExcludeSuperClassProperties The script object will not expose properties inherited from the superclass.
   320     \value ExcludeSuperClassProperties The script object will not expose properties inherited from the superclass.
   297     \value ExcludeSuperClassContents Shorthand form for ExcludeSuperClassMethods | ExcludeSuperClassProperties
   321     \value ExcludeSuperClassContents Shorthand form for ExcludeSuperClassMethods | ExcludeSuperClassProperties
   298     \value ExcludeDeleteLater The script object will not expose the QObject::deleteLater() slot.
   322     \value ExcludeDeleteLater The script object will not expose the QObject::deleteLater() slot.
       
   323     \value ExcludeSlots The script object will not expose the QObject's slots.
   299     \value AutoCreateDynamicProperties Properties that don't already exist in the QObject will be created as dynamic properties of that object, rather than as properties of the script object.
   324     \value AutoCreateDynamicProperties Properties that don't already exist in the QObject will be created as dynamic properties of that object, rather than as properties of the script object.
   300     \value PreferExistingWrapperObject If a wrapper object with the requested configuration already exists, return that object.
   325     \value PreferExistingWrapperObject If a wrapper object with the requested configuration already exists, return that object.
   301     \value SkipMethodsInEnumeration Don't include methods (signals and slots) when enumerating the object's properties.
   326     \value SkipMethodsInEnumeration Don't include methods (signals and slots) when enumerating the object's properties.
   302 */
   327 */
   303 
   328 
   326     JSC::JSValue prototype;
   351     JSC::JSValue prototype;
   327 };
   352 };
   328 
   353 
   329 namespace QScript
   354 namespace QScript
   330 {
   355 {
       
   356 
       
   357 static const qsreal D32 = 4294967296.0;
       
   358 
       
   359 qint32 ToInt32(qsreal n)
       
   360 {
       
   361     if (qIsNaN(n) || qIsInf(n) || (n == 0))
       
   362         return 0;
       
   363 
       
   364     qsreal sign = (n < 0) ? -1.0 : 1.0;
       
   365     qsreal abs_n = fabs(n);
       
   366 
       
   367     n = ::fmod(sign * ::floor(abs_n), D32);
       
   368     const double D31 = D32 / 2.0;
       
   369 
       
   370     if (sign == -1 && n < -D31)
       
   371         n += D32;
       
   372 
       
   373     else if (sign != -1 && n >= D31)
       
   374         n -= D32;
       
   375 
       
   376     return qint32 (n);
       
   377 }
       
   378 
       
   379 quint32 ToUInt32(qsreal n)
       
   380 {
       
   381     if (qIsNaN(n) || qIsInf(n) || (n == 0))
       
   382         return 0;
       
   383 
       
   384     qsreal sign = (n < 0) ? -1.0 : 1.0;
       
   385     qsreal abs_n = fabs(n);
       
   386 
       
   387     n = ::fmod(sign * ::floor(abs_n), D32);
       
   388 
       
   389     if (n < 0)
       
   390         n += D32;
       
   391 
       
   392     return quint32 (n);
       
   393 }
       
   394 
       
   395 quint16 ToUInt16(qsreal n)
       
   396 {
       
   397     static const qsreal D16 = 65536.0;
       
   398 
       
   399     if (qIsNaN(n) || qIsInf(n) || (n == 0))
       
   400         return 0;
       
   401 
       
   402     qsreal sign = (n < 0) ? -1.0 : 1.0;
       
   403     qsreal abs_n = fabs(n);
       
   404 
       
   405     n = ::fmod(sign * ::floor(abs_n), D16);
       
   406 
       
   407     if (n < 0)
       
   408         n += D16;
       
   409 
       
   410     return quint16 (n);
       
   411 }
       
   412 
       
   413 qsreal ToInteger(qsreal n)
       
   414 {
       
   415     if (qIsNaN(n))
       
   416         return 0;
       
   417 
       
   418     if (n == 0 || qIsInf(n))
       
   419         return n;
       
   420 
       
   421     int sign = n < 0 ? -1 : 1;
       
   422     return sign * ::floor(::fabs(n));
       
   423 }
       
   424 
       
   425 #ifdef Q_CC_MSVC
       
   426 // MSVC2008 crashes if these are inlined.
       
   427 
       
   428 QString ToString(qsreal value)
       
   429 {
       
   430     return JSC::UString::from(value);
       
   431 }
       
   432 
       
   433 qsreal ToNumber(const QString &value)
       
   434 {
       
   435     return ((JSC::UString)value).toDouble();
       
   436 }
       
   437 
       
   438 #endif
   331 
   439 
   332 void GlobalClientData::mark(JSC::MarkStack& markStack)
   440 void GlobalClientData::mark(JSC::MarkStack& markStack)
   333 {
   441 {
   334     engine->mark(markStack);
   442     engine->mark(markStack);
   335 }
   443 }
   481         receiver = arg0;
   589         receiver = arg0;
   482         JSC::JSValue arg1 = args.at(1);
   590         JSC::JSValue arg1 = args.at(1);
   483         if (isFunction(arg1))
   591         if (isFunction(arg1))
   484             slot = arg1;
   592             slot = arg1;
   485         else {
   593         else {
   486             // ### don't go via QScriptValue
       
   487             QScript::SaveFrameHelper saveFrame(engine, exec);
   594             QScript::SaveFrameHelper saveFrame(engine, exec);
   488             QScriptValue tmp = engine->scriptValueFromJSCValue(arg0);
   595             JSC::UString propertyName = QScriptEnginePrivate::toString(exec, arg1);
   489             QString propertyName(arg1.toString(exec));
   596             slot = QScriptEnginePrivate::property(exec, arg0, propertyName, QScriptValue::ResolvePrototype);
   490             slot = engine->scriptValueToJSCValue(tmp.property(propertyName, QScriptValue::ResolvePrototype));
       
   491         }
   597         }
   492     }
   598     }
   493 
   599 
   494     if (!isFunction(slot)) {
   600     if (!isFunction(slot)) {
   495         return JSC::throwError(exec, JSC::TypeError, "Function.prototype.disconnect: target is not a function");
   601         return JSC::throwError(exec, JSC::TypeError, "Function.prototype.disconnect: target is not a function");
   565         receiver = arg0;
   671         receiver = arg0;
   566         JSC::JSValue arg1 = args.at(1);
   672         JSC::JSValue arg1 = args.at(1);
   567         if (isFunction(arg1))
   673         if (isFunction(arg1))
   568             slot = arg1;
   674             slot = arg1;
   569         else {
   675         else {
   570             // ### don't go via QScriptValue
       
   571             QScript::SaveFrameHelper saveFrame(engine, exec);
   676             QScript::SaveFrameHelper saveFrame(engine, exec);
   572             QScriptValue tmp = engine->scriptValueFromJSCValue(arg0);
   677             JSC::UString propertyName = QScriptEnginePrivate::toString(exec, arg1);
   573             QString propertyName = arg1.toString(exec);
   678             slot = QScriptEnginePrivate::property(exec, arg0, propertyName, QScriptValue::ResolvePrototype);
   574             slot = engine->scriptValueToJSCValue(tmp.property(propertyName, QScriptValue::ResolvePrototype));
       
   575         }
   679         }
   576     }
   680     }
   577 
   681 
   578     if (!isFunction(slot)) {
   682     if (!isFunction(slot)) {
   579         return JSC::throwError(exec, JSC::TypeError, "Function.prototype.connect: target is not a function");
   683         return JSC::throwError(exec, JSC::TypeError, "Function.prototype.connect: target is not a function");
   646     if ((args.size() > 3) && !args.at(3).isString())
   750     if ((args.size() > 3) && !args.at(3).isString())
   647         return JSC::throwError(exec, JSC::GeneralError, "qsTranslate(): fourth argument (encoding) must be a string");
   751         return JSC::throwError(exec, JSC::GeneralError, "qsTranslate(): fourth argument (encoding) must be a string");
   648     if ((args.size() > 4) && !args.at(4).isNumber())
   752     if ((args.size() > 4) && !args.at(4).isNumber())
   649         return JSC::throwError(exec, JSC::GeneralError, "qsTranslate(): fifth argument (n) must be a number");
   753         return JSC::throwError(exec, JSC::GeneralError, "qsTranslate(): fifth argument (n) must be a number");
   650 #ifndef QT_NO_QOBJECT
   754 #ifndef QT_NO_QOBJECT
   651     QString context(args.at(0).toString(exec));
   755     JSC::UString context = args.at(0).toString(exec);
   652 #endif
   756 #endif
   653     QString text(args.at(1).toString(exec));
   757     JSC::UString text = args.at(1).toString(exec);
   654 #ifndef QT_NO_QOBJECT
   758 #ifndef QT_NO_QOBJECT
   655     QString comment;
   759     JSC::UString comment;
   656     if (args.size() > 2)
   760     if (args.size() > 2)
   657         comment = args.at(2).toString(exec);
   761         comment = args.at(2).toString(exec);
   658     QCoreApplication::Encoding encoding = QCoreApplication::CodecForTr;
   762     QCoreApplication::Encoding encoding = QCoreApplication::CodecForTr;
   659     if (args.size() > 3) {
   763     if (args.size() > 3) {
   660         QString encStr(args.at(3).toString(exec));
   764         JSC::UString encStr = args.at(3).toString(exec);
   661         if (encStr == QLatin1String("CodecForTr"))
   765         if (encStr == "CodecForTr")
   662             encoding = QCoreApplication::CodecForTr;
   766             encoding = QCoreApplication::CodecForTr;
   663         else if (encStr == QLatin1String("UnicodeUTF8"))
   767         else if (encStr == "UnicodeUTF8")
   664             encoding = QCoreApplication::UnicodeUTF8;
   768             encoding = QCoreApplication::UnicodeUTF8;
   665         else
   769         else
   666             return JSC::throwError(exec, JSC::GeneralError, QString::fromLatin1("qsTranslate(): invalid encoding '%0'").arg(encStr));
   770             return JSC::throwError(exec, JSC::GeneralError, QString::fromLatin1("qsTranslate(): invalid encoding '%0'").arg(encStr));
   667     }
   771     }
   668     int n = -1;
   772     int n = -1;
   669     if (args.size() > 4)
   773     if (args.size() > 4)
   670         n = args.at(4).toInt32(exec);
   774         n = args.at(4).toInt32(exec);
   671 #endif
   775 #endif
   672     QString result;
   776     JSC::UString result;
   673 #ifndef QT_NO_QOBJECT
   777 #ifndef QT_NO_QOBJECT
   674     result = QCoreApplication::translate(context.toLatin1().constData(),
   778     result = QCoreApplication::translate(QScript::convertToLatin1(context).constData(),
   675                                          text.toLatin1().constData(),
   779                                          QScript::convertToLatin1(text).constData(),
   676                                          comment.toLatin1().constData(),
   780                                          QScript::convertToLatin1(comment).constData(),
   677                                          encoding, n);
   781                                          encoding, n);
   678 #else
   782 #else
   679     result = text;
   783     result = text;
   680 #endif
   784 #endif
   681     return JSC::jsString(exec, result);
   785     return JSC::jsString(exec, result);
   697     if ((args.size() > 1) && !args.at(1).isString())
   801     if ((args.size() > 1) && !args.at(1).isString())
   698         return JSC::throwError(exec, JSC::GeneralError, "qsTr(): second argument (comment) must be a string");
   802         return JSC::throwError(exec, JSC::GeneralError, "qsTr(): second argument (comment) must be a string");
   699     if ((args.size() > 2) && !args.at(2).isNumber())
   803     if ((args.size() > 2) && !args.at(2).isNumber())
   700         return JSC::throwError(exec, JSC::GeneralError, "qsTr(): third argument (n) must be a number");
   804         return JSC::throwError(exec, JSC::GeneralError, "qsTr(): third argument (n) must be a number");
   701 #ifndef QT_NO_QOBJECT
   805 #ifndef QT_NO_QOBJECT
   702     QString context;
   806     QScriptEnginePrivate *engine = scriptEngineFromExec(exec);
       
   807     JSC::UString context;
   703     // The first non-empty source URL in the call stack determines the translation context.
   808     // The first non-empty source URL in the call stack determines the translation context.
   704     {
   809     {
   705         JSC::ExecState *frame = exec->removeHostCallFrameFlag();
   810         JSC::ExecState *frame = exec->callerFrame()->removeHostCallFrameFlag();
   706         while (frame) {
   811         while (frame) {
   707             if (frame->codeBlock() && frame->codeBlock()->source()
   812             if (frame->codeBlock() && frame->codeBlock()->source()
   708                 && !frame->codeBlock()->source()->url().isEmpty()) {
   813                 && !frame->codeBlock()->source()->url().isEmpty()) {
   709                 context = QFileInfo(frame->codeBlock()->source()->url()).baseName();
   814                 context = engine->translationContextFromUrl(frame->codeBlock()->source()->url());
   710                 break;
   815                 break;
   711             }
   816             }
   712             frame = frame->callerFrame()->removeHostCallFrameFlag();
   817             frame = frame->callerFrame()->removeHostCallFrameFlag();
   713         }
   818         }
   714     }
   819     }
   715 #endif
   820 #endif
   716     QString text(args.at(0).toString(exec));
   821     JSC::UString text = args.at(0).toString(exec);
   717 #ifndef QT_NO_QOBJECT
   822 #ifndef QT_NO_QOBJECT
   718     QString comment;
   823     JSC::UString comment;
   719     if (args.size() > 1)
   824     if (args.size() > 1)
   720         comment = args.at(1).toString(exec);
   825         comment = args.at(1).toString(exec);
   721     int n = -1;
   826     int n = -1;
   722     if (args.size() > 2)
   827     if (args.size() > 2)
   723         n = args.at(2).toInt32(exec);
   828         n = args.at(2).toInt32(exec);
   724 #endif
   829 #endif
   725     QString result;
   830     JSC::UString result;
   726 #ifndef QT_NO_QOBJECT
   831 #ifndef QT_NO_QOBJECT
   727     result = QCoreApplication::translate(context.toLatin1().constData(),
   832     result = QCoreApplication::translate(QScript::convertToLatin1(context).constData(),
   728                                          text.toLatin1().constData(),
   833                                          QScript::convertToLatin1(text).constData(),
   729                                          comment.toLatin1().constData(),
   834                                          QScript::convertToLatin1(comment).constData(),
   730                                          QCoreApplication::CodecForTr, n);
   835                                          QCoreApplication::CodecForTr, n);
   731 #else
   836 #else
   732     result = text;
   837     result = text;
   733 #endif
   838 #endif
   734     return JSC::jsString(exec, result);
   839     return JSC::jsString(exec, result);
   790     if (!QCoreApplication::instance()) {
   895     if (!QCoreApplication::instance()) {
   791         qFatal("QScriptEngine: Must construct a Q(Core)Application before a QScriptEngine");
   896         qFatal("QScriptEngine: Must construct a Q(Core)Application before a QScriptEngine");
   792         return;
   897         return;
   793     }
   898     }
   794     JSC::initializeThreading();
   899     JSC::initializeThreading();
   795 
   900     JSC::IdentifierTable *oldTable = JSC::currentIdentifierTable();
   796     globalData = JSC::JSGlobalData::create().releaseRef();
   901     globalData = JSC::JSGlobalData::create().releaseRef();
   797     globalData->clientData = new QScript::GlobalClientData(this);
   902     globalData->clientData = new QScript::GlobalClientData(this);
   798     JSC::JSGlobalObject *globalObject = new (globalData)QScript::GlobalObject();
   903     JSC::JSGlobalObject *globalObject = new (globalData)QScript::GlobalObject();
   799 
   904 
   800     JSC::ExecState* exec = globalObject->globalExec();
   905     JSC::ExecState* exec = globalObject->globalExec();
   826 
   931 
   827     originalGlobalObjectProxy = 0;
   932     originalGlobalObjectProxy = 0;
   828     activeAgent = 0;
   933     activeAgent = 0;
   829     agentLineNumber = -1;
   934     agentLineNumber = -1;
   830     processEventsInterval = -1;
   935     processEventsInterval = -1;
       
   936     cachedTranslationUrl = JSC::UString();
       
   937     cachedTranslationContext = JSC::UString();
       
   938     JSC::setCurrentIdentifierTable(oldTable);
   831 }
   939 }
   832 
   940 
   833 QScriptEnginePrivate::~QScriptEnginePrivate()
   941 QScriptEnginePrivate::~QScriptEnginePrivate()
   834 {
   942 {
       
   943     QScript::APIShim shim(this);
       
   944 
   835     //disconnect all loadedScripts and generate all jsc::debugger::scriptUnload events
   945     //disconnect all loadedScripts and generate all jsc::debugger::scriptUnload events
   836     QHash<intptr_t,QScript::UStringSourceProviderWithFeedback*>::const_iterator it;
   946     QHash<intptr_t,QScript::UStringSourceProviderWithFeedback*>::const_iterator it;
   837     for (it = loadedScripts.constBegin(); it != loadedScripts.constEnd(); ++it)
   947     for (it = loadedScripts.constBegin(); it != loadedScripts.constEnd(); ++it)
   838         it.value()->disconnectFromEngine();
   948         it.value()->disconnectFromEngine();
   839 
   949 
   852         freeScriptValues = p->next;
   962         freeScriptValues = p->next;
   853         qFree(p);
   963         qFree(p);
   854     }
   964     }
   855 }
   965 }
   856 
   966 
   857 QScriptValue QScriptEnginePrivate::scriptValueFromVariant(const QVariant &v)
   967 QVariant QScriptEnginePrivate::jscValueToVariant(JSC::ExecState *exec, JSC::JSValue value, int targetType)
   858 {
       
   859     Q_Q(QScriptEngine);
       
   860     QScriptValue result = q->create(v.userType(), v.data());
       
   861     Q_ASSERT(result.isValid());
       
   862     return result;
       
   863 }
       
   864 
       
   865 QVariant QScriptEnginePrivate::scriptValueToVariant(const QScriptValue &value, int targetType)
       
   866 {
   968 {
   867     QVariant v(targetType, (void *)0);
   969     QVariant v(targetType, (void *)0);
   868     if (QScriptEnginePrivate::convert(value, targetType, v.data(), this))
   970     if (convertValue(exec, value, targetType, v.data()))
   869         return v;
   971         return v;
   870     if (uint(targetType) == QVariant::LastType)
   972     if (uint(targetType) == QVariant::LastType)
   871         return value.toVariant();
   973         return toVariant(exec, value);
   872     if (value.isVariant()) {
   974     if (isVariant(value)) {
   873         v = value.toVariant();
   975         v = variantValue(value);
   874         if (v.canConvert(QVariant::Type(targetType))) {
   976         if (v.canConvert(QVariant::Type(targetType))) {
   875             v.convert(QVariant::Type(targetType));
   977             v.convert(QVariant::Type(targetType));
   876             return v;
   978             return v;
   877         }
   979         }
   878         QByteArray typeName = v.typeName();
   980         QByteArray typeName = v.typeName();
   879         if (typeName.endsWith('*')
   981         if (typeName.endsWith('*')
   880             && (QMetaType::type(typeName.left(typeName.size()-1)) == targetType)) {
   982             && (QMetaType::type(typeName.left(typeName.size()-1)) == targetType)) {
   881             return QVariant(targetType, *reinterpret_cast<void* *>(v.data()));
   983             return QVariant(targetType, *reinterpret_cast<void* *>(v.data()));
   882         }
   984         }
   883     }
   985     }
   884 
       
   885     return QVariant();
   986     return QVariant();
   886 }
   987 }
   887 
   988 
   888 JSC::JSValue QScriptEnginePrivate::jscValueFromVariant(const QVariant &v)
   989 JSC::JSValue QScriptEnginePrivate::arrayFromStringList(JSC::ExecState *exec, const QStringList &lst)
   889 {
   990 {
   890     // ### it's inefficient to convert to QScriptValue and then to JSValue
   991     JSC::JSValue arr =  newArray(exec, lst.size());
   891     QScriptValue vv = scriptValueFromVariant(v);
       
   892     QScriptValuePrivate *p = QScriptValuePrivate::get(vv);
       
   893     switch (p->type) {
       
   894     case QScriptValuePrivate::JavaScriptCore:
       
   895         return p->jscValue;
       
   896     case QScriptValuePrivate::Number:
       
   897         return JSC::jsNumber(currentFrame, p->numberValue);
       
   898     case QScriptValuePrivate::String: {
       
   899         JSC::UString str = p->stringValue;
       
   900         return JSC::jsString(currentFrame, str);
       
   901       }
       
   902     }
       
   903     return JSC::JSValue();
       
   904 }
       
   905 
       
   906 QVariant QScriptEnginePrivate::jscValueToVariant(JSC::JSValue value, int targetType)
       
   907 {
       
   908     // ### it's inefficient to convert to QScriptValue and then to QVariant
       
   909     return scriptValueToVariant(scriptValueFromJSCValue(value), targetType);
       
   910 }
       
   911 
       
   912 QScriptValue QScriptEnginePrivate::arrayFromStringList(const QStringList &lst)
       
   913 {
       
   914     Q_Q(QScriptEngine);
       
   915     QScriptValue arr = q->newArray(lst.size());
       
   916     for (int i = 0; i < lst.size(); ++i)
   992     for (int i = 0; i < lst.size(); ++i)
   917         arr.setProperty(i, QScriptValue(q, lst.at(i)));
   993         setProperty(exec, arr, i, JSC::jsString(exec, lst.at(i)));
   918     return arr;
   994     return arr;
   919 }
   995 }
   920 
   996 
   921 QStringList QScriptEnginePrivate::stringListFromArray(const QScriptValue &arr)
   997 QStringList QScriptEnginePrivate::stringListFromArray(JSC::ExecState *exec, JSC::JSValue arr)
   922 {
   998 {
   923     QStringList lst;
   999     QStringList lst;
   924     uint len = arr.property(QLatin1String("length")).toUInt32();
  1000     uint len = toUInt32(exec, property(exec, arr, exec->propertyNames().length));
   925     for (uint i = 0; i < len; ++i)
  1001     for (uint i = 0; i < len; ++i)
   926         lst.append(arr.property(i).toString());
  1002         lst.append(toString(exec, property(exec, arr, i)));
   927     return lst;
  1003     return lst;
   928 }
  1004 }
   929 
  1005 
   930 QScriptValue QScriptEnginePrivate::arrayFromVariantList(const QVariantList &lst)
  1006 JSC::JSValue QScriptEnginePrivate::arrayFromVariantList(JSC::ExecState *exec, const QVariantList &lst)
   931 {
  1007 {
   932     Q_Q(QScriptEngine);
  1008     JSC::JSValue arr = newArray(exec, lst.size());
   933     QScriptValue arr = q->newArray(lst.size());
       
   934     for (int i = 0; i < lst.size(); ++i)
  1009     for (int i = 0; i < lst.size(); ++i)
   935         arr.setProperty(i, scriptValueFromVariant(lst.at(i)));
  1010         setProperty(exec, arr, i, jscValueFromVariant(exec, lst.at(i)));
   936     return arr;
  1011     return arr;
   937 }
  1012 }
   938 
  1013 
   939 QVariantList QScriptEnginePrivate::variantListFromArray(const QScriptValue &arr)
  1014 QVariantList QScriptEnginePrivate::variantListFromArray(JSC::ExecState *exec, JSC::JSValue arr)
   940 {
  1015 {
   941     QVariantList lst;
  1016     QVariantList lst;
   942     uint len = arr.property(QLatin1String("length")).toUInt32();
  1017     uint len = toUInt32(exec, property(exec, arr, exec->propertyNames().length));
   943     for (uint i = 0; i < len; ++i)
  1018     for (uint i = 0; i < len; ++i)
   944         lst.append(arr.property(i).toVariant());
  1019         lst.append(toVariant(exec, property(exec, arr, i)));
   945     return lst;
  1020     return lst;
   946 }
  1021 }
   947 
  1022 
   948 QScriptValue QScriptEnginePrivate::objectFromVariantMap(const QVariantMap &vmap)
  1023 JSC::JSValue QScriptEnginePrivate::objectFromVariantMap(JSC::ExecState *exec, const QVariantMap &vmap)
   949 {
  1024 {
   950     Q_Q(QScriptEngine);
  1025     JSC::JSValue obj = JSC::constructEmptyObject(exec);
   951     QScriptValue obj = q->newObject();
       
   952     QVariantMap::const_iterator it;
  1026     QVariantMap::const_iterator it;
   953     for (it = vmap.constBegin(); it != vmap.constEnd(); ++it)
  1027     for (it = vmap.constBegin(); it != vmap.constEnd(); ++it)
   954         obj.setProperty(it.key(), scriptValueFromVariant(it.value()));
  1028         setProperty(exec, obj, it.key(), jscValueFromVariant(exec, it.value()));
   955     return obj;
  1029     return obj;
   956 }
  1030 }
   957 
  1031 
   958 QVariantMap QScriptEnginePrivate::variantMapFromObject(const QScriptValue &obj)
  1032 QVariantMap QScriptEnginePrivate::variantMapFromObject(JSC::ExecState *exec, JSC::JSValue obj)
   959 {
  1033 {
       
  1034     JSC::PropertyNameArray propertyNames(exec);
       
  1035     JSC::asObject(obj)->getOwnPropertyNames(exec, propertyNames, JSC::IncludeDontEnumProperties);
   960     QVariantMap vmap;
  1036     QVariantMap vmap;
   961     QScriptValueIterator it(obj);
  1037     JSC::PropertyNameArray::const_iterator it = propertyNames.begin();
   962     while (it.hasNext()) {
  1038     for( ; it != propertyNames.end(); ++it)
   963         it.next();
  1039         vmap.insert(it->ustring(), toVariant(exec, property(exec, obj, *it)));
   964         vmap.insert(it.name(), it.value().toVariant());
       
   965     }
       
   966     return vmap;
  1040     return vmap;
   967 }
  1041 }
   968 
  1042 
   969 JSC::JSValue QScriptEnginePrivate::defaultPrototype(int metaTypeId) const
  1043 JSC::JSValue QScriptEnginePrivate::defaultPrototype(int metaTypeId) const
   970 {
  1044 {
  1158 }
  1232 }
  1159 
  1233 
  1160 void QScriptEnginePrivate::collectGarbage()
  1234 void QScriptEnginePrivate::collectGarbage()
  1161 {
  1235 {
  1162     JSC::JSLock lock(false);
  1236     JSC::JSLock lock(false);
  1163     globalData->heap.collect();
  1237     QScript::APIShim shim(this);
       
  1238     globalData->heap.collectAllGarbage();
       
  1239 }
       
  1240 
       
  1241 void QScriptEnginePrivate::reportAdditionalMemoryCost(int size)
       
  1242 {
       
  1243     if (size > 0)
       
  1244         globalData->heap.reportExtraMemoryCost(size);
  1164 }
  1245 }
  1165 
  1246 
  1166 QScript::TimeoutCheckerProxy *QScriptEnginePrivate::timeoutChecker() const
  1247 QScript::TimeoutCheckerProxy *QScriptEnginePrivate::timeoutChecker() const
  1167 {
  1248 {
  1168     return static_cast<QScript::TimeoutCheckerProxy*>(globalData->timeoutChecker);
  1249     return static_cast<QScript::TimeoutCheckerProxy*>(globalData->timeoutChecker);
  1189     JSC::Debugger* debugger = originalGlobalObject()->debugger();
  1270     JSC::Debugger* debugger = originalGlobalObject()->debugger();
  1190     if (debugger)
  1271     if (debugger)
  1191         debugger->evaluateStart(sourceId);
  1272         debugger->evaluateStart(sourceId);
  1192 
  1273 
  1193     q->clearExceptions();
  1274     q->clearExceptions();
  1194     JSC::DynamicGlobalObjectScope dynamicGlobalObjectScope(exec, exec->scopeChain()->globalObject());
  1275     JSC::DynamicGlobalObjectScope dynamicGlobalObjectScope(exec, exec->scopeChain()->globalObject);
  1195 
  1276 
  1196     if (compile) {
  1277     if (compile) {
  1197         JSC::JSObject* error = executable->compile(exec, exec->scopeChain());
  1278         JSC::JSObject* error = executable->compile(exec, exec->scopeChain());
  1198         if (error) {
  1279         if (error) {
  1199             compile = false;
  1280             compile = false;
  1293     JSC::ExecState* exec = currentFrame;
  1374     JSC::ExecState* exec = currentFrame;
  1294     QScript::QMetaObjectWrapperObject *result = new (exec) QScript::QMetaObjectWrapperObject(exec, metaObject, ctor, qmetaobjectWrapperObjectStructure);
  1375     QScript::QMetaObjectWrapperObject *result = new (exec) QScript::QMetaObjectWrapperObject(exec, metaObject, ctor, qmetaobjectWrapperObjectStructure);
  1295     return result;
  1376     return result;
  1296 }
  1377 }
  1297 
  1378 
  1298 bool QScriptEnginePrivate::convertToNativeQObject(const QScriptValue &value,
  1379 bool QScriptEnginePrivate::convertToNativeQObject(JSC::ExecState *exec, JSC::JSValue value,
  1299                                                   const QByteArray &targetType,
  1380                                                   const QByteArray &targetType,
  1300                                                   void **result)
  1381                                                   void **result)
  1301 {
  1382 {
  1302     if (!targetType.endsWith('*'))
  1383     if (!targetType.endsWith('*'))
  1303         return false;
  1384         return false;
  1304     if (QObject *qobject = value.toQObject()) {
  1385     if (QObject *qobject = toQObject(exec, value)) {
  1305         int start = targetType.startsWith("const ") ? 6 : 0;
  1386         int start = targetType.startsWith("const ") ? 6 : 0;
  1306         QByteArray className = targetType.mid(start, targetType.size()-start-1);
  1387         QByteArray className = targetType.mid(start, targetType.size()-start-1);
  1307         if (void *instance = qobject->qt_metacast(className)) {
  1388         if (void *instance = qobject->qt_metacast(className)) {
  1308             *result = instance;
  1389             *result = instance;
  1309             return true;
  1390             return true;
  1440         it->next = 0;
  1521         it->next = 0;
  1441     }
  1522     }
  1442     registeredScriptStrings = 0;
  1523     registeredScriptStrings = 0;
  1443 }
  1524 }
  1444 
  1525 
  1445 #ifdef QT_NO_QOBJECT
       
  1446 
       
  1447 QScriptEngine::QScriptEngine()
       
  1448     : d_ptr(new QScriptEnginePrivate)
       
  1449 {
       
  1450     d_ptr->q_ptr = this;
       
  1451 }
       
  1452 
       
  1453 /*! \internal
       
  1454 */
       
  1455 QScriptEngine::QScriptEngine(QScriptEnginePrivate &dd)
       
  1456     : d_ptr(&dd)
       
  1457 {
       
  1458     d_ptr->q_ptr = this;
       
  1459 }
       
  1460 #else
       
  1461 
       
  1462 /*!
       
  1463     Constructs a QScriptEngine object.
       
  1464 
       
  1465     The globalObject() is initialized to have properties as described in
       
  1466     \l{ECMA-262}, Section 15.1.
       
  1467 */
       
  1468 QScriptEngine::QScriptEngine()
       
  1469     : QObject(*new QScriptEnginePrivate, 0)
       
  1470 {
       
  1471 }
       
  1472 
       
  1473 /*!
       
  1474     Constructs a QScriptEngine object with the given \a parent.
       
  1475 
       
  1476     The globalObject() is initialized to have properties as described in
       
  1477     \l{ECMA-262}, Section 15.1.
       
  1478 */
       
  1479 
       
  1480 QScriptEngine::QScriptEngine(QObject *parent)
       
  1481     : QObject(*new QScriptEnginePrivate, parent)
       
  1482 {
       
  1483 }
       
  1484 
       
  1485 /*! \internal
       
  1486 */
       
  1487 QScriptEngine::QScriptEngine(QScriptEnginePrivate &dd, QObject *parent)
       
  1488     : QObject(dd, parent)
       
  1489 {
       
  1490 }
       
  1491 #endif
       
  1492 
       
  1493 /*!
       
  1494   Destroys this QScriptEngine.
       
  1495 */
       
  1496 QScriptEngine::~QScriptEngine()
       
  1497 {
       
  1498 #ifdef QT_NO_QOBJECT
       
  1499     delete d_ptr;
       
  1500     d_ptr = 0;
       
  1501 #endif
       
  1502 }
       
  1503 
       
  1504 /*!
       
  1505   Returns this engine's Global Object.
       
  1506 
       
  1507   By default, the Global Object contains the built-in objects that are
       
  1508   part of \l{ECMA-262}, such as Math, Date and String. Additionally,
       
  1509   you can set properties of the Global Object to make your own
       
  1510   extensions available to all script code. Non-local variables in
       
  1511   script code will be created as properties of the Global Object, as
       
  1512   well as local variables in global code.
       
  1513 */
       
  1514 QScriptValue QScriptEngine::globalObject() const
       
  1515 {
       
  1516     Q_D(const QScriptEngine);
       
  1517     JSC::JSObject *result = d->globalObject();
       
  1518     return const_cast<QScriptEnginePrivate*>(d)->scriptValueFromJSCValue(result);
       
  1519 }
       
  1520 
       
  1521 /*!
       
  1522   \since 4.5
       
  1523 
       
  1524   Sets this engine's Global Object to be the given \a object.
       
  1525   If \a object is not a valid script object, this function does
       
  1526   nothing.
       
  1527 
       
  1528   When setting a custom global object, you may want to use
       
  1529   QScriptValueIterator to copy the properties of the standard Global
       
  1530   Object; alternatively, you can set the internal prototype of your
       
  1531   custom object to be the original Global Object.
       
  1532 */
       
  1533 void QScriptEngine::setGlobalObject(const QScriptValue &object)
       
  1534 {
       
  1535     Q_D(QScriptEngine);
       
  1536     if (!object.isObject())
       
  1537         return;
       
  1538     JSC::JSObject *jscObject = JSC::asObject(d->scriptValueToJSCValue(object));
       
  1539     d->setGlobalObject(jscObject);
       
  1540 }
       
  1541 
       
  1542 /*!
       
  1543   Returns a QScriptValue of the primitive type Null.
       
  1544 
       
  1545   \sa undefinedValue()
       
  1546 */
       
  1547 QScriptValue QScriptEngine::nullValue()
       
  1548 {
       
  1549     Q_D(QScriptEngine);
       
  1550     return d->scriptValueFromJSCValue(JSC::jsNull());
       
  1551 }
       
  1552 
       
  1553 /*!
       
  1554   Returns a QScriptValue of the primitive type Undefined.
       
  1555 
       
  1556   \sa nullValue()
       
  1557 */
       
  1558 QScriptValue QScriptEngine::undefinedValue()
       
  1559 {
       
  1560     Q_D(QScriptEngine);
       
  1561     return d->scriptValueFromJSCValue(JSC::jsUndefined());
       
  1562 }
       
  1563 
       
  1564 /*!
       
  1565   Creates a constructor function from \a fun, with the given \a length.
       
  1566   The \c{prototype} property of the resulting function is set to be the
       
  1567   given \a prototype. The \c{constructor} property of \a prototype is
       
  1568   set to be the resulting function.
       
  1569 
       
  1570   When a function is called as a constructor (e.g. \c{new Foo()}), the
       
  1571   `this' object associated with the function call is the new object
       
  1572   that the function is expected to initialize; the prototype of this
       
  1573   default constructed object will be the function's public
       
  1574   \c{prototype} property. If you always want the function to behave as
       
  1575   a constructor (e.g. \c{Foo()} should also create a new object), or
       
  1576   if you need to create your own object rather than using the default
       
  1577   `this' object, you should make sure that the prototype of your
       
  1578   object is set correctly; either by setting it manually, or, when
       
  1579   wrapping a custom type, by having registered the defaultPrototype()
       
  1580   of that type. Example:
       
  1581 
       
  1582   \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 9
       
  1583 
       
  1584   To wrap a custom type and provide a constructor for it, you'd typically
       
  1585   do something like this:
       
  1586 
       
  1587   \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 10
       
  1588 */
       
  1589 QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionSignature fun,
       
  1590                                         const QScriptValue &prototype,
       
  1591                                         int length)
       
  1592 {
       
  1593     Q_D(QScriptEngine);
       
  1594     JSC::ExecState* exec = d->currentFrame;
       
  1595     JSC::JSValue function = new (exec)QScript::FunctionWrapper(exec, length, JSC::Identifier(exec, ""), fun);
       
  1596     QScriptValue result = d->scriptValueFromJSCValue(function);
       
  1597     result.setProperty(QLatin1String("prototype"), prototype, QScriptValue::Undeletable);
       
  1598     const_cast<QScriptValue&>(prototype)
       
  1599         .setProperty(QLatin1String("constructor"), result,
       
  1600                      QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
       
  1601     return result;
       
  1602 }
       
  1603 
       
  1604 #ifndef QT_NO_REGEXP
  1526 #ifndef QT_NO_REGEXP
  1605 
  1527 
  1606 Q_DECL_IMPORT extern QString qt_regexp_toCanonical(const QString &, QRegExp::PatternSyntax);
  1528 Q_DECL_IMPORT extern QString qt_regexp_toCanonical(const QString &, QRegExp::PatternSyntax);
  1607 
  1529 
  1608 /*!
  1530 JSC::JSValue QScriptEnginePrivate::newRegExp(JSC::ExecState *exec, const QRegExp &regexp)
  1609   Creates a QtScript object of class RegExp with the given
  1531 {
  1610   \a regexp.
       
  1611 
       
  1612   \sa QScriptValue::toRegExp()
       
  1613 */
       
  1614 QScriptValue QScriptEngine::newRegExp(const QRegExp &regexp)
       
  1615 {
       
  1616     Q_D(QScriptEngine);
       
  1617     JSC::ExecState* exec = d->currentFrame;
       
  1618     JSC::JSValue buf[2];
  1532     JSC::JSValue buf[2];
  1619     JSC::ArgList args(buf, sizeof(buf));
  1533     JSC::ArgList args(buf, sizeof(buf));
  1620 
  1534 
  1621     //convert the pattern to a ECMAScript pattern
  1535     //convert the pattern to a ECMAScript pattern
  1622     QString pattern = qt_regexp_toCanonical(regexp.pattern(), regexp.patternSyntax());
  1536     QString pattern = qt_regexp_toCanonical(regexp.pattern(), regexp.patternSyntax());
  1645             case '[':
  1559             case '[':
  1646                 inBracket = true;
  1560                 inBracket = true;
  1647                 break;
  1561                 break;
  1648             case ']':
  1562             case ']':
  1649                 inBracket = false;
  1563                 inBracket = false;
  1650                 break;
  1564                break;
  1651             default:
  1565             default:
  1652                 break;
  1566                 break;
  1653             }
  1567             }
  1654         }
  1568         }
  1655         pattern = ecmaPattern;
  1569         pattern = ecmaPattern;
  1660     if (regexp.caseSensitivity() == Qt::CaseInsensitive)
  1574     if (regexp.caseSensitivity() == Qt::CaseInsensitive)
  1661         flags.append(QLatin1Char('i'));
  1575         flags.append(QLatin1Char('i'));
  1662     JSC::UString jscFlags = flags;
  1576     JSC::UString jscFlags = flags;
  1663     buf[0] = JSC::jsString(exec, jscPattern);
  1577     buf[0] = JSC::jsString(exec, jscPattern);
  1664     buf[1] = JSC::jsString(exec, jscFlags);
  1578     buf[1] = JSC::jsString(exec, jscFlags);
  1665     JSC::JSObject* result = JSC::constructRegExp(exec, args);
  1579     return JSC::constructRegExp(exec, args);
  1666     return d->scriptValueFromJSCValue(result);
  1580 }
  1667 }
  1581 
  1668 
  1582 #endif
  1669 #endif // QT_NO_REGEXP
  1583 
  1670 
  1584 JSC::JSValue QScriptEnginePrivate::newRegExp(JSC::ExecState *exec, const QString &pattern, const QString &flags)
  1671 /*!
  1585 {
  1672   Creates a QtScript object holding the given variant \a value.
       
  1673 
       
  1674   If a default prototype has been registered with the meta type id of
       
  1675   \a value, then the prototype of the created object will be that
       
  1676   prototype; otherwise, the prototype will be the Object prototype
       
  1677   object.
       
  1678 
       
  1679   \sa setDefaultPrototype(), QScriptValue::toVariant()
       
  1680 */
       
  1681 QScriptValue QScriptEngine::newVariant(const QVariant &value)
       
  1682 {
       
  1683     Q_D(QScriptEngine);
       
  1684     JSC::ExecState* exec = d->currentFrame;
       
  1685     QScriptObject *obj = new (exec) QScriptObject(d->variantWrapperObjectStructure);
       
  1686     obj->setDelegate(new QScript::QVariantDelegate(value));
       
  1687     QScriptValue result = d->scriptValueFromJSCValue(obj);
       
  1688     QScriptValue proto = defaultPrototype(value.userType());
       
  1689     if (proto.isValid())
       
  1690         result.setPrototype(proto);
       
  1691     return result;
       
  1692 }
       
  1693 
       
  1694 /*!
       
  1695   \since 4.4
       
  1696   \overload
       
  1697 
       
  1698   Initializes the given Qt Script \a object to hold the given variant
       
  1699   \a value, and returns the \a object.
       
  1700 
       
  1701   This function enables you to "promote" a plain Qt Script object
       
  1702   (created by the newObject() function) to a variant, or to replace
       
  1703   the variant contained inside an object previously created by the
       
  1704   newVariant() function.
       
  1705 
       
  1706   The prototype() of the \a object will remain unchanged.
       
  1707 
       
  1708   If \a object is not an object, this function behaves like the normal
       
  1709   newVariant(), i.e. it creates a new script object and returns it.
       
  1710 
       
  1711   This function is useful when you want to provide a script
       
  1712   constructor for a C++ type. If your constructor is invoked in a
       
  1713   \c{new} expression (QScriptContext::isCalledAsConstructor() returns
       
  1714   true), you can pass QScriptContext::thisObject() (the default
       
  1715   constructed script object) to this function to initialize the new
       
  1716   object.
       
  1717 */
       
  1718 QScriptValue QScriptEngine::newVariant(const QScriptValue &object,
       
  1719                                        const QVariant &value)
       
  1720 {
       
  1721     if (!object.isObject())
       
  1722         return newVariant(value);
       
  1723     JSC::JSObject *jscObject = JSC::asObject(QScriptValuePrivate::get(object)->jscValue);
       
  1724     if (!jscObject->inherits(&QScriptObject::info)) {
       
  1725         qWarning("QScriptEngine::newVariant(): changing class of non-QScriptObject not supported");
       
  1726         return QScriptValue();
       
  1727     }
       
  1728     QScriptObject *jscScriptObject = static_cast<QScriptObject*>(jscObject);
       
  1729     if (!object.isVariant()) {
       
  1730         jscScriptObject->setDelegate(new QScript::QVariantDelegate(value));
       
  1731     } else {
       
  1732         QScriptValuePrivate::get(object)->setVariantValue(value);
       
  1733     }
       
  1734     return object;
       
  1735 }
       
  1736 
       
  1737 #ifndef QT_NO_QOBJECT
       
  1738 /*!
       
  1739   Creates a QtScript object that wraps the given QObject \a
       
  1740   object, using the given \a ownership. The given \a options control
       
  1741   various aspects of the interaction with the resulting script object.
       
  1742 
       
  1743   Signals and slots, properties and children of \a object are
       
  1744   available as properties of the created QScriptValue. For more
       
  1745   information, see the \l{QtScript} documentation.
       
  1746 
       
  1747   If \a object is a null pointer, this function returns nullValue().
       
  1748 
       
  1749   If a default prototype has been registered for the \a object's class
       
  1750   (or its superclass, recursively), the prototype of the new script
       
  1751   object will be set to be that default prototype.
       
  1752 
       
  1753   If the given \a object is deleted outside of QtScript's control, any
       
  1754   attempt to access the deleted QObject's members through the QtScript
       
  1755   wrapper object (either by script code or C++) will result in a
       
  1756   script exception.
       
  1757 
       
  1758   \sa QScriptValue::toQObject()
       
  1759 */
       
  1760 QScriptValue QScriptEngine::newQObject(QObject *object, ValueOwnership ownership,
       
  1761                                        const QObjectWrapOptions &options)
       
  1762 {
       
  1763     Q_D(QScriptEngine);
       
  1764     JSC::JSValue jscQObject = d->newQObject(object, ownership, options);
       
  1765     return d->scriptValueFromJSCValue(jscQObject);
       
  1766 }
       
  1767 
       
  1768 /*!
       
  1769   \since 4.4
       
  1770   \overload
       
  1771 
       
  1772   Initializes the given \a scriptObject to hold the given \a qtObject,
       
  1773   and returns the \a scriptObject.
       
  1774 
       
  1775   This function enables you to "promote" a plain Qt Script object
       
  1776   (created by the newObject() function) to a QObject proxy, or to
       
  1777   replace the QObject contained inside an object previously created by
       
  1778   the newQObject() function.
       
  1779 
       
  1780   The prototype() of the \a scriptObject will remain unchanged.
       
  1781 
       
  1782   If \a scriptObject is not an object, this function behaves like the
       
  1783   normal newQObject(), i.e. it creates a new script object and returns
       
  1784   it.
       
  1785 
       
  1786   This function is useful when you want to provide a script
       
  1787   constructor for a QObject-based class. If your constructor is
       
  1788   invoked in a \c{new} expression
       
  1789   (QScriptContext::isCalledAsConstructor() returns true), you can pass
       
  1790   QScriptContext::thisObject() (the default constructed script object)
       
  1791   to this function to initialize the new object.
       
  1792 */
       
  1793 QScriptValue QScriptEngine::newQObject(const QScriptValue &scriptObject,
       
  1794                                        QObject *qtObject,
       
  1795                                        ValueOwnership ownership,
       
  1796                                        const QObjectWrapOptions &options)
       
  1797 {
       
  1798     if (!scriptObject.isObject())
       
  1799         return newQObject(qtObject, ownership, options);
       
  1800     JSC::JSObject *jscObject = JSC::asObject(QScriptValuePrivate::get(scriptObject)->jscValue);
       
  1801     if (!jscObject->inherits(&QScriptObject::info)) {
       
  1802         qWarning("QScriptEngine::newQObject(): changing class of non-QScriptObject not supported");
       
  1803         return QScriptValue();
       
  1804     }
       
  1805     QScriptObject *jscScriptObject = static_cast<QScriptObject*>(jscObject);
       
  1806     if (!scriptObject.isQObject()) {
       
  1807         jscScriptObject->setDelegate(new QScript::QObjectDelegate(qtObject, ownership, options));
       
  1808     } else {
       
  1809         QScript::QObjectDelegate *delegate = static_cast<QScript::QObjectDelegate*>(jscScriptObject->delegate());
       
  1810         delegate->setValue(qtObject);
       
  1811         delegate->setOwnership(ownership);
       
  1812         delegate->setOptions(options);
       
  1813     }
       
  1814     return scriptObject;
       
  1815 }
       
  1816 
       
  1817 #endif // QT_NO_QOBJECT
       
  1818 
       
  1819 /*!
       
  1820   Creates a QtScript object of class Object.
       
  1821 
       
  1822   The prototype of the created object will be the Object
       
  1823   prototype object.
       
  1824 
       
  1825   \sa newArray(), QScriptValue::setProperty()
       
  1826 */
       
  1827 QScriptValue QScriptEngine::newObject()
       
  1828 {
       
  1829     Q_D(QScriptEngine);
       
  1830     JSC::ExecState* exec = d->currentFrame;
       
  1831     JSC::JSObject *result = new (exec)QScriptObject(d->scriptObjectStructure);
       
  1832     return d->scriptValueFromJSCValue(result);
       
  1833 }
       
  1834 
       
  1835 /*!
       
  1836   \since 4.4
       
  1837   \overload
       
  1838 
       
  1839   Creates a QtScript Object of the given class, \a scriptClass.
       
  1840 
       
  1841   The prototype of the created object will be the Object
       
  1842   prototype object.
       
  1843 
       
  1844   \a data, if specified, is set as the internal data of the
       
  1845   new object (using QScriptValue::setData()).
       
  1846 
       
  1847   \sa QScriptValue::scriptClass()
       
  1848 */
       
  1849 QScriptValue QScriptEngine::newObject(QScriptClass *scriptClass,
       
  1850                                       const QScriptValue &data)
       
  1851 {
       
  1852     Q_D(QScriptEngine);
       
  1853     JSC::ExecState* exec = d->currentFrame;
       
  1854     QScriptObject *result = new (exec) QScriptObject(d->scriptObjectStructure);
       
  1855     result->setDelegate(new QScript::ClassObjectDelegate(scriptClass));
       
  1856     QScriptValue scriptObject = d->scriptValueFromJSCValue(result);
       
  1857     scriptObject.setData(data);
       
  1858     QScriptValue proto = scriptClass->prototype();
       
  1859     if (proto.isValid())
       
  1860         scriptObject.setPrototype(proto);
       
  1861     return scriptObject;
       
  1862 }
       
  1863 
       
  1864 /*!
       
  1865   \internal
       
  1866 */
       
  1867 QScriptValue QScriptEngine::newActivationObject()
       
  1868 {
       
  1869     qWarning("QScriptEngine::newActivationObject() not implemented");
       
  1870     // ### JSActivation or JSVariableObject?
       
  1871     return QScriptValue();
       
  1872 }
       
  1873 
       
  1874 /*!
       
  1875   Creates a QScriptValue that wraps a native (C++) function. \a fun
       
  1876   must be a C++ function with signature QScriptEngine::FunctionSignature.  \a
       
  1877   length is the number of arguments that \a fun expects; this becomes
       
  1878   the \c{length} property of the created QScriptValue.
       
  1879 
       
  1880   Note that \a length only gives an indication of the number of
       
  1881   arguments that the function expects; an actual invocation of a
       
  1882   function can include any number of arguments. You can check the
       
  1883   \l{QScriptContext::argumentCount()}{argumentCount()} of the
       
  1884   QScriptContext associated with the invocation to determine the
       
  1885   actual number of arguments passed.
       
  1886 
       
  1887   A \c{prototype} property is automatically created for the resulting
       
  1888   function object, to provide for the possibility that the function
       
  1889   will be used as a constructor.
       
  1890 
       
  1891   By combining newFunction() and the property flags
       
  1892   QScriptValue::PropertyGetter and QScriptValue::PropertySetter, you
       
  1893   can create script object properties that behave like normal
       
  1894   properties in script code, but are in fact accessed through
       
  1895   functions (analogous to how properties work in \l{Qt's Property
       
  1896   System}). Example:
       
  1897 
       
  1898   \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 11
       
  1899 
       
  1900   When the property \c{foo} of the script object is subsequently
       
  1901   accessed in script code, \c{getSetFoo()} will be invoked to handle
       
  1902   the access.  In this particular case, we chose to store the "real"
       
  1903   value of \c{foo} as a property of the accessor function itself; you
       
  1904   are of course free to do whatever you like in this function.
       
  1905 
       
  1906   In the above example, a single native function was used to handle
       
  1907   both reads and writes to the property; the argument count is used to
       
  1908   determine if we are handling a read or write. You can also use two
       
  1909   separate functions; just specify the relevant flag
       
  1910   (QScriptValue::PropertyGetter or QScriptValue::PropertySetter) when
       
  1911   setting the property, e.g.:
       
  1912 
       
  1913   \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 12
       
  1914 
       
  1915   \sa QScriptValue::call()
       
  1916 */
       
  1917 QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionSignature fun, int length)
       
  1918 {
       
  1919     Q_D(QScriptEngine);
       
  1920     JSC::ExecState* exec = d->currentFrame;
       
  1921     JSC::JSValue function = new (exec)QScript::FunctionWrapper(exec, length, JSC::Identifier(exec, ""), fun);
       
  1922     QScriptValue result = d->scriptValueFromJSCValue(function);
       
  1923     QScriptValue proto = newObject();
       
  1924     result.setProperty(QLatin1String("prototype"), proto, QScriptValue::Undeletable);
       
  1925     proto.setProperty(QLatin1String("constructor"), result,
       
  1926                       QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
       
  1927     return result;
       
  1928 }
       
  1929 
       
  1930 /*!
       
  1931   \internal
       
  1932   \since 4.4
       
  1933 */
       
  1934 QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionWithArgSignature fun, void *arg)
       
  1935 {
       
  1936     Q_D(QScriptEngine);
       
  1937     JSC::ExecState* exec = d->currentFrame;
       
  1938     JSC::JSValue function = new (exec)QScript::FunctionWithArgWrapper(exec, /*length=*/0, JSC::Identifier(exec, ""), fun, arg);
       
  1939     QScriptValue result = d->scriptValueFromJSCValue(function);
       
  1940     QScriptValue proto = newObject();
       
  1941     result.setProperty(QLatin1String("prototype"), proto, QScriptValue::Undeletable);
       
  1942     proto.setProperty(QLatin1String("constructor"), result,
       
  1943                       QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
       
  1944     return result;
       
  1945 }
       
  1946 
       
  1947 /*!
       
  1948   Creates a QtScript object of class Array with the given \a length.
       
  1949 
       
  1950   \sa newObject()
       
  1951 */
       
  1952 QScriptValue QScriptEngine::newArray(uint length)
       
  1953 {
       
  1954     Q_D(QScriptEngine);
       
  1955     JSC::ExecState* exec = d->currentFrame;
       
  1956     JSC::JSArray* result = JSC::constructEmptyArray(exec, length);
       
  1957     return d->scriptValueFromJSCValue(result);
       
  1958 }
       
  1959 
       
  1960 /*!
       
  1961   Creates a QtScript object of class RegExp with the given
       
  1962   \a pattern and \a flags.
       
  1963 
       
  1964   The legal flags are 'g' (global), 'i' (ignore case), and 'm'
       
  1965   (multiline).
       
  1966 */
       
  1967 QScriptValue QScriptEngine::newRegExp(const QString &pattern, const QString &flags)
       
  1968 {
       
  1969     Q_D(QScriptEngine);
       
  1970     JSC::ExecState* exec = d->currentFrame;
       
  1971     JSC::JSValue buf[2];
  1586     JSC::JSValue buf[2];
  1972     JSC::ArgList args(buf, sizeof(buf));
  1587     JSC::ArgList args(buf, sizeof(buf));
  1973     JSC::UString jscPattern = pattern;
  1588     JSC::UString jscPattern = pattern;
  1974     QString strippedFlags;
  1589     QString strippedFlags;
  1975     if (flags.contains(QLatin1Char('i')))
  1590     if (flags.contains(QLatin1Char('i')))
  1979     if (flags.contains(QLatin1Char('g')))
  1594     if (flags.contains(QLatin1Char('g')))
  1980         strippedFlags += QLatin1Char('g');
  1595         strippedFlags += QLatin1Char('g');
  1981     JSC::UString jscFlags = strippedFlags;
  1596     JSC::UString jscFlags = strippedFlags;
  1982     buf[0] = JSC::jsString(exec, jscPattern);
  1597     buf[0] = JSC::jsString(exec, jscPattern);
  1983     buf[1] = JSC::jsString(exec, jscFlags);
  1598     buf[1] = JSC::jsString(exec, jscFlags);
  1984     JSC::JSObject* result = JSC::constructRegExp(exec, args);
  1599     return JSC::constructRegExp(exec, args);
  1985     return d->scriptValueFromJSCValue(result);
  1600 }
       
  1601 
       
  1602 JSC::JSValue QScriptEnginePrivate::newVariant(const QVariant &value)
       
  1603 {
       
  1604     QScriptObject *obj = new (currentFrame) QScriptObject(variantWrapperObjectStructure);
       
  1605     obj->setDelegate(new QScript::QVariantDelegate(value));
       
  1606     JSC::JSValue proto = defaultPrototype(value.userType());
       
  1607     if (proto)
       
  1608         obj->setPrototype(proto);
       
  1609     return obj;
       
  1610 }
       
  1611 
       
  1612 JSC::JSValue QScriptEnginePrivate::newVariant(JSC::JSValue objectValue,
       
  1613                                               const QVariant &value)
       
  1614 {
       
  1615     if (!isObject(objectValue))
       
  1616         return newVariant(value);
       
  1617     JSC::JSObject *jscObject = JSC::asObject(objectValue);
       
  1618     if (!jscObject->inherits(&QScriptObject::info)) {
       
  1619         qWarning("QScriptEngine::newVariant(): changing class of non-QScriptObject not supported");
       
  1620         return JSC::JSValue();
       
  1621     }
       
  1622     QScriptObject *jscScriptObject = static_cast<QScriptObject*>(jscObject);
       
  1623     if (!isVariant(objectValue)) {
       
  1624         jscScriptObject->setDelegate(new QScript::QVariantDelegate(value));
       
  1625     } else {
       
  1626         setVariantValue(objectValue, value);
       
  1627     }
       
  1628     return objectValue;
       
  1629 }
       
  1630 
       
  1631 #ifndef QT_NO_REGEXP
       
  1632 
       
  1633 QRegExp QScriptEnginePrivate::toRegExp(JSC::ExecState *exec, JSC::JSValue value)
       
  1634 {
       
  1635     if (!isRegExp(value))
       
  1636         return QRegExp();
       
  1637     QString pattern = toString(exec, property(exec, value, "source", QScriptValue::ResolvePrototype));
       
  1638     Qt::CaseSensitivity kase = Qt::CaseSensitive;
       
  1639     if (toBool(exec, property(exec, value, "ignoreCase", QScriptValue::ResolvePrototype)))
       
  1640         kase = Qt::CaseInsensitive;
       
  1641     return QRegExp(pattern, kase, QRegExp::RegExp2);
       
  1642 }
       
  1643 
       
  1644 #endif
       
  1645 
       
  1646 QVariant QScriptEnginePrivate::toVariant(JSC::ExecState *exec, JSC::JSValue value)
       
  1647 {
       
  1648     if (!value) {
       
  1649         return QVariant();
       
  1650     } else if (isObject(value)) {
       
  1651         if (isVariant(value))
       
  1652             return variantValue(value);
       
  1653 #ifndef QT_NO_QOBJECT
       
  1654         else if (isQObject(value))
       
  1655             return qVariantFromValue(toQObject(exec, value));
       
  1656 #endif
       
  1657         else if (isDate(value))
       
  1658             return QVariant(toDateTime(exec, value));
       
  1659 #ifndef QT_NO_REGEXP
       
  1660         else if (isRegExp(value))
       
  1661             return QVariant(toRegExp(exec, value));
       
  1662 #endif
       
  1663         else if (isArray(value))
       
  1664             return variantListFromArray(exec, value);
       
  1665         else if (QScriptDeclarativeClass *dc = declarativeClass(value))
       
  1666             return dc->toVariant(declarativeObject(value));
       
  1667         // try to convert to primitive
       
  1668         JSC::JSValue savedException;
       
  1669         saveException(exec, &savedException);
       
  1670         JSC::JSValue prim = value.toPrimitive(exec);
       
  1671         restoreException(exec, savedException);
       
  1672         if (!prim.isObject())
       
  1673             return toVariant(exec, prim);
       
  1674     } else if (value.isNumber()) {
       
  1675         return QVariant(toNumber(exec, value));
       
  1676     } else if (value.isString()) {
       
  1677         return QVariant(toString(exec, value));
       
  1678     } else if (value.isBoolean()) {
       
  1679         return QVariant(toBool(exec, value));
       
  1680     }
       
  1681     return QVariant();
       
  1682 }
       
  1683 
       
  1684 JSC::JSValue QScriptEnginePrivate::propertyHelper(JSC::ExecState *exec, JSC::JSValue value, const JSC::Identifier &id, int resolveMode)
       
  1685 {
       
  1686     JSC::JSValue result;
       
  1687     if (!(resolveMode & QScriptValue::ResolvePrototype)) {
       
  1688         // Look in the object's own properties
       
  1689         JSC::JSObject *object = JSC::asObject(value);
       
  1690         JSC::PropertySlot slot(object);
       
  1691         if (object->getOwnPropertySlot(exec, id, slot))
       
  1692             result = slot.getValue(exec, id);
       
  1693     }
       
  1694     if (!result && (resolveMode & QScriptValue::ResolveScope)) {
       
  1695         // ### check if it's a function object and look in the scope chain
       
  1696         JSC::JSValue scope = property(exec, value, "__qt_scope__", QScriptValue::ResolveLocal);
       
  1697         if (isObject(scope))
       
  1698             result = property(exec, scope, id, resolveMode);
       
  1699     }
       
  1700     return result;
       
  1701 }
       
  1702 
       
  1703 JSC::JSValue QScriptEnginePrivate::propertyHelper(JSC::ExecState *exec, JSC::JSValue value, quint32 index, int resolveMode)
       
  1704 {
       
  1705     JSC::JSValue result;
       
  1706     if (!(resolveMode & QScriptValue::ResolvePrototype)) {
       
  1707         // Look in the object's own properties
       
  1708         JSC::JSObject *object = JSC::asObject(value);
       
  1709         JSC::PropertySlot slot(object);
       
  1710         if (object->getOwnPropertySlot(exec, index, slot))
       
  1711             result = slot.getValue(exec, index);
       
  1712     }
       
  1713     return result;
       
  1714 }
       
  1715 
       
  1716 void QScriptEnginePrivate::setProperty(JSC::ExecState *exec, JSC::JSValue objectValue, const JSC::Identifier &id,
       
  1717                                        JSC::JSValue value, const QScriptValue::PropertyFlags &flags)
       
  1718 {
       
  1719     JSC::JSObject *thisObject = JSC::asObject(objectValue);
       
  1720     JSC::JSValue setter = thisObject->lookupSetter(exec, id);
       
  1721     JSC::JSValue getter = thisObject->lookupGetter(exec, id);
       
  1722     if ((flags & QScriptValue::PropertyGetter) || (flags & QScriptValue::PropertySetter)) {
       
  1723         if (!value) {
       
  1724             // deleting getter/setter
       
  1725             if ((flags & QScriptValue::PropertyGetter) && (flags & QScriptValue::PropertySetter)) {
       
  1726                 // deleting both: just delete the property
       
  1727                 thisObject->deleteProperty(exec, id);
       
  1728             } else if (flags & QScriptValue::PropertyGetter) {
       
  1729                 // preserve setter, if there is one
       
  1730                 thisObject->deleteProperty(exec, id);
       
  1731                 if (setter && setter.isObject())
       
  1732                     thisObject->defineSetter(exec, id, JSC::asObject(setter));
       
  1733             } else { // flags & QScriptValue::PropertySetter
       
  1734                 // preserve getter, if there is one
       
  1735                 thisObject->deleteProperty(exec, id);
       
  1736                 if (getter && getter.isObject())
       
  1737                     thisObject->defineGetter(exec, id, JSC::asObject(getter));
       
  1738             }
       
  1739         } else {
       
  1740             if (value.isObject()) { // ### should check if it has callData()
       
  1741                 // defining getter/setter
       
  1742                 if (id == exec->propertyNames().underscoreProto) {
       
  1743                     qWarning("QScriptValue::setProperty() failed: "
       
  1744                              "cannot set getter or setter of native property `__proto__'");
       
  1745                 } else {
       
  1746                     if (flags & QScriptValue::PropertyGetter)
       
  1747                         thisObject->defineGetter(exec, id, JSC::asObject(value));
       
  1748                     if (flags & QScriptValue::PropertySetter)
       
  1749                         thisObject->defineSetter(exec, id, JSC::asObject(value));
       
  1750                 }
       
  1751             } else {
       
  1752                 qWarning("QScriptValue::setProperty(): getter/setter must be a function");
       
  1753             }
       
  1754         }
       
  1755     } else {
       
  1756         // setting the value
       
  1757         if (getter && getter.isObject() && !(setter && setter.isObject())) {
       
  1758             qWarning("QScriptValue::setProperty() failed: "
       
  1759                      "property '%s' has a getter but no setter",
       
  1760                      qPrintable(QString(id.ustring())));
       
  1761             return;
       
  1762         }
       
  1763         if (!value) {
       
  1764             // ### check if it's a getter/setter property
       
  1765             thisObject->deleteProperty(exec, id);
       
  1766         } else if (flags != QScriptValue::KeepExistingFlags) {
       
  1767             if (thisObject->hasOwnProperty(exec, id))
       
  1768                 thisObject->deleteProperty(exec, id); // ### hmmm - can't we just update the attributes?
       
  1769             unsigned attribs = 0;
       
  1770             if (flags & QScriptValue::ReadOnly)
       
  1771                 attribs |= JSC::ReadOnly;
       
  1772             if (flags & QScriptValue::SkipInEnumeration)
       
  1773                 attribs |= JSC::DontEnum;
       
  1774             if (flags & QScriptValue::Undeletable)
       
  1775                 attribs |= JSC::DontDelete;
       
  1776             attribs |= flags & QScriptValue::UserRange;
       
  1777             thisObject->putWithAttributes(exec, id, value, attribs);
       
  1778         } else {
       
  1779             JSC::PutPropertySlot slot;
       
  1780             thisObject->put(exec, id, value, slot);
       
  1781         }
       
  1782     }
       
  1783 }
       
  1784 
       
  1785 void QScriptEnginePrivate::setProperty(JSC::ExecState *exec, JSC::JSValue objectValue, quint32 index,
       
  1786                                        JSC::JSValue value, const QScriptValue::PropertyFlags &flags)
       
  1787 {
       
  1788     if (!value) {
       
  1789         JSC::asObject(objectValue)->deleteProperty(exec, index);
       
  1790     } else {
       
  1791         if ((flags & QScriptValue::PropertyGetter) || (flags & QScriptValue::PropertySetter)) {
       
  1792             // fall back to string-based setProperty(), since there is no
       
  1793             // JSC::JSObject::defineGetter(unsigned)
       
  1794             setProperty(exec, objectValue, JSC::Identifier::from(exec, index), value, flags);
       
  1795         } else {
       
  1796             if (flags != QScriptValue::KeepExistingFlags) {
       
  1797                 //                if (JSC::asObject(d->jscValue)->hasOwnProperty(exec, arrayIndex))
       
  1798                 //                    JSC::asObject(d->jscValue)->deleteProperty(exec, arrayIndex);
       
  1799                 unsigned attribs = 0;
       
  1800                 if (flags & QScriptValue::ReadOnly)
       
  1801                     attribs |= JSC::ReadOnly;
       
  1802                 if (flags & QScriptValue::SkipInEnumeration)
       
  1803                     attribs |= JSC::DontEnum;
       
  1804                 if (flags & QScriptValue::Undeletable)
       
  1805                     attribs |= JSC::DontDelete;
       
  1806                 attribs |= flags & QScriptValue::UserRange;
       
  1807                 JSC::asObject(objectValue)->putWithAttributes(exec, index, value, attribs);
       
  1808             } else {
       
  1809                 JSC::asObject(objectValue)->put(exec, index, value);
       
  1810             }
       
  1811         }
       
  1812     }
       
  1813 }
       
  1814 
       
  1815 QScriptValue::PropertyFlags QScriptEnginePrivate::propertyFlags(JSC::ExecState *exec, JSC::JSValue value, const JSC::Identifier &id,
       
  1816                                                                 const QScriptValue::ResolveFlags &mode)
       
  1817 {
       
  1818     JSC::JSObject *object = JSC::asObject(value);
       
  1819     unsigned attribs = 0;
       
  1820     JSC::PropertyDescriptor descriptor;
       
  1821     if (object->getOwnPropertyDescriptor(exec, id, descriptor))
       
  1822         attribs = descriptor.attributes();
       
  1823     else {
       
  1824         if ((mode & QScriptValue::ResolvePrototype) && object->prototype() && object->prototype().isObject()) {
       
  1825             JSC::JSValue proto = object->prototype();
       
  1826             return propertyFlags(exec, proto, id, mode);
       
  1827         }
       
  1828         return 0;
       
  1829     }
       
  1830     QScriptValue::PropertyFlags result = 0;
       
  1831     if (attribs & JSC::ReadOnly)
       
  1832         result |= QScriptValue::ReadOnly;
       
  1833     if (attribs & JSC::DontEnum)
       
  1834         result |= QScriptValue::SkipInEnumeration;
       
  1835     if (attribs & JSC::DontDelete)
       
  1836         result |= QScriptValue::Undeletable;
       
  1837     //We cannot rely on attribs JSC::Setter/Getter because they are not necesserly set by JSC (bug?)
       
  1838     if (attribs & JSC::Getter || !object->lookupGetter(exec, id).isUndefinedOrNull())
       
  1839         result |= QScriptValue::PropertyGetter;
       
  1840     if (attribs & JSC::Setter || !object->lookupSetter(exec, id).isUndefinedOrNull())
       
  1841         result |= QScriptValue::PropertySetter;
       
  1842 #ifndef QT_NO_QOBJECT
       
  1843     if (attribs & QScript::QObjectMemberAttribute)
       
  1844         result |= QScriptValue::QObjectMember;
       
  1845 #endif
       
  1846     result |= QScriptValue::PropertyFlag(attribs & QScriptValue::UserRange);
       
  1847     return result;
       
  1848 }
       
  1849 
       
  1850 QScriptString QScriptEnginePrivate::toStringHandle(const JSC::Identifier &name)
       
  1851 {
       
  1852     QScriptString result;
       
  1853     QScriptStringPrivate *p = new QScriptStringPrivate(this, name, QScriptStringPrivate::HeapAllocated);
       
  1854     QScriptStringPrivate::init(result, p);
       
  1855     registerScriptString(p);
       
  1856     return result;
       
  1857 }
       
  1858 
       
  1859 #ifdef QT_NO_QOBJECT
       
  1860 
       
  1861 QScriptEngine::QScriptEngine()
       
  1862     : d_ptr(new QScriptEnginePrivate)
       
  1863 {
       
  1864     d_ptr->q_ptr = this;
       
  1865 }
       
  1866 
       
  1867 /*! \internal
       
  1868 */
       
  1869 QScriptEngine::QScriptEngine(QScriptEnginePrivate &dd)
       
  1870     : d_ptr(&dd)
       
  1871 {
       
  1872     d_ptr->q_ptr = this;
       
  1873 }
       
  1874 #else
       
  1875 
       
  1876 /*!
       
  1877     Constructs a QScriptEngine object.
       
  1878 
       
  1879     The globalObject() is initialized to have properties as described in
       
  1880     \l{ECMA-262}, Section 15.1.
       
  1881 */
       
  1882 QScriptEngine::QScriptEngine()
       
  1883     : QObject(*new QScriptEnginePrivate, 0)
       
  1884 {
       
  1885 }
       
  1886 
       
  1887 /*!
       
  1888     Constructs a QScriptEngine object with the given \a parent.
       
  1889 
       
  1890     The globalObject() is initialized to have properties as described in
       
  1891     \l{ECMA-262}, Section 15.1.
       
  1892 */
       
  1893 
       
  1894 QScriptEngine::QScriptEngine(QObject *parent)
       
  1895     : QObject(*new QScriptEnginePrivate, parent)
       
  1896 {
       
  1897 }
       
  1898 
       
  1899 /*! \internal
       
  1900 */
       
  1901 QScriptEngine::QScriptEngine(QScriptEnginePrivate &dd, QObject *parent)
       
  1902     : QObject(dd, parent)
       
  1903 {
       
  1904 }
       
  1905 #endif
       
  1906 
       
  1907 /*!
       
  1908   Destroys this QScriptEngine.
       
  1909 */
       
  1910 QScriptEngine::~QScriptEngine()
       
  1911 {
       
  1912 #ifdef QT_NO_QOBJECT
       
  1913     delete d_ptr;
       
  1914     d_ptr = 0;
       
  1915 #endif
       
  1916 }
       
  1917 
       
  1918 /*!
       
  1919   Returns this engine's Global Object.
       
  1920 
       
  1921   By default, the Global Object contains the built-in objects that are
       
  1922   part of \l{ECMA-262}, such as Math, Date and String. Additionally,
       
  1923   you can set properties of the Global Object to make your own
       
  1924   extensions available to all script code. Non-local variables in
       
  1925   script code will be created as properties of the Global Object, as
       
  1926   well as local variables in global code.
       
  1927 */
       
  1928 QScriptValue QScriptEngine::globalObject() const
       
  1929 {
       
  1930     Q_D(const QScriptEngine);
       
  1931     QScript::APIShim shim(const_cast<QScriptEnginePrivate*>(d));
       
  1932     JSC::JSObject *result = d->globalObject();
       
  1933     return const_cast<QScriptEnginePrivate*>(d)->scriptValueFromJSCValue(result);
       
  1934 }
       
  1935 
       
  1936 /*!
       
  1937   \since 4.5
       
  1938 
       
  1939   Sets this engine's Global Object to be the given \a object.
       
  1940   If \a object is not a valid script object, this function does
       
  1941   nothing.
       
  1942 
       
  1943   When setting a custom global object, you may want to use
       
  1944   QScriptValueIterator to copy the properties of the standard Global
       
  1945   Object; alternatively, you can set the internal prototype of your
       
  1946   custom object to be the original Global Object.
       
  1947 */
       
  1948 void QScriptEngine::setGlobalObject(const QScriptValue &object)
       
  1949 {
       
  1950     Q_D(QScriptEngine);
       
  1951     if (!object.isObject())
       
  1952         return;
       
  1953     QScript::APIShim shim(d);
       
  1954     JSC::JSObject *jscObject = JSC::asObject(d->scriptValueToJSCValue(object));
       
  1955     d->setGlobalObject(jscObject);
       
  1956 }
       
  1957 
       
  1958 /*!
       
  1959   Returns a QScriptValue of the primitive type Null.
       
  1960 
       
  1961   \sa undefinedValue()
       
  1962 */
       
  1963 QScriptValue QScriptEngine::nullValue()
       
  1964 {
       
  1965     Q_D(QScriptEngine);
       
  1966     return d->scriptValueFromJSCValue(JSC::jsNull());
       
  1967 }
       
  1968 
       
  1969 /*!
       
  1970   Returns a QScriptValue of the primitive type Undefined.
       
  1971 
       
  1972   \sa nullValue()
       
  1973 */
       
  1974 QScriptValue QScriptEngine::undefinedValue()
       
  1975 {
       
  1976     Q_D(QScriptEngine);
       
  1977     return d->scriptValueFromJSCValue(JSC::jsUndefined());
       
  1978 }
       
  1979 
       
  1980 /*!
       
  1981   Creates a constructor function from \a fun, with the given \a length.
       
  1982   The \c{prototype} property of the resulting function is set to be the
       
  1983   given \a prototype. The \c{constructor} property of \a prototype is
       
  1984   set to be the resulting function.
       
  1985 
       
  1986   When a function is called as a constructor (e.g. \c{new Foo()}), the
       
  1987   `this' object associated with the function call is the new object
       
  1988   that the function is expected to initialize; the prototype of this
       
  1989   default constructed object will be the function's public
       
  1990   \c{prototype} property. If you always want the function to behave as
       
  1991   a constructor (e.g. \c{Foo()} should also create a new object), or
       
  1992   if you need to create your own object rather than using the default
       
  1993   `this' object, you should make sure that the prototype of your
       
  1994   object is set correctly; either by setting it manually, or, when
       
  1995   wrapping a custom type, by having registered the defaultPrototype()
       
  1996   of that type. Example:
       
  1997 
       
  1998   \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 9
       
  1999 
       
  2000   To wrap a custom type and provide a constructor for it, you'd typically
       
  2001   do something like this:
       
  2002 
       
  2003   \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 10
       
  2004 */
       
  2005 QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionSignature fun,
       
  2006                                         const QScriptValue &prototype,
       
  2007                                         int length)
       
  2008 {
       
  2009     Q_D(QScriptEngine);
       
  2010     QScript::APIShim shim(d);
       
  2011     JSC::ExecState* exec = d->currentFrame;
       
  2012     JSC::JSValue function = new (exec)QScript::FunctionWrapper(exec, length, JSC::Identifier(exec, ""), fun);
       
  2013     QScriptValue result = d->scriptValueFromJSCValue(function);
       
  2014     result.setProperty(QLatin1String("prototype"), prototype, QScriptValue::Undeletable);
       
  2015     const_cast<QScriptValue&>(prototype)
       
  2016         .setProperty(QLatin1String("constructor"), result,
       
  2017                      QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
       
  2018     return result;
       
  2019 }
       
  2020 
       
  2021 #ifndef QT_NO_REGEXP
       
  2022 
       
  2023 Q_DECL_IMPORT extern QString qt_regexp_toCanonical(const QString &, QRegExp::PatternSyntax);
       
  2024 
       
  2025 /*!
       
  2026   Creates a QtScript object of class RegExp with the given
       
  2027   \a regexp.
       
  2028 
       
  2029   \sa QScriptValue::toRegExp()
       
  2030 */
       
  2031 QScriptValue QScriptEngine::newRegExp(const QRegExp &regexp)
       
  2032 {
       
  2033     Q_D(QScriptEngine);
       
  2034     QScript::APIShim shim(d);
       
  2035     return d->scriptValueFromJSCValue(d->newRegExp(d->currentFrame, regexp));
       
  2036 }
       
  2037 
       
  2038 #endif // QT_NO_REGEXP
       
  2039 
       
  2040 /*!
       
  2041   Creates a QtScript object holding the given variant \a value.
       
  2042 
       
  2043   If a default prototype has been registered with the meta type id of
       
  2044   \a value, then the prototype of the created object will be that
       
  2045   prototype; otherwise, the prototype will be the Object prototype
       
  2046   object.
       
  2047 
       
  2048   \sa setDefaultPrototype(), QScriptValue::toVariant(), reportAdditionalMemoryCost()
       
  2049 */
       
  2050 QScriptValue QScriptEngine::newVariant(const QVariant &value)
       
  2051 {
       
  2052     Q_D(QScriptEngine);
       
  2053     QScript::APIShim shim(d);
       
  2054     return d->scriptValueFromJSCValue(d->newVariant(value));
       
  2055 }
       
  2056 
       
  2057 /*!
       
  2058   \since 4.4
       
  2059   \overload
       
  2060 
       
  2061   Initializes the given Qt Script \a object to hold the given variant
       
  2062   \a value, and returns the \a object.
       
  2063 
       
  2064   This function enables you to "promote" a plain Qt Script object
       
  2065   (created by the newObject() function) to a variant, or to replace
       
  2066   the variant contained inside an object previously created by the
       
  2067   newVariant() function.
       
  2068 
       
  2069   The prototype() of the \a object will remain unchanged.
       
  2070 
       
  2071   If \a object is not an object, this function behaves like the normal
       
  2072   newVariant(), i.e. it creates a new script object and returns it.
       
  2073 
       
  2074   This function is useful when you want to provide a script
       
  2075   constructor for a C++ type. If your constructor is invoked in a
       
  2076   \c{new} expression (QScriptContext::isCalledAsConstructor() returns
       
  2077   true), you can pass QScriptContext::thisObject() (the default
       
  2078   constructed script object) to this function to initialize the new
       
  2079   object.
       
  2080 
       
  2081   \sa reportAdditionalMemoryCost()
       
  2082 */
       
  2083 QScriptValue QScriptEngine::newVariant(const QScriptValue &object,
       
  2084                                        const QVariant &value)
       
  2085 {
       
  2086     Q_D(QScriptEngine);
       
  2087     QScript::APIShim shim(d);
       
  2088     JSC::JSValue jsObject = d->scriptValueToJSCValue(object);
       
  2089     return d->scriptValueFromJSCValue(d->newVariant(jsObject, value));
       
  2090 }
       
  2091 
       
  2092 #ifndef QT_NO_QOBJECT
       
  2093 /*!
       
  2094   Creates a QtScript object that wraps the given QObject \a
       
  2095   object, using the given \a ownership. The given \a options control
       
  2096   various aspects of the interaction with the resulting script object.
       
  2097 
       
  2098   Signals and slots, properties and children of \a object are
       
  2099   available as properties of the created QScriptValue. For more
       
  2100   information, see the \l{QtScript} documentation.
       
  2101 
       
  2102   If \a object is a null pointer, this function returns nullValue().
       
  2103 
       
  2104   If a default prototype has been registered for the \a object's class
       
  2105   (or its superclass, recursively), the prototype of the new script
       
  2106   object will be set to be that default prototype.
       
  2107 
       
  2108   If the given \a object is deleted outside of QtScript's control, any
       
  2109   attempt to access the deleted QObject's members through the QtScript
       
  2110   wrapper object (either by script code or C++) will result in a
       
  2111   script exception.
       
  2112 
       
  2113   \sa QScriptValue::toQObject(), reportAdditionalMemoryCost()
       
  2114 */
       
  2115 QScriptValue QScriptEngine::newQObject(QObject *object, ValueOwnership ownership,
       
  2116                                        const QObjectWrapOptions &options)
       
  2117 {
       
  2118     Q_D(QScriptEngine);
       
  2119     QScript::APIShim shim(d);
       
  2120     JSC::JSValue jscQObject = d->newQObject(object, ownership, options);
       
  2121     return d->scriptValueFromJSCValue(jscQObject);
       
  2122 }
       
  2123 
       
  2124 /*!
       
  2125   \since 4.4
       
  2126   \overload
       
  2127 
       
  2128   Initializes the given \a scriptObject to hold the given \a qtObject,
       
  2129   and returns the \a scriptObject.
       
  2130 
       
  2131   This function enables you to "promote" a plain Qt Script object
       
  2132   (created by the newObject() function) to a QObject proxy, or to
       
  2133   replace the QObject contained inside an object previously created by
       
  2134   the newQObject() function.
       
  2135 
       
  2136   The prototype() of the \a scriptObject will remain unchanged.
       
  2137 
       
  2138   If \a scriptObject is not an object, this function behaves like the
       
  2139   normal newQObject(), i.e. it creates a new script object and returns
       
  2140   it.
       
  2141 
       
  2142   This function is useful when you want to provide a script
       
  2143   constructor for a QObject-based class. If your constructor is
       
  2144   invoked in a \c{new} expression
       
  2145   (QScriptContext::isCalledAsConstructor() returns true), you can pass
       
  2146   QScriptContext::thisObject() (the default constructed script object)
       
  2147   to this function to initialize the new object.
       
  2148 
       
  2149   \sa reportAdditionalMemoryCost()
       
  2150 */
       
  2151 QScriptValue QScriptEngine::newQObject(const QScriptValue &scriptObject,
       
  2152                                        QObject *qtObject,
       
  2153                                        ValueOwnership ownership,
       
  2154                                        const QObjectWrapOptions &options)
       
  2155 {
       
  2156     Q_D(QScriptEngine);
       
  2157     if (!scriptObject.isObject())
       
  2158         return newQObject(qtObject, ownership, options);
       
  2159     QScript::APIShim shim(d);
       
  2160     JSC::JSObject *jscObject = JSC::asObject(QScriptValuePrivate::get(scriptObject)->jscValue);
       
  2161     if (!jscObject->inherits(&QScriptObject::info)) {
       
  2162         qWarning("QScriptEngine::newQObject(): changing class of non-QScriptObject not supported");
       
  2163         return QScriptValue();
       
  2164     }
       
  2165     QScriptObject *jscScriptObject = static_cast<QScriptObject*>(jscObject);
       
  2166     if (!scriptObject.isQObject()) {
       
  2167         jscScriptObject->setDelegate(new QScript::QObjectDelegate(qtObject, ownership, options));
       
  2168     } else {
       
  2169         QScript::QObjectDelegate *delegate = static_cast<QScript::QObjectDelegate*>(jscScriptObject->delegate());
       
  2170         delegate->setValue(qtObject);
       
  2171         delegate->setOwnership(ownership);
       
  2172         delegate->setOptions(options);
       
  2173     }
       
  2174     return scriptObject;
       
  2175 }
       
  2176 
       
  2177 #endif // QT_NO_QOBJECT
       
  2178 
       
  2179 /*!
       
  2180   Creates a QtScript object of class Object.
       
  2181 
       
  2182   The prototype of the created object will be the Object
       
  2183   prototype object.
       
  2184 
       
  2185   \sa newArray(), QScriptValue::setProperty()
       
  2186 */
       
  2187 QScriptValue QScriptEngine::newObject()
       
  2188 {
       
  2189     Q_D(QScriptEngine);
       
  2190     QScript::APIShim shim(d);
       
  2191     return d->scriptValueFromJSCValue(d->newObject());
       
  2192 }
       
  2193 
       
  2194 /*!
       
  2195   \since 4.4
       
  2196   \overload
       
  2197 
       
  2198   Creates a QtScript Object of the given class, \a scriptClass.
       
  2199 
       
  2200   The prototype of the created object will be the Object
       
  2201   prototype object.
       
  2202 
       
  2203   \a data, if specified, is set as the internal data of the
       
  2204   new object (using QScriptValue::setData()).
       
  2205 
       
  2206   \sa QScriptValue::scriptClass(), reportAdditionalMemoryCost()
       
  2207 */
       
  2208 QScriptValue QScriptEngine::newObject(QScriptClass *scriptClass,
       
  2209                                       const QScriptValue &data)
       
  2210 {
       
  2211     Q_D(QScriptEngine);
       
  2212     QScript::APIShim shim(d);
       
  2213     JSC::ExecState* exec = d->currentFrame;
       
  2214     QScriptObject *result = new (exec) QScriptObject(d->scriptObjectStructure);
       
  2215     result->setDelegate(new QScript::ClassObjectDelegate(scriptClass));
       
  2216     QScriptValue scriptObject = d->scriptValueFromJSCValue(result);
       
  2217     scriptObject.setData(data);
       
  2218     QScriptValue proto = scriptClass->prototype();
       
  2219     if (proto.isValid())
       
  2220         scriptObject.setPrototype(proto);
       
  2221     return scriptObject;
       
  2222 }
       
  2223 
       
  2224 /*!
       
  2225   \internal
       
  2226 */
       
  2227 QScriptValue QScriptEngine::newActivationObject()
       
  2228 {
       
  2229     qWarning("QScriptEngine::newActivationObject() not implemented");
       
  2230     // ### JSActivation or JSVariableObject?
       
  2231     return QScriptValue();
       
  2232 }
       
  2233 
       
  2234 /*!
       
  2235   Creates a QScriptValue that wraps a native (C++) function. \a fun
       
  2236   must be a C++ function with signature QScriptEngine::FunctionSignature.  \a
       
  2237   length is the number of arguments that \a fun expects; this becomes
       
  2238   the \c{length} property of the created QScriptValue.
       
  2239 
       
  2240   Note that \a length only gives an indication of the number of
       
  2241   arguments that the function expects; an actual invocation of a
       
  2242   function can include any number of arguments. You can check the
       
  2243   \l{QScriptContext::argumentCount()}{argumentCount()} of the
       
  2244   QScriptContext associated with the invocation to determine the
       
  2245   actual number of arguments passed.
       
  2246 
       
  2247   A \c{prototype} property is automatically created for the resulting
       
  2248   function object, to provide for the possibility that the function
       
  2249   will be used as a constructor.
       
  2250 
       
  2251   By combining newFunction() and the property flags
       
  2252   QScriptValue::PropertyGetter and QScriptValue::PropertySetter, you
       
  2253   can create script object properties that behave like normal
       
  2254   properties in script code, but are in fact accessed through
       
  2255   functions (analogous to how properties work in \l{Qt's Property
       
  2256   System}). Example:
       
  2257 
       
  2258   \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 11
       
  2259 
       
  2260   When the property \c{foo} of the script object is subsequently
       
  2261   accessed in script code, \c{getSetFoo()} will be invoked to handle
       
  2262   the access.  In this particular case, we chose to store the "real"
       
  2263   value of \c{foo} as a property of the accessor function itself; you
       
  2264   are of course free to do whatever you like in this function.
       
  2265 
       
  2266   In the above example, a single native function was used to handle
       
  2267   both reads and writes to the property; the argument count is used to
       
  2268   determine if we are handling a read or write. You can also use two
       
  2269   separate functions; just specify the relevant flag
       
  2270   (QScriptValue::PropertyGetter or QScriptValue::PropertySetter) when
       
  2271   setting the property, e.g.:
       
  2272 
       
  2273   \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 12
       
  2274 
       
  2275   \sa QScriptValue::call()
       
  2276 */
       
  2277 QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionSignature fun, int length)
       
  2278 {
       
  2279     Q_D(QScriptEngine);
       
  2280     QScript::APIShim shim(d);
       
  2281     JSC::ExecState* exec = d->currentFrame;
       
  2282     JSC::JSValue function = new (exec)QScript::FunctionWrapper(exec, length, JSC::Identifier(exec, ""), fun);
       
  2283     QScriptValue result = d->scriptValueFromJSCValue(function);
       
  2284     QScriptValue proto = newObject();
       
  2285     result.setProperty(QLatin1String("prototype"), proto, QScriptValue::Undeletable);
       
  2286     proto.setProperty(QLatin1String("constructor"), result,
       
  2287                       QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
       
  2288     return result;
       
  2289 }
       
  2290 
       
  2291 /*!
       
  2292   \internal
       
  2293   \since 4.4
       
  2294 */
       
  2295 QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionWithArgSignature fun, void *arg)
       
  2296 {
       
  2297     Q_D(QScriptEngine);
       
  2298     QScript::APIShim shim(d);
       
  2299     JSC::ExecState* exec = d->currentFrame;
       
  2300     JSC::JSValue function = new (exec)QScript::FunctionWithArgWrapper(exec, /*length=*/0, JSC::Identifier(exec, ""), fun, arg);
       
  2301     QScriptValue result = d->scriptValueFromJSCValue(function);
       
  2302     QScriptValue proto = newObject();
       
  2303     result.setProperty(QLatin1String("prototype"), proto, QScriptValue::Undeletable);
       
  2304     proto.setProperty(QLatin1String("constructor"), result,
       
  2305                       QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
       
  2306     return result;
       
  2307 }
       
  2308 
       
  2309 /*!
       
  2310   Creates a QtScript object of class Array with the given \a length.
       
  2311 
       
  2312   \sa newObject()
       
  2313 */
       
  2314 QScriptValue QScriptEngine::newArray(uint length)
       
  2315 {
       
  2316     Q_D(QScriptEngine);
       
  2317     QScript::APIShim shim(d);
       
  2318     return d->scriptValueFromJSCValue(d->newArray(d->currentFrame, length));
       
  2319 }
       
  2320 
       
  2321 /*!
       
  2322   Creates a QtScript object of class RegExp with the given
       
  2323   \a pattern and \a flags.
       
  2324 
       
  2325   The legal flags are 'g' (global), 'i' (ignore case), and 'm'
       
  2326   (multiline).
       
  2327 */
       
  2328 QScriptValue QScriptEngine::newRegExp(const QString &pattern, const QString &flags)
       
  2329 {
       
  2330     Q_D(QScriptEngine);
       
  2331     QScript::APIShim shim(d);
       
  2332     return d->scriptValueFromJSCValue(d->newRegExp(d->currentFrame, pattern, flags));
  1986 }
  2333 }
  1987 
  2334 
  1988 /*!
  2335 /*!
  1989   Creates a QtScript object of class Date with the given
  2336   Creates a QtScript object of class Date with the given
  1990   \a value (the number of milliseconds since 01 January 1970,
  2337   \a value (the number of milliseconds since 01 January 1970,
  1991   UTC).
  2338   UTC).
  1992 */
  2339 */
  1993 QScriptValue QScriptEngine::newDate(qsreal value)
  2340 QScriptValue QScriptEngine::newDate(qsreal value)
  1994 {
  2341 {
  1995     Q_D(QScriptEngine);
  2342     Q_D(QScriptEngine);
  1996     JSC::ExecState* exec = d->currentFrame;
  2343     QScript::APIShim shim(d);
  1997     JSC::JSValue val = JSC::jsNumber(exec, value);
  2344     return d->scriptValueFromJSCValue(d->newDate(d->currentFrame, value));
  1998     JSC::ArgList args(&val, 1);
       
  1999     JSC::JSObject *result = JSC::constructDate(exec, args);
       
  2000     return d->scriptValueFromJSCValue(result);
       
  2001 }
  2345 }
  2002 
  2346 
  2003 /*!
  2347 /*!
  2004   Creates a QtScript object of class Date from the given \a value.
  2348   Creates a QtScript object of class Date from the given \a value.
  2005 
  2349 
  2006   \sa QScriptValue::toDateTime()
  2350   \sa QScriptValue::toDateTime()
  2007 */
  2351 */
  2008 QScriptValue QScriptEngine::newDate(const QDateTime &value)
  2352 QScriptValue QScriptEngine::newDate(const QDateTime &value)
  2009 {
  2353 {
  2010     return newDate(QScript::FromDateTime(value));
  2354     Q_D(QScriptEngine);
       
  2355     QScript::APIShim shim(d);
       
  2356     return d->scriptValueFromJSCValue(d->newDate(d->currentFrame, value));
  2011 }
  2357 }
  2012 
  2358 
  2013 #ifndef QT_NO_QOBJECT
  2359 #ifndef QT_NO_QOBJECT
  2014 /*!
  2360 /*!
  2015   Creates a QtScript object that represents a QObject class, using the
  2361   Creates a QtScript object that represents a QObject class, using the
  2028 */
  2374 */
  2029 QScriptValue QScriptEngine::newQMetaObject(
  2375 QScriptValue QScriptEngine::newQMetaObject(
  2030     const QMetaObject *metaObject, const QScriptValue &ctor)
  2376     const QMetaObject *metaObject, const QScriptValue &ctor)
  2031 {
  2377 {
  2032     Q_D(QScriptEngine);
  2378     Q_D(QScriptEngine);
       
  2379     QScript::APIShim shim(d);
  2033     JSC::JSValue jscCtor = d->scriptValueToJSCValue(ctor);
  2380     JSC::JSValue jscCtor = d->scriptValueToJSCValue(ctor);
  2034     JSC::JSValue jscQMetaObject = d->newQMetaObject(metaObject, jscCtor);
  2381     JSC::JSValue jscQMetaObject = d->newQMetaObject(metaObject, jscCtor);
  2035     return d->scriptValueFromJSCValue(jscQMetaObject);
  2382     return d->scriptValueFromJSCValue(jscQMetaObject);
  2036 }
  2383 }
  2037 
  2384 
  2202 */
  2549 */
  2203 
  2550 
  2204 QScriptValue QScriptEngine::evaluate(const QString &program, const QString &fileName, int lineNumber)
  2551 QScriptValue QScriptEngine::evaluate(const QString &program, const QString &fileName, int lineNumber)
  2205 {
  2552 {
  2206     Q_D(QScriptEngine);
  2553     Q_D(QScriptEngine);
       
  2554     QScript::APIShim shim(d);
  2207     WTF::PassRefPtr<QScript::UStringSourceProviderWithFeedback> provider
  2555     WTF::PassRefPtr<QScript::UStringSourceProviderWithFeedback> provider
  2208             = QScript::UStringSourceProviderWithFeedback::create(program, fileName, lineNumber, d);
  2556             = QScript::UStringSourceProviderWithFeedback::create(program, fileName, lineNumber, d);
  2209     intptr_t sourceId = provider->asID();
  2557     intptr_t sourceId = provider->asID();
  2210     JSC::SourceCode source(provider, lineNumber); //after construction of SourceCode provider variable will be null.
  2558     JSC::SourceCode source(provider, lineNumber); //after construction of SourceCode provider variable will be null.
  2211 
  2559 
  2212     JSC::ExecState* exec = d->currentFrame;
  2560     JSC::ExecState* exec = d->currentFrame;
  2213     JSC::EvalExecutable executable(exec, source);
  2561     WTF::RefPtr<JSC::EvalExecutable> executable = JSC::EvalExecutable::create(exec, source);
  2214     bool compile = true;
  2562     bool compile = true;
  2215     return d->scriptValueFromJSCValue(d->evaluateHelper(exec, sourceId, &executable, compile));
  2563     return d->scriptValueFromJSCValue(d->evaluateHelper(exec, sourceId, executable.get(), compile));
  2216 }
  2564 }
  2217 
  2565 
  2218 /*!
  2566 /*!
  2219   \internal
  2567   \internal
  2220   \since 4.6
  2568   \since 4.6
  2227     Q_D(QScriptEngine);
  2575     Q_D(QScriptEngine);
  2228     QScriptProgramPrivate *program_d = QScriptProgramPrivate::get(program);
  2576     QScriptProgramPrivate *program_d = QScriptProgramPrivate::get(program);
  2229     if (!program_d)
  2577     if (!program_d)
  2230         return QScriptValue();
  2578         return QScriptValue();
  2231 
  2579 
       
  2580     QScript::APIShim shim(d);
  2232     JSC::ExecState* exec = d->currentFrame;
  2581     JSC::ExecState* exec = d->currentFrame;
  2233     JSC::EvalExecutable *executable = program_d->executable(exec, d);
  2582     JSC::EvalExecutable *executable = program_d->executable(exec, d);
  2234     bool compile = !program_d->isCompiled;
  2583     bool compile = !program_d->isCompiled;
  2235     JSC::JSValue result = d->evaluateHelper(exec, program_d->sourceId,
  2584     JSC::JSValue result = d->evaluateHelper(exec, program_d->sourceId,
  2236                                             executable, compile);
  2585                                             executable, compile);
  2278   \sa popContext()
  2627   \sa popContext()
  2279 */
  2628 */
  2280 QScriptContext *QScriptEngine::pushContext()
  2629 QScriptContext *QScriptEngine::pushContext()
  2281 {
  2630 {
  2282     Q_D(QScriptEngine);
  2631     Q_D(QScriptEngine);
       
  2632     QScript::APIShim shim(d);
  2283 
  2633 
  2284     JSC::CallFrame* newFrame = d->pushContext(d->currentFrame, d->currentFrame->globalData().dynamicGlobalObject,
  2634     JSC::CallFrame* newFrame = d->pushContext(d->currentFrame, d->currentFrame->globalData().dynamicGlobalObject,
  2285                                               JSC::ArgList(), /*callee = */0);
  2635                                               JSC::ArgList(), /*callee = */0);
  2286 
  2636 
  2287     if (agent())
  2637     if (agent())
  2339 
  2689 
  2340         if (!clearScopeChain) {
  2690         if (!clearScopeChain) {
  2341             newCallFrame->init(0, /*vPC=*/0, exec->scopeChain(), exec, flags | ShouldRestoreCallFrame, argc, callee);
  2691             newCallFrame->init(0, /*vPC=*/0, exec->scopeChain(), exec, flags | ShouldRestoreCallFrame, argc, callee);
  2342         } else {
  2692         } else {
  2343             JSC::JSObject *jscObject = originalGlobalObject();
  2693             JSC::JSObject *jscObject = originalGlobalObject();
  2344             JSC::ScopeChainNode *scn = new JSC::ScopeChainNode(0, jscObject, &exec->globalData(), jscObject);
  2694             JSC::ScopeChainNode *scn = new JSC::ScopeChainNode(0, jscObject, &exec->globalData(), exec->lexicalGlobalObject(), jscObject);
  2345             newCallFrame->init(0, /*vPC=*/0, scn, exec, flags | ShouldRestoreCallFrame, argc, callee);
  2695             newCallFrame->init(0, /*vPC=*/0, scn, exec, flags | ShouldRestoreCallFrame, argc, callee);
  2346         }
  2696         }
  2347     } else {
  2697     } else {
  2348         setContextFlags(newCallFrame, flags);
  2698         setContextFlags(newCallFrame, flags);
  2349 #if ENABLE(JIT)
  2699 #if ENABLE(JIT)
  2369 void QScriptEngine::popContext()
  2719 void QScriptEngine::popContext()
  2370 {
  2720 {
  2371     if (agent())
  2721     if (agent())
  2372         agent()->contextPop();
  2722         agent()->contextPop();
  2373     Q_D(QScriptEngine);
  2723     Q_D(QScriptEngine);
       
  2724     QScript::APIShim shim(d);
  2374     if (d->currentFrame->returnPC() != 0 || d->currentFrame->codeBlock() != 0
  2725     if (d->currentFrame->returnPC() != 0 || d->currentFrame->codeBlock() != 0
  2375         || !currentContext()->parentContext()) {
  2726         || !currentContext()->parentContext()) {
  2376         qWarning("QScriptEngine::popContext() doesn't match with pushContext()");
  2727         qWarning("QScriptEngine::popContext() doesn't match with pushContext()");
  2377         return;
  2728         return;
  2378     }
  2729     }
  2564     \internal
  2915     \internal
  2565 */
  2916 */
  2566 QScriptValue QScriptEngine::create(int type, const void *ptr)
  2917 QScriptValue QScriptEngine::create(int type, const void *ptr)
  2567 {
  2918 {
  2568     Q_D(QScriptEngine);
  2919     Q_D(QScriptEngine);
  2569     return d->create(type, ptr);
  2920     QScript::APIShim shim(d);
  2570 }
  2921     return d->scriptValueFromJSCValue(d->create(d->currentFrame, type, ptr));
  2571 
  2922 }
  2572 QScriptValue QScriptEnginePrivate::create(int type, const void *ptr)
  2923 
  2573 {
  2924 JSC::JSValue QScriptEnginePrivate::create(JSC::ExecState *exec, int type, const void *ptr)
  2574     Q_Q(QScriptEngine);
  2925 {
  2575     Q_ASSERT(ptr != 0);
  2926     Q_ASSERT(ptr != 0);
  2576     QScriptValue result;
  2927     JSC::JSValue result;
  2577     QScriptTypeInfo *info = m_typeInfos.value(type);
  2928     QScriptEnginePrivate *eng = exec ? QScript::scriptEngineFromExec(exec) : 0;
       
  2929     QScriptTypeInfo *info = eng ? eng->m_typeInfos.value(type) : 0;
  2578     if (info && info->marshal) {
  2930     if (info && info->marshal) {
  2579         result = info->marshal(q, ptr);
  2931         result = eng->scriptValueToJSCValue(info->marshal(eng->q_func(), ptr));
  2580     } else {
  2932     } else {
  2581         // check if it's one of the types we know
  2933         // check if it's one of the types we know
  2582         switch (QMetaType::Type(type)) {
  2934         switch (QMetaType::Type(type)) {
  2583         case QMetaType::Void:
  2935         case QMetaType::Void:
  2584             return QScriptValue(q, QScriptValue::UndefinedValue);
  2936             return JSC::jsUndefined();
  2585         case QMetaType::Bool:
  2937         case QMetaType::Bool:
  2586             return QScriptValue(q, *reinterpret_cast<const bool*>(ptr));
  2938             return JSC::jsBoolean(*reinterpret_cast<const bool*>(ptr));
  2587         case QMetaType::Int:
  2939         case QMetaType::Int:
  2588             return QScriptValue(q, *reinterpret_cast<const int*>(ptr));
  2940             return JSC::jsNumber(exec, *reinterpret_cast<const int*>(ptr));
  2589         case QMetaType::UInt:
  2941         case QMetaType::UInt:
  2590             return QScriptValue(q, *reinterpret_cast<const uint*>(ptr));
  2942             return JSC::jsNumber(exec, *reinterpret_cast<const uint*>(ptr));
  2591         case QMetaType::LongLong:
  2943         case QMetaType::LongLong:
  2592             return QScriptValue(q, qsreal(*reinterpret_cast<const qlonglong*>(ptr)));
  2944             return JSC::jsNumber(exec, qsreal(*reinterpret_cast<const qlonglong*>(ptr)));
  2593         case QMetaType::ULongLong:
  2945         case QMetaType::ULongLong:
  2594 #if defined(Q_OS_WIN) && defined(_MSC_FULL_VER) && _MSC_FULL_VER <= 12008804
  2946 #if defined(Q_OS_WIN) && defined(_MSC_FULL_VER) && _MSC_FULL_VER <= 12008804
  2595 #pragma message("** NOTE: You need the Visual Studio Processor Pack to compile support for 64bit unsigned integers.")
  2947 #pragma message("** NOTE: You need the Visual Studio Processor Pack to compile support for 64bit unsigned integers.")
  2596             return QScriptValue(q, qsreal((qlonglong)*reinterpret_cast<const qulonglong*>(ptr)));
  2948             return JSC::jsNumber(exec, qsreal((qlonglong)*reinterpret_cast<const qulonglong*>(ptr)));
  2597 #elif defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET)
  2949 #elif defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET)
  2598             return QScriptValue(q, qsreal((qlonglong)*reinterpret_cast<const qulonglong*>(ptr)));
  2950             return JSC::jsNumber(exec, qsreal((qlonglong)*reinterpret_cast<const qulonglong*>(ptr)));
  2599 #else
  2951 #else
  2600             return QScriptValue(q, qsreal(*reinterpret_cast<const qulonglong*>(ptr)));
  2952             return JSC::jsNumber(exec, qsreal(*reinterpret_cast<const qulonglong*>(ptr)));
  2601 #endif
  2953 #endif
  2602         case QMetaType::Double:
  2954         case QMetaType::Double:
  2603             return QScriptValue(q, qsreal(*reinterpret_cast<const double*>(ptr)));
  2955             return JSC::jsNumber(exec, qsreal(*reinterpret_cast<const double*>(ptr)));
  2604         case QMetaType::QString:
  2956         case QMetaType::QString:
  2605             return QScriptValue(q, *reinterpret_cast<const QString*>(ptr));
  2957             return JSC::jsString(exec, *reinterpret_cast<const QString*>(ptr));
  2606         case QMetaType::Float:
  2958         case QMetaType::Float:
  2607             return QScriptValue(q, *reinterpret_cast<const float*>(ptr));
  2959             return JSC::jsNumber(exec, *reinterpret_cast<const float*>(ptr));
  2608         case QMetaType::Short:
  2960         case QMetaType::Short:
  2609             return QScriptValue(q, *reinterpret_cast<const short*>(ptr));
  2961             return JSC::jsNumber(exec, *reinterpret_cast<const short*>(ptr));
  2610         case QMetaType::UShort:
  2962         case QMetaType::UShort:
  2611             return QScriptValue(q, *reinterpret_cast<const unsigned short*>(ptr));
  2963             return JSC::jsNumber(exec, *reinterpret_cast<const unsigned short*>(ptr));
  2612         case QMetaType::Char:
  2964         case QMetaType::Char:
  2613             return QScriptValue(q, *reinterpret_cast<const char*>(ptr));
  2965             return JSC::jsNumber(exec, *reinterpret_cast<const char*>(ptr));
  2614         case QMetaType::UChar:
  2966         case QMetaType::UChar:
  2615             return QScriptValue(q, *reinterpret_cast<const unsigned char*>(ptr));
  2967             return JSC::jsNumber(exec, *reinterpret_cast<const unsigned char*>(ptr));
  2616         case QMetaType::QChar:
  2968         case QMetaType::QChar:
  2617             return QScriptValue(q, (*reinterpret_cast<const QChar*>(ptr)).unicode());
  2969             return JSC::jsNumber(exec, (*reinterpret_cast<const QChar*>(ptr)).unicode());
  2618         case QMetaType::QStringList:
  2970         case QMetaType::QStringList:
  2619             result = arrayFromStringList(*reinterpret_cast<const QStringList *>(ptr));
  2971             result = arrayFromStringList(exec, *reinterpret_cast<const QStringList *>(ptr));
  2620             break;
  2972             break;
  2621         case QMetaType::QVariantList:
  2973         case QMetaType::QVariantList:
  2622             result = arrayFromVariantList(*reinterpret_cast<const QVariantList *>(ptr));
  2974             result = arrayFromVariantList(exec, *reinterpret_cast<const QVariantList *>(ptr));
  2623             break;
  2975             break;
  2624         case QMetaType::QVariantMap:
  2976         case QMetaType::QVariantMap:
  2625             result = objectFromVariantMap(*reinterpret_cast<const QVariantMap *>(ptr));
  2977             result = objectFromVariantMap(exec, *reinterpret_cast<const QVariantMap *>(ptr));
  2626             break;
  2978             break;
  2627         case QMetaType::QDateTime:
  2979         case QMetaType::QDateTime:
  2628             result = q->newDate(*reinterpret_cast<const QDateTime *>(ptr));
  2980             result = newDate(exec, *reinterpret_cast<const QDateTime *>(ptr));
  2629             break;
  2981             break;
  2630         case QMetaType::QDate:
  2982         case QMetaType::QDate:
  2631             result = q->newDate(QDateTime(*reinterpret_cast<const QDate *>(ptr)));
  2983             result = newDate(exec, QDateTime(*reinterpret_cast<const QDate *>(ptr)));
  2632             break;
  2984             break;
  2633 #ifndef QT_NO_REGEXP
  2985 #ifndef QT_NO_REGEXP
  2634         case QMetaType::QRegExp:
  2986         case QMetaType::QRegExp:
  2635             result = q->newRegExp(*reinterpret_cast<const QRegExp *>(ptr));
  2987             result = newRegExp(exec, *reinterpret_cast<const QRegExp *>(ptr));
  2636             break;
  2988             break;
  2637 #endif
  2989 #endif
  2638 #ifndef QT_NO_QOBJECT
  2990 #ifndef QT_NO_QOBJECT
  2639         case QMetaType::QObjectStar:
  2991         case QMetaType::QObjectStar:
  2640         case QMetaType::QWidgetStar:
  2992         case QMetaType::QWidgetStar:
  2641             result = q->newQObject(*reinterpret_cast<QObject* const *>(ptr));
  2993             result = eng->newQObject(*reinterpret_cast<QObject* const *>(ptr));
  2642             break;
  2994             break;
  2643 #endif
  2995 #endif
       
  2996         case QMetaType::QVariant:
       
  2997             result = jscValueFromVariant(exec, *reinterpret_cast<const QVariant*>(ptr));
       
  2998             break;
  2644         default:
  2999         default:
  2645             if (type == qMetaTypeId<QScriptValue>()) {
  3000             if (type == qMetaTypeId<QScriptValue>()) {
  2646                 result = *reinterpret_cast<const QScriptValue*>(ptr);
  3001                 result = eng->scriptValueToJSCValue(*reinterpret_cast<const QScriptValue*>(ptr));
  2647                 if (!result.isValid())
  3002                 if (!result)
  2648                     return QScriptValue(q, QScriptValue::UndefinedValue);
  3003                     return JSC::jsUndefined();
  2649             }
  3004             }
  2650 
  3005 
  2651 #ifndef QT_NO_QOBJECT
  3006 #ifndef QT_NO_QOBJECT
  2652             // lazy registration of some common list types
  3007             // lazy registration of some common list types
  2653             else if (type == qMetaTypeId<QObjectList>()) {
  3008             else if (type == qMetaTypeId<QObjectList>()) {
  2654                 qScriptRegisterSequenceMetaType<QObjectList>(q);
  3009                 qScriptRegisterSequenceMetaType<QObjectList>(eng->q_func());
  2655                 return create(type, ptr);
  3010                 return create(exec, type, ptr);
  2656             }
  3011             }
  2657 #endif
  3012 #endif
  2658             else if (type == qMetaTypeId<QList<int> >()) {
  3013             else if (type == qMetaTypeId<QList<int> >()) {
  2659                 qScriptRegisterSequenceMetaType<QList<int> >(q);
  3014                 qScriptRegisterSequenceMetaType<QList<int> >(eng->q_func());
  2660                 return create(type, ptr);
  3015                 return create(exec, type, ptr);
  2661             }
  3016             }
  2662 
  3017 
  2663             else {
  3018             else {
  2664                 QByteArray typeName = QMetaType::typeName(type);
  3019                 QByteArray typeName = QMetaType::typeName(type);
  2665                 if (typeName == "QVariant")
       
  2666                     result = scriptValueFromVariant(*reinterpret_cast<const QVariant*>(ptr));
       
  2667                 if (typeName.endsWith('*') && !*reinterpret_cast<void* const *>(ptr))
  3020                 if (typeName.endsWith('*') && !*reinterpret_cast<void* const *>(ptr))
  2668                     return QScriptValue(q, QScriptValue::NullValue);
  3021                     return JSC::jsNull();
  2669                 else
  3022                 else
  2670                     result = q->newVariant(QVariant(type, ptr));
  3023                     result = eng->newVariant(QVariant(type, ptr));
  2671             }
  3024             }
  2672         }
  3025         }
  2673     }
  3026     }
  2674     if (result.isObject() && info && info->prototype
  3027     if (result && result.isObject() && info && info->prototype
  2675         && JSC::JSValue::strictEqual(scriptValueToJSCValue(result.prototype()), originalGlobalObject()->objectPrototype())) {
  3028         && JSC::JSValue::strictEqual(exec, JSC::asObject(result)->prototype(), eng->originalGlobalObject()->objectPrototype())) {
  2676         result.setPrototype(scriptValueFromJSCValue(info->prototype));
  3029         JSC::asObject(result)->setPrototype(info->prototype);
  2677     }
  3030     }
  2678     return result;
  3031     return result;
  2679 }
  3032 }
  2680 
  3033 
  2681 bool QScriptEnginePrivate::convert(const QScriptValue &value,
  3034 bool QScriptEnginePrivate::convertValue(JSC::ExecState *exec, JSC::JSValue value,
  2682                                    int type, void *ptr,
  3035                                         int type, void *ptr)
  2683                                    QScriptEnginePrivate *eng)
  3036 {
  2684 {
  3037     QScriptEnginePrivate *eng = exec ? QScript::scriptEngineFromExec(exec) : 0;
  2685     if (!eng)
       
  2686         eng = QScriptValuePrivate::getEngine(value);
       
  2687     if (eng) {
  3038     if (eng) {
  2688         QScriptTypeInfo *info = eng->m_typeInfos.value(type);
  3039         QScriptTypeInfo *info = eng->m_typeInfos.value(type);
  2689         if (info && info->demarshal) {
  3040         if (info && info->demarshal) {
  2690             info->demarshal(value, ptr);
  3041             info->demarshal(eng->scriptValueFromJSCValue(value), ptr);
  2691             return true;
  3042             return true;
  2692         }
  3043         }
  2693     }
  3044     }
  2694 
  3045 
  2695     // check if it's one of the types we know
  3046     // check if it's one of the types we know
  2696     switch (QMetaType::Type(type)) {
  3047     switch (QMetaType::Type(type)) {
  2697     case QMetaType::Bool:
  3048     case QMetaType::Bool:
  2698         *reinterpret_cast<bool*>(ptr) = value.toBoolean();
  3049         *reinterpret_cast<bool*>(ptr) = toBool(exec, value);
  2699         return true;
  3050         return true;
  2700     case QMetaType::Int:
  3051     case QMetaType::Int:
  2701         *reinterpret_cast<int*>(ptr) = value.toInt32();
  3052         *reinterpret_cast<int*>(ptr) = toInt32(exec, value);
  2702         return true;
  3053         return true;
  2703     case QMetaType::UInt:
  3054     case QMetaType::UInt:
  2704         *reinterpret_cast<uint*>(ptr) = value.toUInt32();
  3055         *reinterpret_cast<uint*>(ptr) = toUInt32(exec, value);
  2705         return true;
  3056         return true;
  2706     case QMetaType::LongLong:
  3057     case QMetaType::LongLong:
  2707         *reinterpret_cast<qlonglong*>(ptr) = qlonglong(value.toInteger());
  3058         *reinterpret_cast<qlonglong*>(ptr) = qlonglong(toInteger(exec, value));
  2708         return true;
  3059         return true;
  2709     case QMetaType::ULongLong:
  3060     case QMetaType::ULongLong:
  2710         *reinterpret_cast<qulonglong*>(ptr) = qulonglong(value.toInteger());
  3061         *reinterpret_cast<qulonglong*>(ptr) = qulonglong(toInteger(exec, value));
  2711         return true;
  3062         return true;
  2712     case QMetaType::Double:
  3063     case QMetaType::Double:
  2713         *reinterpret_cast<double*>(ptr) = value.toNumber();
  3064         *reinterpret_cast<double*>(ptr) = toNumber(exec, value);
  2714         return true;
  3065         return true;
  2715     case QMetaType::QString:
  3066     case QMetaType::QString:
  2716         if (value.isUndefined() || value.isNull())
  3067         if (value.isUndefined() || value.isNull())
  2717             *reinterpret_cast<QString*>(ptr) = QString();
  3068             *reinterpret_cast<QString*>(ptr) = QString();
  2718         else
  3069         else
  2719             *reinterpret_cast<QString*>(ptr) = value.toString();
  3070             *reinterpret_cast<QString*>(ptr) = toString(exec, value);
  2720         return true;
  3071         return true;
  2721     case QMetaType::Float:
  3072     case QMetaType::Float:
  2722         *reinterpret_cast<float*>(ptr) = value.toNumber();
  3073         *reinterpret_cast<float*>(ptr) = toNumber(exec, value);
  2723         return true;
  3074         return true;
  2724     case QMetaType::Short:
  3075     case QMetaType::Short:
  2725         *reinterpret_cast<short*>(ptr) = short(value.toInt32());
  3076         *reinterpret_cast<short*>(ptr) = short(toInt32(exec, value));
  2726         return true;
  3077         return true;
  2727     case QMetaType::UShort:
  3078     case QMetaType::UShort:
  2728         *reinterpret_cast<unsigned short*>(ptr) = value.toUInt16();
  3079         *reinterpret_cast<unsigned short*>(ptr) = QScript::ToUInt16(toNumber(exec, value));
  2729         return true;
  3080         return true;
  2730     case QMetaType::Char:
  3081     case QMetaType::Char:
  2731         *reinterpret_cast<char*>(ptr) = char(value.toInt32());
  3082         *reinterpret_cast<char*>(ptr) = char(toInt32(exec, value));
  2732         return true;
  3083         return true;
  2733     case QMetaType::UChar:
  3084     case QMetaType::UChar:
  2734         *reinterpret_cast<unsigned char*>(ptr) = (unsigned char)(value.toInt32());
  3085         *reinterpret_cast<unsigned char*>(ptr) = (unsigned char)(toInt32(exec, value));
  2735         return true;
  3086         return true;
  2736     case QMetaType::QChar:
  3087     case QMetaType::QChar:
  2737         if (value.isString()) {
  3088         if (value.isString()) {
  2738             QString str = value.toString();
  3089             QString str = toString(exec, value);
  2739             *reinterpret_cast<QChar*>(ptr) = str.isEmpty() ? QChar() : str.at(0);
  3090             *reinterpret_cast<QChar*>(ptr) = str.isEmpty() ? QChar() : str.at(0);
  2740         } else {
  3091         } else {
  2741             *reinterpret_cast<QChar*>(ptr) = QChar(value.toUInt16());
  3092             *reinterpret_cast<QChar*>(ptr) = QChar(QScript::ToUInt16(toNumber(exec, value)));
  2742         }
  3093         }
  2743         return true;
  3094         return true;
  2744     case QMetaType::QDateTime:
  3095     case QMetaType::QDateTime:
  2745         if (value.isDate()) {
  3096         if (isDate(value)) {
  2746             *reinterpret_cast<QDateTime *>(ptr) = value.toDateTime();
  3097             *reinterpret_cast<QDateTime *>(ptr) = toDateTime(exec, value);
  2747             return true;
  3098             return true;
  2748         } break;
  3099         } break;
  2749     case QMetaType::QDate:
  3100     case QMetaType::QDate:
  2750         if (value.isDate()) {
  3101         if (isDate(value)) {
  2751             *reinterpret_cast<QDate *>(ptr) = value.toDateTime().date();
  3102             *reinterpret_cast<QDate *>(ptr) = toDateTime(exec, value).date();
  2752             return true;
  3103             return true;
  2753         } break;
  3104         } break;
  2754 #ifndef QT_NO_REGEXP
  3105 #ifndef QT_NO_REGEXP
  2755     case QMetaType::QRegExp:
  3106     case QMetaType::QRegExp:
  2756         if (value.isRegExp()) {
  3107         if (isRegExp(value)) {
  2757             *reinterpret_cast<QRegExp *>(ptr) = value.toRegExp();
  3108             *reinterpret_cast<QRegExp *>(ptr) = toRegExp(exec, value);
  2758             return true;
  3109             return true;
  2759         } break;
  3110         } break;
  2760 #endif
  3111 #endif
  2761 #ifndef QT_NO_QOBJECT
  3112 #ifndef QT_NO_QOBJECT
  2762     case QMetaType::QObjectStar:
  3113     case QMetaType::QObjectStar:
  2763         if (value.isQObject() || value.isNull()) {
  3114         if (isQObject(value) || value.isNull()) {
  2764             *reinterpret_cast<QObject* *>(ptr) = value.toQObject();
  3115             *reinterpret_cast<QObject* *>(ptr) = toQObject(exec, value);
  2765             return true;
  3116             return true;
  2766         } break;
  3117         } break;
  2767     case QMetaType::QWidgetStar:
  3118     case QMetaType::QWidgetStar:
  2768         if (value.isQObject() || value.isNull()) {
  3119         if (isQObject(value) || value.isNull()) {
  2769             QObject *qo = value.toQObject();
  3120             QObject *qo = toQObject(exec, value);
  2770             if (!qo || qo->isWidgetType()) {
  3121             if (!qo || qo->isWidgetType()) {
  2771                 *reinterpret_cast<QWidget* *>(ptr) = reinterpret_cast<QWidget*>(qo);
  3122                 *reinterpret_cast<QWidget* *>(ptr) = reinterpret_cast<QWidget*>(qo);
  2772                 return true;
  3123                 return true;
  2773             }
  3124             }
  2774         } break;
  3125         } break;
  2775 #endif
  3126 #endif
  2776     case QMetaType::QStringList:
  3127     case QMetaType::QStringList:
  2777         if (value.isArray()) {
  3128         if (isArray(value)) {
  2778             *reinterpret_cast<QStringList *>(ptr) = stringListFromArray(value);
  3129             *reinterpret_cast<QStringList *>(ptr) = stringListFromArray(exec, value);
  2779             return true;
  3130             return true;
  2780         } break;
  3131         } break;
  2781     case QMetaType::QVariantList:
  3132     case QMetaType::QVariantList:
  2782         if (value.isArray()) {
  3133         if (isArray(value)) {
  2783             *reinterpret_cast<QVariantList *>(ptr) = variantListFromArray(value);
  3134             *reinterpret_cast<QVariantList *>(ptr) = variantListFromArray(exec, value);
  2784             return true;
  3135             return true;
  2785         } break;
  3136         } break;
  2786     case QMetaType::QVariantMap:
  3137     case QMetaType::QVariantMap:
  2787         if (value.isObject()) {
  3138         if (isObject(value)) {
  2788             *reinterpret_cast<QVariantMap *>(ptr) = variantMapFromObject(value);
  3139             *reinterpret_cast<QVariantMap *>(ptr) = variantMapFromObject(exec, value);
  2789             return true;
  3140             return true;
  2790         } break;
  3141         } break;
       
  3142     case QMetaType::QVariant:
       
  3143         *reinterpret_cast<QVariant*>(ptr) = toVariant(exec, value);
       
  3144         return true;
  2791     default:
  3145     default:
  2792     ;
  3146     ;
  2793     }
  3147     }
  2794 
  3148 
  2795     QByteArray name = QMetaType::typeName(type);
  3149     QByteArray name = QMetaType::typeName(type);
  2796 #ifndef QT_NO_QOBJECT
  3150 #ifndef QT_NO_QOBJECT
  2797     if (convertToNativeQObject(value, name, reinterpret_cast<void* *>(ptr)))
  3151     if (convertToNativeQObject(exec, value, name, reinterpret_cast<void* *>(ptr)))
  2798         return true;
  3152         return true;
  2799 #endif
  3153 #endif
  2800     if (value.isVariant() && name.endsWith('*')) {
  3154     if (isVariant(value) && name.endsWith('*')) {
  2801         int valueType = QMetaType::type(name.left(name.size()-1));
  3155         int valueType = QMetaType::type(name.left(name.size()-1));
  2802         QVariant &var = QScriptValuePrivate::get(value)->variantValue();
  3156         QVariant &var = variantValue(value);
  2803         if (valueType == var.userType()) {
  3157         if (valueType == var.userType()) {
  2804             *reinterpret_cast<void* *>(ptr) = var.data();
  3158             *reinterpret_cast<void* *>(ptr) = var.data();
  2805             return true;
  3159             return true;
  2806         } else {
  3160         } else {
  2807             // look in the prototype chain
  3161             // look in the prototype chain
  2808             QScriptValue proto = value.prototype();
  3162             JSC::JSValue proto = JSC::asObject(value)->prototype();
  2809             while (proto.isObject()) {
  3163             while (proto.isObject()) {
  2810                 bool canCast = false;
  3164                 bool canCast = false;
  2811                 if (proto.isVariant()) {
  3165                 if (isVariant(proto)) {
  2812                     canCast = (type == proto.toVariant().userType())
  3166                     canCast = (type == variantValue(proto).userType())
  2813                               || (valueType && (valueType == proto.toVariant().userType()));
  3167                               || (valueType && (valueType == variantValue(proto).userType()));
  2814                 }
  3168                 }
  2815 #ifndef QT_NO_QOBJECT
  3169 #ifndef QT_NO_QOBJECT
  2816                 else if (proto.isQObject()) {
  3170                 else if (isQObject(proto)) {
  2817                     QByteArray className = name.left(name.size()-1);
  3171                     QByteArray className = name.left(name.size()-1);
  2818                     if (QObject *qobject = proto.toQObject())
  3172                     if (QObject *qobject = toQObject(exec, proto))
  2819                         canCast = qobject->qt_metacast(className) != 0;
  3173                         canCast = qobject->qt_metacast(className) != 0;
  2820                 }
  3174                 }
  2821 #endif
  3175 #endif
  2822                 if (canCast) {
  3176                 if (canCast) {
  2823                     QByteArray varTypeName = QMetaType::typeName(var.userType());
  3177                     QByteArray varTypeName = QMetaType::typeName(var.userType());
  2825                         *reinterpret_cast<void* *>(ptr) = *reinterpret_cast<void* *>(var.data());
  3179                         *reinterpret_cast<void* *>(ptr) = *reinterpret_cast<void* *>(var.data());
  2826                     else
  3180                     else
  2827                         *reinterpret_cast<void* *>(ptr) = var.data();
  3181                         *reinterpret_cast<void* *>(ptr) = var.data();
  2828                     return true;
  3182                     return true;
  2829                 }
  3183                 }
  2830                 proto = proto.prototype();
  3184                 proto = JSC::asObject(proto)->prototype();
  2831             }
  3185             }
  2832         }
  3186         }
  2833     } else if (value.isNull() && name.endsWith('*')) {
  3187     } else if (value.isNull() && name.endsWith('*')) {
  2834         *reinterpret_cast<void* *>(ptr) = 0;
  3188         *reinterpret_cast<void* *>(ptr) = 0;
  2835         return true;
  3189         return true;
  2836     } else if (type == qMetaTypeId<QScriptValue>()) {
  3190     } else if (type == qMetaTypeId<QScriptValue>()) {
  2837         if (!eng)
  3191         if (!eng)
  2838             return false;
  3192             return false;
  2839         *reinterpret_cast<QScriptValue*>(ptr) = value;
  3193         *reinterpret_cast<QScriptValue*>(ptr) = eng->scriptValueFromJSCValue(value);
  2840         return true;
       
  2841     } else if (name == "QVariant") {
       
  2842         *reinterpret_cast<QVariant*>(ptr) = value.toVariant();
       
  2843         return true;
  3194         return true;
  2844     }
  3195     }
  2845 
  3196 
  2846     // lazy registration of some common list types
  3197     // lazy registration of some common list types
  2847 #ifndef QT_NO_QOBJECT
  3198 #ifndef QT_NO_QOBJECT
  2848     else if (type == qMetaTypeId<QObjectList>()) {
  3199     else if (type == qMetaTypeId<QObjectList>()) {
  2849         if (!eng)
  3200         if (!eng)
  2850             return false;
  3201             return false;
  2851         qScriptRegisterSequenceMetaType<QObjectList>(eng->q_func());
  3202         qScriptRegisterSequenceMetaType<QObjectList>(eng->q_func());
  2852         return convert(value, type, ptr, eng);
  3203         return convertValue(exec, value, type, ptr);
  2853     }
  3204     }
  2854 #endif
  3205 #endif
  2855     else if (type == qMetaTypeId<QList<int> >()) {
  3206     else if (type == qMetaTypeId<QList<int> >()) {
  2856         if (!eng)
  3207         if (!eng)
  2857             return false;
  3208             return false;
  2858         qScriptRegisterSequenceMetaType<QList<int> >(eng->q_func());
  3209         qScriptRegisterSequenceMetaType<QList<int> >(eng->q_func());
  2859         return convert(value, type, ptr, eng);
  3210         return convertValue(exec, value, type, ptr);
  2860     }
  3211     }
  2861 
  3212 
  2862 #if 0
  3213 #if 0
  2863     if (!name.isEmpty()) {
  3214     if (!name.isEmpty()) {
  2864         qWarning("QScriptEngine::convert: unable to convert value to type `%s'",
  3215         qWarning("QScriptEngine::convert: unable to convert value to type `%s'",
  2866     }
  3217     }
  2867 #endif
  3218 #endif
  2868     return false;
  3219     return false;
  2869 }
  3220 }
  2870 
  3221 
       
  3222 bool QScriptEnginePrivate::convertNumber(qsreal value, int type, void *ptr)
       
  3223 {
       
  3224     switch (QMetaType::Type(type)) {
       
  3225     case QMetaType::Bool:
       
  3226         *reinterpret_cast<bool*>(ptr) = QScript::ToBool(value);
       
  3227         return true;
       
  3228     case QMetaType::Int:
       
  3229         *reinterpret_cast<int*>(ptr) = QScript::ToInt32(value);
       
  3230         return true;
       
  3231     case QMetaType::UInt:
       
  3232         *reinterpret_cast<uint*>(ptr) = QScript::ToUInt32(value);
       
  3233         return true;
       
  3234     case QMetaType::LongLong:
       
  3235         *reinterpret_cast<qlonglong*>(ptr) = qlonglong(QScript::ToInteger(value));
       
  3236         return true;
       
  3237     case QMetaType::ULongLong:
       
  3238         *reinterpret_cast<qulonglong*>(ptr) = qulonglong(QScript::ToInteger(value));
       
  3239         return true;
       
  3240     case QMetaType::Double:
       
  3241         *reinterpret_cast<double*>(ptr) = value;
       
  3242         return true;
       
  3243     case QMetaType::QString:
       
  3244         *reinterpret_cast<QString*>(ptr) = QScript::ToString(value);
       
  3245         return true;
       
  3246     case QMetaType::Float:
       
  3247         *reinterpret_cast<float*>(ptr) = value;
       
  3248         return true;
       
  3249     case QMetaType::Short:
       
  3250         *reinterpret_cast<short*>(ptr) = short(QScript::ToInt32(value));
       
  3251         return true;
       
  3252     case QMetaType::UShort:
       
  3253         *reinterpret_cast<unsigned short*>(ptr) = QScript::ToUInt16(value);
       
  3254         return true;
       
  3255     case QMetaType::Char:
       
  3256         *reinterpret_cast<char*>(ptr) = char(QScript::ToInt32(value));
       
  3257         return true;
       
  3258     case QMetaType::UChar:
       
  3259         *reinterpret_cast<unsigned char*>(ptr) = (unsigned char)(QScript::ToInt32(value));
       
  3260         return true;
       
  3261     case QMetaType::QChar:
       
  3262         *reinterpret_cast<QChar*>(ptr) = QChar(QScript::ToUInt16(value));
       
  3263         return true;
       
  3264     default:
       
  3265         break;
       
  3266     }
       
  3267     return false;
       
  3268 }
       
  3269 
       
  3270 bool QScriptEnginePrivate::convertString(const QString &value, int type, void *ptr)
       
  3271 {
       
  3272     switch (QMetaType::Type(type)) {
       
  3273     case QMetaType::Bool:
       
  3274         *reinterpret_cast<bool*>(ptr) = QScript::ToBool(value);
       
  3275         return true;
       
  3276     case QMetaType::Int:
       
  3277         *reinterpret_cast<int*>(ptr) = QScript::ToInt32(value);
       
  3278         return true;
       
  3279     case QMetaType::UInt:
       
  3280         *reinterpret_cast<uint*>(ptr) = QScript::ToUInt32(value);
       
  3281         return true;
       
  3282     case QMetaType::LongLong:
       
  3283         *reinterpret_cast<qlonglong*>(ptr) = qlonglong(QScript::ToInteger(value));
       
  3284         return true;
       
  3285     case QMetaType::ULongLong:
       
  3286         *reinterpret_cast<qulonglong*>(ptr) = qulonglong(QScript::ToInteger(value));
       
  3287         return true;
       
  3288     case QMetaType::Double:
       
  3289         *reinterpret_cast<double*>(ptr) = QScript::ToNumber(value);
       
  3290         return true;
       
  3291     case QMetaType::QString:
       
  3292         *reinterpret_cast<QString*>(ptr) = value;
       
  3293         return true;
       
  3294     case QMetaType::Float:
       
  3295         *reinterpret_cast<float*>(ptr) = QScript::ToNumber(value);
       
  3296         return true;
       
  3297     case QMetaType::Short:
       
  3298         *reinterpret_cast<short*>(ptr) = short(QScript::ToInt32(value));
       
  3299         return true;
       
  3300     case QMetaType::UShort:
       
  3301         *reinterpret_cast<unsigned short*>(ptr) = QScript::ToUInt16(value);
       
  3302         return true;
       
  3303     case QMetaType::Char:
       
  3304         *reinterpret_cast<char*>(ptr) = char(QScript::ToInt32(value));
       
  3305         return true;
       
  3306     case QMetaType::UChar:
       
  3307         *reinterpret_cast<unsigned char*>(ptr) = (unsigned char)(QScript::ToInt32(value));
       
  3308         return true;
       
  3309     case QMetaType::QChar:
       
  3310         *reinterpret_cast<QChar*>(ptr) = QChar(QScript::ToUInt16(value));
       
  3311         return true;
       
  3312     default:
       
  3313         break;
       
  3314     }
       
  3315     return false;
       
  3316 }
       
  3317 
  2871 bool QScriptEnginePrivate::hasDemarshalFunction(int type) const
  3318 bool QScriptEnginePrivate::hasDemarshalFunction(int type) const
  2872 {
  3319 {
  2873     QScriptTypeInfo *info = m_typeInfos.value(type);
  3320     QScriptTypeInfo *info = m_typeInfos.value(type);
  2874     return info && (info->demarshal != 0);
  3321     return info && (info->demarshal != 0);
  2875 }
  3322 }
  2876 
  3323 
       
  3324 JSC::UString QScriptEnginePrivate::translationContextFromUrl(const JSC::UString &url)
       
  3325 {
       
  3326     if (url != cachedTranslationUrl) {
       
  3327         cachedTranslationContext = QFileInfo(url).baseName();
       
  3328         cachedTranslationUrl = url;
       
  3329     }
       
  3330     return cachedTranslationContext;
       
  3331 }
       
  3332 
  2877 /*!
  3333 /*!
  2878     \internal
  3334     \internal
  2879 */
  3335 */
  2880 bool QScriptEngine::convert(const QScriptValue &value, int type, void *ptr)
  3336 bool QScriptEngine::convert(const QScriptValue &value, int type, void *ptr)
  2881 {
  3337 {
  2882     Q_D(QScriptEngine);
  3338     Q_D(QScriptEngine);
  2883     return QScriptEnginePrivate::convert(value, type, ptr, d);
  3339     QScript::APIShim shim(d);
       
  3340     return QScriptEnginePrivate::convertValue(d->currentFrame, d->scriptValueToJSCValue(value), type, ptr);
  2884 }
  3341 }
  2885 
  3342 
  2886 /*!
  3343 /*!
  2887     \internal
  3344     \internal
  2888 */
  3345 */
  2889 bool QScriptEngine::convertV2(const QScriptValue &value, int type, void *ptr)
  3346 bool QScriptEngine::convertV2(const QScriptValue &value, int type, void *ptr)
  2890 {
  3347 {
  2891     return QScriptEnginePrivate::convert(value, type, ptr, /*engine=*/0);
  3348     QScriptValuePrivate *vp = QScriptValuePrivate::get(value);
       
  3349     if (vp) {
       
  3350         switch (vp->type) {
       
  3351         case QScriptValuePrivate::JavaScriptCore: {
       
  3352             if (vp->engine) {
       
  3353                 QScript::APIShim shim(vp->engine);
       
  3354                 return QScriptEnginePrivate::convertValue(vp->engine->currentFrame, vp->jscValue, type, ptr);
       
  3355             } else {
       
  3356                 return QScriptEnginePrivate::convertValue(0, vp->jscValue, type, ptr);
       
  3357             }
       
  3358         }
       
  3359         case QScriptValuePrivate::Number:
       
  3360             return QScriptEnginePrivate::convertNumber(vp->numberValue, type, ptr);
       
  3361         case QScriptValuePrivate::String:
       
  3362             return QScriptEnginePrivate::convertString(vp->stringValue, type, ptr);
       
  3363         }
       
  3364     }
       
  3365     return false;
  2892 }
  3366 }
  2893 
  3367 
  2894 /*!
  3368 /*!
  2895     \internal
  3369     \internal
  2896 */
  3370 */
  2897 void QScriptEngine::registerCustomType(int type, MarshalFunction mf,
  3371 void QScriptEngine::registerCustomType(int type, MarshalFunction mf,
  2898                                        DemarshalFunction df,
  3372                                        DemarshalFunction df,
  2899                                        const QScriptValue &prototype)
  3373                                        const QScriptValue &prototype)
  2900 {
  3374 {
  2901     Q_D(QScriptEngine);
  3375     Q_D(QScriptEngine);
       
  3376     QScript::APIShim shim(d);
  2902     QScriptTypeInfo *info = d->m_typeInfos.value(type);
  3377     QScriptTypeInfo *info = d->m_typeInfos.value(type);
  2903     if (!info) {
  3378     if (!info) {
  2904         info = new QScriptTypeInfo();
  3379         info = new QScriptTypeInfo();
  2905         d->m_typeInfos.insert(type, info);
  3380         d->m_typeInfos.insert(type, info);
  2906     }
  3381     }
  2929   \sa {Internationalization with Qt}
  3404   \sa {Internationalization with Qt}
  2930 */
  3405 */
  2931 void QScriptEngine::installTranslatorFunctions(const QScriptValue &object)
  3406 void QScriptEngine::installTranslatorFunctions(const QScriptValue &object)
  2932 {
  3407 {
  2933     Q_D(QScriptEngine);
  3408     Q_D(QScriptEngine);
       
  3409     QScript::APIShim shim(d);
  2934     JSC::ExecState* exec = d->currentFrame;
  3410     JSC::ExecState* exec = d->currentFrame;
  2935     JSC::JSValue jscObject = d->scriptValueToJSCValue(object);
  3411     JSC::JSValue jscObject = d->scriptValueToJSCValue(object);
  2936     JSC::JSGlobalObject *glob = d->originalGlobalObject();
  3412     JSC::JSGlobalObject *glob = d->originalGlobalObject();
  2937     if (!jscObject || !jscObject.isObject())
  3413     if (!jscObject || !jscObject.isObject())
  2938         jscObject = d->globalObject();
  3414         jscObject = d->globalObject();
  2939 //    unsigned attribs = JSC::DontEnum;
  3415 //    unsigned attribs = JSC::DontEnum;
  2940     JSC::asObject(jscObject)->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, glob->prototypeFunctionStructure(), 5, JSC::Identifier(exec, "qsTranslate"), QScript::functionQsTranslate));
  3416     JSC::asObject(jscObject)->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, glob->prototypeFunctionStructure(), 5, JSC::Identifier(exec, "qsTranslate"), QScript::functionQsTranslate));
  2941     JSC::asObject(jscObject)->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, glob->prototypeFunctionStructure(), 2, JSC::Identifier(exec, "QT_TRANSLATE_NOOP"), QScript::functionQsTranslateNoOp));
  3417     JSC::asObject(jscObject)->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, glob->prototypeFunctionStructure(), 2, JSC::Identifier(exec, "QT_TRANSLATE_NOOP"), QScript::functionQsTranslateNoOp));
  2942     JSC::asObject(jscObject)->putDirectFunction(exec, new (exec)JSC::PrototypeFunction(exec, glob->prototypeFunctionStructure(), 3, JSC::Identifier(exec, "qsTr"), QScript::functionQsTr));
  3418     JSC::asObject(jscObject)->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, glob->prototypeFunctionStructure(), 3, JSC::Identifier(exec, "qsTr"), QScript::functionQsTr));
  2943     JSC::asObject(jscObject)->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, glob->prototypeFunctionStructure(), 1, JSC::Identifier(exec, "QT_TR_NOOP"), QScript::functionQsTrNoOp));
  3419     JSC::asObject(jscObject)->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, glob->prototypeFunctionStructure(), 1, JSC::Identifier(exec, "QT_TR_NOOP"), QScript::functionQsTrNoOp));
  2944 
  3420 
  2945     glob->stringPrototype()->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, glob->prototypeFunctionStructure(), 1, JSC::Identifier(exec, "arg"), QScript::stringProtoFuncArg));
  3421     glob->stringPrototype()->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, glob->prototypeFunctionStructure(), 1, JSC::Identifier(exec, "arg"), QScript::stringProtoFuncArg));
  2946 }
  3422 }
  2947 
  3423 
  2962 {
  3438 {
  2963 #if defined(QT_NO_QOBJECT) || defined(QT_NO_LIBRARY) || defined(QT_NO_SETTINGS)
  3439 #if defined(QT_NO_QOBJECT) || defined(QT_NO_LIBRARY) || defined(QT_NO_SETTINGS)
  2964     Q_UNUSED(extension);
  3440     Q_UNUSED(extension);
  2965 #else
  3441 #else
  2966     Q_D(QScriptEngine);
  3442     Q_D(QScriptEngine);
       
  3443     QScript::APIShim shim(d);
  2967     if (d->importedExtensions.contains(extension))
  3444     if (d->importedExtensions.contains(extension))
  2968         return undefinedValue(); // already imported
  3445         return undefinedValue(); // already imported
  2969 
  3446 
  2970     QScriptContext *context = currentContext();
  3447     QScriptContext *context = currentContext();
  2971     QCoreApplication *app = QCoreApplication::instance();
  3448     QCoreApplication *app = QCoreApplication::instance();
  3458   will automatically be invoked when the QScriptEngine decides that
  3935   will automatically be invoked when the QScriptEngine decides that
  3459   it's wise to do so (i.e. when a certain number of new objects have
  3936   it's wise to do so (i.e. when a certain number of new objects have
  3460   been created). However, you can call this function to explicitly
  3937   been created). However, you can call this function to explicitly
  3461   request that garbage collection should be performed as soon as
  3938   request that garbage collection should be performed as soon as
  3462   possible.
  3939   possible.
       
  3940 
       
  3941   \sa reportAdditionalMemoryCost()
  3463 */
  3942 */
  3464 void QScriptEngine::collectGarbage()
  3943 void QScriptEngine::collectGarbage()
  3465 {
  3944 {
  3466     Q_D(QScriptEngine);
  3945     Q_D(QScriptEngine);
  3467     d->collectGarbage();
  3946     d->collectGarbage();
       
  3947 }
       
  3948 
       
  3949 /*!
       
  3950   \since 4.7
       
  3951 
       
  3952   Reports an additional memory cost of the given \a size, measured in
       
  3953   bytes, to the garbage collector.
       
  3954 
       
  3955   This function can be called to indicate that a Qt Script object has
       
  3956   memory associated with it that isn't managed by Qt Script itself.
       
  3957   Reporting the additional cost makes it more likely that the garbage
       
  3958   collector will be triggered.
       
  3959 
       
  3960   Note that if the additional memory is shared with objects outside
       
  3961   the scripting environment, the cost should not be reported, since
       
  3962   collecting the Qt Script object would not cause the memory to be
       
  3963   freed anyway.
       
  3964 
       
  3965   Negative \a size values are ignored, i.e. this function can't be
       
  3966   used to report that the additional memory has been deallocated.
       
  3967 
       
  3968   \sa collectGarbage()
       
  3969 */
       
  3970 void QScriptEngine::reportAdditionalMemoryCost(int size)
       
  3971 {
       
  3972     Q_D(QScriptEngine);
       
  3973     d->reportAdditionalMemoryCost(size);
  3468 }
  3974 }
  3469 
  3975 
  3470 /*!
  3976 /*!
  3471 
  3977 
  3472   Sets the interval between calls to QCoreApplication::processEvents
  3978   Sets the interval between calls to QCoreApplication::processEvents
  3573     if (!function.isFunction())
  4079     if (!function.isFunction())
  3574         return false;
  4080         return false;
  3575     if (receiver.isObject() && (receiver.engine() != function.engine()))
  4081     if (receiver.isObject() && (receiver.engine() != function.engine()))
  3576         return false;
  4082         return false;
  3577     QScriptEnginePrivate *engine = QScriptEnginePrivate::get(function.engine());
  4083     QScriptEnginePrivate *engine = QScriptEnginePrivate::get(function.engine());
       
  4084     QScript::APIShim shim(engine);
  3578     JSC::JSValue jscReceiver = engine->scriptValueToJSCValue(receiver);
  4085     JSC::JSValue jscReceiver = engine->scriptValueToJSCValue(receiver);
  3579     JSC::JSValue jscFunction = engine->scriptValueToJSCValue(function);
  4086     JSC::JSValue jscFunction = engine->scriptValueToJSCValue(function);
  3580     return engine->scriptConnect(sender, signal, jscReceiver, jscFunction,
  4087     return engine->scriptConnect(sender, signal, jscReceiver, jscFunction,
  3581                                  Qt::AutoConnection);
  4088                                  Qt::AutoConnection);
  3582 }
  4089 }
  3599     if (!function.isFunction())
  4106     if (!function.isFunction())
  3600         return false;
  4107         return false;
  3601     if (receiver.isObject() && (receiver.engine() != function.engine()))
  4108     if (receiver.isObject() && (receiver.engine() != function.engine()))
  3602         return false;
  4109         return false;
  3603     QScriptEnginePrivate *engine = QScriptEnginePrivate::get(function.engine());
  4110     QScriptEnginePrivate *engine = QScriptEnginePrivate::get(function.engine());
       
  4111     QScript::APIShim shim(engine);
  3604     JSC::JSValue jscReceiver = engine->scriptValueToJSCValue(receiver);
  4112     JSC::JSValue jscReceiver = engine->scriptValueToJSCValue(receiver);
  3605     JSC::JSValue jscFunction = engine->scriptValueToJSCValue(function);
  4113     JSC::JSValue jscFunction = engine->scriptValueToJSCValue(function);
  3606     return engine->scriptDisconnect(sender, signal, jscReceiver, jscFunction);
  4114     return engine->scriptDisconnect(sender, signal, jscReceiver, jscFunction);
  3607 }
  4115 }
  3608 
  4116 
  3678   \sa QScriptValue::property()
  4186   \sa QScriptValue::property()
  3679 */
  4187 */
  3680 QScriptString QScriptEngine::toStringHandle(const QString &str)
  4188 QScriptString QScriptEngine::toStringHandle(const QString &str)
  3681 {
  4189 {
  3682     Q_D(QScriptEngine);
  4190     Q_D(QScriptEngine);
  3683     QScriptString result;
  4191     QScript::APIShim shim(d);
  3684     QScriptStringPrivate *p = new QScriptStringPrivate(d, JSC::Identifier(d->currentFrame, str), QScriptStringPrivate::HeapAllocated);
  4192     return d->toStringHandle(JSC::Identifier(d->currentFrame, str));
  3685     QScriptStringPrivate::init(result, p);
       
  3686     d->registerScriptString(p);
       
  3687     return result;
       
  3688 }
  4193 }
  3689 
  4194 
  3690 /*!
  4195 /*!
  3691   \since 4.5
  4196   \since 4.5
  3692 
  4197 
  3707     \sa newObject()
  4212     \sa newObject()
  3708 */
  4213 */
  3709 QScriptValue QScriptEngine::toObject(const QScriptValue &value)
  4214 QScriptValue QScriptEngine::toObject(const QScriptValue &value)
  3710 {
  4215 {
  3711     Q_D(QScriptEngine);
  4216     Q_D(QScriptEngine);
       
  4217     QScript::APIShim shim(d);
  3712     JSC::JSValue jscValue = d->scriptValueToJSCValue(value);
  4218     JSC::JSValue jscValue = d->scriptValueToJSCValue(value);
  3713     if (!jscValue || jscValue.isUndefined() || jscValue.isNull())
  4219     if (!jscValue || jscValue.isUndefined() || jscValue.isNull())
  3714         return QScriptValue();
  4220         return QScriptValue();
  3715     JSC::ExecState* exec = d->currentFrame;
  4221     JSC::ExecState* exec = d->currentFrame;
  3716     JSC::JSValue result = jscValue.toObject(exec);
  4222     JSC::JSValue result = jscValue.toObject(exec);
  3858     return false;
  4364     return false;
  3859 #endif
  4365 #endif
  3860 }
  4366 }
  3861 #endif
  4367 #endif
  3862 
  4368 
       
  4369 #ifdef Q_CC_MSVC
       
  4370 // Try to prevent compiler from crashing.
       
  4371 #pragma optimize("", off)
       
  4372 #endif
       
  4373 
  3863 QT_END_NAMESPACE
  4374 QT_END_NAMESPACE