Qt 4.8
qscriptqobject.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
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-project.org/.
19 **
20 ** $QT_END_LICENSE$
21 **
22 ****************************************************************************/
23 
24 #include "config.h"
25 #include "qscriptqobject_p.h"
26 
27 #include <QtCore/qmetaobject.h>
28 #include <QtCore/qvarlengtharray.h>
29 #include <QtCore/qdebug.h>
30 #include <QtScript/qscriptable.h>
31 #include "../api/qscriptengine_p.h"
32 #include "../api/qscriptable_p.h"
33 #include "../api/qscriptcontext_p.h"
34 #include "qscriptfunction_p.h"
35 
36 #include "Error.h"
37 #include "PrototypeFunction.h"
38 #include "NativeFunctionWrapper.h"
39 #include "PropertyNameArray.h"
40 #include "JSFunction.h"
41 #include "JSString.h"
42 #include "JSValue.h"
43 #include "JSArray.h"
44 #include "RegExpObject.h"
45 #include "RegExpConstructor.h"
46 
47 namespace JSC
48 {
55 }
56 
58 
59 namespace QScript
60 {
61 
63 {
64  int slotIndex;
65  JSC::JSValue receiver;
66  JSC::JSValue slot;
67  JSC::JSValue senderWrapper;
68 
69  QObjectConnection(int i, JSC::JSValue r, JSC::JSValue s,
70  JSC::JSValue sw)
71  : slotIndex(i), receiver(r), slot(s), senderWrapper(sw) {}
72  QObjectConnection() : slotIndex(-1) {}
73 
74  bool hasTarget(JSC::JSValue r, JSC::JSValue s) const
75  {
76  if ((r && r.isObject()) != (receiver && receiver.isObject()))
77  return false;
78  if (((r && r.isObject()) && (receiver && receiver.isObject()))
79  && (r != receiver)) {
80  return false;
81  }
82  return (s == slot);
83  }
84 
85  void mark(JSC::MarkStack& markStack)
86  {
87  if (senderWrapper) {
88  // see if the sender should be marked or not;
89  // if the C++ object is owned by script, we don't want
90  // it to stay alive due to a script connection.
91  Q_ASSERT(senderWrapper.inherits(&QScriptObject::info));
92  QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(senderWrapper));
93  if (!JSC::Heap::isCellMarked(scriptObject)) {
94  QScriptObjectDelegate *delegate = scriptObject->delegate();
95  Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::QtObject));
96  QObjectDelegate *inst = static_cast<QObjectDelegate*>(delegate);
99  && inst->value() && !inst->value()->parent())) {
100  senderWrapper = JSC::JSValue();
101  } else {
102  markStack.append(senderWrapper);
103  }
104  }
105  }
106  if (receiver)
107  markStack.append(receiver);
108  if (slot)
109  markStack.append(slot);
110  }
111 };
112 
114 {
115 public:
116  void callConnectNotify(const char *signal)
117  { connectNotify(signal); }
118  void callDisconnectNotify(const char *signal)
119  { disconnectNotify(signal); }
120 };
121 
123 {
124 public:
127 
128  bool addSignalHandler(QObject *sender, int signalIndex,
129  JSC::JSValue receiver,
130  JSC::JSValue slot,
131  JSC::JSValue senderWrapper,
133  bool removeSignalHandler(QObject *sender, int signalIndex,
134  JSC::JSValue receiver,
135  JSC::JSValue slot);
136 
138  virtual const QMetaObject *metaObject() const;
139  virtual void *qt_metacast(const char *);
140  virtual int qt_metacall(QMetaObject::Call, int, void **argv);
141 
142  void execute(int slotIndex, void **argv);
143 
144  void mark(JSC::MarkStack&);
145 
146 private:
150 };
151 
152 static bool hasMethodAccess(const QMetaMethod &method, int index, const QScriptEngine::QObjectWrapOptions &opt)
153 {
154  return (method.access() != QMetaMethod::Private)
155  && ((index != 2) || !(opt & QScriptEngine::ExcludeDeleteLater))
156  && (!(opt & QScriptEngine::ExcludeSlots) || (method.methodType() != QMetaMethod::Slot));
157 }
158 
159 static bool isEnumerableMetaProperty(const QMetaProperty &prop,
160  const QMetaObject *mo, int index)
161 {
162  return prop.isScriptable() && prop.isValid()
163  // the following lookup is to ensure that we have the
164  // "most derived" occurrence of the property with this name
165  && (mo->indexOfProperty(prop.name()) == index);
166 }
167 
175 static inline int methodNameLength(const QMetaMethod &method)
176 {
177  const char *signature = method.signature();
178  const char *s = signature;
179  while (*s && (*s != '('))
180  ++s;
181  return s - signature;
182 }
183 
191 static inline QByteArray methodName(const char *signature, int nameLength)
192 {
193  return QByteArray(signature, nameLength);
194 }
195 
205 static inline bool methodNameEquals(const QMetaMethod &method,
206  const char *signature, int nameLength)
207 {
208  const char *otherSignature = method.signature();
209  return !qstrncmp(otherSignature, signature, nameLength)
210  && (otherSignature[nameLength] == '(');
211 }
212 
213 static QVariant variantFromValue(JSC::ExecState *exec, int targetType, JSC::JSValue value)
214 {
215  QVariant v(targetType, (void *)0);
216  if (QScriptEnginePrivate::convertValue(exec, value, targetType, v.data()))
217  return v;
218  if (uint(targetType) == QVariant::LastType)
219  return QScriptEnginePrivate::toVariant(exec, value);
220  if (QScriptEnginePrivate::isVariant(value)) {
222  if (v.canConvert(QVariant::Type(targetType))) {
223  v.convert(QVariant::Type(targetType));
224  return v;
225  }
227  if (typeName.endsWith('*')
228  && (QMetaType::type(typeName.left(typeName.size()-1)) == targetType)) {
229  return QVariant(targetType, *reinterpret_cast<void* *>(v.data()));
230  }
231  }
232 
233  return QVariant();
234 }
235 
236 static const bool GeneratePropertyFunctions = true;
237 
238 static unsigned flagsForMetaProperty(const QMetaProperty &prop)
239 {
240  return (JSC::DontDelete
241  | (!prop.isWritable() ? unsigned(JSC::ReadOnly) : unsigned(0))
242  | (GeneratePropertyFunctions
243  ? unsigned(JSC::Getter | JSC::Setter)
244  : unsigned(0))
246 }
247 
248 static int indexOfMetaEnum(const QMetaObject *meta, const QByteArray &str)
249 {
250  QByteArray scope;
252  int scopeIdx = str.lastIndexOf("::");
253  if (scopeIdx != -1) {
254  scope = str.left(scopeIdx);
255  name = str.mid(scopeIdx + 2);
256  } else {
257  name = str;
258  }
259  for (int i = meta->enumeratorCount() - 1; i >= 0; --i) {
260  QMetaEnum m = meta->enumerator(i);
261  if ((m.name() == name) && (scope.isEmpty() || (m.scope() == scope)))
262  return i;
263  }
264  return -1;
265 }
266 
268 {
269  void *ptr = qobj->qt_metacast("QScriptable");
270  return reinterpret_cast<QScriptable*>(ptr);
271 }
272 
273 QtFunction::QtFunction(JSC::JSValue object, int initialIndex, bool maybeOverloaded,
274  JSC::JSGlobalData *data, WTF::PassRefPtr<JSC::Structure> sid,
275  const JSC::Identifier &ident)
276  : JSC::InternalFunction(data, sid, ident),
277  data(new Data(object, initialIndex, maybeOverloaded))
278 {
279 }
280 
282 {
283  delete data;
284 }
285 
286 JSC::CallType QtFunction::getCallData(JSC::CallData &callData)
287 {
288  callData.native.function = call;
289  return JSC::CallTypeHost;
290 }
291 
292 void QtFunction::markChildren(JSC::MarkStack& markStack)
293 {
294  if (data->object)
295  markStack.append(data->object);
296  JSC::InternalFunction::markChildren(markStack);
297 }
298 
300 {
301  Q_ASSERT(JSC::asObject(data->object)->inherits(&QScriptObject::info));
302  return static_cast<QScriptObject*>(JSC::asObject(data->object));
303 }
304 
306 {
307  QScriptObject *scriptObject = wrapperObject();
308  QScriptObjectDelegate *delegate = scriptObject->delegate();
309  Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::QtObject));
310  return static_cast<QScript::QObjectDelegate*>(delegate)->value();
311 }
312 
314 {
315  QObject *qobj = qobject();
316  if (!qobj)
317  return 0;
318  return qobj->metaObject();
319 }
320 
322 {
323  return data->initialIndex;
324 }
325 
327 {
328  return data->maybeOverloaded;
329 }
330 
332 {
333  const QMetaObject *meta = metaObject();
334  if (!meta)
335  return -1;
336  int index = initialIndex();
337  QMetaMethod method = meta->method(index);
338  if (maybeOverloaded() && (method.attributes() & QMetaMethod::Cloned)) {
339  // find the most general method
340  do {
341  method = meta->method(--index);
342  } while (method.attributes() & QMetaMethod::Cloned);
343  }
344  if (out)
345  *out = method;
346  return index;
347 }
348 
350 {
351  if (!maybeOverloaded())
352  return QList<int>();
353  QList<int> result;
354  const QMetaObject *meta = metaObject();
355  QMetaMethod method = meta->method(initialIndex());
356  int nameLength = methodNameLength(method);
357  for (int index = mostGeneralMethod() - 1; index >= 0; --index) {
358  if (methodNameEquals(meta->method(index), method.signature(), nameLength))
359  result.append(index);
360  }
361  return result;
362 }
363 
365 {
366 public:
367  enum Kind {
372  MetaEnum
373  };
374 
376  : m_kind(Invalid) { }
377 
378  inline Kind kind() const
379  { return m_kind; }
380 
381  int typeId() const;
382 
383  inline bool isValid() const
384  { return (m_kind != Invalid); }
385 
386  inline bool isVariant() const
387  { return (m_kind == Variant); }
388 
389  inline bool isMetaType() const
390  { return (m_kind == MetaType); }
391 
392  inline bool isUnresolved() const
393  { return (m_kind == Unresolved); }
394 
395  inline bool isMetaEnum() const
396  { return (m_kind == MetaEnum); }
397 
398  QByteArray name() const;
399 
400  inline int enumeratorIndex() const
401  { Q_ASSERT(isMetaEnum()); return m_typeId; }
402 
403  inline bool operator==(const QScriptMetaType &other) const
404  {
405  return (m_kind == other.m_kind) && (m_typeId == other.m_typeId);
406  }
407 
408  static inline QScriptMetaType variant()
409  { return QScriptMetaType(Variant); }
410 
411  static inline QScriptMetaType metaType(int typeId, const QByteArray &name)
412  { return QScriptMetaType(MetaType, typeId, name); }
413 
414  static inline QScriptMetaType metaEnum(int enumIndex, const QByteArray &name)
415  { return QScriptMetaType(MetaEnum, enumIndex, name); }
416 
417  static inline QScriptMetaType unresolved(const QByteArray &name)
418  { return QScriptMetaType(Unresolved, /*typeId=*/0, name); }
419 
420 private:
421  inline QScriptMetaType(Kind kind, int typeId = 0, const QByteArray &name = QByteArray())
422  : m_kind(kind), m_typeId(typeId), m_name(name) { }
423 
425  int m_typeId;
427 };
428 
430 {
431  if (isVariant())
432  return QMetaType::type("QVariant");
433  return isMetaEnum() ? 2/*int*/ : m_typeId;
434 }
435 
437 {
438  if (!m_name.isEmpty())
439  return m_name;
440  else if (m_kind == Variant)
441  return "QVariant";
442  return QMetaType::typeName(typeId());
443 }
444 
446 {
447 public:
449  { }
451  : m_types(types), m_firstUnresolvedIndex(-1)
452  {
454  for (it = m_types.constBegin(); it != m_types.constEnd(); ++it) {
455  if ((*it).kind() == QScriptMetaType::Unresolved) {
456  m_firstUnresolvedIndex = it - m_types.constBegin();
457  break;
458  }
459  }
460  }
461  inline bool isValid() const
462  { return !m_types.isEmpty(); }
463 
465  { return m_types.at(0); }
466 
467  inline int argumentCount() const
468  { return m_types.count() - 1; }
469 
470  inline QScriptMetaType argumentType(int arg) const
471  { return m_types.at(arg + 1); }
472 
473  inline bool fullyResolved() const
474  { return m_firstUnresolvedIndex == -1; }
475 
476  inline bool hasUnresolvedReturnType() const
477  { return (m_firstUnresolvedIndex == 0); }
478 
479  inline int firstUnresolvedIndex() const
480  { return m_firstUnresolvedIndex; }
481 
482  inline int count() const
483  { return m_types.count(); }
484 
485  inline QScriptMetaType type(int index) const
486  { return m_types.at(index); }
487 
489  { return m_types; }
490 
491 private:
494 };
495 
497 {
499  int index;
502 
503  inline QScriptMetaArguments(int dist, int idx, const QScriptMetaMethod &mtd,
505  : matchDistance(dist), index(idx), method(mtd), args(as) { }
507  : index(-1) { }
508 
509  inline bool isValid() const
510  { return (index != -1); }
511 };
512 
513 static QMetaMethod metaMethod(const QMetaObject *meta,
515  int index)
516 {
517  if (type != QMetaMethod::Constructor)
518  return meta->method(index);
519  else
520  return meta->constructor(index);
521 }
522 
523 static JSC::JSValue callQtMethod(JSC::ExecState *exec, QMetaMethod::MethodType callType,
524  QObject *thisQObject, const JSC::ArgList &scriptArgs,
525  const QMetaObject *meta, int initialIndex,
526  bool maybeOverloaded)
527 {
528  QScriptMetaMethod chosenMethod;
529  int chosenIndex = -1;
533  QVector<int> tooFewArgs;
534  QVector<int> conversionFailed;
535  int index;
536  int nameLength = 0;
537  const char *initialMethodSignature = 0;
538  exec->clearException();
540  for (index = initialIndex; index >= 0; --index) {
541  QMetaMethod method = metaMethod(meta, callType, index);
542 
543  if (index == initialIndex) {
544  initialMethodSignature = method.signature();
545  nameLength = methodNameLength(method);
546  } else {
547  if (!methodNameEquals(method, initialMethodSignature, nameLength))
548  continue;
549  }
550 
551  QList<QByteArray> parameterTypeNames = method.parameterTypes();
552 
554  types.resize(1 + parameterTypeNames.size());
555  QScriptMetaType *typesData = types.data();
556  // resolve return type
557  QByteArray returnTypeName = method.typeName();
558  int rtype = QMetaType::type(returnTypeName);
559  if ((rtype == 0) && !returnTypeName.isEmpty()) {
560  int enumIndex = indexOfMetaEnum(meta, returnTypeName);
561  if (enumIndex != -1)
562  typesData[0] = QScriptMetaType::metaEnum(enumIndex, returnTypeName);
563  else
564  typesData[0] = QScriptMetaType::unresolved(returnTypeName);
565  } else {
566  if (callType == QMetaMethod::Constructor)
567  typesData[0] = QScriptMetaType::metaType(QMetaType::QObjectStar, "QObject*");
568  else if (rtype == QMetaType::QVariant)
569  typesData[0] = QScriptMetaType::variant();
570  else
571  typesData[0] = QScriptMetaType::metaType(rtype, returnTypeName);
572  }
573 
574  // resolve argument types
575  for (int i = 0; i < parameterTypeNames.count(); ++i) {
576  QByteArray argTypeName = parameterTypeNames.at(i);
577  int atype = QMetaType::type(argTypeName);
578  if (atype == 0) {
579  int enumIndex = indexOfMetaEnum(meta, argTypeName);
580  if (enumIndex != -1)
581  typesData[1 + i] = QScriptMetaType::metaEnum(enumIndex, argTypeName);
582  else
583  typesData[1 + i] = QScriptMetaType::unresolved(argTypeName);
584  } else if (atype == QMetaType::QVariant) {
585  typesData[1 + i] = QScriptMetaType::variant();
586  } else {
587  typesData[1 + i] = QScriptMetaType::metaType(atype, argTypeName);
588  }
589  }
590 
592 
593  if (int(scriptArgs.size()) < mtd.argumentCount()) {
594  tooFewArgs.append(index);
595  continue;
596  }
597 
598  if (!mtd.fullyResolved()) {
599  // remember it so we can give an error message later, if necessary
600  unresolved.append(QScriptMetaArguments(/*matchDistance=*/INT_MAX, index,
602  if (mtd.hasUnresolvedReturnType())
603  continue;
604  }
605 
606  if (args.count() != mtd.count())
607  args.resize(mtd.count());
608 
609  QScriptMetaType retType = mtd.returnType();
610  args[0] = QVariant(retType.typeId(), (void *)0); // the result
611 
612  // try to convert arguments
613  bool converted = true;
614  int matchDistance = 0;
615  for (int i = 0; converted && i < mtd.argumentCount(); ++i) {
616  JSC::JSValue actual;
617  if (i < (int)scriptArgs.size())
618  actual = scriptArgs.at(i);
619  else
620  actual = JSC::jsUndefined();
621  QScriptMetaType argType = mtd.argumentType(i);
622  int tid = -1;
623  QVariant v;
624  if (argType.isUnresolved()) {
625  v = QVariant(QMetaType::QObjectStar, (void *)0);
627  exec, actual, argType.name(), reinterpret_cast<void* *>(v.data()));
628  } else if (argType.isVariant()) {
629  if (QScriptEnginePrivate::isVariant(actual)) {
631  } else {
632  v = QScriptEnginePrivate::toVariant(exec, actual);
633  converted = v.isValid() || actual.isUndefined() || actual.isNull();
634  }
635  } else {
636  tid = argType.typeId();
637  v = QVariant(tid, (void *)0);
638  converted = QScriptEnginePrivate::convertValue(exec, actual, tid, v.data());
639  if (exec->hadException())
640  return exec->exception();
641  }
642 
643  if (!converted) {
644  if (QScriptEnginePrivate::isVariant(actual)) {
645  if (tid == -1)
646  tid = argType.typeId();
648  if (vv.canConvert(QVariant::Type(tid))) {
649  v = vv;
650  converted = v.convert(QVariant::Type(tid));
651  if (converted && (vv.userType() != tid))
652  matchDistance += 10;
653  } else {
654  QByteArray vvTypeName = vv.typeName();
655  if (vvTypeName.endsWith('*')
656  && (vvTypeName.left(vvTypeName.size()-1) == argType.name())) {
657  v = QVariant(tid, *reinterpret_cast<void* *>(vv.data()));
658  converted = true;
659  matchDistance += 10;
660  }
661  }
662  } else if (actual.isNumber() || actual.isString()) {
663  // see if it's an enum value
664  QMetaEnum m;
665  if (argType.isMetaEnum()) {
666  m = meta->enumerator(argType.enumeratorIndex());
667  } else {
668  int mi = indexOfMetaEnum(meta, argType.name());
669  if (mi != -1)
670  m = meta->enumerator(mi);
671  }
672  if (m.isValid()) {
673  if (actual.isNumber()) {
674  int ival = QScriptEnginePrivate::toInt32(exec, actual);
675  if (m.valueToKey(ival) != 0) {
676  v.setValue(ival);
677  converted = true;
678  matchDistance += 10;
679  }
680  } else {
681  JSC::UString sval = QScriptEnginePrivate::toString(exec, actual);
682  int ival = m.keyToValue(convertToLatin1(sval));
683  if (ival != -1) {
684  v.setValue(ival);
685  converted = true;
686  matchDistance += 10;
687  }
688  }
689  }
690  }
691  } else {
692  // determine how well the conversion matched
693  if (actual.isNumber()) {
694  switch (tid) {
695  case QMetaType::Double:
696  // perfect
697  break;
698  case QMetaType::Float:
699  matchDistance += 1;
700  break;
701  case QMetaType::LongLong:
703  matchDistance += 2;
704  break;
705  case QMetaType::Long:
706  case QMetaType::ULong:
707  matchDistance += 3;
708  break;
709  case QMetaType::Int:
710  case QMetaType::UInt:
711  matchDistance += 4;
712  break;
713  case QMetaType::Short:
714  case QMetaType::UShort:
715  matchDistance += 5;
716  break;
717  case QMetaType::Char:
718  case QMetaType::UChar:
719  matchDistance += 6;
720  break;
721  default:
722  matchDistance += 10;
723  break;
724  }
725  } else if (actual.isString()) {
726  switch (tid) {
727  case QMetaType::QString:
728  // perfect
729  break;
730  default:
731  matchDistance += 10;
732  break;
733  }
734  } else if (actual.isBoolean()) {
735  switch (tid) {
736  case QMetaType::Bool:
737  // perfect
738  break;
739  default:
740  matchDistance += 10;
741  break;
742  }
743  } else if (QScriptEnginePrivate::isDate(actual)) {
744  switch (tid) {
746  // perfect
747  break;
748  case QMetaType::QDate:
749  matchDistance += 1;
750  break;
751  case QMetaType::QTime:
752  matchDistance += 2;
753  break;
754  default:
755  matchDistance += 10;
756  break;
757  }
758  } else if (QScriptEnginePrivate::isRegExp(actual)) {
759  switch (tid) {
760  case QMetaType::QRegExp:
761  // perfect
762  break;
763  default:
764  matchDistance += 10;
765  break;
766  }
767  } else if (QScriptEnginePrivate::isVariant(actual)) {
768  if (argType.isVariant()
769  || (QScriptEnginePrivate::toVariant(exec, actual).userType() == tid)) {
770  // perfect
771  } else {
772  matchDistance += 10;
773  }
774  } else if (QScriptEnginePrivate::isArray(actual)) {
775  switch (tid) {
778  matchDistance += 5;
779  break;
780  default:
781  matchDistance += 10;
782  break;
783  }
784  } else if (QScriptEnginePrivate::isQObject(actual)) {
785  switch (tid) {
788  // perfect
789  break;
790  default:
791  matchDistance += 10;
792  break;
793  }
794  } else if (actual.isNull()) {
795  switch (tid) {
796  case QMetaType::VoidStar:
799  // perfect
800  break;
801  default:
802  if (!argType.name().endsWith('*'))
803  matchDistance += 10;
804  break;
805  }
806  } else {
807  matchDistance += 10;
808  }
809  }
810 
811  if (converted)
812  args[i+1] = v;
813  }
814 
815  if (converted) {
816  if ((scriptArgs.size() == (size_t)mtd.argumentCount())
817  && (matchDistance == 0)) {
818  // perfect match, use this one
819  chosenMethod = mtd;
820  chosenIndex = index;
821  break;
822  } else {
823  bool redundant = false;
824  if ((callType != QMetaMethod::Constructor)
825  && (index < meta->methodOffset())) {
826  // it is possible that a virtual method is redeclared in a subclass,
827  // in which case we want to ignore the superclass declaration
828  for (int i = 0; i < candidates.size(); ++i) {
829  const QScriptMetaArguments &other = candidates.at(i);
830  if (mtd.types() == other.method.types()) {
831  redundant = true;
832  break;
833  }
834  }
835  }
836  if (!redundant) {
837  QScriptMetaArguments metaArgs(matchDistance, index, mtd, args);
838  if (candidates.isEmpty()) {
839  candidates.append(metaArgs);
840  } else {
841  const QScriptMetaArguments &otherArgs = candidates.at(0);
842  if ((args.count() > otherArgs.args.count())
843  || ((args.count() == otherArgs.args.count())
844  && (matchDistance <= otherArgs.matchDistance))) {
845  candidates.prepend(metaArgs);
846  } else {
847  candidates.append(metaArgs);
848  }
849  }
850  }
851  }
852  } else if (mtd.fullyResolved()) {
853  conversionFailed.append(index);
854  }
855 
856  if (!maybeOverloaded)
857  break;
858  }
859 
860  JSC::JSValue result;
861  if ((chosenIndex == -1) && candidates.isEmpty()) {
862 // context->calleeMetaIndex = initialIndex;
863 //#ifndef Q_SCRIPT_NO_EVENT_NOTIFY
864 // engine->notifyFunctionEntry(context);
865 //#endif
866  QString funName = QString::fromLatin1(methodName(initialMethodSignature, nameLength));
867  if (!conversionFailed.isEmpty()) {
868  QString message = QString::fromLatin1("incompatible type of argument(s) in call to %0(); candidates were\n")
869  .arg(funName);
870  for (int i = 0; i < conversionFailed.size(); ++i) {
871  if (i > 0)
872  message += QLatin1String("\n");
873  QMetaMethod mtd = metaMethod(meta, callType, conversionFailed.at(i));
874  message += QString::fromLatin1(" %0").arg(QString::fromLatin1(mtd.signature()));
875  }
876  result = JSC::throwError(exec, JSC::TypeError, message);
877  } else if (!unresolved.isEmpty()) {
878  QScriptMetaArguments argsInstance = unresolved.first();
879  int unresolvedIndex = argsInstance.method.firstUnresolvedIndex();
880  Q_ASSERT(unresolvedIndex != -1);
881  QScriptMetaType unresolvedType = argsInstance.method.type(unresolvedIndex);
882  QString unresolvedTypeName = QString::fromLatin1(unresolvedType.name());
883  QString message = QString::fromLatin1("cannot call %0(): ")
884  .arg(funName);
885  if (unresolvedIndex > 0) {
886  message.append(QString::fromLatin1("argument %0 has unknown type `%1'").
887  arg(unresolvedIndex).arg(unresolvedTypeName));
888  } else {
889  message.append(QString::fromLatin1("unknown return type `%0'")
890  .arg(unresolvedTypeName));
891  }
892  message.append(QString::fromLatin1(" (register the type with qScriptRegisterMetaType())"));
893  result = JSC::throwError(exec, JSC::TypeError, message);
894  } else {
895  QString message = QString::fromLatin1("too few arguments in call to %0(); candidates are\n")
896  .arg(funName);
897  for (int i = 0; i < tooFewArgs.size(); ++i) {
898  if (i > 0)
899  message += QLatin1String("\n");
900  QMetaMethod mtd = metaMethod(meta, callType, tooFewArgs.at(i));
901  message += QString::fromLatin1(" %0").arg(QString::fromLatin1(mtd.signature()));
902  }
903  result = JSC::throwError(exec, JSC::SyntaxError, message);
904  }
905  } else {
906  if (chosenIndex == -1) {
907  QScriptMetaArguments metaArgs = candidates.at(0);
908  if ((candidates.size() > 1)
909  && (metaArgs.args.count() == candidates.at(1).args.count())
910  && (metaArgs.matchDistance == candidates.at(1).matchDistance)) {
911  // ambiguous call
912  QByteArray funName = methodName(initialMethodSignature, nameLength);
913  QString message = QString::fromLatin1("ambiguous call of overloaded function %0(); candidates were\n")
914  .arg(QLatin1String(funName));
915  for (int i = 0; i < candidates.size(); ++i) {
916  if (i > 0)
917  message += QLatin1String("\n");
918  QMetaMethod mtd = metaMethod(meta, callType, candidates.at(i).index);
919  message += QString::fromLatin1(" %0").arg(QString::fromLatin1(mtd.signature()));
920  }
921  result = JSC::throwError(exec, JSC::TypeError, message);
922  } else {
923  chosenMethod = metaArgs.method;
924  chosenIndex = metaArgs.index;
925  args = metaArgs.args;
926  }
927  }
928 
929  if (chosenIndex != -1) {
930  // call it
931 // context->calleeMetaIndex = chosenIndex;
932 
933  QVarLengthArray<void*, 9> array(args.count());
934  void **params = array.data();
935  for (int i = 0; i < args.count(); ++i) {
936  const QVariant &v = args[i];
937  switch (chosenMethod.type(i).kind()) {
939  params[i] = const_cast<QVariant*>(&v);
940  break;
944  params[i] = const_cast<void*>(v.constData());
945  break;
946  default:
947  Q_ASSERT(0);
948  }
949  }
950 
951  QScriptable *scriptable = 0;
952  if (thisQObject)
953  scriptable = scriptableFromQObject(thisQObject);
954  QScriptEngine *oldEngine = 0;
955  if (scriptable) {
956  oldEngine = QScriptablePrivate::get(scriptable)->engine;
958  }
959 
960 // ### fixme
961 //#ifndef Q_SCRIPT_NO_EVENT_NOTIFY
962 // engine->notifyFunctionEntry(context);
963 //#endif
964 
965  if (callType == QMetaMethod::Constructor) {
966  Q_ASSERT(meta != 0);
967  meta->static_metacall(QMetaObject::CreateInstance, chosenIndex, params);
968  } else {
969  QMetaObject::metacall(thisQObject, QMetaObject::InvokeMetaMethod, chosenIndex, params);
970  }
971 
972  if (scriptable)
973  QScriptablePrivate::get(scriptable)->engine = oldEngine;
974 
975  if (exec->hadException()) {
976  result = exec->exception() ; // propagate
977  } else {
978  QScriptMetaType retType = chosenMethod.returnType();
979  if (retType.isVariant()) {
980  result = QScriptEnginePrivate::jscValueFromVariant(exec, *(QVariant *)params[0]);
981  } else if (retType.typeId() != 0) {
982  result = QScriptEnginePrivate::create(exec, retType.typeId(), params[0]);
983  if (!result)
984  result = engine->newVariant(QVariant(retType.typeId(), params[0]));
985  } else {
986  result = JSC::jsUndefined();
987  }
988  }
989  }
990  }
991 
992  return result;
993 }
994 
995 JSC::JSValue QtFunction::execute(JSC::ExecState *exec, JSC::JSValue thisValue,
996  const JSC::ArgList &scriptArgs)
997 {
999  QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(data->object));
1000  QScriptObjectDelegate *delegate = scriptObject->delegate();
1001  Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::QtObject));
1002  QObject *qobj = static_cast<QScript::QObjectDelegate*>(delegate)->value();
1003  if (!qobj)
1004  return JSC::throwError(exec, JSC::GeneralError, QString::fromLatin1("cannot call function of deleted QObject"));
1006 
1007  const QMetaObject *meta = qobj->metaObject();
1008  QObject *thisQObject = 0;
1009  thisValue = engine->toUsableValue(thisValue);
1010  if (thisValue.inherits(&QScriptObject::info)) {
1011  delegate = static_cast<QScriptObject*>(JSC::asObject(thisValue))->delegate();
1012  if (delegate && (delegate->type() == QScriptObjectDelegate::QtObject))
1013  thisQObject = static_cast<QScript::QObjectDelegate*>(delegate)->value();
1014  }
1015  if (!thisQObject)
1016  thisQObject = qobj; // ### TypeError
1017 
1018  if (!meta->cast(thisQObject)) {
1019  // invoking a function in the prototype
1020  thisQObject = qobj;
1021  }
1022 
1023  return callQtMethod(exec, QMetaMethod::Method, thisQObject, scriptArgs,
1025 }
1026 
1027 const JSC::ClassInfo QtFunction::info = { "QtFunction", &InternalFunction::info, 0, 0 };
1028 
1029 JSC::JSValue JSC_HOST_CALL QtFunction::call(JSC::ExecState *exec, JSC::JSObject *callee,
1030  JSC::JSValue thisValue, const JSC::ArgList &args)
1031 {
1032  if (!callee->inherits(&QtFunction::info))
1033  return throwError(exec, JSC::TypeError, "callee is not a QtFunction object");
1034  QtFunction *qfun = static_cast<QtFunction*>(callee);
1036  JSC::ExecState *previousFrame = eng_p->currentFrame;
1037  eng_p->currentFrame = exec;
1038  eng_p->pushContext(exec, thisValue, args, callee);
1039  JSC::JSValue result = qfun->execute(eng_p->currentFrame, thisValue, args);
1040  eng_p->popContext();
1041  eng_p->currentFrame = previousFrame;
1042  return result;
1043 }
1044 
1045 const JSC::ClassInfo QtPropertyFunction::info = { "QtPropertyFunction", &InternalFunction::info, 0, 0 };
1046 
1048  JSC::JSGlobalData *data,
1049  WTF::PassRefPtr<JSC::Structure> sid,
1050  const JSC::Identifier &ident)
1051  : JSC::InternalFunction(data, sid, ident),
1052  data(new Data(meta, index))
1053 {
1054 }
1055 
1057 {
1058  delete data;
1059 }
1060 
1061 JSC::CallType QtPropertyFunction::getCallData(JSC::CallData &callData)
1062 {
1063  callData.native.function = call;
1064  return JSC::CallTypeHost;
1065 }
1066 
1067 JSC::JSValue JSC_HOST_CALL QtPropertyFunction::call(
1068  JSC::ExecState *exec, JSC::JSObject *callee,
1069  JSC::JSValue thisValue, const JSC::ArgList &args)
1070 {
1071  if (!callee->inherits(&QtPropertyFunction::info))
1072  return throwError(exec, JSC::TypeError, "callee is not a QtPropertyFunction object");
1073  QtPropertyFunction *qfun = static_cast<QtPropertyFunction*>(callee);
1074  return qfun->execute(exec, thisValue, args);
1075 }
1076 
1077 JSC::JSValue QtPropertyFunction::execute(JSC::ExecState *exec,
1078  JSC::JSValue thisValue,
1079  const JSC::ArgList &args)
1080 {
1081  JSC::JSValue result = JSC::jsUndefined();
1082 
1084  JSC::ExecState *previousFrame = engine->currentFrame;
1085  engine->currentFrame = exec;
1086 
1087  JSC::JSValue qobjectValue = engine->toUsableValue(thisValue);
1088  QObject *qobject = QScriptEnginePrivate::toQObject(exec, qobjectValue);
1089  while ((!qobject || (qobject->metaObject() != data->meta))
1090  && JSC::asObject(qobjectValue)->prototype().isObject()) {
1091  qobjectValue = JSC::asObject(qobjectValue)->prototype();
1092  qobject = QScriptEnginePrivate::toQObject(exec, qobjectValue);
1093  }
1094  Q_ASSERT_X(qobject, Q_FUNC_INFO, "this-object must be a QObject");
1095 
1097  Q_ASSERT(prop.isScriptable());
1098  if (args.size() == 0) {
1099  // get
1100  if (prop.isValid()) {
1101  QScriptable *scriptable = scriptableFromQObject(qobject);
1102  QScriptEngine *oldEngine = 0;
1103  if (scriptable) {
1104  engine->pushContext(exec, thisValue, args, this);
1105  oldEngine = QScriptablePrivate::get(scriptable)->engine;
1107  }
1108 
1109  QVariant v = prop.read(qobject);
1110 
1111  if (scriptable) {
1112  QScriptablePrivate::get(scriptable)->engine = oldEngine;
1113  engine->popContext();
1114  }
1115 
1117  }
1118  } else {
1119  // set
1120  JSC::JSValue arg = args.at(0);
1121  QVariant v;
1122  if (prop.isEnumType() && arg.isString()
1123  && !engine->hasDemarshalFunction(prop.userType())) {
1124  // give QMetaProperty::write() a chance to convert from
1125  // string to enum value
1126  v = (QString)arg.toString(exec);
1127  } else {
1128  v = variantFromValue(exec, prop.userType(), arg);
1129  }
1130 
1131  QScriptable *scriptable = scriptableFromQObject(qobject);
1132  QScriptEngine *oldEngine = 0;
1133  if (scriptable) {
1134  engine->pushContext(exec, thisValue, args, this);
1135  oldEngine = QScriptablePrivate::get(scriptable)->engine;
1137  }
1138 
1139  prop.write(qobject, v);
1140 
1141  if (scriptable) {
1142  QScriptablePrivate::get(scriptable)->engine = oldEngine;
1143  engine->popContext();
1144  }
1145 
1146  result = arg;
1147  }
1148  engine->currentFrame = previousFrame;
1149  return result;
1150 }
1151 
1153 {
1154  return data->meta;
1155 }
1156 
1158 {
1159  return data->index;
1160 }
1161 
1162 
1164  QObject *object, QScriptEngine::ValueOwnership ownership,
1165  const QScriptEngine::QObjectWrapOptions &options)
1166  : data(new Data(object, ownership, options))
1167 {
1168 }
1169 
1171 {
1172  switch (data->ownership) {
1174  break;
1176  if (data->value)
1177  delete data->value; // ### fixme
1178 // eng->disposeQObject(value);
1179  break;
1181  if (data->value && !data->value->parent())
1182  delete data->value; // ### fixme
1183 // eng->disposeQObject(value);
1184  break;
1185  }
1186  delete data;
1187 }
1188 
1190 {
1191  return QtObject;
1192 }
1193 
1194 bool QObjectDelegate::getOwnPropertySlot(QScriptObject *object, JSC::ExecState *exec,
1195  const JSC::Identifier &propertyName,
1196  JSC::PropertySlot &slot)
1197 {
1198  //Note: this has to be kept in sync with getOwnPropertyDescriptor
1199 #ifndef QT_NO_PROPERTIES
1200  QByteArray name = convertToLatin1(propertyName.ustring());
1201  QObject *qobject = data->value;
1202  if (!qobject) {
1203  QString message = QString::fromLatin1("cannot access member `%0' of deleted QObject")
1204  .arg(QString::fromLatin1(name));
1205  slot.setValue(JSC::throwError(exec, JSC::GeneralError, message));
1206  return true;
1207  }
1208 
1209  const QMetaObject *meta = qobject->metaObject();
1210  {
1212  if (it != data->cachedMembers.constEnd()) {
1213  if (GeneratePropertyFunctions && (meta->indexOfProperty(name) != -1))
1214  slot.setGetterSlot(JSC::asObject(it.value()));
1215  else
1216  slot.setValue(it.value());
1217  return true;
1218  }
1219  }
1220 
1221  const QScriptEngine::QObjectWrapOptions &opt = data->options;
1223  int index = -1;
1224  if (name.contains('(')) {
1225  QByteArray normalized = QMetaObject::normalizedSignature(name);
1226  if (-1 != (index = meta->indexOfMethod(normalized))) {
1227  QMetaMethod method = meta->method(index);
1228  if (hasMethodAccess(method, index, opt)) {
1230  || (index >= meta->methodOffset())) {
1231  QtFunction *fun = new (exec)QtFunction(
1232  object, index, /*maybeOverloaded=*/false,
1233  &exec->globalData(), eng->originalGlobalObject()->functionStructure(),
1234  propertyName);
1235  slot.setValue(fun);
1236  data->cachedMembers.insert(name, fun);
1237  return true;
1238  }
1239  }
1240  }
1241  }
1242 
1243  index = meta->indexOfProperty(name);
1244  if (index != -1) {
1245  QMetaProperty prop = meta->property(index);
1246  if (prop.isScriptable()) {
1248  || (index >= meta->propertyOffset())) {
1249  if (GeneratePropertyFunctions) {
1250  QtPropertyFunction *fun = new (exec)QtPropertyFunction(
1251  meta, index, &exec->globalData(),
1252  eng->originalGlobalObject()->functionStructure(),
1253  propertyName);
1254  data->cachedMembers.insert(name, fun);
1255  slot.setGetterSlot(fun);
1256  } else {
1257  JSC::JSValue val;
1258  if (!prop.isValid())
1259  val = JSC::jsUndefined();
1260  else
1261  val = QScriptEnginePrivate::jscValueFromVariant(exec, prop.read(qobject));
1262  slot.setValue(val);
1263  }
1264  return true;
1265  }
1266  }
1267  }
1268 
1269  index = qobject->dynamicPropertyNames().indexOf(name);
1270  if (index != -1) {
1271  JSC::JSValue val = QScriptEnginePrivate::jscValueFromVariant(exec, qobject->property(name));
1272  slot.setValue(val);
1273  return true;
1274  }
1275 
1276  const int offset = (opt & QScriptEngine::ExcludeSuperClassMethods)
1277  ? meta->methodOffset() : 0;
1278  for (index = meta->methodCount() - 1; index >= offset; --index) {
1279  QMetaMethod method = meta->method(index);
1280  if (hasMethodAccess(method, index, opt)
1281  && methodNameEquals(method, name.constData(), name.length())) {
1282  QtFunction *fun = new (exec)QtFunction(
1283  object, index, /*maybeOverloaded=*/true,
1284  &exec->globalData(), eng->originalGlobalObject()->functionStructure(),
1285  propertyName);
1286  slot.setValue(fun);
1287  data->cachedMembers.insert(name, fun);
1288  return true;
1289  }
1290  }
1291 
1292  if (!(opt & QScriptEngine::ExcludeChildObjects)) {
1293  QList<QObject*> children = qobject->children();
1294  for (index = 0; index < children.count(); ++index) {
1295  QObject *child = children.at(index);
1296  if (child->objectName() == QString(propertyName.ustring())) {
1297  QScriptEngine::QObjectWrapOptions opt = QScriptEngine::PreferExistingWrapperObject;
1298  slot.setValue(eng->newQObject(child, QScriptEngine::QtOwnership, opt));
1299  return true;
1300  }
1301  }
1302  }
1303 
1304  return QScriptObjectDelegate::getOwnPropertySlot(object, exec, propertyName, slot);
1305 #else //QT_NO_PROPERTIES
1306  return false;
1307 #endif //QT_NO_PROPERTIES
1308 }
1309 
1310 
1312  const JSC::Identifier &propertyName,
1313  JSC::PropertyDescriptor &descriptor)
1314 {
1315  //Note: this has to be kept in sync with getOwnPropertySlot
1316 #ifndef QT_NO_PROPERTIES
1317  QByteArray name = convertToLatin1(propertyName.ustring());
1318  QObject *qobject = data->value;
1319  if (!qobject) {
1320  QString message = QString::fromLatin1("cannot access member `%0' of deleted QObject")
1321  .arg(QString::fromLatin1(name));
1322  descriptor.setValue(JSC::throwError(exec, JSC::GeneralError, message));
1323  return true;
1324  }
1325 
1326  const QScriptEngine::QObjectWrapOptions &opt = data->options;
1327 
1328  const QMetaObject *meta = qobject->metaObject();
1329  {
1331  if (it != data->cachedMembers.constEnd()) {
1332  int index;
1333  if (GeneratePropertyFunctions && ((index = meta->indexOfProperty(name)) != -1)) {
1334  QMetaProperty prop = meta->property(index);
1335  descriptor.setAccessorDescriptor(it.value(), it.value(), flagsForMetaProperty(prop));
1336  if (!prop.isWritable())
1337  descriptor.setWritable(false);
1338  } else {
1339  unsigned attributes = QObjectMemberAttribute;
1341  attributes |= JSC::DontEnum;
1342  descriptor.setDescriptor(it.value(), attributes);
1343  }
1344  return true;
1345  }
1346  }
1347 
1349  int index = -1;
1350  if (name.contains('(')) {
1351  QByteArray normalized = QMetaObject::normalizedSignature(name);
1352  if (-1 != (index = meta->indexOfMethod(normalized))) {
1353  QMetaMethod method = meta->method(index);
1354  if (hasMethodAccess(method, index, opt)) {
1356  || (index >= meta->methodOffset())) {
1357  QtFunction *fun = new (exec)QtFunction(
1358  object, index, /*maybeOverloaded=*/false,
1359  &exec->globalData(), eng->originalGlobalObject()->functionStructure(),
1360  propertyName);
1361  data->cachedMembers.insert(name, fun);
1362  unsigned attributes = QObjectMemberAttribute;
1364  attributes |= JSC::DontEnum;
1365  descriptor.setDescriptor(fun, attributes);
1366  return true;
1367  }
1368  }
1369  }
1370  }
1371 
1372  index = meta->indexOfProperty(name);
1373  if (index != -1) {
1374  QMetaProperty prop = meta->property(index);
1375  if (prop.isScriptable()) {
1377  || (index >= meta->propertyOffset())) {
1378  unsigned attributes = flagsForMetaProperty(prop);
1379  if (GeneratePropertyFunctions) {
1380  QtPropertyFunction *fun = new (exec)QtPropertyFunction(
1381  meta, index, &exec->globalData(),
1382  eng->originalGlobalObject()->functionStructure(),
1383  propertyName);
1384  data->cachedMembers.insert(name, fun);
1385  descriptor.setAccessorDescriptor(fun, fun, attributes);
1386  if (attributes & JSC::ReadOnly)
1387  descriptor.setWritable(false);
1388  } else {
1389  JSC::JSValue val;
1390  if (!prop.isValid())
1391  val = JSC::jsUndefined();
1392  else
1393  val = QScriptEnginePrivate::jscValueFromVariant(exec, prop.read(qobject));
1394  descriptor.setDescriptor(val, attributes);
1395  }
1396  return true;
1397  }
1398  }
1399  }
1400 
1401  index = qobject->dynamicPropertyNames().indexOf(name);
1402  if (index != -1) {
1403  JSC::JSValue val = QScriptEnginePrivate::jscValueFromVariant(exec, qobject->property(name));
1404  descriptor.setDescriptor(val, QObjectMemberAttribute);
1405  return true;
1406  }
1407 
1408  const int offset = (opt & QScriptEngine::ExcludeSuperClassMethods)
1409  ? meta->methodOffset() : 0;
1410  for (index = meta->methodCount() - 1; index >= offset; --index) {
1411  QMetaMethod method = meta->method(index);
1412  if (hasMethodAccess(method, index, opt)
1413  && methodNameEquals(method, name.constData(), name.length())) {
1414  QtFunction *fun = new (exec)QtFunction(
1415  object, index, /*maybeOverloaded=*/true,
1416  &exec->globalData(), eng->originalGlobalObject()->functionStructure(),
1417  propertyName);
1418  unsigned attributes = QObjectMemberAttribute;
1420  attributes |= JSC::DontEnum;
1421  descriptor.setDescriptor(fun, attributes);
1422  data->cachedMembers.insert(name, fun);
1423  return true;
1424  }
1425  }
1426 
1427  if (!(opt & QScriptEngine::ExcludeChildObjects)) {
1428  QList<QObject*> children = qobject->children();
1429  for (index = 0; index < children.count(); ++index) {
1430  QObject *child = children.at(index);
1431  if (child->objectName() == QString(propertyName.ustring())) {
1432  QScriptEngine::QObjectWrapOptions opt = QScriptEngine::PreferExistingWrapperObject;
1433  descriptor.setDescriptor(eng->newQObject(child, QScriptEngine::QtOwnership, opt),
1434  JSC::ReadOnly | JSC::DontDelete | JSC::DontEnum);
1435  return true;
1436  }
1437  }
1438  }
1439 
1440  return QScriptObjectDelegate::getOwnPropertyDescriptor(object, exec, propertyName, descriptor);
1441 #else //QT_NO_PROPERTIES
1442  return false;
1443 #endif //QT_NO_PROPERTIES
1444 }
1445 
1446 void QObjectDelegate::put(QScriptObject *object, JSC::ExecState* exec,
1447  const JSC::Identifier& propertyName,
1448  JSC::JSValue value, JSC::PutPropertySlot &slot)
1449 {
1450 #ifndef QT_NO_PROPERTIES
1451  QByteArray name = convertToLatin1(propertyName.ustring());
1452  QObject *qobject = data->value;
1453  if (!qobject) {
1454  QString message = QString::fromLatin1("cannot access member `%0' of deleted QObject")
1455  .arg(QString::fromLatin1(name));
1456  JSC::throwError(exec, JSC::GeneralError, message);
1457  return;
1458  }
1459 
1460  const QScriptEngine::QObjectWrapOptions &opt = data->options;
1461  const QMetaObject *meta = qobject->metaObject();
1463  int index = -1;
1464  if (name.contains('(')) {
1465  QByteArray normalized = QMetaObject::normalizedSignature(name);
1466  if (-1 != (index = meta->indexOfMethod(normalized))) {
1467  QMetaMethod method = meta->method(index);
1468  if (hasMethodAccess(method, index, opt)) {
1470  || (index >= meta->methodOffset())) {
1471  data->cachedMembers.insert(name, value);
1472  return;
1473  }
1474  }
1475  }
1476  }
1477 
1478  index = meta->indexOfProperty(name);
1479  if (index != -1) {
1480  QMetaProperty prop = meta->property(index);
1481  if (prop.isScriptable()) {
1483  || (index >= meta->propertyOffset())) {
1484  if (GeneratePropertyFunctions) {
1485  // ### ideally JSC would do this for us already, i.e. find out
1486  // that the property is a setter and call the setter.
1487  // Maybe QtPropertyFunction needs to inherit JSC::GetterSetter.
1488  JSC::JSValue fun;
1490  it = data->cachedMembers.constFind(name);
1491  if (it != data->cachedMembers.constEnd()) {
1492  fun = it.value();
1493  } else {
1494  fun = new (exec)QtPropertyFunction(
1495  meta, index, &exec->globalData(),
1496  eng->originalGlobalObject()->functionStructure(),
1497  propertyName);
1498  data->cachedMembers.insert(name, fun);
1499  }
1500  JSC::CallData callData;
1501  JSC::CallType callType = fun.getCallData(callData);
1502  JSC::JSValue argv[1] = { value };
1503  JSC::ArgList args(argv, 1);
1504  (void)JSC::call(exec, fun, callType, callData, object, args);
1505  } else {
1506  QVariant v;
1507  if (prop.isEnumType() && value.isString()
1508  && !eng->hasDemarshalFunction(prop.userType())) {
1509  // give QMetaProperty::write() a chance to convert from
1510  // string to enum value
1511  v = (QString)value.toString(exec);
1512  } else {
1513  v = QScriptEnginePrivate::jscValueToVariant(exec, value, prop.userType());
1514  }
1515  (void)prop.write(qobject, v);
1516  }
1517  return;
1518  }
1519  }
1520  }
1521 
1522  const int offset = (opt & QScriptEngine::ExcludeSuperClassMethods)
1523  ? meta->methodOffset() : 0;
1524  for (index = meta->methodCount() - 1; index >= offset; --index) {
1525  QMetaMethod method = meta->method(index);
1526  if (hasMethodAccess(method, index, opt)
1527  && methodNameEquals(method, name.constData(), name.length())) {
1528  data->cachedMembers.insert(name, value);
1529  return;
1530  }
1531  }
1532 
1533  index = qobject->dynamicPropertyNames().indexOf(name);
1534  if ((index != -1) || (opt & QScriptEngine::AutoCreateDynamicProperties)) {
1535  QVariant v = QScriptEnginePrivate::toVariant(exec, value);
1536  (void)qobject->setProperty(name, v);
1537  return;
1538  }
1539 
1540  QScriptObjectDelegate::put(object, exec, propertyName, value, slot);
1541 #endif //QT_NO_PROPERTIES
1542 }
1543 
1544 bool QObjectDelegate::deleteProperty(QScriptObject *object, JSC::ExecState *exec,
1545  const JSC::Identifier& propertyName)
1546 {
1547 #ifndef QT_NO_PROPERTIES
1548  QByteArray name = convertToLatin1(propertyName.ustring());
1549  QObject *qobject = data->value;
1550  if (!qobject) {
1551  QString message = QString::fromLatin1("cannot access member `%0' of deleted QObject")
1552  .arg(QString::fromLatin1(name));
1553  JSC::throwError(exec, JSC::GeneralError, message);
1554  return false;
1555  }
1556 
1557  const QMetaObject *meta = qobject->metaObject();
1558  {
1560  if (it != data->cachedMembers.end()) {
1561  if (GeneratePropertyFunctions && (meta->indexOfProperty(name) != -1))
1562  return false;
1563  data->cachedMembers.erase(it);
1564  return true;
1565  }
1566  }
1567 
1568  const QScriptEngine::QObjectWrapOptions &opt = data->options;
1569  int index = meta->indexOfProperty(name);
1570  if (index != -1) {
1571  QMetaProperty prop = meta->property(index);
1572  if (prop.isScriptable() &&
1574  || (index >= meta->propertyOffset()))) {
1575  return false;
1576  }
1577  }
1578 
1579  index = qobject->dynamicPropertyNames().indexOf(name);
1580  if (index != -1) {
1581  (void)qobject->setProperty(name, QVariant());
1582  return true;
1583  }
1584 
1585  return QScriptObjectDelegate::deleteProperty(object, exec, propertyName);
1586 #else //QT_NO_PROPERTIES
1587  return false;
1588 #endif //QT_NO_PROPERTIES
1589 }
1590 
1591 void QObjectDelegate::getOwnPropertyNames(QScriptObject *object, JSC::ExecState *exec,
1592  JSC::PropertyNameArray &propertyNames,
1593  JSC::EnumerationMode mode)
1594 {
1595 #ifndef QT_NO_PROPERTIES
1596  QObject *qobject = data->value;
1597  if (!qobject) {
1598  QString message = QString::fromLatin1("cannot get property names of deleted QObject");
1599  JSC::throwError(exec, JSC::GeneralError, message);
1600  return;
1601  }
1602 
1603  const QScriptEngine::QObjectWrapOptions &opt = data->options;
1604  const QMetaObject *meta = qobject->metaObject();
1605  {
1607  ? meta->propertyOffset() : 0;
1608  for ( ; i < meta->propertyCount(); ++i) {
1609  QMetaProperty prop = meta->property(i);
1610  if (isEnumerableMetaProperty(prop, meta, i)) {
1611  QString name = QString::fromLatin1(prop.name());
1612  propertyNames.add(JSC::Identifier(exec, name));
1613  }
1614  }
1615  }
1616 
1617  {
1618  QList<QByteArray> dpNames = qobject->dynamicPropertyNames();
1619  for (int i = 0; i < dpNames.size(); ++i) {
1620  QString name = QString::fromLatin1(dpNames.at(i));
1621  propertyNames.add(JSC::Identifier(exec, name));
1622  }
1623  }
1624 
1627  ? meta->methodOffset() : 0;
1628  for ( ; i < meta->methodCount(); ++i) {
1629  QMetaMethod method = meta->method(i);
1630  if (hasMethodAccess(method, i, opt)) {
1631  QMetaMethod method = meta->method(i);
1632  QString sig = QString::fromLatin1(method.signature());
1633  propertyNames.add(JSC::Identifier(exec, sig));
1634  }
1635  }
1636  }
1637 
1638  QScriptObjectDelegate::getOwnPropertyNames(object, exec, propertyNames, mode);
1639 #endif //QT_NO_PROPERTIES
1640 }
1641 
1642 void QObjectDelegate::markChildren(QScriptObject *object, JSC::MarkStack& markStack)
1643 {
1645  for (it = data->cachedMembers.constBegin(); it != data->cachedMembers.constEnd(); ++it) {
1646  JSC::JSValue val = it.value();
1647  if (val)
1648  markStack.append(val);
1649  }
1650 
1651  QScriptObjectDelegate::markChildren(object, markStack);
1652 }
1653 
1654 bool QObjectDelegate::compareToObject(QScriptObject *, JSC::ExecState *exec, JSC::JSObject *o2)
1655 {
1656  if (!o2->inherits(&QScriptObject::info))
1657  return false;
1658  QScriptObject *object = static_cast<QScriptObject*>(o2);
1659  QScriptObjectDelegate *delegate = object->delegate();
1660  if (!delegate || (delegate->type() != QScriptObjectDelegate::QtObject))
1661  return false;
1662  return value() == static_cast<QObjectDelegate *>(delegate)->value();
1663 }
1664 
1665 static JSC::JSValue JSC_HOST_CALL qobjectProtoFuncFindChild(JSC::ExecState *exec, JSC::JSObject*,
1666  JSC::JSValue thisValue, const JSC::ArgList &args)
1667 {
1669  thisValue = engine->toUsableValue(thisValue);
1670  if (!thisValue.inherits(&QScriptObject::info))
1671  return throwError(exec, JSC::TypeError, "this object is not a QObject");
1672  QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(thisValue));
1673  QScriptObjectDelegate *delegate = scriptObject->delegate();
1674  if (!delegate || (delegate->type() != QScriptObjectDelegate::QtObject))
1675  return throwError(exec, JSC::TypeError, "this object is not a QObject");
1676  QObject *obj = static_cast<QObjectDelegate*>(delegate)->value();
1677  QString name;
1678  if (args.size() != 0)
1679  name = args.at(0).toString(exec);
1680  QObject *child = obj->findChild<QObject*>(name);
1681  QScriptEngine::QObjectWrapOptions opt = QScriptEngine::PreferExistingWrapperObject;
1682  return engine->newQObject(child, QScriptEngine::QtOwnership, opt);
1683 }
1684 
1685 static JSC::JSValue JSC_HOST_CALL qobjectProtoFuncFindChildren(JSC::ExecState *exec, JSC::JSObject*,
1686  JSC::JSValue thisValue, const JSC::ArgList &args)
1687 {
1689  thisValue = engine->toUsableValue(thisValue);
1690  // extract the QObject
1691  if (!thisValue.inherits(&QScriptObject::info))
1692  return throwError(exec, JSC::TypeError, "this object is not a QObject");
1693  QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(thisValue));
1694  QScriptObjectDelegate *delegate = scriptObject->delegate();
1695  if (!delegate || (delegate->type() != QScriptObjectDelegate::QtObject))
1696  return throwError(exec, JSC::TypeError, "this object is not a QObject");
1697  const QObject *const obj = static_cast<QObjectDelegate*>(delegate)->value();
1698 
1699  // find the children
1700  QList<QObject *> children;
1701  if (args.size() != 0) {
1702  const JSC::JSValue arg = args.at(0);
1703  if (arg.inherits(&JSC::RegExpObject::info)) {
1704  const QObjectList allChildren= obj->children();
1705 
1706  JSC::RegExpObject *const regexp = JSC::asRegExpObject(arg);
1707 
1708  const int allChildrenCount = allChildren.size();
1709  for (int i = 0; i < allChildrenCount; ++i) {
1710  QObject *const child = allChildren.at(i);
1711  const JSC::UString childName = child->objectName();
1712  JSC::RegExpConstructor* regExpConstructor = engine->originalGlobalObject()->regExpConstructor();
1713  int position;
1714  int length;
1715  regExpConstructor->performMatch(regexp->regExp(), childName, 0, position, length);
1716  if (position >= 0)
1717  children.append(child);
1718  }
1719  } else {
1720  const QString name(args.at(0).toString(exec));
1721  children = obj->findChildren<QObject*>(name);
1722  }
1723  } else {
1724  children = obj->findChildren<QObject*>(QString());
1725  }
1726  // create the result array with the children
1727  const int length = children.size();
1728  JSC::JSArray *const result = JSC::constructEmptyArray(exec, length);
1729 
1730  QScriptEngine::QObjectWrapOptions opt = QScriptEngine::PreferExistingWrapperObject;
1731  for (int i = 0; i < length; ++i) {
1732  QObject *const child = children.at(i);
1733  result->put(exec, i, engine->newQObject(child, QScriptEngine::QtOwnership, opt));
1734  }
1735  return JSC::JSValue(result);
1736 }
1737 
1738 static JSC::JSValue JSC_HOST_CALL qobjectProtoFuncToString(JSC::ExecState *exec, JSC::JSObject*,
1739  JSC::JSValue thisValue, const JSC::ArgList&)
1740 {
1742  thisValue = engine->toUsableValue(thisValue);
1743  if (!thisValue.inherits(&QScriptObject::info))
1744  return JSC::jsUndefined();
1745  QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(thisValue));
1746  QScriptObjectDelegate *delegate = scriptObject->delegate();
1747  if (!delegate || (delegate->type() != QScriptObjectDelegate::QtObject))
1748  return JSC::jsUndefined();
1749  QObject *obj = static_cast<QObjectDelegate*>(delegate)->value();
1750  const QMetaObject *meta = obj ? obj->metaObject() : &QObject::staticMetaObject;
1751  QString name = obj ? obj->objectName() : QString::fromUtf8("unnamed");
1752  QString str = QString::fromUtf8("%0(name = \"%1\")")
1753  .arg(QLatin1String(meta->className())).arg(name);
1754  return JSC::jsString(exec, str);
1755 }
1756 
1757 QObjectPrototype::QObjectPrototype(JSC::ExecState* exec, WTF::PassRefPtr<JSC::Structure> structure,
1758  JSC::Structure* prototypeFunctionStructure)
1759  : QScriptObject(structure)
1760 {
1765 
1766  putDirectFunction(exec, new (exec) JSC::NativeFunctionWrapper(exec, prototypeFunctionStructure, /*length=*/0, exec->propertyNames().toString, qobjectProtoFuncToString), JSC::DontEnum);
1767  putDirectFunction(exec, new (exec) JSC::NativeFunctionWrapper(exec, prototypeFunctionStructure, /*length=*/1, JSC::Identifier(exec, "findChild"), qobjectProtoFuncFindChild), JSC::DontEnum);
1768  putDirectFunction(exec, new (exec) JSC::NativeFunctionWrapper(exec, prototypeFunctionStructure, /*length=*/1, JSC::Identifier(exec, "findChildren"), qobjectProtoFuncFindChildren), JSC::DontEnum);
1769  this->structure()->setHasGetterSetterProperties(true);
1770 }
1771 
1772 const JSC::ClassInfo QMetaObjectWrapperObject::info = { "QMetaObject", 0, 0, 0 };
1773 
1775  JSC::ExecState *exec, const QMetaObject *metaObject, JSC::JSValue ctor,
1776  WTF::PassRefPtr<JSC::Structure> sid)
1777  : JSC::JSObject(sid),
1778  data(new Data(metaObject, ctor))
1779 {
1780  if (!ctor)
1781  data->prototype = new (exec)JSC::JSObject(exec->lexicalGlobalObject()->emptyObjectStructure());
1782 }
1783 
1785 {
1786  delete data;
1787 }
1788 
1790  JSC::ExecState *exec, const JSC::Identifier& propertyName,
1791  JSC::PropertySlot &slot)
1792 {
1793  const QMetaObject *meta = data->value;
1794  if (!meta)
1795  return false;
1796 
1797  if (propertyName == exec->propertyNames().prototype) {
1798  if (data->ctor)
1799  slot.setValue(data->ctor.get(exec, propertyName));
1800  else
1801  slot.setValue(data->prototype);
1802  return true;
1803  }
1804 
1805  QByteArray name = convertToLatin1(propertyName.ustring());
1806 
1807  for (int i = 0; i < meta->enumeratorCount(); ++i) {
1808  QMetaEnum e = meta->enumerator(i);
1809  for (int j = 0; j < e.keyCount(); ++j) {
1810  const char *key = e.key(j);
1811  if (!qstrcmp(key, name.constData())) {
1812  slot.setValue(JSC::JSValue(exec, e.value(j)));
1813  return true;
1814  }
1815  }
1816  }
1817 
1818  return JSC::JSObject::getOwnPropertySlot(exec, propertyName, slot);
1819 }
1820 
1822  JSC::ExecState* exec, const JSC::Identifier& propertyName,
1823  JSC::PropertyDescriptor& descriptor)
1824 {
1825  const QMetaObject *meta = data->value;
1826  if (!meta)
1827  return false;
1828 
1829  if (propertyName == exec->propertyNames().prototype) {
1830  descriptor.setDescriptor(data->ctor
1831  ? data->ctor.get(exec, propertyName)
1832  : data->prototype,
1833  JSC::DontDelete | JSC::DontEnum);
1834  return true;
1835  }
1836 
1837  QByteArray name = QString(propertyName.ustring()).toLatin1();
1838 
1839  for (int i = 0; i < meta->enumeratorCount(); ++i) {
1840  QMetaEnum e = meta->enumerator(i);
1841  for (int j = 0; j < e.keyCount(); ++j) {
1842  const char *key = e.key(j);
1843  if (!qstrcmp(key, name.constData())) {
1844  descriptor.setDescriptor(JSC::JSValue(exec, e.value(j)),
1845  JSC::ReadOnly | JSC::DontDelete);
1846  return true;
1847  }
1848  }
1849  }
1850 
1851  return JSC::JSObject::getOwnPropertyDescriptor(exec, propertyName, descriptor);
1852 }
1853 
1854 void QMetaObjectWrapperObject::put(JSC::ExecState* exec, const JSC::Identifier& propertyName,
1855  JSC::JSValue value, JSC::PutPropertySlot &slot)
1856 {
1857  if (propertyName == exec->propertyNames().prototype) {
1858  if (data->ctor)
1859  data->ctor.put(exec, propertyName, value, slot);
1860  else
1861  data->prototype = value;
1862  return;
1863  }
1864  const QMetaObject *meta = data->value;
1865  if (meta) {
1866  QByteArray name = convertToLatin1(propertyName.ustring());
1867  for (int i = 0; i < meta->enumeratorCount(); ++i) {
1868  QMetaEnum e = meta->enumerator(i);
1869  for (int j = 0; j < e.keyCount(); ++j) {
1870  if (!qstrcmp(e.key(j), name.constData()))
1871  return;
1872  }
1873  }
1874  }
1875  JSC::JSObject::put(exec, propertyName, value, slot);
1876 }
1877 
1879  JSC::ExecState *exec, const JSC::Identifier& propertyName)
1880 {
1881  if (propertyName == exec->propertyNames().prototype)
1882  return false;
1883  const QMetaObject *meta = data->value;
1884  if (meta) {
1885  QByteArray name = convertToLatin1(propertyName.ustring());
1886  for (int i = 0; i < meta->enumeratorCount(); ++i) {
1887  QMetaEnum e = meta->enumerator(i);
1888  for (int j = 0; j < e.keyCount(); ++j) {
1889  if (!qstrcmp(e.key(j), name.constData()))
1890  return false;
1891  }
1892  }
1893  }
1894  return JSC::JSObject::deleteProperty(exec, propertyName);
1895 }
1896 
1898  JSC::PropertyNameArray &propertyNames,
1899  JSC::EnumerationMode mode)
1900 {
1901  const QMetaObject *meta = data->value;
1902  if (!meta)
1903  return;
1904  for (int i = 0; i < meta->enumeratorCount(); ++i) {
1905  QMetaEnum e = meta->enumerator(i);
1906  for (int j = 0; j < e.keyCount(); ++j)
1907  propertyNames.add(JSC::Identifier(exec, e.key(j)));
1908  }
1909  JSC::JSObject::getOwnPropertyNames(exec, propertyNames, mode);
1910 }
1911 
1912 void QMetaObjectWrapperObject::markChildren(JSC::MarkStack& markStack)
1913 {
1914  if (data->ctor)
1915  markStack.append(data->ctor);
1916  if (data->prototype)
1917  markStack.append(data->prototype);
1918  JSC::JSObject::markChildren(markStack);
1919 }
1920 
1921 JSC::CallType QMetaObjectWrapperObject::getCallData(JSC::CallData& callData)
1922 {
1923  callData.native.function = call;
1924  return JSC::CallTypeHost;
1925 }
1926 
1927 JSC::ConstructType QMetaObjectWrapperObject::getConstructData(JSC::ConstructData& constructData)
1928 {
1929  constructData.native.function = construct;
1930  return JSC::ConstructTypeHost;
1931 }
1932 
1933 JSC::JSValue JSC_HOST_CALL QMetaObjectWrapperObject::call(
1934  JSC::ExecState *exec, JSC::JSObject *callee,
1935  JSC::JSValue thisValue, const JSC::ArgList &args)
1936 {
1938  thisValue = eng_p->toUsableValue(thisValue);
1939  if (!callee->inherits(&QMetaObjectWrapperObject::info))
1940  return throwError(exec, JSC::TypeError, "callee is not a QMetaObject");
1941  QMetaObjectWrapperObject *self = static_cast<QMetaObjectWrapperObject*>(callee);
1942  JSC::ExecState *previousFrame = eng_p->currentFrame;
1943  eng_p->pushContext(exec, thisValue, args, callee);
1944  JSC::JSValue result = self->execute(eng_p->currentFrame, args);
1945  eng_p->popContext();
1946  eng_p->currentFrame = previousFrame;
1947  return result;
1948 }
1949 
1950 JSC::JSObject* QMetaObjectWrapperObject::construct(JSC::ExecState *exec, JSC::JSObject *callee, const JSC::ArgList &args)
1951 {
1952  QMetaObjectWrapperObject *self = static_cast<QMetaObjectWrapperObject*>(callee);
1954  JSC::ExecState *previousFrame = eng_p->currentFrame;
1955  eng_p->pushContext(exec, JSC::JSValue(), args, callee, true);
1956  JSC::JSValue result = self->execute(eng_p->currentFrame, args);
1957  eng_p->popContext();
1958  eng_p->currentFrame = previousFrame;
1959  if (!result || !result.isObject())
1960  return 0;
1961  return JSC::asObject(result);
1962 }
1963 
1964 JSC::JSValue QMetaObjectWrapperObject::execute(JSC::ExecState *exec,
1965  const JSC::ArgList &args)
1966 {
1967  if (data->ctor) {
1969  QScriptContext *ctx = eng_p->contextForFrame(exec);
1970  JSC::CallData callData;
1971  JSC::CallType callType = data->ctor.getCallData(callData);
1972  Q_UNUSED(callType);
1973  Q_ASSERT_X(callType == JSC::CallTypeHost, Q_FUNC_INFO, "script constructors not supported");
1974  if (data->ctor.inherits(&FunctionWithArgWrapper::info)) {
1975  FunctionWithArgWrapper *wrapper = static_cast<FunctionWithArgWrapper*>(JSC::asObject(data->ctor));
1976  QScriptValue result = wrapper->function()(ctx, QScriptEnginePrivate::get(eng_p), wrapper->arg());
1977  return eng_p->scriptValueToJSCValue(result);
1978  } else {
1979  Q_ASSERT(data->ctor.inherits(&FunctionWrapper::info));
1980  FunctionWrapper *wrapper = static_cast<FunctionWrapper*>(JSC::asObject(data->ctor));
1981  QScriptValue result = wrapper->function()(ctx, QScriptEnginePrivate::get(eng_p));
1982  return eng_p->scriptValueToJSCValue(result);
1983  }
1984  } else {
1985  const QMetaObject *meta = data->value;
1986  if (meta->constructorCount() > 0) {
1987  JSC::JSValue result = callQtMethod(exec, QMetaMethod::Constructor, /*thisQObject=*/0,
1988  args, meta, meta->constructorCount()-1, /*maybeOverloaded=*/true);
1989  if (!exec->hadException()) {
1990  Q_ASSERT(result && result.inherits(&QScriptObject::info));
1991  QScriptObject *object = static_cast<QScriptObject*>(JSC::asObject(result));
1992  QScript::QObjectDelegate *delegate = static_cast<QScript::QObjectDelegate*>(object->delegate());
1994  if (data->prototype)
1995  object->setPrototype(data->prototype);
1996  }
1997  return result;
1998  } else {
1999  QString message = QString::fromLatin1("no constructor for %0")
2000  .arg(QLatin1String(meta->className()));
2001  return JSC::throwError(exec, JSC::TypeError, message);
2002  }
2003  }
2004 }
2005 
2007 {
2008  static const QMetaObject *get()
2009  { return &static_cast<StaticQtMetaObject*> (0)->staticQtMetaObject; }
2010 };
2011 
2012 static JSC::JSValue JSC_HOST_CALL qmetaobjectProtoFuncClassName(
2013  JSC::ExecState *exec, JSC::JSObject*, JSC::JSValue thisValue, const JSC::ArgList&)
2014 {
2016  thisValue = engine->toUsableValue(thisValue);
2017  if (!thisValue.inherits(&QMetaObjectWrapperObject::info))
2018  return throwError(exec, JSC::TypeError, "this object is not a QMetaObject");
2019  const QMetaObject *meta = static_cast<QMetaObjectWrapperObject*>(JSC::asObject(thisValue))->value();
2020  return JSC::jsString(exec, meta->className());
2021 }
2022 
2024  JSC::ExecState *exec, WTF::PassRefPtr<JSC::Structure> structure,
2025  JSC::Structure* prototypeFunctionStructure)
2026  : QMetaObjectWrapperObject(exec, StaticQtMetaObject::get(), /*ctor=*/JSC::JSValue(), structure)
2027 {
2028  putDirectFunction(exec, new (exec) JSC::NativeFunctionWrapper(exec, prototypeFunctionStructure, /*length=*/0, JSC::Identifier(exec, "className"), qmetaobjectProtoFuncClassName), JSC::DontEnum);
2029 }
2030 
2032 
2033  // content:
2034  1, // revision
2035  0, // classname
2036  0, 0, // classinfo
2037  1, 10, // methods
2038  0, 0, // properties
2039  0, 0, // enums/sets
2040 
2041  // slots: signature, parameters, type, tag, flags
2042  35, 34, 34, 34, 0x0a,
2043 
2044  0 // eod
2045 };
2046 
2048  "QScript::QObjectConnectionManager\0\0execute()\0"
2049 };
2050 
2054 };
2055 
2057 {
2058  return &staticMetaObject;
2059 }
2060 
2061 void *QObjectConnectionManager::qt_metacast(const char *_clname)
2062 {
2063  if (!_clname) return 0;
2064  if (!strcmp(_clname, qt_meta_stringdata_QObjectConnectionManager))
2065  return static_cast<void*>(const_cast<QObjectConnectionManager*>(this));
2066  return QObject::qt_metacast(_clname);
2067 }
2068 
2070 {
2071  _id = QObject::qt_metacall(_c, _id, _a);
2072  if (_id < 0)
2073  return _id;
2074  if (_c == QMetaObject::InvokeMetaMethod) {
2075  execute(_id, _a);
2076  _id -= slotCounter;
2077  }
2078  return _id;
2079 }
2080 
2081 void QObjectConnectionManager::execute(int slotIndex, void **argv)
2082 {
2083  JSC::JSValue receiver;
2084  JSC::JSValue slot;
2085  JSC::JSValue senderWrapper;
2086  int signalIndex = -1;
2087  QScript::APIShim shim(engine);
2088  for (int i = 0; i < connections.size(); ++i) {
2089  const QVector<QObjectConnection> &cs = connections.at(i);
2090  for (int j = 0; j < cs.size(); ++j) {
2091  const QObjectConnection &c = cs.at(j);
2092  if (c.slotIndex == slotIndex) {
2093  receiver = c.receiver;
2094  slot = c.slot;
2095  senderWrapper = c.senderWrapper;
2096  signalIndex = i;
2097  break;
2098  }
2099  }
2100  }
2101  if (!slot) {
2102  // This connection no longer exists (can happen if the signal is
2103  // emitted from another thread and the call gets queued, but the
2104  // connection is removed before the QMetaCallEvent gets processed).
2105  return;
2106  }
2107  Q_ASSERT(slot.isObject());
2108 
2109  if (engine->isCollecting()) {
2110  qWarning("QtScript: can't execute signal handler during GC");
2111  // we can't do a script function call during GC,
2112  // so we're forced to ignore this signal
2113  return;
2114  }
2115 
2116 #if 0
2117  QScriptFunction *fun = engine->convertToNativeFunction(slot);
2118  if (fun == 0) {
2119  // the signal handler has been GC'ed. This can only happen when
2120  // a QObject is owned by the engine, the engine is destroyed, and
2121  // there is a script function connected to the destroyed() signal
2122  Q_ASSERT(signalIndex <= 1); // destroyed(QObject*)
2123  return;
2124  }
2125 #endif
2126 
2127  const QMetaObject *meta = sender()->metaObject();
2128  const QMetaMethod method = meta->method(signalIndex);
2129 
2130  QList<QByteArray> parameterTypes = method.parameterTypes();
2131  int argc = parameterTypes.count();
2132 
2133  JSC::ExecState *exec = engine->currentFrame;
2134  QVarLengthArray<JSC::JSValue, 8> argsVector(argc);
2135  for (int i = 0; i < argc; ++i) {
2136  JSC::JSValue actual;
2137  void *arg = argv[i + 1];
2138  QByteArray typeName = parameterTypes.at(i);
2139  int argType = QMetaType::type(parameterTypes.at(i));
2140  if (!argType) {
2141  qWarning("QScriptEngine: Unable to handle unregistered datatype '%s' "
2142  "when invoking handler of signal %s::%s",
2143  typeName.constData(), meta->className(), method.signature());
2144  actual = JSC::jsUndefined();
2145  } else if (argType == QMetaType::QVariant) {
2146  actual = QScriptEnginePrivate::jscValueFromVariant(exec, *reinterpret_cast<QVariant*>(arg));
2147  } else {
2148  actual = QScriptEnginePrivate::create(exec, argType, arg);
2149  }
2150  argsVector[i] = actual;
2151  }
2152  JSC::ArgList jscArgs(argsVector.data(), argsVector.size());
2153 
2154  JSC::JSValue senderObject;
2155  if (senderWrapper && senderWrapper.inherits(&QScriptObject::info)) // ### check if it's actually a QObject wrapper
2156  senderObject = senderWrapper;
2157  else {
2158  QScriptEngine::QObjectWrapOptions opt = QScriptEngine::PreferExistingWrapperObject;
2159  senderObject = engine->newQObject(sender(), QScriptEngine::QtOwnership, opt);
2160  }
2161 
2162  JSC::JSValue thisObject;
2163  if (receiver && receiver.isObject())
2164  thisObject = receiver;
2165  else
2166  thisObject = engine->globalObject();
2167 
2168  JSC::CallData callData;
2169  JSC::CallType callType = slot.getCallData(callData);
2170  if (exec->hadException())
2171  exec->clearException(); // ### otherwise JSC asserts
2172  JSC::call(exec, slot, callType, callData, thisObject, jscArgs);
2173 
2174  if (exec->hadException()) {
2175  if (slot.inherits(&QtFunction::info) && !static_cast<QtFunction*>(JSC::asObject(slot))->qobject()) {
2176  // The function threw an error because the target QObject has been deleted.
2177  // The connections list is stale; remove the signal handler and ignore the exception.
2178  removeSignalHandler(sender(), signalIndex, receiver, slot);
2179  exec->clearException();
2180  } else {
2181  engine->emitSignalHandlerException();
2182  }
2183  }
2184 }
2185 
2187  : engine(eng), slotCounter(0)
2188 {
2189 }
2190 
2192 {
2193 }
2194 
2195 void QObjectConnectionManager::mark(JSC::MarkStack& markStack)
2196 {
2197  for (int i = 0; i < connections.size(); ++i) {
2199  for (int j = 0; j < cs.size(); ++j)
2200  cs[j].mark(markStack);
2201  }
2202 }
2203 
2205  QObject *sender, int signalIndex, JSC::JSValue receiver,
2206  JSC::JSValue function, JSC::JSValue senderWrapper,
2208 {
2209  if (connections.size() <= signalIndex)
2210  connections.resize(signalIndex+1);
2211  QVector<QObjectConnection> &cs = connections[signalIndex];
2212  int absSlotIndex = slotCounter + metaObject()->methodOffset();
2213  bool ok = QMetaObject::connect(sender, signalIndex, this, absSlotIndex, type);
2214  if (ok) {
2215  cs.append(QObjectConnection(slotCounter++, receiver, function, senderWrapper));
2216  QMetaMethod signal = sender->metaObject()->method(signalIndex);
2217  QByteArray signalString;
2218  signalString.append('2'); // signal code
2219  signalString.append(signal.signature());
2220  static_cast<QObjectNotifyCaller*>(sender)->callConnectNotify(signalString);
2221  }
2222  return ok;
2223 }
2224 
2226  QObject *sender, int signalIndex,
2227  JSC::JSValue receiver, JSC::JSValue slot)
2228 {
2229  if (connections.size() <= signalIndex)
2230  return false;
2231  QVector<QObjectConnection> &cs = connections[signalIndex];
2232  for (int i = 0; i < cs.size(); ++i) {
2233  const QObjectConnection &c = cs.at(i);
2234  if (c.hasTarget(receiver, slot)) {
2235  int absSlotIndex = c.slotIndex + metaObject()->methodOffset();
2236  bool ok = QMetaObject::disconnect(sender, signalIndex, this, absSlotIndex);
2237  if (ok) {
2238  cs.remove(i);
2239  QMetaMethod signal = sender->metaObject()->method(signalIndex);
2240  QByteArray signalString;
2241  signalString.append('2'); // signal code
2242  signalString.append(signal.signature());
2243  static_cast<QScript::QObjectNotifyCaller*>(sender)->callDisconnectNotify(signalString);
2244  }
2245  return ok;
2246  }
2247  }
2248  return false;
2249 }
2250 
2252  : engine(eng), connectionManager(0)
2253 {
2254 }
2255 
2257 {
2258  if (connectionManager) {
2259  delete connectionManager;
2260  connectionManager = 0;
2261  }
2262 }
2263 
2264 void QObjectData::mark(JSC::MarkStack& markStack)
2265 {
2266  if (connectionManager)
2267  connectionManager->mark(markStack);
2268  {
2270  for (it = wrappers.begin(); it != wrappers.end(); ) {
2272  // ### don't mark if there are no other references.
2273  // we need something like isMarked()
2274  markStack.append(info.object);
2275  ++it;
2276  }
2277  }
2278 }
2279 
2281  int signalIndex,
2282  JSC::JSValue receiver,
2283  JSC::JSValue slot,
2284  JSC::JSValue senderWrapper,
2286 {
2287  if (!connectionManager)
2290  sender, signalIndex, receiver, slot, senderWrapper, type);
2291 }
2292 
2294  int signalIndex,
2295  JSC::JSValue receiver,
2296  JSC::JSValue slot)
2297 {
2298  if (!connectionManager)
2299  return false;
2301  sender, signalIndex, receiver, slot);
2302 }
2303 
2305  const QScriptEngine::QObjectWrapOptions &options) const
2306 {
2307  for (int i = 0; i < wrappers.size(); ++i) {
2308  const QObjectWrapperInfo &info = wrappers.at(i);
2309  if ((info.ownership == ownership) && (info.options == options))
2310  return info.object;
2311  }
2312  return 0;
2313 }
2314 
2317  const QScriptEngine::QObjectWrapOptions &options)
2318 {
2319  wrappers.append(QObjectWrapperInfo(wrapper, ownership, options));
2320 }
2321 
2322 } // namespace QScript
2323 
2325 
2326 namespace JSC
2327 {
2329 }
2330 
2331 #include "moc_qscriptqobject_p.cpp"
2332 
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:92
static const JSC::ClassInfo info
void resize(int size)
The QScriptContext class represents a Qt Script function invocation.
The QMetaObject class contains meta-information about Qt objects.
Definition: qobjectdefs.h:304
static QVariant variantFromValue(JSC::ExecState *exec, int targetType, JSC::JSValue value)
QList< QScript::QObjectWrapperInfo > wrappers
void mark(JSC::MarkStack &markStack)
QScriptObject * wrapperObject() const
QScriptEnginePrivate * engine
int type
Definition: qmetatype.cpp:239
virtual bool deleteProperty(QScriptObject *, JSC::ExecState *, const JSC::Identifier &propertyName)
QScriptEnginePrivate * scriptEngineFromExec(const JSC::ExecState *exec)
virtual void getOwnPropertyNames(QScriptObject *, JSC::ExecState *, JSC::PropertyNameArray &, JSC::EnumerationMode mode=JSC::ExcludeDontEnumProperties)
QVector< QScriptMetaType > types() const
bool isScriptable(const QObject *obj=0) const
Returns true if the property is scriptable for the given object; otherwise returns false...
bool isWritable() const
Returns true if this property is writable; otherwise returns false.
static mach_timebase_info_data_t info
unsigned char c[8]
Definition: qnumeric_p.h:62
static bool connect(const QObject *sender, int signal_index, const QObject *receiver, int method_index, int type=0, int *types=0)
Definition: qobject.cpp:3194
The QMetaEnum class provides meta-data about an enumerator.
Definition: qmetaobject.h:147
virtual Type type() const =0
bool removeSignalHandler(QObject *sender, int signalIndex, JSC::JSValue receiver, JSC::JSValue slot)
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
JSC::JSValue execute(JSC::ExecState *exec, JSC::JSValue thisValue, const JSC::ArgList &args)
QObjectDelegate(QObject *object, QScriptEngine::ValueOwnership ownership, const QScriptEngine::QObjectWrapOptions &options)
static JSC::JSValue jscValueFromVariant(JSC::ExecState *, const QVariant &value)
static QByteArray normalizedSignature(const char *method)
Normalizes the signature of the given method.
static JSC::JSValue JSC_HOST_CALL call(JSC::ExecState *, JSC::JSObject *, JSC::JSValue, const JSC::ArgList &)
const QChar at(int i) const
Returns the character at the given index position in the string.
Definition: qstring.h:698
static JSC::JSValue JSC_HOST_CALL call(JSC::ExecState *, JSC::JSObject *, JSC::JSValue, const JSC::ArgList &)
static const JSC::ClassInfo info
void remove(int i)
Removes the element at index position i.
Definition: qvector.h:374
bool addSignalHandler(QObject *sender, int signalIndex, JSC::JSValue receiver, JSC::JSValue slot, JSC::JSValue senderWrapper, Qt::ConnectionType type)
QScriptMetaType(Kind kind, int typeId=0, const QByteArray &name=QByteArray())
static QScriptMetaType metaEnum(int enumIndex, const QByteArray &name)
#define it(className, varName)
virtual void markChildren(QScriptObject *, JSC::MarkStack &markStack)
QObject * qobject() const
static QScriptEnginePrivate * get(QScriptEngine *q)
QByteArray & append(char c)
Appends the character ch to this byte array.
virtual int qt_metacall(QMetaObject::Call, int, void **argv)
bool isValid() const
Returns true if this enum is valid (has a name); otherwise returns false.
Definition: qmetaobject.h:168
ASSERT_CLASS_FITS_IN_CELL(::QScript::QScriptActivationObject)
static QVariant toVariant(JSC::ExecState *, JSC::JSValue)
QScriptMetaArguments(int dist, int idx, const QScriptMetaMethod &mtd, const QVarLengthArray< QVariant, 9 > &as)
QMetaObjectWrapperObject(JSC::ExecState *, const QMetaObject *metaobject, JSC::JSValue ctor, WTF::PassRefPtr< JSC::Structure > sid)
static JSC::JSValue create(JSC::ExecState *, int type, const void *ptr)
virtual void put(JSC::ExecState *exec, const JSC::Identifier &propertyName, JSC::JSValue, JSC::PutPropertySlot &)
virtual bool deleteProperty(QScriptObject *, JSC::ExecState *, const JSC::Identifier &propertyName)
static int metacall(QObject *, Call, int, void **)
static JSC::JSValue callQtMethod(JSC::ExecState *exec, QMetaMethod::MethodType callType, QObject *thisQObject, const JSC::ArgList &scriptArgs, const QMetaObject *meta, int initialIndex, bool maybeOverloaded)
QString objectName
the name of this object
Definition: qobject.h:114
QObjectPrototype(JSC::ExecState *, WTF::PassRefPtr< JSC::Structure >, JSC::Structure *prototypeFunctionStructure)
T & first()
Returns a reference to the first item in the vector.
Definition: qvector.h:260
static JSC::JSValue JSC_HOST_CALL qobjectProtoFuncFindChildren(JSC::ExecState *exec, JSC::JSObject *, JSC::JSValue thisValue, const JSC::ArgList &args)
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
int static_metacall(Call, int, void **) const
QScriptEngine::ValueOwnership ownership() const
bool removeSignalHandler(QObject *sender, int signalIndex, JSC::JSValue receiver, JSC::JSValue slot)
virtual void markChildren(QScriptObject *, JSC::MarkStack &markStack)
static qreal position(QGraphicsObject *item, QDeclarativeAnchorLine::AnchorLine anchorLine)
const_iterator constEnd() const
Returns a const STL-style iterator pointing to the imaginary item after the last item in the vector...
Definition: qvector.h:252
JSC::CallFrame * pushContext(JSC::CallFrame *exec, JSC::JSValue thisObject, const JSC::ArgList &args, JSC::JSObject *callee, bool calledAsConstructor=false, bool clearScopeChain=false)
JSC native function doesn&#39;t have different stackframe or context.
iterator begin()
Returns an STL-style iterator pointing to the first item in the list.
Definition: qlist.h:267
QString toString() const
Returns the variant as a QString if the variant has type() String , Bool , ByteArray ...
Definition: qvariant.cpp:2270
const char * valueToKey(int value) const
Returns the string that is used as the name of the given enumeration value, or 0 if value is not defi...
static JSC::JSValue JSC_HOST_CALL qobjectProtoFuncFindChild(JSC::ExecState *exec, JSC::JSObject *, JSC::JSValue thisValue, const JSC::ArgList &args)
static const QMetaObject staticMetaObject
This variable stores the meta-object for the class.
Definition: qobject.h:128
static QObject * toQObject(JSC::ExecState *, JSC::JSValue)
QScriptObjectDelegate * delegate() const
virtual bool getOwnPropertyDescriptor(QScriptObject *, JSC::ExecState *, const JSC::Identifier &propertyName, JSC::PropertyDescriptor &)
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
QObjectConnection(int i, JSC::JSValue r, JSC::JSValue s, JSC::JSValue sw)
static int indexOfMetaEnum(const QMetaObject *meta, const QByteArray &str)
const char * key(int index) const
Returns the key with the given index, or 0 if no such key exists.
virtual JSC::CallType getCallData(JSC::CallData &)
virtual JSC::CallType getCallData(JSC::CallData &)
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
bool isValid() const
Returns true if this property is valid (readable); otherwise returns false.
Definition: qmetaobject.h:213
bool hasDemarshalFunction(int type) const
static const JSC::ClassInfo info
int constructorCount() const
Returns the number of constructors in this class.
int propertyCount() const
Returns the number of properties in this class, including the number of properties provided by each b...
The QString class provides a Unicode character string.
Definition: qstring.h:83
const char * typeName() const
Returns the return type of this method, or an empty string if the return type is void.
virtual void put(QScriptObject *, JSC::ExecState *exec, const JSC::Identifier &propertyName, JSC::JSValue, JSC::PutPropertySlot &)
void callDisconnectNotify(const char *signal)
The QHash class is a template class that provides a hash-table-based dictionary.
Definition: qdatastream.h:66
QObject * value() const
void setValue(const T &value)
Stores a copy of value.
Definition: qvariant.h:527
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
The QVector class is a template class that provides a dynamic array.
Definition: qdatastream.h:64
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
const char * scope() const
Returns the scope this enumerator was declared in.
bool addSignalHandler(QObject *sender, int signalIndex, JSC::JSValue receiver, JSC::JSValue slot, JSC::JSValue senderWrapper, Qt::ConnectionType type)
QScriptEngine::FunctionWithArgSignature function() const
int indexOfProperty(const char *name) const
Finds property name and returns its index; otherwise returns -1.
virtual const QMetaObject * metaObject() const
Returns a pointer to the meta-object of this object.
const char * name() const
Returns the name of the enumerator (without the scope).
virtual void * qt_metacast(const char *)
const T value(const Key &key) const
Returns the value associated with the key.
Definition: qhash.h:606
JSC::ExecState * currentFrame
void resize(int size)
Sets the size of the vector to size.
Definition: qvector.h:342
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
Definition: qhash.h:753
QObject * sender() const
Returns a pointer to the object that sent the signal, if called in a slot activated by a signal; othe...
Definition: qobject.cpp:2327
static JSC::JSValue JSC_HOST_CALL qobjectProtoFuncToString(JSC::ExecState *exec, JSC::JSObject *, JSC::JSValue thisValue, const JSC::ArgList &)
const QMetaObject * value() const
The QScriptable class provides access to the Qt Script environment from Qt C++ member functions...
Definition: qscriptable.h:45
QObject * cast(QObject *obj) const
Returns obj if object obj inherits from this meta-object; otherwise returns 0.
static QScriptablePrivate * get(QScriptable *q)
Definition: qscriptable_p.h:51
virtual bool getOwnPropertySlot(QScriptObject *, JSC::ExecState *, const JSC::Identifier &propertyName, JSC::PropertySlot &)
ConnectionType
Definition: qnamespace.h:1469
static const JSC::ClassInfo info
virtual void markChildren(JSC::MarkStack &)
const_iterator constBegin() const
Returns a const STL-style iterator pointing to the first item in the vector.
Definition: qvector.h:249
void setOwnership(QScriptEngine::ValueOwnership ownership)
static bool convertToNativeQObject(JSC::ExecState *, JSC::JSValue, const QByteArray &targetType, void **result)
void append(const T &t)
Inserts value at the end of the list.
Definition: qlist.h:507
void * data()
Definition: qvariant.cpp:3077
The QScriptEngine class provides an environment for evaluating Qt Script code.
QVector< QVector< QObjectConnection > > connections
static bool isVariant(JSC::JSValue)
static qint32 toInt32(JSC::ExecState *, JSC::JSValue)
virtual void getOwnPropertyNames(QScriptObject *, JSC::ExecState *, JSC::PropertyNameArray &, JSC::EnumerationMode mode=JSC::ExcludeDontEnumProperties)
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
JSC::JSValue data() const
bool isEnumType() const
Returns true if the property&#39;s type is an enumeration value; otherwise returns false.
int lastIndexOf(char c, int from=-1) const
Returns the index position of the last occurrence of character ch in the byte array, searching backward from index position from.
JSC::JSValue scriptValueToJSCValue(const QScriptValue &value)
bool canConvert(Type t) const
Returns true if the variant&#39;s type can be cast to the requested type, t.
Definition: qvariant.cpp:2886
int methodOffset() const
Returns the method offset for this class; i.e.
static QScriptable * scriptableFromQObject(QObject *qobj)
int userType() const
Returns this property&#39;s user type.
QScriptEngine::ValueOwnership ownership
static QScriptContext * contextForFrame(JSC::ExecState *frame)
const char * typeName
Definition: qmetatype.cpp:239
JSC::JSGlobalObject * originalGlobalObject() const
static const char qt_meta_stringdata_QObjectConnectionManager[]
iterator end()
Returns an STL-style iterator pointing to the imaginary item after the last item in the list...
Definition: qlist.h:270
static QScriptMetaType unresolved(const QByteArray &name)
static JSC::UString toString(JSC::ExecState *, JSC::JSValue)
const char * name
QObjectConnectionManager(QScriptEnginePrivate *engine)
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
void mark(JSC::MarkStack &)
QMetaObjectPrototype(JSC::ExecState *, WTF::PassRefPtr< JSC::Structure >, JSC::Structure *prototypeFunctionStructure)
virtual void getOwnPropertyNames(JSC::ExecState *, JSC::PropertyNameArray &, JSC::EnumerationMode mode=JSC::ExcludeDontEnumProperties)
static QString fromUtf8(const char *, int size=-1)
Returns a QString initialized with the first size bytes of the UTF-8 string str.
Definition: qstring.cpp:4302
void append(const T &t)
Inserts value at the end of the vector.
Definition: qvector.h:573
static Type type(const QScriptValue &v)
QScriptMetaType type(int index) const
Q_CORE_EXPORT void qWarning(const char *,...)
static bool methodNameEquals(const QMetaMethod &method, const char *signature, int nameLength)
Returns true if the name of the given method is the same as that specified by the (signature...
JSC::JSValue toUsableValue(JSC::JSValue value)
If the given value is the original global object, returns the custom global object or a proxy to the ...
QVarLengthArray< QVariant, 9 > args
static const char * data(const QByteArray &arr)
unsigned int uint
Definition: qglobal.h:996
const_iterator constFind(const Key &key) const
Returns an iterator pointing to the item with the key in the hash.
Definition: qhash.h:859
T findChild(const QString &aName=QString()) const
Returns the child of this object that can be cast into type T and that is called name, or 0 if there is no such object.
Definition: qobject.h:158
Type
This enum type defines the types of variable that a QVariant can contain.
Definition: qvariant.h:95
QScript::QObjectConnectionManager * connectionManager
JSC::JSValue execute(JSC::ExecState *exec, JSC::JSValue thisValue, const JSC::ArgList &args)
static bool disconnect(const QObject *sender, int signal_index, const QObject *receiver, int method_index)
Definition: qobject.cpp:3276
ValueOwnership
This enum specifies the ownership when wrapping a C++ value, e.
virtual void put(QScriptObject *, JSC::ExecState *exec, const JSC::Identifier &propertyName, JSC::JSValue, JSC::PutPropertySlot &)
int enumeratorCount() const
Returns the number of enumerators in this class.
static QMetaMethod metaMethod(const QMetaObject *meta, QMetaMethod::MethodType type, int index)
virtual bool getOwnPropertyDescriptor(QScriptObject *, JSC::ExecState *, const JSC::Identifier &propertyName, JSC::PropertyDescriptor &)
QHash< QByteArray, JSC::JSValue > cachedMembers
const T * ptr(const T &t)
QScriptObject * findWrapper(QScriptEngine::ValueOwnership ownership, const QScriptEngine::QObjectWrapOptions &options) const
const QMetaObject * metaObject() const
QByteArray left(int len) const
Returns a byte array that contains the leftmost len bytes of this byte array.
static int type(const char *typeName)
Returns a handle to the type called typeName, or 0 if there is no such type.
Definition: qmetatype.cpp:607
JSC::JSValue execute(JSC::ExecState *exec, const JSC::ArgList &args)
int count() const
QByteArray mid(int index, int len=-1) const
Returns a byte array containing len bytes from this byte array, starting at position pos...
const char * typeName() const
Returns the name of the type stored in the variant.
Definition: qvariant.cpp:1984
ASSERT_CLASS_FITS_IN_CELL(QScript::QtPropertyFunction)
bool hasTarget(JSC::JSValue r, JSC::JSValue s) const
QtPropertyFunction(const QMetaObject *meta, int index, JSC::JSGlobalData *, WTF::PassRefPtr< JSC::Structure >, const JSC::Identifier &)
virtual void markChildren(JSC::MarkStack &markStack)
QVector< QScriptMetaType > m_types
int keyCount() const
Returns the number of keys.
const T & at(int i) const
Returns the item at index position i in the vector.
Definition: qvector.h:350
JSC::JSValue newVariant(const QVariant &)
static QScriptMetaType variant()
bool convert(Type t)
Casts the variant to the requested type, t.
Definition: qvariant.cpp:2959
static JSC::JSValue JSC_HOST_CALL qmetaobjectProtoFuncClassName(JSC::ExecState *exec, JSC::JSObject *, JSC::JSValue thisValue, const JSC::ArgList &)
int length() const
Same as size().
Definition: qbytearray.h:356
QScriptEngine::ValueOwnership ownership
static const QMetaObject staticMetaObject
static bool hasMethodAccess(const QMetaMethod &method, int index, const QScriptEngine::QObjectWrapOptions &opt)
const char * constData() const
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:433
static bool convertValue(JSC::ExecState *, JSC::JSValue value, int type, void *ptr)
MethodType methodType() const
Returns the type of this method (signal, slot, or method).
static unsigned flagsForMetaProperty(const QMetaProperty &prop)
static bool isDate(JSC::JSValue)
const_iterator constBegin() const
Returns a const STL-style iterator pointing to the first item in the hash.
Definition: qhash.h:466
virtual Type type() const
const_iterator constEnd() const
Returns a const STL-style iterator pointing to the imaginary item after the last item in the hash...
Definition: qhash.h:469
virtual JSC::ConstructType getConstructData(JSC::ConstructData &)
QList< QByteArray > parameterTypes() const
Returns a list of parameter types.
static bool isRegExp(JSC::JSValue)
#define Q_ASSERT_X(cond, where, what)
Definition: qglobal.h:1837
QScriptMetaType argumentType(int arg) const
static int methodNameLength(const QMetaMethod &method)
Calculates the length of the name of the given method by looking for the first &#39;(&#39; character...
QString arg(qlonglong a, int fieldwidth=0, int base=10, const QChar &fillChar=QLatin1Char(' ')) const Q_REQUIRED_RESULT
Definition: qstring.cpp:7186
int userType() const
Returns the storage type of the value stored in the variant.
Definition: qvariant.cpp:1913
QString & append(QChar c)
Definition: qstring.cpp:1777
iterator end()
Returns an STL-style iterator pointing to the imaginary item after the last item in the hash...
Definition: qhash.h:467
const char * name() const
Returns this property&#39;s name.
static const struct @32 types[]
static bool isEnumerableMetaProperty(const QMetaProperty &prop, const QMetaObject *mo, int index)
static const bool GeneratePropertyFunctions
static const char * typeName(int type)
Returns the type name associated with the given type, or 0 if no matching type was found...
Definition: qmetatype.cpp:406
virtual bool getOwnPropertySlot(QScriptObject *, JSC::ExecState *, const JSC::Identifier &propertyName, JSC::PropertySlot &)
QObjectData(QScriptEnginePrivate *engine)
static QString fromLatin1(const char *, int size=-1)
Returns a QString initialized with the first size characters of the Latin-1 string str...
Definition: qstring.cpp:4188
int indexOfMethod(const char *method) const
Finds method and returns its index; otherwise returns -1.
QList< QByteArray > dynamicPropertyNames() const
Returns the names of all properties that were dynamically added to the object using setProperty()...
Definition: qobject.cpp:3839
static bool isQObject(JSC::JSValue)
QObject * parent() const
Returns a pointer to the parent object.
Definition: qobject.h:273
#define ctx
Definition: qgl.cpp:6094
bool maybeOverloaded() const
virtual bool getOwnPropertyDescriptor(JSC::ExecState *, const JSC::Identifier &propertyName, JSC::PropertyDescriptor &)
const void * constData() const
Definition: qvariant.cpp:3065
static QScriptMetaType metaType(int typeId, const QByteArray &name)
int key
int size() const
Returns the number of items in the list.
Definition: qlist.h:137
static const JSC::ClassInfo info
const char * className() const
Returns the class name.
Definition: qobjectdefs.h:491
static QByteArray methodName(const char *signature, int nameLength)
Makes a deep copy of the first nameLength characters of the given method signature and returns the co...
int qstrncmp(const char *str1, const char *str2, uint len)
Definition: qbytearray.h:101
QVariant read(const QObject *obj) const
Reads the property&#39;s value from the given object.
const QObjectList & children() const
Returns a list of child objects.
Definition: qobject.h:197
static const char * get(QDBusError::ErrorType code)
Definition: qdbuserror.cpp:141
JSC::JSValue newQObject(QObject *object, QScriptEngine::ValueOwnership ownership=QScriptEngine::QtOwnership, const QScriptEngine::QObjectWrapOptions &options=0)
QMetaEnum enumerator(int index) const
Returns the meta-data for the enumerator with the given index.
int keyToValue(const char *key) const
Returns the integer value of the given enumeration key, or -1 if key is not defined.
int size() const
Returns the number of bytes in this byte array.
Definition: qbytearray.h:402
int attributes() const
#define QT_USE_NAMESPACE
This macro expands to using QT_NAMESPACE if QT_NAMESPACE is defined and nothing otherwise.
Definition: qglobal.h:88
quint16 index
static QVariant & variantValue(JSC::JSValue value)
const QMetaObject * metaObject() const
QScriptEngine::QObjectWrapOptions options
static JSC::JSValue JSC_HOST_CALL call(JSC::ExecState *, JSC::JSObject *, JSC::JSValue, const JSC::ArgList &)
int mostGeneralMethod(QMetaMethod *out=0) const
QMetaMethod constructor(int index) const
Returns the meta-data for the constructor with the given index.
const T * const_iterator
The QVector::const_iterator typedef provides an STL-style const iterator for QVector and QStack...
Definition: qvector.h:245
void setDelegate(QScriptObjectDelegate *delegate)
QMetaMethod method(int index) const
Returns the meta-data for the method with the given index.
The QMetaProperty class provides meta-data about a property.
Definition: qmetaobject.h:176
bool isEmpty() const
Returns true if the byte array has size 0; otherwise returns false.
Definition: qbytearray.h:421
T * data()
Returns a pointer to the data stored in the vector.
Definition: qvector.h:152
QByteArray name() const
bool isEmpty() const
Returns true if the vector has size 0; otherwise returns false.
Definition: qvector.h:139
int qstrcmp(const QByteArray &str1, const char *str2)
Definition: qbytearray.cpp:336
virtual bool deleteProperty(JSC::ExecState *, const JSC::Identifier &propertyName)
QScriptMetaType returnType() const
int propertyOffset() const
Returns the property offset for this class; i.e.
const char * signature() const
Returns the signature of this method (e.g., setValue(double)).
iterator find(const Key &key)
Returns an iterator pointing to the item with the key in the hash.
Definition: qhash.h:865
virtual bool compareToObject(QScriptObject *, JSC::ExecState *, JSC::JSObject *)
Access access() const
Returns the access specification of this method (private, protected, or public).
QScriptEngine::QObjectWrapOptions options
QList< int > overloadedIndexes() const
bool write(QObject *obj, const QVariant &value) const
Writes value as the property&#39;s value to the given object.
static bool isArray(JSC::JSValue)
bool isValid() const
Returns true if the storage type of this variant is not QVariant::Invalid; otherwise returns false...
Definition: qvariant.h:485
bool operator==(const QScriptMetaType &other) const
void callConnectNotify(const char *signal)
void prepend(const T &t)
Inserts value at the beginning of the vector.
Definition: qvector.h:378
The QScriptValue class acts as a container for the Qt Script data types.
Definition: qscriptvalue.h:57
static const JSC::ClassInfo info
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
void execute(int slotIndex, void **argv)
static JSC::JSObject * construct(JSC::ExecState *, JSC::JSObject *, const JSC::ArgList &)
QScriptMetaMethod(const QVector< QScriptMetaType > &types)
int size() const
Returns the number of items in the vector.
Definition: qvector.h:137
int methodCount() const
Returns the number of methods known to the meta-object system in this class, including the number of ...
virtual JSC::CallType getCallData(JSC::CallData &)
QList< T > findChildren(const QString &aName=QString()) const
Returns all children of this object with the given name that can be cast to type T, or an empty list if there are no such objects.
Definition: qobject.h:162
iterator erase(iterator it)
Removes the (key, value) pair associated with the iterator pos from the hash, and returns an iterator...
Definition: qhash.h:827
#define INT_MAX
static QVariant jscValueToVariant(JSC::ExecState *, JSC::JSValue value, int targetType)
QByteArray convertToLatin1(const JSC::UString &str)
The QMetaMethod class provides meta-data about a member function.
Definition: qmetaobject.h:56
static const uint qt_meta_data_QObjectConnectionManager[]
virtual const QMetaObject * metaObject() const
Returns a pointer to the meta-object of this object.
QMetaProperty property(int index) const
Returns the meta-data for the property with the given index.
void registerWrapper(QScriptObject *wrapper, QScriptEngine::ValueOwnership ownership, const QScriptEngine::QObjectWrapOptions &options)
int size() const
bool endsWith(const QByteArray &a) const
Returns true if this byte array ends with byte array ba; otherwise returns false. ...
QBool contains(char c) const
Returns true if the byte array contains the character ch; otherwise returns false.
Definition: qbytearray.h:525
virtual bool getOwnPropertySlot(JSC::ExecState *, const JSC::Identifier &propertyName, JSC::PropertySlot &)
QScriptEngine * engine
Definition: qscriptable_p.h:54
int value(int index) const
Returns the value with the given index; or returns -1 if there is no such value.
#define Q_FUNC_INFO
Definition: qglobal.h:1871