1 /****************************************************************************
2 **
3 ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the Qt Solutions component.
7 **
8 ** $QT_BEGIN_LICENSE:BSD$
9 ** You may use this file under the terms of the BSD license as follows:
10 **
11 ** "Redistribution and use in source and binary forms, with or without
12 ** modification, are permitted provided that the following conditions are
13 ** met:
14 ** * Redistributions of source code must retain the above copyright
15 ** notice, this list of conditions and the following disclaimer.
16 ** * Redistributions in binary form must reproduce the above copyright
17 ** notice, this list of conditions and the following disclaimer in
18 ** the documentation and/or other materials provided with the
19 ** distribution.
20 ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
21 ** of its contributors may be used to endorse or promote products derived
22 ** from this software without specific prior written permission.
23 **
24 **
25 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
36 **
37 ** $QT_END_LICENSE$
38 **
39 ****************************************************************************/
40
41
42 #ifndef QSCRIPTENGINE_P_H
43 #define QSCRIPTENGINE_P_H
44
45 #include "qscriptenginefwd_p.h"
46
47
48 #include <QDateTime>
49 #include <QMutex>
50 #include <QLinkedList>
51 #include <QString>
52 #include <QVector>
53 #include <QHash>
54 #include <qnumeric.h>
55
56 #include "qscriptengine.h"
57 #include "qscriptnameid_p.h"
58 #include "qscriptobjectfwd_p.h"
59 #include "qscriptrepository_p.h"
60 #include "qscriptgc_p.h"
61 #include "qscriptecmaarray_p.h"
62 #include "qscriptecmadate_p.h"
63 #include "qscriptecmaobject_p.h"
64 #include "qscriptecmaboolean_p.h"
65 #include "qscriptecmanumber_p.h"
66 #include "qscriptecmastring_p.h"
67 #include "qscriptecmafunction_p.h"
68 #include "qscriptextvariant_p.h"
69 #include "qscriptextqobject_p.h"
70 #include "qscriptvalue_p.h"
71 #include "qscriptcontextfwd_p.h"
72
73 #include <math.h>
74
75 QT_BEGIN_NAMESPACE
76
77 //
78 // W A R N I N G
79 // -------------
80 //
81 // This file is not part of the Qt API. It exists purely as an
82 // implementation detail. This header file may change from version to
83 // version without notice, or even be removed.
84 //
85 // We mean it.
86 //
87
88 namespace QScript {
89
90 class ArgumentsObjectData: public QScriptObjectData
91 {
92 public:
ArgumentsObjectData()93 ArgumentsObjectData() : length(0) {}
~ArgumentsObjectData()94 virtual ~ArgumentsObjectData() {}
95
96 public: // attributes
97 QScriptValueImpl activation;
98 uint length;
99 };
100
101 } // namespace QScript
102
get(QScriptEngine * q)103 inline QScriptEnginePrivate *QScriptEnginePrivate::get(QScriptEngine *q)
104 {
105 if (q)
106 return q->d_func();
107 return 0;
108 }
109
get(const QScriptEngine * q)110 inline const QScriptEnginePrivate *QScriptEnginePrivate::get(const QScriptEngine *q)
111 {
112 if (q)
113 return q->d_func();
114 return 0;
115 }
116
get(QScriptEnginePrivate * d)117 inline QScriptEngine *QScriptEnginePrivate::get(QScriptEnginePrivate *d)
118 {
119 return d->q_func();
120 }
121
toString(QScriptNameIdImpl * id)122 inline QString QScriptEnginePrivate::toString(QScriptNameIdImpl *id)
123 {
124 if (! id)
125 return QString();
126
127 return id->s;
128 }
129
memberName(const QScript::Member & member)130 inline QString QScriptEnginePrivate::memberName(const QScript::Member &member) const
131 {
132 return toString(member.nameId());
133 }
134
newReference(QScriptValueImpl * o,int mode)135 inline void QScriptEnginePrivate::newReference(QScriptValueImpl *o, int mode)
136 {
137 Q_ASSERT(o);
138 o->m_type = QScript::ReferenceType;
139 o->m_int_value = (mode);
140 }
141
newActivation(QScriptValueImpl * o)142 inline void QScriptEnginePrivate::newActivation(QScriptValueImpl *o)
143 {
144 Q_ASSERT(o);
145 newObject(o, nullValue(), m_class_activation);
146 }
147
newPointer(QScriptValueImpl * o,void * ptr)148 inline void QScriptEnginePrivate::newPointer(QScriptValueImpl *o, void *ptr)
149 {
150 Q_ASSERT(o);
151 o->m_type = QScript::PointerType;
152 o->m_ptr_value = ptr;
153 }
154
newInteger(QScriptValueImpl * o,int i)155 inline void QScriptEnginePrivate::newInteger(QScriptValueImpl *o, int i)
156 {
157 Q_ASSERT(o);
158 o->m_type = QScript::IntegerType;
159 o->m_int_value = (i);
160 }
161
newNameId(QScriptValueImpl * o,const QString & s)162 inline void QScriptEnginePrivate::newNameId(QScriptValueImpl *o, const QString &s)
163 {
164 Q_ASSERT(o);
165 o->m_type = QScript::StringType;
166 o->m_string_value = (nameId(s, /*persistent=*/false));
167 }
168
newString(QScriptValueImpl * o,const QString & s)169 inline void QScriptEnginePrivate::newString(QScriptValueImpl *o, const QString &s)
170 {
171 Q_ASSERT(o);
172 o->m_type = QScript::StringType;
173 QScriptNameIdImpl *entry = new QScriptNameIdImpl(s);
174 m_tempStringRepository.append(entry);
175 o->m_string_value = (entry);
176 m_newAllocatedTempStringRepositoryChars += s.length();
177 }
178
newNameId(QScriptValueImpl * o,QScriptNameIdImpl * id)179 inline void QScriptEnginePrivate::newNameId(QScriptValueImpl *o, QScriptNameIdImpl *id)
180 {
181 Q_ASSERT(o);
182 o->m_type = QScript::StringType;
183 o->m_string_value = (id);
184 }
185
idTable()186 inline const QScript::IdTable *QScriptEnginePrivate::idTable() const
187 {
188 return &m_id_table;
189 }
190
convertToNativeDouble(const QScriptValueImpl & value)191 inline qsreal QScriptEnginePrivate::convertToNativeDouble(const QScriptValueImpl &value)
192 {
193 Q_ASSERT (value.isValid());
194
195 if (value.isNumber())
196 return value.m_number_value;
197
198 return convertToNativeDouble_helper(value);
199 }
200
convertToNativeInt32(const QScriptValueImpl & value)201 inline qint32 QScriptEnginePrivate::convertToNativeInt32(const QScriptValueImpl &value)
202 {
203 Q_ASSERT (value.isValid());
204
205 return toInt32 (convertToNativeDouble(value));
206 }
207
208
convertToNativeBoolean(const QScriptValueImpl & value)209 inline bool QScriptEnginePrivate::convertToNativeBoolean(const QScriptValueImpl &value)
210 {
211 Q_ASSERT (value.isValid());
212
213 if (value.isBoolean())
214 return value.m_bool_value;
215
216 return convertToNativeBoolean_helper(value);
217 }
218
convertToNativeString(const QScriptValueImpl & value)219 inline QString QScriptEnginePrivate::convertToNativeString(const QScriptValueImpl &value)
220 {
221 Q_ASSERT (value.isValid());
222
223 if (value.isString())
224 return value.m_string_value->s;
225
226 return convertToNativeString_helper(value);
227 }
228
toInteger(qsreal n)229 inline qsreal QScriptEnginePrivate::toInteger(qsreal n)
230 {
231 if (qIsNaN(n))
232 return 0;
233
234 if (n == 0 || qIsInf(n))
235 return n;
236
237 int sign = n < 0 ? -1 : 1;
238 return sign * ::floor(::fabs(n));
239 }
240
toInt32(qsreal n)241 inline qint32 QScriptEnginePrivate::toInt32(qsreal n)
242 {
243 if (qIsNaN(n) || qIsInf(n) || (n == 0))
244 return 0;
245
246 double sign = (n < 0) ? -1.0 : 1.0;
247 qsreal abs_n = fabs(n);
248
249 n = ::fmod(sign * ::floor(abs_n), D32);
250 const double D31 = D32 / 2.0;
251
252 if (sign == -1 && n < -D31)
253 n += D32;
254
255 else if (sign != -1 && n >= D31)
256 n -= D32;
257
258 return qint32 (n);
259 }
260
toUint32(qsreal n)261 inline quint32 QScriptEnginePrivate::toUint32(qsreal n)
262 {
263 if (qIsNaN(n) || qIsInf(n) || (n == 0))
264 return 0;
265
266 double sign = (n < 0) ? -1.0 : 1.0;
267 qsreal abs_n = fabs(n);
268
269 n = ::fmod(sign * ::floor(abs_n), D32);
270
271 if (n < 0)
272 n += D32;
273
274 return quint32 (n);
275 }
276
toUint16(qsreal n)277 inline quint16 QScriptEnginePrivate::toUint16(qsreal n)
278 {
279 if (qIsNaN(n) || qIsInf(n) || (n == 0))
280 return 0;
281
282 double sign = (n < 0) ? -1.0 : 1.0;
283 qsreal abs_n = fabs(n);
284
285 n = ::fmod(sign * ::floor(abs_n), D16);
286
287 if (n < 0)
288 n += D16;
289
290 return quint16 (n);
291 }
292
abstractSyntaxTree()293 inline QScript::AST::Node *QScriptEnginePrivate::abstractSyntaxTree() const
294 {
295 return m_abstractSyntaxTree;
296 }
297
nodePool()298 inline QScript::MemoryPool *QScriptEnginePrivate::nodePool()
299 {
300 return m_pool;
301 }
302
setNodePool(QScript::MemoryPool * pool)303 inline void QScriptEnginePrivate::setNodePool(QScript::MemoryPool *pool)
304 {
305 m_pool = pool;
306 }
307
lexer()308 inline QScript::Lexer *QScriptEnginePrivate::lexer()
309 {
310 return m_lexer;
311 }
312
setLexer(QScript::Lexer * lexer)313 inline void QScriptEnginePrivate::setLexer(QScript::Lexer *lexer)
314 {
315 m_lexer = lexer;
316 }
317
allocObject()318 inline QScriptObject *QScriptEnginePrivate::allocObject()
319 {
320 return objectAllocator(m_objectGeneration);
321 }
322
currentContext()323 inline QScriptContextPrivate *QScriptEnginePrivate::currentContext() const
324 {
325 return m_context;
326 }
327
pushContext()328 inline QScriptContextPrivate *QScriptEnginePrivate::pushContext()
329 {
330 QScriptContext *context = m_frameRepository.get();
331 QScriptContextPrivate *ctx_p = QScriptContextPrivate::get(context);
332 ctx_p->init(m_context);
333 m_context = ctx_p;
334 #ifndef Q_SCRIPT_NO_EVENT_NOTIFY
335 notifyContextPush();
336 #endif
337 return m_context;
338 }
339
popContext()340 inline void QScriptEnginePrivate::popContext()
341 {
342 Q_ASSERT(m_context != 0);
343 #ifndef Q_SCRIPT_NO_EVENT_NOTIFY
344 notifyContextPop();
345 #endif
346 QScriptContextPrivate *context = m_context;
347 m_context = context->parentContext();
348 if (m_context) {
349 QScriptContextPrivate *p1 = m_context;
350 QScriptContextPrivate *p2 = context;
351 if ((p1->m_state != QScriptContext::ExceptionState)
352 || (p2->m_state == QScriptContext::ExceptionState)) {
353 // propagate the state
354 p1->m_result = p2->m_result;
355 p1->m_state = p2->m_state;
356 // only update errorLineNumber if there actually was an exception
357 if (p2->m_state == QScriptContext::ExceptionState) {
358 if (p2->errorLineNumber != -1)
359 p1->errorLineNumber = p2->errorLineNumber;
360 else
361 p1->errorLineNumber = p1->currentLine;
362 }
363 }
364 }
365 m_frameRepository.release(QScriptContextPrivate::get(context));
366 }
367
maybeGC()368 inline void QScriptEnginePrivate::maybeGC()
369 {
370 if (objectAllocator.blocked())
371 return;
372
373 bool do_string_gc = ((m_stringRepository.size() - m_oldStringRepositorySize) > 256)
374 || (m_newAllocatedStringRepositoryChars > 0x800000);
375 do_string_gc |= ((m_tempStringRepository.size() - m_oldTempStringRepositorySize) > 1024)
376 || (m_newAllocatedTempStringRepositoryChars > 0x800000);
377
378 if (! do_string_gc && ! objectAllocator.poll())
379 return;
380
381 maybeGC_helper(do_string_gc);
382 }
383
adjustBytesAllocated(int bytes)384 inline void QScriptEnginePrivate::adjustBytesAllocated(int bytes)
385 {
386 objectAllocator.adjustBytesAllocated(bytes);
387 }
388
blockGC(bool block)389 inline bool QScriptEnginePrivate::blockGC(bool block)
390 {
391 return objectAllocator.blockGC(block);
392 }
393
markString(QScriptNameIdImpl * id,int)394 inline void QScriptEnginePrivate::markString(QScriptNameIdImpl *id, int /*generation*/)
395 {
396 id->used = true;
397 }
398
createFunction(QScriptFunction * fun)399 inline QScriptValueImpl QScriptEnginePrivate::createFunction(QScriptFunction *fun)
400 {
401 QScriptValueImpl v;
402 newFunction(&v, fun);
403 return v;
404 }
405
newArray(const QScript::Array & value)406 inline QScriptValueImpl QScriptEnginePrivate::newArray(const QScript::Array &value)
407 {
408 QScriptValueImpl v;
409 newArray(&v, value);
410 return v;
411 }
412
newArray(uint length)413 inline QScriptValueImpl QScriptEnginePrivate::newArray(uint length)
414 {
415 QScriptValueImpl v;
416 QScript::Array a(this);
417 a.resize(length);
418 newArray(&v, a);
419 return v;
420 }
421
registerClass(const QString & pname,int type)422 inline QScriptClassInfo *QScriptEnginePrivate::registerClass(const QString &pname, int type)
423 {
424 if (type == -1)
425 type = ++m_class_prev_id;
426
427 QScriptClassInfo *oc = new QScriptClassInfo(this, QScriptClassInfo::Type(type), pname);
428 m_allocated_classes.append(oc);
429
430 return oc;
431 }
432
registerClass(const QString & name)433 inline QScriptClassInfo *QScriptEnginePrivate::registerClass(const QString &name)
434 {
435 return registerClass(name, -1);
436 }
437
createFunction(QScriptInternalFunctionSignature fun,int length,QScriptClassInfo * classInfo,const QString & name)438 inline QScriptValueImpl QScriptEnginePrivate::createFunction(QScriptInternalFunctionSignature fun,
439 int length, QScriptClassInfo *classInfo, const QString &name)
440 {
441 return createFunction(new QScript::C2Function(fun, length, classInfo, name));
442 }
443
newFunction(QScriptValueImpl * o,QScriptFunction * function)444 inline void QScriptEnginePrivate::newFunction(QScriptValueImpl *o, QScriptFunction *function)
445 {
446 QScriptValueImpl proto;
447 if (functionConstructor)
448 proto = functionConstructor->publicPrototype;
449 else {
450 // creating the Function prototype object
451 Q_ASSERT(objectConstructor);
452 proto = objectConstructor->publicPrototype;
453 }
454 newObject(o, proto, m_class_function);
455 o->setObjectData(function);
456 }
457
newConstructor(QScriptValueImpl * ctor,QScriptFunction * function,QScriptValueImpl & proto)458 inline void QScriptEnginePrivate::newConstructor(QScriptValueImpl *ctor,
459 QScriptFunction *function,
460 QScriptValueImpl &proto)
461 {
462 newFunction(ctor, function);
463 ctor->setProperty(m_id_table.id_prototype, proto,
464 QScriptValue::Undeletable
465 | QScriptValue::ReadOnly
466 | QScriptValue::SkipInEnumeration);
467 proto.setProperty(m_id_table.id_constructor, *ctor,
468 QScriptValue::Undeletable
469 | QScriptValue::SkipInEnumeration);
470 }
471
newArguments(QScriptValueImpl * object,const QScriptValueImpl & activation,uint length,const QScriptValueImpl & callee)472 inline void QScriptEnginePrivate::newArguments(QScriptValueImpl *object,
473 const QScriptValueImpl &activation,
474 uint length,
475 const QScriptValueImpl &callee)
476 {
477 QScript::ArgumentsObjectData *data = new QScript::ArgumentsObjectData();
478 data->activation = activation;
479 data->length = length;
480 newObject(object, m_class_arguments);
481 object->setObjectData(data);
482 object->setProperty(m_id_table.id_callee, callee,
483 QScriptValue::SkipInEnumeration);
484 object->setProperty(m_id_table.id_length, QScriptValueImpl(length),
485 QScriptValue::SkipInEnumeration);
486 }
487
convertToNativeFunction(const QScriptValueImpl & object)488 inline QScriptFunction *QScriptEnginePrivate::convertToNativeFunction(const QScriptValueImpl &object)
489 {
490 if (object.isFunction())
491 return static_cast<QScriptFunction*> (object.objectData());
492 return 0;
493 }
494
toPublic(const QScriptValueImpl & value)495 inline QScriptValue QScriptEnginePrivate::toPublic(const QScriptValueImpl &value)
496 {
497 if (!value.isValid())
498 return QScriptValue();
499
500 QScriptValuePrivate *p = registerValue(value);
501 QScriptValue v;
502 QScriptValuePrivate::init(v, p);
503 return v;
504 }
505
toImpl(const QScriptValue & value)506 inline QScriptValueImpl QScriptEnginePrivate::toImpl(const QScriptValue &value)
507 {
508 QScriptValuePrivate *p = QScriptValuePrivate::get(value);
509 if (!p)
510 return QScriptValueImpl();
511 if (p->value.type() == QScript::LazyStringType)
512 return toImpl_helper(value);
513 return p->value;
514 }
515
toImplList(const QScriptValueList & lst)516 inline QScriptValueImplList QScriptEnginePrivate::toImplList(const QScriptValueList &lst)
517 {
518 QScriptValueImplList result;
519 QScriptValueList::const_iterator it;
520 for (it = lst.constBegin(); it != lst.constEnd(); ++it)
521 result.append(toImpl(*it));
522 return result;
523 }
524
toObject(const QScriptValueImpl & value)525 inline QScriptValueImpl QScriptEnginePrivate::toObject(const QScriptValueImpl &value)
526 {
527 if (value.isObject() || !value.isValid())
528 return value;
529 return toObject_helper(value);
530 }
531
toPrimitive(const QScriptValueImpl & object,QScriptValueImpl::TypeHint hint)532 inline QScriptValueImpl QScriptEnginePrivate::toPrimitive(const QScriptValueImpl &object,
533 QScriptValueImpl::TypeHint hint)
534 {
535 Q_ASSERT(object.isValid());
536
537 if (! object.isObject())
538 return object;
539
540 return toPrimitive_helper(object, hint);
541 }
542
toDateTime(const QScriptValueImpl & value)543 inline QDateTime QScriptEnginePrivate::toDateTime(const QScriptValueImpl &value) const
544 {
545 return dateConstructor->toDateTime(value);
546 }
547
newArray(QScriptValueImpl * object,const QScript::Array & value)548 inline void QScriptEnginePrivate::newArray(QScriptValueImpl *object, const QScript::Array &value)
549 {
550 arrayConstructor->newArray(object, value);
551 }
552
newObject(QScriptValueImpl * o,const QScriptValueImpl & proto,QScriptClassInfo * oc)553 inline void QScriptEnginePrivate::newObject(QScriptValueImpl *o, const QScriptValueImpl &proto,
554 QScriptClassInfo *oc)
555 {
556 Q_ASSERT(o != 0);
557
558 QScriptObject *od = allocObject();
559 od->reset();
560 od->m_id = ++m_next_object_id;
561 if (proto.isValid())
562 od->m_prototype = proto;
563 else {
564 Q_ASSERT(objectConstructor);
565 od->m_prototype = objectConstructor->publicPrototype;
566 }
567
568 o->m_type = QScript::ObjectType;
569 od->m_class = (oc ? oc : m_class_object);
570 o->m_object_value = od;
571 }
572
newObject(QScriptValueImpl * o,QScriptClassInfo * oc)573 inline void QScriptEnginePrivate::newObject(QScriptValueImpl *o, QScriptClassInfo *oc)
574 {
575 newObject(o, objectConstructor->publicPrototype, oc);
576 }
577
newObject()578 inline QScriptValueImpl QScriptEnginePrivate::newObject()
579 {
580 QScriptValueImpl v;
581 newObject(&v);
582 return v;
583 }
584
newVariant(QScriptValueImpl * out,const QVariant & value,bool setDefaultPrototype)585 inline void QScriptEnginePrivate::newVariant(QScriptValueImpl *out,
586 const QVariant &value,
587 bool setDefaultPrototype)
588 {
589 Q_ASSERT(variantConstructor != 0);
590 variantConstructor->newVariant(out, value);
591 if (setDefaultPrototype) {
592 QScriptValueImpl proto = defaultPrototype(value.userType());
593 if (proto.isValid())
594 out->setPrototype(proto);
595 }
596 }
597
598 #ifndef QT_NO_QOBJECT
599 # ifndef Q_SCRIPT_NO_QMETAOBJECT_CACHE
cachedMetaObject(const QMetaObject * meta)600 inline QScriptMetaObject *QScriptEnginePrivate::cachedMetaObject(const QMetaObject *meta)
601 {
602 QScriptMetaObject *value = m_cachedMetaObjects.value(meta);
603 if (!value) {
604 value = new QScriptMetaObject;
605 m_cachedMetaObjects.insert(meta, value);
606 }
607 return value;
608 }
609 # endif
610 #endif // !QT_NO_QOBJECT
611
nameId(const QString & str,bool persistent)612 inline QScriptNameIdImpl *QScriptEnginePrivate::nameId(const QString &str, bool persistent)
613 {
614 QScriptNameIdImpl *entry = toStringEntry(str);
615 if (! entry)
616 entry = insertStringEntry(str);
617
618 Q_ASSERT(entry->unique);
619
620 if (persistent)
621 entry->persistent = true;
622
623 return entry;
624 }
625
intern(const QChar * u,int s)626 inline QScriptNameIdImpl *QScriptEnginePrivate::intern(const QChar *u, int s)
627 {
628 QString tmp(u, s);
629 return nameId(tmp, /*persistent=*/ true);
630 }
631
valueFromVariant(const QVariant & v)632 inline QScriptValueImpl QScriptEnginePrivate::valueFromVariant(const QVariant &v)
633 {
634 QScriptValueImpl result = create(v.userType(), v.data());
635 Q_ASSERT(result.isValid());
636 return result;
637 }
638
undefinedValue()639 inline QScriptValueImpl QScriptEnginePrivate::undefinedValue()
640 {
641 return m_undefinedValue;
642 }
643
nullValue()644 inline QScriptValueImpl QScriptEnginePrivate::nullValue()
645 {
646 return m_nullValue;
647 }
648
defaultPrototype(int metaTypeId)649 inline QScriptValueImpl QScriptEnginePrivate::defaultPrototype(int metaTypeId) const
650 {
651 QScriptCustomTypeInfo info = m_customTypes.value(metaTypeId);
652 return info.prototype;
653 }
654
setDefaultPrototype(int metaTypeId,const QScriptValueImpl & prototype)655 inline void QScriptEnginePrivate::setDefaultPrototype(int metaTypeId, const QScriptValueImpl &prototype)
656 {
657 QScriptCustomTypeInfo info = m_customTypes.value(metaTypeId);
658 info.prototype = prototype;
659 m_customTypes.insert(metaTypeId, info);
660 }
661
_q_scriptHash(const QString & key)662 inline uint _q_scriptHash(const QString &key)
663 {
664 const QChar *p = key.unicode();
665 int n = qMin(key.size(), 128);
666 uint h = key.size();
667 uint g;
668
669 while (n--) {
670 h = (h << 4) + (*p++).unicode();
671 if ((g = (h & 0xf0000000)) != 0)
672 h ^= g >> 23;
673 h &= ~g;
674 }
675 return h;
676 }
677
toStringEntry(const QString & s)678 inline QScriptNameIdImpl *QScriptEnginePrivate::toStringEntry(const QString &s)
679 {
680 uint h = _q_scriptHash(s) % m_string_hash_size;
681
682 for (QScriptNameIdImpl *entry = m_string_hash_base[h]; entry && entry->h == h; entry = entry->next) {
683 if (entry->s == s)
684 return entry;
685 }
686
687 return 0;
688 }
689
lessThan(const QScriptValueImpl & lhs,const QScriptValueImpl & rhs)690 inline bool QScriptEnginePrivate::lessThan(const QScriptValueImpl &lhs, const QScriptValueImpl &rhs)
691 {
692 return QScriptContextPrivate::lt_cmp(lhs, rhs);
693 }
694
equals(const QScriptValueImpl & lhs,const QScriptValueImpl & rhs)695 inline bool QScriptEnginePrivate::equals(const QScriptValueImpl &lhs, const QScriptValueImpl &rhs)
696 {
697 return QScriptContextPrivate::eq_cmp(lhs, rhs);
698 }
699
strictlyEquals(const QScriptValueImpl & lhs,const QScriptValueImpl & rhs)700 inline bool QScriptEnginePrivate::strictlyEquals(const QScriptValueImpl &lhs, const QScriptValueImpl &rhs)
701 {
702 return QScriptContextPrivate::strict_eq_cmp(lhs, rhs);
703 }
704
unregisterValue(QScriptValuePrivate * p)705 inline void QScriptEnginePrivate::unregisterValue(QScriptValuePrivate *p)
706 {
707 QScriptValueImpl &v = p->value;
708 Q_ASSERT(v.isValid());
709 if (v.isString()) {
710 QScriptNameIdImpl *id = v.stringValue();
711 m_stringHandles.remove(id);
712 } else if (v.isObject()) {
713 QScriptObject *instance = v.objectValue();
714 m_objectHandles.remove(instance);
715 } else {
716 int i = m_otherHandles.indexOf(p);
717 Q_ASSERT(i != -1);
718 m_otherHandles.remove(i);
719 }
720 m_handleRepository.release(p);
721 }
722
globalObject()723 inline QScriptValueImpl QScriptEnginePrivate::globalObject() const
724 {
725 return m_globalObject;
726 }
727
hasUncaughtException()728 inline bool QScriptEnginePrivate::hasUncaughtException() const
729 {
730 return (currentContext()->state() == QScriptContext::ExceptionState);
731 }
732
uncaughtException()733 inline QScriptValueImpl QScriptEnginePrivate::uncaughtException() const
734 {
735 if (!hasUncaughtException())
736 return QScriptValueImpl();
737 return currentContext()->returnValue();
738 }
739
maybeProcessEvents()740 inline void QScriptEnginePrivate::maybeProcessEvents()
741 {
742 if (m_processEventsInterval > 0 && ++m_processEventIncr > 512) {
743 m_processEventIncr = 0;
744 processEvents();
745 }
746 }
747
shouldAbort()748 inline bool QScriptEnginePrivate::shouldAbort() const
749 {
750 return m_abort;
751 }
752
resetAbortFlag()753 inline void QScriptEnginePrivate::resetAbortFlag()
754 {
755 m_abort = false;
756 }
757
758 #ifndef Q_SCRIPT_NO_EVENT_NOTIFY
759
shouldNotify()760 inline bool QScriptEnginePrivate::shouldNotify() const
761 {
762 return m_agent != 0;
763 }
764
notifyScriptLoad(qint64 id,const QString & program,const QString & fileName,int lineNumber)765 inline void QScriptEnginePrivate::notifyScriptLoad(
766 qint64 id, const QString &program,
767 const QString &fileName, int lineNumber)
768 {
769 if (shouldNotify())
770 notifyScriptLoad_helper(id, program, fileName, lineNumber);
771 }
772
notifyScriptUnload(qint64 id)773 inline void QScriptEnginePrivate::notifyScriptUnload(qint64 id)
774 {
775 if (shouldNotify())
776 notifyScriptUnload_helper(id);
777 }
778
notifyPositionChange(QScriptContextPrivate * ctx)779 inline void QScriptEnginePrivate::notifyPositionChange(QScriptContextPrivate *ctx)
780 {
781 Q_ASSERT(m_agent != 0);
782 notifyPositionChange_helper(ctx);
783 }
784
notifyContextPush()785 inline void QScriptEnginePrivate::notifyContextPush()
786 {
787 if (shouldNotify())
788 notifyContextPush_helper();
789 }
790
notifyContextPop()791 inline void QScriptEnginePrivate::notifyContextPop()
792 {
793 if (shouldNotify())
794 notifyContextPop_helper();
795 }
796
notifyFunctionEntry(QScriptContextPrivate * ctx)797 inline void QScriptEnginePrivate::notifyFunctionEntry(QScriptContextPrivate *ctx)
798 {
799 if (shouldNotify())
800 notifyFunctionEntry_helper(ctx);
801 }
802
notifyFunctionExit(QScriptContextPrivate * ctx)803 inline void QScriptEnginePrivate::notifyFunctionExit(QScriptContextPrivate *ctx)
804 {
805 if (shouldNotify())
806 notifyFunctionExit_helper(ctx);
807 }
808
notifyException(QScriptContextPrivate * ctx)809 inline void QScriptEnginePrivate::notifyException(QScriptContextPrivate *ctx)
810 {
811 if (shouldNotify())
812 notifyException_helper(ctx);
813 }
814
notifyExceptionCatch(QScriptContextPrivate * ctx)815 inline void QScriptEnginePrivate::notifyExceptionCatch(QScriptContextPrivate *ctx)
816 {
817 if (shouldNotify())
818 notifyExceptionCatch_helper(ctx);
819 }
820
821 #endif // Q_SCRIPT_NO_EVENT_NOTIFY
822
823 QT_END_NAMESPACE
824
825
826 #endif
827