Qt 4.8
qscriptdeclarativeclass.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 QtDeclarative 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 
26 #include "qscriptobject_p.h"
28 #include <QtScript/qscriptstring.h>
29 #include <QtScript/qscriptengine.h>
30 #include <QtScript/qscriptengineagent.h>
31 #include <private/qscriptengine_p.h>
32 #include <private/qscriptvalue_p.h>
33 #include <private/qscriptqobject_p.h>
34 #include <private/qscriptactivationobject_p.h>
35 #include <QtCore/qstringlist.h>
36 
38 
53 {
54  new (this) JSC::JSValue(JSC::jsUndefined());
55 }
56 
58 {
59  new (this) JSC::JSValue((JSC::JSValue &)other);
60 }
61 
62 static QScriptDeclarativeClass::Value jscToValue(const JSC::JSValue &val)
63 {
65 }
66 
68 {
69  new (this) JSC::JSValue(QScriptEnginePrivate::frameForContext(ctxt), value);
70 }
71 
73 {
74  new (this) JSC::JSValue(QScriptEnginePrivate::frameForContext(ctxt), value);
75 }
76 
78 {
79  if (value)
80  new (this) JSC::JSValue(JSC::JSValue::JSTrue);
81  else
82  new (this) JSC::JSValue(JSC::JSValue::JSFalse);
83 }
84 
86 {
87  new (this) JSC::JSValue(QScriptEnginePrivate::frameForContext(ctxt), value);
88 }
89 
91 {
92  new (this) JSC::JSValue(QScriptEnginePrivate::frameForContext(ctxt), value);
93 }
94 
96 {
97  new (this) JSC::JSValue(JSC::jsString(QScriptEnginePrivate::frameForContext(ctxt), value));
98 }
99 
101 {
102  new (this) JSC::JSValue(QScriptEnginePrivate::get(ctxt->engine())->scriptValueToJSCValue(value));
103 }
104 
106 {
107  new (this) JSC::JSValue(QScriptEnginePrivate::get(eng)->currentFrame, value);
108 }
109 
111 {
112  new (this) JSC::JSValue(QScriptEnginePrivate::get(eng)->currentFrame, value);
113 }
114 
116 {
117  if (value)
118  new (this) JSC::JSValue(JSC::JSValue::JSTrue);
119  else
120  new (this) JSC::JSValue(JSC::JSValue::JSFalse);
121 }
122 
124 {
125  new (this) JSC::JSValue(QScriptEnginePrivate::get(eng)->currentFrame, value);
126 }
127 
129 {
130  new (this) JSC::JSValue(QScriptEnginePrivate::get(eng)->currentFrame, value);
131 }
132 
134 {
135  new (this) JSC::JSValue(JSC::jsString(QScriptEnginePrivate::get(eng)->currentFrame, value));
136 }
137 
139 {
140  new (this) JSC::JSValue(QScriptEnginePrivate::get(eng)->scriptValueToJSCValue(value));
141 }
142 
144 {
145  ((JSC::JSValue *)(this))->~JSValue();
146 }
147 
149 {
150  return QScriptEnginePrivate::get(engine)->scriptValueFromJSCValue((JSC::JSValue &)*this);
151 }
152 
154  : identifier(0), engine(0)
155 {
156  new (&d) JSC::Identifier();
157 }
158 
160 {
161  if (engine) {
162  QScript::APIShim shim(engine);
163  ((JSC::Identifier &)d).JSC::Identifier::~Identifier();
164  } else {
165  ((JSC::Identifier &)d).JSC::Identifier::~Identifier();
166  }
167 }
168 
170 {
171  identifier = other.identifier;
172  engine = other.engine;
173  new (&d) JSC::Identifier((JSC::Identifier &)(other.d));
174 }
175 
178 {
179  identifier = other.identifier;
180  engine = other.engine;
181  ((JSC::Identifier &)d) = (JSC::Identifier &)(other.d);
182  return *this;
183 }
184 
186 {
187  return ((JSC::Identifier &)d).ustring();
188 }
189 
192 {
193  Q_ASSERT(sizeof(void*) == sizeof(JSC::Identifier));
194  d_ptr->q_ptr = this;
195  d_ptr->engine = engine;
196 }
197 
200  Object *object)
201 {
202  Q_ASSERT(engine);
203  Q_ASSERT(scriptClass);
204 
206  QScript::APIShim shim(p);
207 
208  JSC::ExecState* exec = p->currentFrame;
209  QScriptObject *result = new (exec) QScriptObject(p->scriptObjectStructure);
210  result->setDelegate(new QScript::DeclarativeObjectDelegate(scriptClass, object));
211  return p->scriptValueFromJSCValue(result);
212 }
213 
217  Object *object)
218 {
219  Q_ASSERT(engine);
220  Q_ASSERT(scriptClass);
221 
222  QScriptEnginePrivate *p = static_cast<QScriptEnginePrivate *>(QObjectPrivate::get(engine));
223  QScript::APIShim shim(p);
224 
225  JSC::ExecState* exec = p->currentFrame;
226  QScriptObject *result = new (exec) QScriptObject(p->scriptObjectStructure);
227  result->setDelegate(new QScript::DeclarativeObjectDelegate(scriptClass, object));
228  return jscToValue(JSC::JSValue(result));
229 }
230 
232 {
234  if (!d || !d->isJSC())
235  return 0;
237 }
238 
240 {
242  if (!d || !d->isJSC())
243  return 0;
245 }
246 
248 {
250 
251  if (!d->isObject())
252  return QScriptValue();
253 
254  QScript::APIShim shim(d->engine);
255  JSC::ExecState *exec = d->engine->currentFrame;
256  JSC::JSObject *object = d->jscValue.getObject();
257  JSC::PropertySlot slot(const_cast<JSC::JSObject*>(object));
258  JSC::JSValue result;
259 
260  JSC::Identifier id(exec, (JSC::UString::Rep *)name);
261 
262  if (const_cast<JSC::JSObject*>(object)->getOwnPropertySlot(exec, id, slot)) {
263  result = slot.getValue(exec, id);
264  if (QScript::isFunction(result))
265  return d->engine->scriptValueFromJSCValue(result);
266  }
267 
268  return QScriptValue();
269 }
270 
272 {
274 
275  if (!d->isObject())
276  return QScriptValue();
277 
278  QScript::APIShim shim(d->engine);
279  JSC::ExecState *exec = d->engine->currentFrame;
280  JSC::JSObject *object = d->jscValue.getObject();
281  JSC::PropertySlot slot(const_cast<JSC::JSObject*>(object));
282  JSC::JSValue result;
283 
284  JSC::Identifier id(exec, (JSC::UString::Rep *)name);
285 
286  if (const_cast<JSC::JSObject*>(object)->getOwnPropertySlot(exec, id, slot)) {
287  result = slot.getValue(exec, id);
288  return d->engine->scriptValueFromJSCValue(result);
289  }
290 
291  return QScriptValue();
292 }
293 
296 {
298 
299  if (!d->isObject())
300  return Value();
301 
302  QScript::APIShim shim(d->engine);
303  JSC::ExecState *exec = d->engine->currentFrame;
304  JSC::JSObject *object = d->jscValue.getObject();
305  JSC::PropertySlot slot(const_cast<JSC::JSObject*>(object));
306  JSC::JSValue result;
307 
308  JSC::Identifier id(exec, (JSC::UString::Rep *)name);
309 
310  if (const_cast<JSC::JSObject*>(object)->getOwnPropertySlot(exec, id, slot)) {
311  result = slot.getValue(exec, id);
312  if (QScript::isFunction(result))
313  return jscToValue(result);
314  }
315 
316  return Value();
317 }
318 
321 {
323 
324  if (!d->isObject())
325  return Value();
326 
327  QScript::APIShim shim(d->engine);
328  JSC::ExecState *exec = d->engine->currentFrame;
329  JSC::JSObject *object = d->jscValue.getObject();
330  JSC::PropertySlot slot(const_cast<JSC::JSObject*>(object));
331  JSC::JSValue result;
332 
333  JSC::Identifier id(exec, (JSC::UString::Rep *)name);
334 
335  if (const_cast<JSC::JSObject*>(object)->getOwnPropertySlot(exec, id, slot)) {
336  result = slot.getValue(exec, id);
337  return jscToValue(result);
338  }
339 
340  return Value();
341 }
342 
343 /*
344 Returns the scope chain entry at \a index. If index is less than 0, returns
345 entries starting at the end. For example, scopeChainValue(context, -1) will return
346 the value last in the scope chain.
347 */
349 {
350  context->activationObject(); //ensure the creation of the normal scope for native context
353  QScript::APIShim shim(engine);
354 
355  JSC::ScopeChainNode *node = frame->scopeChain();
356  JSC::ScopeChainIterator it(node);
357 
358  if (index < 0) {
359  int count = 0;
360  for (it = node->begin(); it != node->end(); ++it)
361  ++count;
362 
363  index = qAbs(index);
364  if (index > count)
365  return QScriptValue();
366  else
367  index = count - index;
368  }
369 
370  for (it = node->begin(); it != node->end(); ++it) {
371 
372  if (index == 0) {
373 
374  JSC::JSObject *object = *it;
375  if (!object) return QScriptValue();
376 
377  if (object->inherits(&QScript::QScriptActivationObject::info)
378  && (static_cast<QScript::QScriptActivationObject*>(object)->delegate() != 0)) {
379  // Return the object that property access is being delegated to
380  object = static_cast<QScript::QScriptActivationObject*>(object)->delegate();
381  }
382  return engine->scriptValueFromJSCValue(object);
383 
384  } else {
385  --index;
386  }
387 
388  }
389 
390  return QScriptValue();
391 }
392 
409 {
410  if (!engine)
411  return 0;
412 
414  QScript::APIShim shim(d);
415 
416  JSC::CallFrame* newFrame = d->pushContext(d->currentFrame,
417  d->currentFrame->globalData().dynamicGlobalObject,
418  JSC::ArgList(), /*callee = */0, false, true);
419 
420  if (engine->agent())
421  engine->agent()->contextPush();
422 
423  return d->contextForFrame(newFrame);
424 }
425 
427 {
428 }
429 
431 {
432  return d_ptr->engine;
433 }
434 
436 {
437  return d_ptr->supportsCall;
438 }
439 
441 {
442  d_ptr->supportsCall = c;
443 }
444 
447 {
450  QScript::APIShim shim(p);
451  JSC::ExecState* exec = p->currentFrame;
452 
453  PersistentIdentifier rv(p);
454  new (&rv.d) JSC::Identifier(exec, (UChar *)str.constData(), str.size());
455  rv.identifier = (void *)((JSC::Identifier &)rv.d).ustring().rep();
456  return rv;
457 }
458 
461 {
464  QScript::APIShim shim(p);
465  JSC::ExecState* exec = p->currentFrame;
466 
467  PersistentIdentifier rv(p);
468  new (&rv.d) JSC::Identifier(exec, (JSC::UString::Rep *)id);
469  rv.identifier = (void *)((JSC::Identifier &)rv.d).ustring().rep();
470  return rv;
471 }
472 
474 {
475  JSC::UString::Rep *r = (JSC::UString::Rep *)identifier;
476  return QString((QChar *)r->data(), r->size());
477 }
478 
480 {
481  JSC::UString::Rep *r = (JSC::UString::Rep *)identifier;
482  if (r->size() < 1)
483  return false;
484  return QChar::category((ushort)(r->data()[0])) == QChar::Letter_Uppercase;
485 }
486 
488 {
489  JSC::UString::Rep *r = (JSC::UString::Rep *)identifier;
490  JSC::UString s(r);
491  return s.toArrayIndex(ok);
492 }
493 
494 QScriptClass::QueryFlags
496  QScriptClass::QueryFlags flags)
497 {
498  Q_UNUSED(object);
499  Q_UNUSED(name);
500  Q_UNUSED(flags);
501  return 0;
502 }
503 
506 {
507  Q_UNUSED(object);
508  Q_UNUSED(name);
509  return Value();
510 }
511 
513  const QScriptValue &value)
514 {
515  Q_UNUSED(object);
516  Q_UNUSED(name);
517  Q_UNUSED(value);
518 }
519 
522 {
523  Q_UNUSED(object);
524  Q_UNUSED(name);
525  return 0;
526 }
527 
529  QScriptContext *ctxt)
530 {
531  Q_UNUSED(object);
532  Q_UNUSED(ctxt);
533  return Value();
534 }
535 
537 {
538  return o == o2;
539 }
540 
542 {
543  Q_UNUSED(object);
544  return QStringList();
545 }
546 
548 {
549  return false;
550 }
551 
553 {
554  if (ok) *ok = false;
555  return 0;
556 }
557 
559 {
560  if (ok) *ok = false;
561  return QVariant();
562 }
563 
565 {
566  return d_ptr->context;
567 }
568 
573  QScriptEngine *engine, int propertyCount, const QString *names,
574  const QScriptValue *values, const QScriptValue::PropertyFlags *flags)
575 {
577  QScript::APIShim shim(eng_p);
578  JSC::ExecState *exec = eng_p->currentFrame;
580  for (int i = 0; i < propertyCount; ++i) {
581  unsigned attribs = QScriptEnginePrivate::propertyFlagsToJSCAttributes(flags[i]);
582  Q_ASSERT_X(attribs & JSC::DontDelete, Q_FUNC_INFO, "All properties must be undeletable");
583  JSC::Identifier id = JSC::Identifier(exec, names[i]);
584  JSC::JSValue jsval = eng_p->scriptValueToJSCValue(values[i]);
585  props[i] = QScriptStaticScopeObject::PropertyInfo(id, jsval, attribs);
586  }
588  propertyCount, props));
589  delete[] props;
590  return result;
591 }
592 
598 {
600  QScript::APIShim shim(eng_p);
602 }
603 
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:92
static unsigned propertyFlagsToJSCAttributes(const QScriptValue::PropertyFlags &flags)
double d
Definition: qnumeric_p.h:62
The QScriptContext class represents a Qt Script function invocation.
virtual Value call(Object *, QScriptContext *)
static JSC::ExecState * frameForContext(QScriptContext *context)
QScriptEnginePrivate * scriptEngineFromExec(const JSC::ExecState *exec)
unsigned char c[8]
Definition: qnumeric_p.h:62
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
bool startsWithUpper(const Identifier &)
virtual QVariant toVariant(Object *, bool *ok=0)
#define it(className, varName)
static QScriptEnginePrivate * get(QScriptEngine *q)
QScopedPointer< QScriptDeclarativeClassPrivate > d_ptr
static QScriptValue newObject(QScriptEngine *, QScriptDeclarativeClass *, Object *)
WTF::RefPtr< JSC::Structure > staticScopeObjectStructure
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.
static QScriptValuePrivate * get(const QScriptValue &q)
static QScriptValue function(const QScriptValue &, const Identifier &)
static QScriptDeclarativeClass::Value jscToValue(const JSC::JSValue &val)
static Object * object(const QScriptValue &)
QScriptEngine * engine() const
Returns the QScriptEngine that this QScriptContext belongs to.
static QScriptDeclarativeClass * declarativeClass(JSC::JSValue)
The QString class provides a Unicode character string.
Definition: qstring.h:83
Q_DECL_CONSTEXPR T qAbs(const T &t)
Definition: qglobal.h:1201
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
static QObjectPrivate * get(QObject *o)
Definition: qobject_p.h:177
PersistentIdentifier createPersistentIdentifier(const QString &)
The QChar class provides a 16-bit Unicode character.
Definition: qchar.h:72
The QScriptDeclarativeClass::Value class acts as a container for JavaScript data types.
virtual void setProperty(Object *, const Identifier &name, const QScriptValue &)
JSC::ExecState * currentFrame
Category category() const
Returns the character&#39;s category.
Definition: qchar.cpp:853
virtual bool compare(Object *, Object *)
The QScriptEngine class provides an environment for evaluating Qt Script code.
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
virtual QScriptClass::QueryFlags queryProperty(Object *, const Identifier &, QScriptClass::QueryFlags flags)
JSC::JSValue scriptValueToJSCValue(const QScriptValue &value)
static QScriptContext * contextForFrame(JSC::ExecState *frame)
static Value newObjectValue(QScriptEngine *, QScriptDeclarativeClass *, Object *)
int size() const
Returns the number of characters in this string.
Definition: qstring.h:102
QScriptValue toScriptValue(QScriptEngine *) const
virtual QScriptValue::PropertyFlags propertyFlags(Object *, const Identifier &)
const char * name
QScriptEngine * engine() const
The QStringList class provides a list of strings.
Definition: qstringlist.h:66
static Value functionValue(const QScriptValue &, const Identifier &)
bool isFunction(JSC::JSValue value)
unsigned int uint
Definition: qglobal.h:996
static Value propertyValue(const QScriptValue &, const Identifier &)
quint16 values[128]
bool isObject() const
static QScriptValue newStaticScopeObject(QScriptEngine *, int propertyCount, const QString *names, const QScriptValue *values, const QScriptValue::PropertyFlags *flags)
Creates a scope object with a fixed set of undeletable properties.
#define Q_ASSERT_X(cond, where, what)
Definition: qglobal.h:1837
quint32 toArrayIndex(const Identifier &, bool *ok)
WTF::RefPtr< JSC::Structure > scriptObjectStructure
PropertyFlags
Definition: qmetaobject_p.h:61
unsigned short ushort
Definition: qglobal.h:995
virtual QObject * toQObject(Object *, bool *ok=0)
unsigned int quint32
Definition: qglobal.h:938
static QScriptDeclarativeClass::Object * declarativeObject(JSC::JSValue)
static QScriptValue scopeChainValue(QScriptContext *, int index)
quint16 index
JSC::JSValue jscValue
QScriptEngineAgent * agent() const
Returns the agent currently installed on this engine, or 0 if no agent is installed.
void setDelegate(QScriptObjectDelegate *delegate)
static QScriptDeclarativeClass * scriptClass(const QScriptValue &)
virtual void contextPush()
This function is called when a new script context has been pushed.
QScriptValue scriptValueFromJSCValue(JSC::JSValue value)
QScriptValue activationObject() const
Returns the activation object of this QScriptContext.
Represent a scope for native function call.
QScriptDeclarativeClass(QScriptEngine *engine)
QScriptContext * context() const
ExecState CallFrame
Represents a static scope object.
The QScriptValue class acts as a container for the Qt Script data types.
Definition: qscriptvalue.h:57
#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
QString toString(const Identifier &)
QScriptEnginePrivate * engine
const QChar * constData() const
Returns a pointer to the data stored in the QString.
Definition: qstring.h:712
static QScriptContext * pushCleanContext(QScriptEngine *)
Enters a new execution context and returns the associated QScriptContext object.
static QScriptValue property(const QScriptValue &, const Identifier &)
PersistentIdentifier & operator=(const PersistentIdentifier &other)
virtual QStringList propertyNames(Object *)
#define Q_FUNC_INFO
Definition: qglobal.h:1871