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