1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the QtScript module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL-ONLY$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser
11 ** General Public License version 2.1 as published by the Free Software
12 ** Foundation and appearing in the file LICENSE.LGPL included in the
13 ** packaging of this file.  Please review the following information to
14 ** ensure the GNU Lesser General Public License version 2.1 requirements
15 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** If you have questions regarding the use of this file, please contact
18 ** us via http://www.qt.io/contact-us/.
19 **
20 ** $QT_END_LICENSE$
21 **
22 ****************************************************************************/
23 
24 #ifndef QSCRIPTENGINE_P_H
25 #define QSCRIPTENGINE_P_H
26 
27 //
28 //  W A R N I N G
29 //  -------------
30 //
31 // This file is not part of the Qt API.  It exists purely as an
32 // implementation detail.  This header file may change from version to
33 // version without notice, or even be removed.
34 //
35 // We mean it.
36 //
37 
38 #include "private/qobject_p.h"
39 
40 #include <QtCore/qdatetime.h>
41 #include <QtCore/qhash.h>
42 #include <QtCore/qnumeric.h>
43 #include <QtCore/qregexp.h>
44 #include <QtCore/qset.h>
45 #include "qscriptvalue_p.h"
46 #include "qscriptstring_p.h"
47 #include "bridge/qscriptclassobject_p.h"
48 #include "bridge/qscriptdeclarativeclass_p.h"
49 #include "bridge/qscriptdeclarativeobject_p.h"
50 #include "bridge/qscriptobject_p.h"
51 #include "bridge/qscriptqobject_p.h"
52 #include "bridge/qscriptvariant_p.h"
53 #include "bridge/qscriptactivationobject_p.h"
54 
55 #include "DateConstructor.h"
56 #include "DateInstance.h"
57 #include "Debugger.h"
58 #include "ErrorInstance.h"
59 #include "JSArray.h"
60 #include "Executable.h"
61 #include "Lexer.h"
62 #include "RefPtr.h"
63 #include "RegExpConstructor.h"
64 #include "RegExpObject.h"
65 #include "SourceProvider.h"
66 #include "Structure.h"
67 #include "UString.h"
68 #include "JSGlobalObject.h"
69 #include "JSValue.h"
70 
71 namespace JSC
72 {
73     class EvalExecutable;
74     class ExecState;
75     typedef ExecState CallFrame;
76     class JSCell;
77     class JSGlobalObject;
78 }
79 
80 
81 QT_BEGIN_NAMESPACE
82 
83 class QString;
84 class QStringList;
85 class QScriptContext;
86 class QScriptValue;
87 class QScriptTypeInfo;
88 class QScriptEngineAgent;
89 class QScriptEnginePrivate;
90 class QScriptSyntaxCheckResult;
91 class QScriptEngine;
92 class QScriptProgramPrivate;
93 
94 namespace QScript
95 {
96     class QObjectPrototype;
97     class QMetaObjectPrototype;
98     class QVariantPrototype;
99 #ifndef QT_NO_QOBJECT
100     class QObjectData;
101 #endif
102     class TimeoutCheckerProxy;
103 
104     qint32 ToInt32(qsreal);
105     quint32 ToUInt32(qsreal);
106     quint16 ToUInt16(qsreal);
107     qsreal ToInteger(qsreal);
108 
109     inline bool ToBool(qsreal);
110     inline bool ToBool(const QString &);
111     inline qint32 ToInt32(const QString &);
112     inline quint32 ToUInt32(const QString &);
113     inline quint16 ToUInt16(const QString &);
114     inline qsreal ToInteger(const QString &);
115 #ifdef Q_CC_MSVC
116     // MSVC2008 crashes if these are inlined.
117     qsreal ToNumber(const QString &);
118     QString ToString(qsreal);
119 #else
120     inline qsreal ToNumber(const QString &);
121     inline QString ToString(qsreal);
122 #endif
123 
124     QDateTime MsToDateTime(JSC::ExecState *, qsreal);
125     qsreal DateTimeToMs(JSC::ExecState *, const QDateTime &);
126 
127     //some conversion helper functions
128     inline QScriptEnginePrivate *scriptEngineFromExec(const JSC::ExecState *exec);
129     bool isFunction(JSC::JSValue value);
130 
131     inline void convertToLatin1_helper(const UChar *i, int length, char *s);
132     inline QByteArray convertToLatin1(const JSC::UString &str);
133 
134     class UStringSourceProviderWithFeedback;
135 
136 struct GlobalClientData : public JSC::JSGlobalData::ClientData
137 {
GlobalClientDataGlobalClientData138     GlobalClientData(QScriptEnginePrivate *e)
139         : engine(e) {}
~GlobalClientDataGlobalClientData140     virtual ~GlobalClientData() {}
141     virtual void mark(JSC::MarkStack& markStack);
142 
143     QScriptEnginePrivate *engine;
144 };
145 
146 } // namespace QScript
147 
148 class QScriptEnginePrivate
149 #ifndef QT_NO_QOBJECT
150     : public QObjectPrivate
151 #endif
152 {
153     Q_DECLARE_PUBLIC(QScriptEngine)
154 public:
155     QScriptEnginePrivate();
156     virtual ~QScriptEnginePrivate();
157 
get(QScriptEngine * q)158     static QScriptEnginePrivate *get(QScriptEngine *q) { return q ? q->d_func() : 0; }
get(QScriptEnginePrivate * d)159     static QScriptEngine *get(QScriptEnginePrivate *d) { return d ? d->q_func() : 0; }
160 
161     static inline bool isArray(JSC::JSValue);
162     static inline bool isDate(JSC::JSValue);
163     static inline bool isError(JSC::JSValue);
164     static inline bool isObject(JSC::JSValue);
165     static inline bool isRegExp(JSC::JSValue);
166     static inline bool isVariant(JSC::JSValue);
167     static inline bool isQObject(JSC::JSValue);
168     static inline bool isQMetaObject(JSC::JSValue);
169 
170     static inline bool toBool(JSC::ExecState *, JSC::JSValue);
171     static inline qsreal toInteger(JSC::ExecState *, JSC::JSValue);
172     static inline qsreal toNumber(JSC::ExecState *, JSC::JSValue);
173     static inline qint32 toInt32(JSC::ExecState *, JSC::JSValue);
174     static inline quint32 toUInt32(JSC::ExecState *, JSC::JSValue);
175     static inline quint16 toUInt16(JSC::ExecState *, JSC::JSValue);
176     static inline JSC::UString toString(JSC::ExecState *, JSC::JSValue);
177 
178     static inline QDateTime toDateTime(JSC::ExecState *, JSC::JSValue);
179 #ifndef QT_NO_REGEXP
180     static QRegExp toRegExp(JSC::ExecState*, JSC::JSValue);
181 #endif
182     static QVariant toVariant(JSC::ExecState *, JSC::JSValue);
183     static inline QObject *toQObject(JSC::ExecState *, JSC::JSValue);
184     static inline const QMetaObject *toQMetaObject(JSC::ExecState *, JSC::JSValue);
185 
186     static inline JSC::JSValue property(JSC::ExecState*, JSC::JSValue, const JSC::Identifier &id,
187                                  int resolveMode = QScriptValue::ResolvePrototype);
188     static JSC::JSValue propertyHelper(JSC::ExecState*, JSC::JSValue, const JSC::Identifier &id, int resolveMode);
189     static inline JSC::JSValue property(JSC::ExecState*, JSC::JSValue, quint32 index,
190                                  int resolveMode = QScriptValue::ResolvePrototype);
191     static JSC::JSValue propertyHelper(JSC::ExecState*, JSC::JSValue, quint32, int resolveMode);
192     static inline JSC::JSValue property(JSC::ExecState*, JSC::JSValue, const JSC::UString &, int resolveMode);
193     static inline void setProperty(JSC::ExecState*, JSC::JSValue object, const JSC::UString &name, JSC::JSValue,
194                      const QScriptValue::PropertyFlags &flags = QScriptValue::KeepExistingFlags);
195     static void setProperty(JSC::ExecState*, JSC::JSValue object, const JSC::Identifier &id, JSC::JSValue,
196                      const QScriptValue::PropertyFlags &flags = QScriptValue::KeepExistingFlags);
197     static void setProperty(JSC::ExecState*, JSC::JSValue object, quint32 index, JSC::JSValue,
198                      const QScriptValue::PropertyFlags &flags = QScriptValue::KeepExistingFlags);
199     static QScriptValue::PropertyFlags propertyFlags(JSC::ExecState*, JSC::JSValue value,
200                                               const JSC::Identifier &id, const QScriptValue::ResolveFlags &mode);
201     static inline QScriptValue::PropertyFlags propertyFlags(JSC::ExecState*, JSC::JSValue value,
202                                               const JSC::UString &name, const QScriptValue::ResolveFlags &mode);
203 
204     static bool convertValue(JSC::ExecState*, JSC::JSValue value,
205                              int type, void *ptr);
206     static bool convertNumber(qsreal, int type, void *ptr);
207     static bool convertString(const QString &, int type, void *ptr);
208     static JSC::JSValue create(JSC::ExecState*, int type, const void *ptr);
209     bool hasDemarshalFunction(int type) const;
210 
211     inline QScriptValue scriptValueFromJSCValue(JSC::JSValue value);
212     inline JSC::JSValue scriptValueToJSCValue(const QScriptValue &value);
213     static inline unsigned propertyFlagsToJSCAttributes(const QScriptValue::PropertyFlags &flags);
214 
215     static inline JSC::JSValue jscValueFromVariant(JSC::ExecState*, const QVariant &value);
216     static QVariant jscValueToVariant(JSC::ExecState*, JSC::JSValue value, int targetType);
217     static inline QVariant &variantValue(JSC::JSValue value);
218     static inline void setVariantValue(JSC::JSValue objectValue, const QVariant &value);
219 
220     static JSC::JSValue arrayFromStringList(JSC::ExecState*, const QStringList &lst);
221     static QStringList stringListFromArray(JSC::ExecState*, JSC::JSValue arr);
222 
223     static JSC::JSValue arrayFromVariantList(JSC::ExecState*, const QVariantList &lst);
224     static QVariantList variantListFromArray(JSC::ExecState*, JSC::JSArray *arr);
225 
226     static JSC::JSValue objectFromVariantMap(JSC::ExecState*, const QVariantMap &vmap);
227     static QVariantMap variantMapFromObject(JSC::ExecState*, JSC::JSObject *obj);
228 
229     JSC::JSValue defaultPrototype(int metaTypeId) const;
230     void setDefaultPrototype(int metaTypeId, JSC::JSValue prototype);
231 
232     static inline QScriptContext *contextForFrame(JSC::ExecState *frame);
233     static inline JSC::ExecState *frameForContext(QScriptContext *context);
234     static inline const JSC::ExecState *frameForContext(const QScriptContext *context);
235 
236     static inline bool hasValidCodeBlockRegister(JSC::ExecState *frame);
237 
238     JSC::JSGlobalObject *originalGlobalObject() const;
239     JSC::JSObject *getOriginalGlobalObjectProxy();
240     JSC::JSObject *customGlobalObject() const;
241     JSC::JSObject *globalObject() const;
242     void setGlobalObject(JSC::JSObject *object);
243     inline JSC::ExecState *globalExec() const;
244     JSC::JSValue toUsableValue(JSC::JSValue value);
245     static JSC::JSValue thisForContext(JSC::ExecState *frame);
246     static JSC::Register *thisRegisterForFrame(JSC::ExecState *frame);
247 
248     JSC::CallFrame *pushContext(JSC::CallFrame *exec, JSC::JSValue thisObject, const JSC::ArgList& args,
249                                 JSC::JSObject *callee, bool calledAsConstructor = false, bool clearScopeChain = false);
250     void popContext();
251 
252     void mark(JSC::MarkStack& markStack);
253     bool isCollecting() const;
254     void collectGarbage();
255     void reportAdditionalMemoryCost(int size);
256 
257     //flags that we set on the return value register for native function. (ie when codeBlock is 0)
258     enum ContextFlags {
259         NativeContext = 1,
260         CalledAsConstructorContext = 2,
261         HasScopeContext = 4, // Specifies that the is a QScriptActivationObject
262         ShouldRestoreCallFrame = 8
263     };
264     static uint contextFlags(JSC::ExecState *);
265     static void setContextFlags(JSC::ExecState *, uint);
266 
267     QScript::TimeoutCheckerProxy *timeoutChecker() const;
268 
269     void agentDeleted(QScriptEngineAgent *agent);
270 
271     static inline void saveException(JSC::ExecState *, JSC::JSValue *);
272     static inline void restoreException(JSC::ExecState *, JSC::JSValue);
273 
setCurrentException(QScriptValue exception)274     void setCurrentException(QScriptValue exception) { m_currentException = exception; }
currentException()275     QScriptValue currentException() const { return m_currentException; }
clearCurrentException()276     void clearCurrentException() { m_currentException.d_ptr.reset(); }
277 
278     static QScriptSyntaxCheckResult checkSyntax(const QString &program);
279     static bool canEvaluate(const QString &program);
280 
281     inline void registerScriptProgram(QScriptProgramPrivate *program);
282     inline void unregisterScriptProgram(QScriptProgramPrivate *program);
283     void detachAllRegisteredScriptPrograms();
284 
285     inline QScriptValuePrivate *allocateScriptValuePrivate(size_t);
286     inline void freeScriptValuePrivate(QScriptValuePrivate *p);
287 
288     inline void registerScriptValue(QScriptValuePrivate *value);
289     inline void unregisterScriptValue(QScriptValuePrivate *value);
290     void detachAllRegisteredScriptValues();
291 
292     inline void registerScriptString(QScriptStringPrivate *value);
293     inline void unregisterScriptString(QScriptStringPrivate *value);
294     void detachAllRegisteredScriptStrings();
295     QScriptString toStringHandle(const JSC::Identifier &name);
296 
297     static inline JSC::JSValue newArray(JSC::ExecState *, uint length);
298     static inline JSC::JSValue newDate(JSC::ExecState *, qsreal value);
299     static inline JSC::JSValue newDate(JSC::ExecState *, const QDateTime &);
300     inline JSC::JSValue newObject();
301 
302 #ifndef QT_NO_REGEXP
303     static JSC::JSValue newRegExp(JSC::ExecState *, const QRegExp &);
304 #endif
305 
306     static JSC::JSValue newRegExp(JSC::ExecState *, const QString &pattern, const QString &flags);
307     JSC::JSValue newVariant(const QVariant &);
308     JSC::JSValue newVariant(JSC::JSValue objectValue, const QVariant &);
309 
310     static inline QScriptDeclarativeClass *declarativeClass(JSC::JSValue);
311     static inline QScriptDeclarativeClass::Object *declarativeObject(JSC::JSValue);
312 
313     JSC::UString translationContextFromUrl(const JSC::UString &);
314 
315 #ifndef QT_NO_QOBJECT
316     JSC::JSValue newQObject(QObject *object,
317         QScriptEngine::ValueOwnership ownership = QScriptEngine::QtOwnership,
318         const QScriptEngine:: QObjectWrapOptions &options = 0);
319     JSC::JSValue newQMetaObject(const QMetaObject *metaObject,
320                                 JSC::JSValue ctor);
321 
322     static bool convertToNativeQObject(JSC::ExecState*, JSC::JSValue,
323                                        const QByteArray &targetType,
324                                        void **result);
325 
326     JSC::JSValue evaluateHelper(JSC::ExecState *exec, intptr_t sourceId,
327                                 JSC::EvalExecutable *executable,
328                                 bool &compile);
329 
330     QScript::QObjectData *qobjectData(QObject *object);
331     void disposeQObject(QObject *object);
332     void emitSignalHandlerException();
333 
334     bool scriptConnect(QObject *sender, const char *signal,
335                        JSC::JSValue receiver, JSC::JSValue function,
336                        Qt::ConnectionType type);
337     bool scriptDisconnect(QObject *sender, const char *signal,
338                           JSC::JSValue receiver, JSC::JSValue function);
339 
340     bool scriptConnect(QObject *sender, int index,
341                        JSC::JSValue receiver, JSC::JSValue function,
342                        JSC::JSValue senderWrapper,
343                        Qt::ConnectionType type);
344     bool scriptDisconnect(QObject *sender, int index,
345                           JSC::JSValue receiver, JSC::JSValue function);
346 
347     bool scriptConnect(JSC::JSValue signal, JSC::JSValue receiver,
348                        JSC::JSValue function, Qt::ConnectionType type);
349     bool scriptDisconnect(JSC::JSValue signal, JSC::JSValue receiver,
350                           JSC::JSValue function);
351 
352     // private slots
353     void _q_objectDestroyed(QObject *);
354 #endif
355 
356     JSC::JSGlobalData *globalData;
357     JSC::JSObject *originalGlobalObjectProxy;
358     JSC::ExecState *currentFrame;
359 
360     WTF::RefPtr<JSC::Structure> scriptObjectStructure;
361     WTF::RefPtr<JSC::Structure> staticScopeObjectStructure;
362 
363     QScript::QObjectPrototype *qobjectPrototype;
364     WTF::RefPtr<JSC::Structure> qobjectWrapperObjectStructure;
365 
366     QScript::QMetaObjectPrototype *qmetaobjectPrototype;
367     WTF::RefPtr<JSC::Structure> qmetaobjectWrapperObjectStructure;
368 
369     QScript::QVariantPrototype *variantPrototype;
370     WTF::RefPtr<JSC::Structure> variantWrapperObjectStructure;
371 
372     QList<QScriptEngineAgent*> ownedAgents;
373     QScriptEngineAgent *activeAgent;
374     int agentLineNumber;
375     QScriptValuePrivate *registeredScriptValues;
376     QScriptValuePrivate *freeScriptValues;
377     static const int maxFreeScriptValues = 256;
378     int freeScriptValuesCount;
379     QScriptStringPrivate *registeredScriptStrings;
380     QSet<QScriptProgramPrivate*> registeredScriptPrograms;
381     QHash<int, QScriptTypeInfo*> m_typeInfos;
382     int processEventsInterval;
383     QScriptValue abortResult;
384     bool inEval;
385 
386     JSC::UString cachedTranslationUrl;
387     JSC::UString cachedTranslationContext;
388 
389     QSet<QString> importedExtensions;
390     QSet<QString> extensionsBeingImported;
391 
392     QHash<intptr_t, QScript::UStringSourceProviderWithFeedback*> loadedScripts;
393     QScriptValue m_currentException;
394 
395     QSet<JSC::JSObject*> visitedConversionObjects;
396 
397 #ifndef QT_NO_QOBJECT
398     QHash<QObject*, QScript::QObjectData*> m_qobjectData;
399 #endif
400 
401 #ifdef QT_NO_QOBJECT
402     QScriptEngine *q_ptr;
403 #endif
404 };
405 
406 namespace QScript
407 {
408 
409 class APIShim
410 {
411 public:
APIShim(QScriptEnginePrivate * engine)412     APIShim(QScriptEnginePrivate *engine)
413         : m_engine(engine), m_oldTable(JSC::setCurrentIdentifierTable(engine->globalData->identifierTable))
414     {
415     }
~APIShim()416     ~APIShim()
417     {
418         JSC::setCurrentIdentifierTable(m_oldTable);
419     }
420 
421 private:
422     QScriptEnginePrivate *m_engine;
423     JSC::IdentifierTable *m_oldTable;
424 };
425 
426 /*Helper class. Main purpose is to give debugger feedback about unloading and loading scripts.
427   It keeps pointer to JSGlobalObject assuming that it is always the same - there is no way to update
428   this data. Class is internal and used as an implementation detail in and only in QScriptEngine::evaluate.*/
429 class UStringSourceProviderWithFeedback: public JSC::UStringSourceProvider
430 {
431 public:
create(const JSC::UString & source,const JSC::UString & url,int lineNumber,QScriptEnginePrivate * engine)432     static PassRefPtr<UStringSourceProviderWithFeedback> create(
433         const JSC::UString& source, const JSC::UString& url,
434         int lineNumber, QScriptEnginePrivate* engine)
435     {
436         return adoptRef(new UStringSourceProviderWithFeedback(source, url, lineNumber, engine));
437     }
438 
439     /* Destruction means that there is no more copies of script so create scriptUnload event
440        and unregister script in QScriptEnginePrivate::loadedScripts */
~UStringSourceProviderWithFeedback()441     virtual ~UStringSourceProviderWithFeedback()
442     {
443         if (m_ptr) {
444             if (JSC::Debugger* debugger = this->debugger())
445                 debugger->scriptUnload(asID());
446             m_ptr->loadedScripts.remove(asID());
447         }
448     }
449 
450     /* set internal QScriptEnginePrivate pointer to null and create unloadScript event, should be called
451        only if QScriptEnginePrivate is about to be  destroyed.*/
disconnectFromEngine()452     void disconnectFromEngine()
453     {
454         if (JSC::Debugger* debugger = this->debugger())
455             debugger->scriptUnload(asID());
456         m_ptr = 0;
457     }
458 
columnNumberFromOffset(int offset)459     int columnNumberFromOffset(int offset) const
460     {
461         for (const UChar *c = m_source.data() + offset; c >= m_source.data(); --c) {
462             if (JSC::Lexer::isLineTerminator(*c))
463                 return offset - static_cast<int>(c - data());
464         }
465         return offset + 1;
466     }
467 
468 protected:
UStringSourceProviderWithFeedback(const JSC::UString & source,const JSC::UString & url,int lineNumber,QScriptEnginePrivate * engine)469     UStringSourceProviderWithFeedback(const JSC::UString& source, const JSC::UString& url,
470                                       int lineNumber, QScriptEnginePrivate* engine)
471         : UStringSourceProvider(source, url),
472           m_ptr(engine)
473     {
474         if (JSC::Debugger* debugger = this->debugger())
475             debugger->scriptLoad(asID(), source, url, lineNumber);
476         if (m_ptr)
477             m_ptr->loadedScripts.insert(asID(), this);
478     }
479 
debugger()480     JSC::Debugger* debugger()
481     {
482         //if m_ptr is null it mean that QScriptEnginePrivate was destroyed and scriptUnload was called
483         //else m_ptr is stable and we can use it as normal pointer without hesitation
484         if(!m_ptr)
485             return 0; //we are in ~QScriptEnginePrivate
486         else
487             return m_ptr->originalGlobalObject()->debugger(); //QScriptEnginePrivate is still alive
488     }
489 
490     //trace global object and debugger instance
491     QScriptEnginePrivate* m_ptr;
492 };
493 
494 class SaveFrameHelper
495 {
496 public:
SaveFrameHelper(QScriptEnginePrivate * eng,JSC::ExecState * newFrame)497     SaveFrameHelper(QScriptEnginePrivate *eng,
498                     JSC::ExecState *newFrame)
499         : engine(eng), oldFrame(eng->currentFrame)
500     {
501         eng->currentFrame = newFrame;
502     }
~SaveFrameHelper()503     ~SaveFrameHelper()
504     {
505         engine->currentFrame = oldFrame;
506     }
507 private:
508     QScriptEnginePrivate *engine;
509     JSC::ExecState *oldFrame;
510 };
511 
scriptEngineFromExec(const JSC::ExecState * exec)512 inline QScriptEnginePrivate *scriptEngineFromExec(const JSC::ExecState *exec)
513 {
514     return static_cast<GlobalClientData*>(exec->globalData().clientData)->engine;
515 }
516 
517 #ifndef Q_CC_MSVC
518 // MSVC2008 crashes if these are inlined.
519 
ToString(qsreal value)520 inline QString ToString(qsreal value)
521 {
522     return JSC::UString::from(value);
523 }
524 
ToNumber(const QString & value)525 inline qsreal ToNumber(const QString &value)
526 {
527     return ((JSC::UString)value).toDouble();
528 }
529 
530 #endif
531 
ToInt32(const QString & value)532 inline qint32 ToInt32(const QString &value)
533 {
534     return ToInt32(ToNumber(value));
535 }
536 
ToUInt32(const QString & value)537 inline quint32 ToUInt32(const QString &value)
538 {
539     return ToUInt32(ToNumber(value));
540 }
541 
ToUInt16(const QString & value)542 inline quint16 ToUInt16(const QString &value)
543 {
544     return ToUInt16(ToNumber(value));
545 }
546 
ToInteger(const QString & value)547 inline qsreal ToInteger(const QString &value)
548 {
549     return ToInteger(ToNumber(value));
550 }
551 
ToBool(qsreal value)552 inline bool ToBool(qsreal value)
553 {
554     return (value != 0) && !qIsNaN(value);
555 }
556 
ToBool(const QString & value)557 inline bool ToBool(const QString &value)
558 {
559      return !value.isEmpty();
560 }
561 
convertToLatin1_helper(const UChar * i,int length,char * s)562 inline void convertToLatin1_helper(const UChar *i, int length, char *s)
563 {
564     const UChar *e = i + length;
565     while (i != e)
566         *(s++) = (uchar) *(i++);
567     *s = '\0';
568 }
569 
convertToLatin1(const JSC::UString & str)570 inline QByteArray convertToLatin1(const JSC::UString &str)
571 {
572     QByteArray ba(str.size(), Qt::Uninitialized);
573     convertToLatin1_helper(str.data(), str.size(), ba.data());
574     return ba;
575 }
576 
577 } // namespace QScript
578 
registerScriptProgram(QScriptProgramPrivate * program)579 inline void QScriptEnginePrivate::registerScriptProgram(QScriptProgramPrivate *program)
580 {
581     Q_ASSERT(!registeredScriptPrograms.contains(program));
582     registeredScriptPrograms.insert(program);
583 }
584 
unregisterScriptProgram(QScriptProgramPrivate * program)585 inline void QScriptEnginePrivate::unregisterScriptProgram(QScriptProgramPrivate *program)
586 {
587     Q_ASSERT(registeredScriptPrograms.contains(program));
588     registeredScriptPrograms.remove(program);
589 }
590 
allocateScriptValuePrivate(size_t size)591 inline QScriptValuePrivate *QScriptEnginePrivate::allocateScriptValuePrivate(size_t size)
592 {
593     if (freeScriptValues) {
594         QScriptValuePrivate *p = freeScriptValues;
595         freeScriptValues = p->next;
596         --freeScriptValuesCount;
597         return p;
598     }
599     return reinterpret_cast<QScriptValuePrivate*>(qMalloc(size));
600 }
601 
freeScriptValuePrivate(QScriptValuePrivate * p)602 inline void QScriptEnginePrivate::freeScriptValuePrivate(QScriptValuePrivate *p)
603 {
604     if (freeScriptValuesCount < maxFreeScriptValues) {
605         p->next = freeScriptValues;
606         freeScriptValues = p;
607         ++freeScriptValuesCount;
608     } else {
609         qFree(p);
610     }
611 }
612 
registerScriptValue(QScriptValuePrivate * value)613 inline void QScriptEnginePrivate::registerScriptValue(QScriptValuePrivate *value)
614 {
615     value->prev = 0;
616     value->next = registeredScriptValues;
617     if (registeredScriptValues)
618         registeredScriptValues->prev = value;
619     registeredScriptValues = value;
620 }
621 
unregisterScriptValue(QScriptValuePrivate * value)622 inline void QScriptEnginePrivate::unregisterScriptValue(QScriptValuePrivate *value)
623 {
624     if (value->prev)
625         value->prev->next = value->next;
626     if (value->next)
627         value->next->prev = value->prev;
628     if (value == registeredScriptValues)
629         registeredScriptValues = value->next;
630     value->prev = 0;
631     value->next = 0;
632 }
633 
jscValueFromVariant(JSC::ExecState * exec,const QVariant & v)634 inline JSC::JSValue QScriptEnginePrivate::jscValueFromVariant(JSC::ExecState *exec, const QVariant &v)
635 {
636     JSC::JSValue result = create(exec, v.userType(), v.data());
637     Q_ASSERT(result);
638     return result;
639 }
640 
scriptValueFromJSCValue(JSC::JSValue value)641 inline QScriptValue QScriptEnginePrivate::scriptValueFromJSCValue(JSC::JSValue value)
642 {
643     if (!value)
644         return QScriptValue();
645 
646     QScriptValuePrivate *p_value = new (this)QScriptValuePrivate(this);
647     p_value->initFrom(value);
648     return QScriptValuePrivate::toPublic(p_value);
649 }
650 
scriptValueToJSCValue(const QScriptValue & value)651 inline JSC::JSValue QScriptEnginePrivate::scriptValueToJSCValue(const QScriptValue &value)
652 {
653     QScriptValuePrivate *vv = QScriptValuePrivate::get(value);
654     if (!vv)
655         return JSC::JSValue();
656     if (vv->type != QScriptValuePrivate::JavaScriptCore) {
657         Q_ASSERT(!vv->engine || vv->engine == this);
658         vv->engine = this;
659         if (vv->type == QScriptValuePrivate::Number) {
660             vv->initFrom(JSC::jsNumber(currentFrame, vv->numberValue));
661         } else { //QScriptValuePrivate::String
662             vv->initFrom(JSC::jsString(currentFrame, vv->stringValue));
663         }
664     }
665     return vv->jscValue;
666 }
667 
propertyFlagsToJSCAttributes(const QScriptValue::PropertyFlags & flags)668 inline unsigned QScriptEnginePrivate::propertyFlagsToJSCAttributes(const QScriptValue::PropertyFlags &flags)
669 {
670     unsigned attribs = 0;
671     if (flags & QScriptValue::ReadOnly)
672         attribs |= JSC::ReadOnly;
673     if (flags & QScriptValue::SkipInEnumeration)
674         attribs |= JSC::DontEnum;
675     if (flags & QScriptValue::Undeletable)
676         attribs |= JSC::DontDelete;
677     attribs |= flags & QScriptValue::UserRange;
678     return attribs;
679 }
680 
~QScriptValuePrivate()681 inline QScriptValuePrivate::~QScriptValuePrivate()
682 {
683     if (engine)
684         engine->unregisterScriptValue(this);
685 }
686 
initFrom(JSC::JSValue value)687 inline void QScriptValuePrivate::initFrom(JSC::JSValue value)
688 {
689     if (value.isCell()) {
690         Q_ASSERT(engine != 0);
691         value = engine->toUsableValue(value);
692     }
693     type = JavaScriptCore;
694     jscValue = value;
695     if (engine)
696         engine->registerScriptValue(this);
697 }
698 
initFrom(qsreal value)699 inline void QScriptValuePrivate::initFrom(qsreal value)
700 {
701     type = Number;
702     numberValue = value;
703     if (engine)
704         engine->registerScriptValue(this);
705 }
706 
initFrom(const QString & value)707 inline void QScriptValuePrivate::initFrom(const QString &value)
708 {
709     type = String;
710     stringValue = value;
711     if (engine)
712         engine->registerScriptValue(this);
713 }
714 
property(JSC::ExecState * exec,JSC::JSValue value,const JSC::UString & name,int resolveMode)715 inline JSC::JSValue QScriptEnginePrivate::property(JSC::ExecState *exec, JSC::JSValue value, const JSC::UString &name, int resolveMode)
716 {
717     return property(exec, value, JSC::Identifier(exec, name), resolveMode);
718 }
719 
property(JSC::ExecState * exec,JSC::JSValue value,const JSC::Identifier & id,int resolveMode)720 inline JSC::JSValue QScriptEnginePrivate::property(JSC::ExecState *exec, JSC::JSValue value, const JSC::Identifier &id, int resolveMode)
721 {
722     Q_ASSERT(isObject(value));
723     JSC::JSObject *object = JSC::asObject(value);
724     JSC::PropertySlot slot(object);
725     if ((resolveMode & QScriptValue::ResolvePrototype) && object->getPropertySlot(exec, id, slot))
726         return slot.getValue(exec, id);
727     return propertyHelper(exec, value, id, resolveMode);
728 }
729 
property(JSC::ExecState * exec,JSC::JSValue value,quint32 index,int resolveMode)730 inline JSC::JSValue QScriptEnginePrivate::property(JSC::ExecState *exec, JSC::JSValue value, quint32 index, int resolveMode)
731 {
732     Q_ASSERT(isObject(value));
733     JSC::JSObject *object = JSC::asObject(value);
734     JSC::PropertySlot slot(object);
735     if ((resolveMode & QScriptValue::ResolvePrototype) && object->getPropertySlot(exec, index, slot))
736         return slot.getValue(exec, index);
737     return propertyHelper(exec, value, index, resolveMode);
738 }
739 
propertyFlags(JSC::ExecState * exec,JSC::JSValue value,const JSC::UString & name,const QScriptValue::ResolveFlags & mode)740 inline QScriptValue::PropertyFlags QScriptEnginePrivate::propertyFlags(JSC::ExecState *exec, JSC::JSValue value,
741                                                                        const JSC::UString &name,
742                                                                        const QScriptValue::ResolveFlags &mode)
743 {
744     return propertyFlags(exec, value, JSC::Identifier(exec, name), mode);
745 }
746 
setProperty(JSC::ExecState * exec,JSC::JSValue objectValue,const JSC::UString & name,JSC::JSValue value,const QScriptValue::PropertyFlags & flags)747 inline void QScriptEnginePrivate::setProperty(JSC::ExecState *exec, JSC::JSValue objectValue, const JSC::UString &name,
748                                               JSC::JSValue value, const QScriptValue::PropertyFlags &flags)
749 {
750     setProperty(exec, objectValue, JSC::Identifier(exec, name), value, flags);
751 }
752 
property(const JSC::Identifier & id,const QScriptValue::ResolveFlags & resolveMode)753 inline JSC::JSValue QScriptValuePrivate::property(const JSC::Identifier &id, const QScriptValue::ResolveFlags &resolveMode) const
754 {
755     return QScriptEnginePrivate::property(engine->currentFrame, jscValue, id, resolveMode);
756 }
757 
property(quint32 index,const QScriptValue::ResolveFlags & resolveMode)758 inline JSC::JSValue QScriptValuePrivate::property(quint32 index, const QScriptValue::ResolveFlags &resolveMode) const
759 {
760     return QScriptEnginePrivate::property(engine->currentFrame, jscValue, index, resolveMode);
761 }
762 
property(const JSC::UString & name,const QScriptValue::ResolveFlags & resolveMode)763 inline JSC::JSValue QScriptValuePrivate::property(const JSC::UString &name, const QScriptValue::ResolveFlags &resolveMode) const
764 {
765     JSC::ExecState *exec = engine->currentFrame;
766     return QScriptEnginePrivate::property(exec, jscValue, JSC::Identifier(exec, name), resolveMode);
767 }
768 
propertyFlags(const JSC::Identifier & id,const QScriptValue::ResolveFlags & mode)769 inline QScriptValue::PropertyFlags QScriptValuePrivate::propertyFlags(
770         const JSC::Identifier &id, const QScriptValue::ResolveFlags &mode) const
771 {
772     return QScriptEnginePrivate::propertyFlags(engine->currentFrame, jscValue, id, mode);
773 }
774 
setProperty(const JSC::Identifier & id,const JSC::JSValue & value,const QScriptValue::PropertyFlags & flags)775 inline void QScriptValuePrivate::setProperty(const JSC::Identifier &id, const JSC::JSValue &value,
776                                              const QScriptValue::PropertyFlags &flags)
777 {
778     QScriptEnginePrivate::setProperty(engine->currentFrame, jscValue, id, value, flags);
779 }
780 
setProperty(quint32 index,const JSC::JSValue & value,const QScriptValue::PropertyFlags & flags)781 inline void QScriptValuePrivate::setProperty(quint32 index, const JSC::JSValue &value,
782                                              const QScriptValue::PropertyFlags &flags)
783 {
784     QScriptEnginePrivate::setProperty(engine->currentFrame, jscValue, index, value, flags);
785 }
786 
setProperty(const JSC::UString & name,const JSC::JSValue & value,const QScriptValue::PropertyFlags & flags)787 inline void QScriptValuePrivate::setProperty(const JSC::UString &name, const JSC::JSValue &value,
788                                              const QScriptValue::PropertyFlags &flags)
789 {
790     JSC::ExecState *exec = engine->currentFrame;
791     QScriptEnginePrivate::setProperty(exec, jscValue, JSC::Identifier(exec, name), value, flags);
792 }
793 
new(size_t size,QScriptEnginePrivate * engine)794 inline void* QScriptValuePrivate::operator new(size_t size, QScriptEnginePrivate *engine)
795 {
796     if (engine)
797         return engine->allocateScriptValuePrivate(size);
798     return qMalloc(size);
799 }
800 
delete(void * ptr)801 inline void QScriptValuePrivate::operator delete(void *ptr)
802 {
803     QScriptValuePrivate *d = reinterpret_cast<QScriptValuePrivate*>(ptr);
804     if (d->engine)
805         d->engine->freeScriptValuePrivate(d);
806     else
807         qFree(d);
808 }
809 
saveException(JSC::ExecState * exec,JSC::JSValue * val)810 inline void QScriptEnginePrivate::saveException(JSC::ExecState *exec, JSC::JSValue *val)
811 {
812     if (exec) {
813         *val = exec->exception();
814         exec->clearException();
815     } else {
816         *val = JSC::JSValue();
817     }
818 }
819 
restoreException(JSC::ExecState * exec,JSC::JSValue val)820 inline void QScriptEnginePrivate::restoreException(JSC::ExecState *exec, JSC::JSValue val)
821 {
822     if (exec && val)
823         exec->setException(val);
824 }
825 
registerScriptString(QScriptStringPrivate * value)826 inline void QScriptEnginePrivate::registerScriptString(QScriptStringPrivate *value)
827 {
828     Q_ASSERT(value->type == QScriptStringPrivate::HeapAllocated);
829     value->prev = 0;
830     value->next = registeredScriptStrings;
831     if (registeredScriptStrings)
832         registeredScriptStrings->prev = value;
833     registeredScriptStrings = value;
834 }
835 
unregisterScriptString(QScriptStringPrivate * value)836 inline void QScriptEnginePrivate::unregisterScriptString(QScriptStringPrivate *value)
837 {
838     Q_ASSERT(value->type == QScriptStringPrivate::HeapAllocated);
839     if (value->prev)
840         value->prev->next = value->next;
841     if (value->next)
842         value->next->prev = value->prev;
843     if (value == registeredScriptStrings)
844         registeredScriptStrings = value->next;
845     value->prev = 0;
846     value->next = 0;
847 }
848 
contextForFrame(JSC::ExecState * frame)849 inline QScriptContext *QScriptEnginePrivate::contextForFrame(JSC::ExecState *frame)
850 {
851     if (frame && frame->callerFrame()->hasHostCallFrameFlag() && !frame->callee()
852         && frame->callerFrame()->removeHostCallFrameFlag() == QScript::scriptEngineFromExec(frame)->globalExec()) {
853         //skip the "fake" context created in Interpreter::execute.
854         frame = frame->callerFrame()->removeHostCallFrameFlag();
855     }
856     return reinterpret_cast<QScriptContext *>(frame);
857 }
858 
frameForContext(QScriptContext * context)859 inline JSC::ExecState *QScriptEnginePrivate::frameForContext(QScriptContext *context)
860 {
861     return reinterpret_cast<JSC::ExecState*>(context);
862 }
863 
frameForContext(const QScriptContext * context)864 inline const JSC::ExecState *QScriptEnginePrivate::frameForContext(const QScriptContext *context)
865 {
866     return reinterpret_cast<const JSC::ExecState*>(context);
867 }
868 
hasValidCodeBlockRegister(JSC::ExecState * frame)869 inline bool QScriptEnginePrivate::hasValidCodeBlockRegister(JSC::ExecState *frame)
870 {
871 #if ENABLE(JIT)
872     // Frames created by the VM don't have their CodeBlock register
873     // initialized. We can detect such frames by checking if the
874     // callee is a host JSFunction.
875     JSC::JSObject *callee = frame->callee();
876     return !(callee && callee->inherits(&JSC::JSFunction::info)
877              && JSC::asFunction(callee)->isHostFunction());
878 #else
879     Q_UNUSED(frame);
880     return true;
881 #endif
882 }
883 
globalExec()884 inline JSC::ExecState *QScriptEnginePrivate::globalExec() const
885 {
886     return originalGlobalObject()->globalExec();
887 }
888 
newArray(JSC::ExecState * exec,uint length)889 inline JSC::JSValue QScriptEnginePrivate::newArray(JSC::ExecState *exec, uint length)
890 {
891     return JSC::constructEmptyArray(exec, length);
892 }
893 
newDate(JSC::ExecState * exec,qsreal value)894 inline JSC::JSValue QScriptEnginePrivate::newDate(JSC::ExecState *exec, qsreal value)
895 {
896     JSC::JSValue val = JSC::jsNumber(exec, value);
897     JSC::ArgList args(&val, 1);
898     return JSC::constructDate(exec, args);
899 }
900 
newDate(JSC::ExecState * exec,const QDateTime & value)901 inline JSC::JSValue QScriptEnginePrivate::newDate(JSC::ExecState *exec, const QDateTime &value)
902 {
903     return newDate(exec, QScript::DateTimeToMs(exec, value));
904 }
905 
newObject()906 inline JSC::JSValue QScriptEnginePrivate::newObject()
907 {
908     return new (currentFrame)QScriptObject(scriptObjectStructure);
909 }
910 
isObject(JSC::JSValue value)911 inline bool QScriptEnginePrivate::isObject(JSC::JSValue value)
912 {
913     return value && value.isObject();
914 }
915 
isArray(JSC::JSValue value)916 inline bool QScriptEnginePrivate::isArray(JSC::JSValue value)
917 {
918     return isObject(value) && value.inherits(&JSC::JSArray::info);
919 }
920 
isDate(JSC::JSValue value)921 inline bool QScriptEnginePrivate::isDate(JSC::JSValue value)
922 {
923     return isObject(value) && value.inherits(&JSC::DateInstance::info);
924 }
925 
isError(JSC::JSValue value)926 inline bool QScriptEnginePrivate::isError(JSC::JSValue value)
927 {
928     return isObject(value) && value.inherits(&JSC::ErrorInstance::info);
929 }
930 
isRegExp(JSC::JSValue value)931 inline bool QScriptEnginePrivate::isRegExp(JSC::JSValue value)
932 {
933     return isObject(value) && value.inherits(&JSC::RegExpObject::info);
934 }
935 
isVariant(JSC::JSValue value)936 inline bool QScriptEnginePrivate::isVariant(JSC::JSValue value)
937 {
938     if (!isObject(value) || !value.inherits(&QScriptObject::info))
939         return false;
940     QScriptObject *object = static_cast<QScriptObject*>(JSC::asObject(value));
941     QScriptObjectDelegate *delegate = object->delegate();
942     return (delegate && (delegate->type() == QScriptObjectDelegate::Variant));
943 }
944 
isQObject(JSC::JSValue value)945 inline bool QScriptEnginePrivate::isQObject(JSC::JSValue value)
946 {
947 #ifndef QT_NO_QOBJECT
948     if (!isObject(value) || !value.inherits(&QScriptObject::info))
949         return false;
950     QScriptObject *object = static_cast<QScriptObject*>(JSC::asObject(value));
951     QScriptObjectDelegate *delegate = object->delegate();
952     return (delegate && (delegate->type() == QScriptObjectDelegate::QtObject ||
953                          (delegate->type() == QScriptObjectDelegate::DeclarativeClassObject &&
954                           static_cast<QScript::DeclarativeObjectDelegate*>(delegate)->scriptClass()->isQObject())));
955 #else
956     return false;
957 #endif
958 }
959 
isQMetaObject(JSC::JSValue value)960 inline bool QScriptEnginePrivate::isQMetaObject(JSC::JSValue value)
961 {
962 #ifndef QT_NO_QOBJECT
963     return isObject(value) && JSC::asObject(value)->inherits(&QScript::QMetaObjectWrapperObject::info);
964 #else
965     return false;
966 #endif
967 }
968 
toBool(JSC::ExecState * exec,JSC::JSValue value)969 inline bool QScriptEnginePrivate::toBool(JSC::ExecState *exec, JSC::JSValue value)
970 {
971     JSC::JSValue savedException;
972     saveException(exec, &savedException);
973     bool result = value.toBoolean(exec);
974     restoreException(exec, savedException);
975     return result;
976 }
977 
toInteger(JSC::ExecState * exec,JSC::JSValue value)978 inline qsreal QScriptEnginePrivate::toInteger(JSC::ExecState *exec, JSC::JSValue value)
979 {
980     JSC::JSValue savedException;
981     saveException(exec, &savedException);
982     qsreal result = value.toInteger(exec);
983     restoreException(exec, savedException);
984     return result;
985 }
986 
toNumber(JSC::ExecState * exec,JSC::JSValue value)987 inline qsreal QScriptEnginePrivate::toNumber(JSC::ExecState *exec, JSC::JSValue value)
988 {
989     JSC::JSValue savedException;
990     saveException(exec, &savedException);
991     qsreal result = value.toNumber(exec);
992     restoreException(exec, savedException);
993     return result;
994 }
995 
toInt32(JSC::ExecState * exec,JSC::JSValue value)996 inline qint32 QScriptEnginePrivate::toInt32(JSC::ExecState *exec, JSC::JSValue value)
997 {
998     JSC::JSValue savedException;
999     saveException(exec, &savedException);
1000     qint32 result = value.toInt32(exec);
1001     restoreException(exec, savedException);
1002     return result;
1003 }
1004 
toUInt32(JSC::ExecState * exec,JSC::JSValue value)1005 inline quint32 QScriptEnginePrivate::toUInt32(JSC::ExecState *exec, JSC::JSValue value)
1006 {
1007     JSC::JSValue savedException;
1008     saveException(exec, &savedException);
1009     quint32 result = value.toUInt32(exec);
1010     restoreException(exec, savedException);
1011     return result;
1012 }
1013 
toUInt16(JSC::ExecState * exec,JSC::JSValue value)1014 inline quint16 QScriptEnginePrivate::toUInt16(JSC::ExecState *exec, JSC::JSValue value)
1015 {
1016     // ### no equivalent function in JSC
1017     return QScript::ToUInt16(toNumber(exec, value));
1018 }
1019 
toString(JSC::ExecState * exec,JSC::JSValue value)1020 inline JSC::UString QScriptEnginePrivate::toString(JSC::ExecState *exec, JSC::JSValue value)
1021 {
1022     if (!value)
1023         return JSC::UString();
1024     JSC::JSValue savedException;
1025     saveException(exec, &savedException);
1026     JSC::UString str = value.toString(exec);
1027     if (exec && exec->hadException() && !str.size()) {
1028         JSC::JSValue savedException2;
1029         saveException(exec, &savedException2);
1030         str = savedException2.toString(exec);
1031         restoreException(exec, savedException2);
1032     }
1033     if (savedException)
1034         restoreException(exec, savedException);
1035     return str;
1036 }
1037 
toDateTime(JSC::ExecState * exec,JSC::JSValue value)1038 inline QDateTime QScriptEnginePrivate::toDateTime(JSC::ExecState *exec, JSC::JSValue value)
1039 {
1040     if (!isDate(value))
1041         return QDateTime();
1042     qsreal t = static_cast<JSC::DateInstance*>(JSC::asObject(value))->internalNumber();
1043     return QScript::MsToDateTime(exec, t);
1044 }
1045 
toQObject(JSC::ExecState * exec,JSC::JSValue value)1046 inline QObject *QScriptEnginePrivate::toQObject(JSC::ExecState *exec, JSC::JSValue value)
1047 {
1048 #ifndef QT_NO_QOBJECT
1049     if (isObject(value) && value.inherits(&QScriptObject::info)) {
1050         QScriptObject *object = static_cast<QScriptObject*>(JSC::asObject(value));
1051         QScriptObjectDelegate *delegate = object->delegate();
1052         if (!delegate)
1053             return 0;
1054         if (delegate->type() == QScriptObjectDelegate::QtObject)
1055             return static_cast<QScript::QObjectDelegate*>(delegate)->value();
1056         if (delegate->type() == QScriptObjectDelegate::DeclarativeClassObject)
1057             return static_cast<QScript::DeclarativeObjectDelegate*>(delegate)->scriptClass()->toQObject(declarativeObject(value));
1058         if (delegate->type() == QScriptObjectDelegate::Variant) {
1059             QVariant var = variantValue(value);
1060             int type = var.userType();
1061             if ((type == QMetaType::QObjectStar) || (type == QMetaType::QWidgetStar))
1062                 return *reinterpret_cast<QObject* const *>(var.constData());
1063         }
1064     } else if (isObject(value) && value.inherits(&QScript::QScriptActivationObject::info)) {
1065         QScript::QScriptActivationObject *proxy = static_cast<QScript::QScriptActivationObject *>(JSC::asObject(value));
1066         return toQObject(exec, proxy->delegate());
1067     }
1068 #endif
1069     return 0;
1070 }
1071 
toQMetaObject(JSC::ExecState *,JSC::JSValue value)1072 inline const QMetaObject *QScriptEnginePrivate::toQMetaObject(JSC::ExecState*, JSC::JSValue value)
1073 {
1074 #ifndef QT_NO_QOBJECT
1075     if (isQMetaObject(value))
1076         return static_cast<QScript::QMetaObjectWrapperObject*>(JSC::asObject(value))->value();
1077 #endif
1078     return 0;
1079 }
1080 
variantValue(JSC::JSValue value)1081 inline QVariant &QScriptEnginePrivate::variantValue(JSC::JSValue value)
1082 {
1083     Q_ASSERT(value.inherits(&QScriptObject::info));
1084     QScriptObjectDelegate *delegate = static_cast<QScriptObject*>(JSC::asObject(value))->delegate();
1085     Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::Variant));
1086     return static_cast<QScript::QVariantDelegate*>(delegate)->value();
1087 }
1088 
setVariantValue(JSC::JSValue objectValue,const QVariant & value)1089 inline void QScriptEnginePrivate::setVariantValue(JSC::JSValue objectValue, const QVariant &value)
1090 {
1091     Q_ASSERT(objectValue.inherits(&QScriptObject::info));
1092     QScriptObjectDelegate *delegate = static_cast<QScriptObject*>(JSC::asObject(objectValue))->delegate();
1093     Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::Variant));
1094     static_cast<QScript::QVariantDelegate*>(delegate)->setValue(value);
1095 }
1096 
declarativeClass(JSC::JSValue v)1097 inline QScriptDeclarativeClass *QScriptEnginePrivate::declarativeClass(JSC::JSValue v)
1098 {
1099     if (!QScriptEnginePrivate::isObject(v) || !v.inherits(&QScriptObject::info))
1100         return 0;
1101     QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(v));
1102     QScriptObjectDelegate *delegate = scriptObject->delegate();
1103     if (!delegate || (delegate->type() != QScriptObjectDelegate::DeclarativeClassObject))
1104         return 0;
1105     return static_cast<QScript::DeclarativeObjectDelegate*>(delegate)->scriptClass();
1106 }
1107 
declarativeObject(JSC::JSValue v)1108 inline QScriptDeclarativeClass::Object *QScriptEnginePrivate::declarativeObject(JSC::JSValue v)
1109 {
1110     if (!QScriptEnginePrivate::isObject(v) || !v.inherits(&QScriptObject::info))
1111         return 0;
1112     QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(v));
1113     QScriptObjectDelegate *delegate = scriptObject->delegate();
1114     if (!delegate || (delegate->type() != QScriptObjectDelegate::DeclarativeClassObject))
1115         return 0;
1116     return static_cast<QScript::DeclarativeObjectDelegate*>(delegate)->object();
1117 }
1118 
1119 QT_END_NAMESPACE
1120 
1121 #endif
1122