1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the QtScript module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39
40 #include "qscriptdeclarativeclass_p.h"
41 #include "qscriptdeclarativeobject_p.h"
42 #include "qscriptobject_p.h"
43 #include "qscriptstaticscopeobject_p.h"
44 #include <QtScript/qscriptstring.h>
45 #include <QtScript/qscriptengine.h>
46 #include <QtScript/qscriptengineagent.h>
47 #include <private/qscriptengine_p.h>
48 #include <private/qscriptvalue_p.h>
49 #include <private/qscriptqobject_p.h>
50 #include <private/qscriptactivationobject_p.h>
51 #include <QtCore/qstringlist.h>
52
53 QT_BEGIN_NAMESPACE
54
55 /*!
56 \class QScriptDeclarativeClass::Value
57 \internal
58 \brief The QScriptDeclarativeClass::Value class acts as a container for JavaScript data types.
59
60 QScriptDeclarativeClass::Value class is similar to QScriptValue, but it is slightly faster.
61 Unlike QScriptValue, however, Value instances cannot be stored as they may not survive garbage
62 collection. If you need to store a Value, convert it to a QScriptValue and store that.
63 */
64
Value()65 QScriptDeclarativeClass::Value::Value()
66 {
67 new (this) JSC::JSValue(JSC::jsUndefined());
68 }
69
Value(const Value & other)70 QScriptDeclarativeClass::Value::Value(const Value &other)
71 {
72 new (this) JSC::JSValue((JSC::JSValue &)other);
73 }
74
jscToValue(const JSC::JSValue & val)75 static QScriptDeclarativeClass::Value jscToValue(const JSC::JSValue &val)
76 {
77 return QScriptDeclarativeClass::Value((QScriptDeclarativeClass::Value &)val);
78 }
79
Value(QScriptContext * ctxt,int value)80 QScriptDeclarativeClass::Value::Value(QScriptContext *ctxt, int value)
81 {
82 new (this) JSC::JSValue(QScriptEnginePrivate::frameForContext(ctxt), value);
83 }
84
Value(QScriptContext * ctxt,uint value)85 QScriptDeclarativeClass::Value::Value(QScriptContext *ctxt, uint value)
86 {
87 new (this) JSC::JSValue(QScriptEnginePrivate::frameForContext(ctxt), value);
88 }
89
Value(QScriptContext *,bool value)90 QScriptDeclarativeClass::Value::Value(QScriptContext *, bool value)
91 {
92 if (value)
93 new (this) JSC::JSValue(JSC::JSValue::JSTrue);
94 else
95 new (this) JSC::JSValue(JSC::JSValue::JSFalse);
96 }
97
Value(QScriptContext * ctxt,double value)98 QScriptDeclarativeClass::Value::Value(QScriptContext *ctxt, double value)
99 {
100 new (this) JSC::JSValue(QScriptEnginePrivate::frameForContext(ctxt), value);
101 }
102
Value(QScriptContext * ctxt,float value)103 QScriptDeclarativeClass::Value::Value(QScriptContext *ctxt, float value)
104 {
105 new (this) JSC::JSValue(QScriptEnginePrivate::frameForContext(ctxt), value);
106 }
107
Value(QScriptContext * ctxt,const QString & value)108 QScriptDeclarativeClass::Value::Value(QScriptContext *ctxt, const QString &value)
109 {
110 new (this) JSC::JSValue(JSC::jsString(QScriptEnginePrivate::frameForContext(ctxt), value));
111 }
112
Value(QScriptContext * ctxt,const QScriptValue & value)113 QScriptDeclarativeClass::Value::Value(QScriptContext *ctxt, const QScriptValue &value)
114 {
115 new (this) JSC::JSValue(QScriptEnginePrivate::get(ctxt->engine())->scriptValueToJSCValue(value));
116 }
117
Value(QScriptEngine * eng,int value)118 QScriptDeclarativeClass::Value::Value(QScriptEngine *eng, int value)
119 {
120 new (this) JSC::JSValue(QScriptEnginePrivate::get(eng)->currentFrame, value);
121 }
122
Value(QScriptEngine * eng,uint value)123 QScriptDeclarativeClass::Value::Value(QScriptEngine *eng, uint value)
124 {
125 new (this) JSC::JSValue(QScriptEnginePrivate::get(eng)->currentFrame, value);
126 }
127
Value(QScriptEngine * eng,bool value)128 QScriptDeclarativeClass::Value::Value(QScriptEngine *eng, bool value)
129 {
130 if (value)
131 new (this) JSC::JSValue(JSC::JSValue::JSTrue);
132 else
133 new (this) JSC::JSValue(JSC::JSValue::JSFalse);
134 }
135
Value(QScriptEngine * eng,double value)136 QScriptDeclarativeClass::Value::Value(QScriptEngine *eng, double value)
137 {
138 new (this) JSC::JSValue(QScriptEnginePrivate::get(eng)->currentFrame, value);
139 }
140
Value(QScriptEngine * eng,float value)141 QScriptDeclarativeClass::Value::Value(QScriptEngine *eng, float value)
142 {
143 new (this) JSC::JSValue(QScriptEnginePrivate::get(eng)->currentFrame, value);
144 }
145
Value(QScriptEngine * eng,const QString & value)146 QScriptDeclarativeClass::Value::Value(QScriptEngine *eng, const QString &value)
147 {
148 new (this) JSC::JSValue(JSC::jsString(QScriptEnginePrivate::get(eng)->currentFrame, value));
149 }
150
Value(QScriptEngine * eng,const QScriptValue & value)151 QScriptDeclarativeClass::Value::Value(QScriptEngine *eng, const QScriptValue &value)
152 {
153 new (this) JSC::JSValue(QScriptEnginePrivate::get(eng)->scriptValueToJSCValue(value));
154 }
155
~Value()156 QScriptDeclarativeClass::Value::~Value()
157 {
158 ((JSC::JSValue *)(this))->~JSValue();
159 }
160
toScriptValue(QScriptEngine * engine) const161 QScriptValue QScriptDeclarativeClass::Value::toScriptValue(QScriptEngine *engine) const
162 {
163 return QScriptEnginePrivate::get(engine)->scriptValueFromJSCValue((JSC::JSValue &)*this);
164 }
165
PersistentIdentifier()166 QScriptDeclarativeClass::PersistentIdentifier::PersistentIdentifier()
167 : identifier(0), engine(0)
168 {
169 new (&d) JSC::Identifier();
170 }
171
~PersistentIdentifier()172 QScriptDeclarativeClass::PersistentIdentifier::~PersistentIdentifier()
173 {
174 if (engine) {
175 QScript::APIShim shim(engine);
176 ((JSC::Identifier &)d).JSC::Identifier::~Identifier();
177 } else {
178 ((JSC::Identifier &)d).JSC::Identifier::~Identifier();
179 }
180 }
181
PersistentIdentifier(const PersistentIdentifier & other)182 QScriptDeclarativeClass::PersistentIdentifier::PersistentIdentifier(const PersistentIdentifier &other)
183 {
184 identifier = other.identifier;
185 engine = other.engine;
186 new (&d) JSC::Identifier((JSC::Identifier &)(other.d));
187 }
188
189 QScriptDeclarativeClass::PersistentIdentifier &
operator =(const PersistentIdentifier & other)190 QScriptDeclarativeClass::PersistentIdentifier::operator=(const PersistentIdentifier &other)
191 {
192 identifier = other.identifier;
193 engine = other.engine;
194 ((JSC::Identifier &)d) = (JSC::Identifier &)(other.d);
195 return *this;
196 }
197
toString() const198 QString QScriptDeclarativeClass::PersistentIdentifier::toString() const
199 {
200 return ((JSC::Identifier &)d).ustring();
201 }
202
QScriptDeclarativeClass(QScriptEngine * engine)203 QScriptDeclarativeClass::QScriptDeclarativeClass(QScriptEngine *engine)
204 : d_ptr(new QScriptDeclarativeClassPrivate)
205 {
206 Q_ASSERT(sizeof(void*) == sizeof(JSC::Identifier));
207 d_ptr->q_ptr = this;
208 d_ptr->engine = engine;
209 }
210
newObject(QScriptEngine * engine,QScriptDeclarativeClass * scriptClass,Object * object)211 QScriptValue QScriptDeclarativeClass::newObject(QScriptEngine *engine,
212 QScriptDeclarativeClass *scriptClass,
213 Object *object)
214 {
215 Q_ASSERT(engine);
216 Q_ASSERT(scriptClass);
217
218 QScriptEnginePrivate *p = static_cast<QScriptEnginePrivate *>(QObjectPrivate::get(engine));
219 QScript::APIShim shim(p);
220
221 JSC::ExecState* exec = p->currentFrame;
222 QScriptObject *result = new (exec) QScriptObject(p->scriptObjectStructure);
223 result->setDelegate(new QScript::DeclarativeObjectDelegate(scriptClass, object));
224 return p->scriptValueFromJSCValue(result);
225 }
226
227 QScriptDeclarativeClass::Value
newObjectValue(QScriptEngine * engine,QScriptDeclarativeClass * scriptClass,Object * object)228 QScriptDeclarativeClass::newObjectValue(QScriptEngine *engine,
229 QScriptDeclarativeClass *scriptClass,
230 Object *object)
231 {
232 Q_ASSERT(engine);
233 Q_ASSERT(scriptClass);
234
235 QScriptEnginePrivate *p = static_cast<QScriptEnginePrivate *>(QObjectPrivate::get(engine));
236 QScript::APIShim shim(p);
237
238 JSC::ExecState* exec = p->currentFrame;
239 QScriptObject *result = new (exec) QScriptObject(p->scriptObjectStructure);
240 result->setDelegate(new QScript::DeclarativeObjectDelegate(scriptClass, object));
241 return jscToValue(JSC::JSValue(result));
242 }
243
scriptClass(const QScriptValue & v)244 QScriptDeclarativeClass *QScriptDeclarativeClass::scriptClass(const QScriptValue &v)
245 {
246 QScriptValuePrivate *d = QScriptValuePrivate::get(v);
247 if (!d || !d->isJSC())
248 return 0;
249 return QScriptEnginePrivate::declarativeClass(d->jscValue);
250 }
251
object(const QScriptValue & v)252 QScriptDeclarativeClass::Object *QScriptDeclarativeClass::object(const QScriptValue &v)
253 {
254 QScriptValuePrivate *d = QScriptValuePrivate::get(v);
255 if (!d || !d->isJSC())
256 return 0;
257 return QScriptEnginePrivate::declarativeObject(d->jscValue);
258 }
259
function(const QScriptValue & v,const Identifier & name)260 QScriptValue QScriptDeclarativeClass::function(const QScriptValue &v, const Identifier &name)
261 {
262 QScriptValuePrivate *d = QScriptValuePrivate::get(v);
263
264 if (!d->isObject())
265 return QScriptValue();
266
267 QScript::APIShim shim(d->engine);
268 JSC::ExecState *exec = d->engine->currentFrame;
269 JSC::JSObject *object = d->jscValue.getObject();
270 JSC::PropertySlot slot(const_cast<JSC::JSObject*>(object));
271 JSC::JSValue result;
272
273 JSC::Identifier id(exec, (JSC::UString::Rep *)name);
274
275 if (const_cast<JSC::JSObject*>(object)->getOwnPropertySlot(exec, id, slot)) {
276 result = slot.getValue(exec, id);
277 if (QScript::isFunction(result))
278 return d->engine->scriptValueFromJSCValue(result);
279 }
280
281 return QScriptValue();
282 }
283
property(const QScriptValue & v,const Identifier & name)284 QScriptValue QScriptDeclarativeClass::property(const QScriptValue &v, const Identifier &name)
285 {
286 QScriptValuePrivate *d = QScriptValuePrivate::get(v);
287
288 if (!d->isObject())
289 return QScriptValue();
290
291 QScript::APIShim shim(d->engine);
292 JSC::ExecState *exec = d->engine->currentFrame;
293 JSC::JSObject *object = d->jscValue.getObject();
294 JSC::PropertySlot slot(const_cast<JSC::JSObject*>(object));
295 JSC::JSValue result;
296
297 JSC::Identifier id(exec, (JSC::UString::Rep *)name);
298
299 if (const_cast<JSC::JSObject*>(object)->getOwnPropertySlot(exec, id, slot)) {
300 result = slot.getValue(exec, id);
301 return d->engine->scriptValueFromJSCValue(result);
302 }
303
304 return QScriptValue();
305 }
306
307 QScriptDeclarativeClass::Value
functionValue(const QScriptValue & v,const Identifier & name)308 QScriptDeclarativeClass::functionValue(const QScriptValue &v, const Identifier &name)
309 {
310 QScriptValuePrivate *d = QScriptValuePrivate::get(v);
311
312 if (!d->isObject())
313 return Value();
314
315 QScript::APIShim shim(d->engine);
316 JSC::ExecState *exec = d->engine->currentFrame;
317 JSC::JSObject *object = d->jscValue.getObject();
318 JSC::PropertySlot slot(const_cast<JSC::JSObject*>(object));
319 JSC::JSValue result;
320
321 JSC::Identifier id(exec, (JSC::UString::Rep *)name);
322
323 if (const_cast<JSC::JSObject*>(object)->getOwnPropertySlot(exec, id, slot)) {
324 result = slot.getValue(exec, id);
325 if (QScript::isFunction(result))
326 return jscToValue(result);
327 }
328
329 return Value();
330 }
331
332 QScriptDeclarativeClass::Value
propertyValue(const QScriptValue & v,const Identifier & name)333 QScriptDeclarativeClass::propertyValue(const QScriptValue &v, const Identifier &name)
334 {
335 QScriptValuePrivate *d = QScriptValuePrivate::get(v);
336
337 if (!d->isObject())
338 return Value();
339
340 QScript::APIShim shim(d->engine);
341 JSC::ExecState *exec = d->engine->currentFrame;
342 JSC::JSObject *object = d->jscValue.getObject();
343 JSC::PropertySlot slot(const_cast<JSC::JSObject*>(object));
344 JSC::JSValue result;
345
346 JSC::Identifier id(exec, (JSC::UString::Rep *)name);
347
348 if (const_cast<JSC::JSObject*>(object)->getOwnPropertySlot(exec, id, slot)) {
349 result = slot.getValue(exec, id);
350 return jscToValue(result);
351 }
352
353 return Value();
354 }
355
356 /*
357 Returns the scope chain entry at \a index. If index is less than 0, returns
358 entries starting at the end. For example, scopeChainValue(context, -1) will return
359 the value last in the scope chain.
360 */
scopeChainValue(QScriptContext * context,int index)361 QScriptValue QScriptDeclarativeClass::scopeChainValue(QScriptContext *context, int index)
362 {
363 context->activationObject(); //ensure the creation of the normal scope for native context
364 const JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(context);
365 QScriptEnginePrivate *engine = QScript::scriptEngineFromExec(frame);
366 QScript::APIShim shim(engine);
367
368 JSC::ScopeChainNode *node = frame->scopeChain();
369 JSC::ScopeChainIterator it(node);
370
371 if (index < 0) {
372 int count = 0;
373 for (it = node->begin(); it != node->end(); ++it)
374 ++count;
375
376 index = qAbs(index);
377 if (index > count)
378 return QScriptValue();
379 else
380 index = count - index;
381 }
382
383 for (it = node->begin(); it != node->end(); ++it) {
384
385 if (index == 0) {
386
387 JSC::JSObject *object = *it;
388 if (!object) return QScriptValue();
389
390 if (object->inherits(&QScript::QScriptActivationObject::info)
391 && (static_cast<QScript::QScriptActivationObject*>(object)->delegate() != 0)) {
392 // Return the object that property access is being delegated to
393 object = static_cast<QScript::QScriptActivationObject*>(object)->delegate();
394 }
395 return engine->scriptValueFromJSCValue(object);
396
397 } else {
398 --index;
399 }
400
401 }
402
403 return QScriptValue();
404 }
405
406 /*!
407 Enters a new execution context and returns the associated
408 QScriptContext object.
409
410 Once you are done with the context, you should call popContext() to
411 restore the old context.
412
413 By default, the `this' object of the new context is the Global Object.
414 The context's \l{QScriptContext::callee()}{callee}() will be invalid.
415
416 The context's scope chain initially contains only the Global Object
417 and the QScriptContext's activation object.
418
419 This function behaves exactly like QScriptEngine::popContext();
420 it exists because QScriptEngine::popContext() used to have a bug
421 that caused the scope chain of the new context to be incorrect.
422 */
pushCleanContext(QScriptEngine * engine)423 QScriptContext * QScriptDeclarativeClass::pushCleanContext(QScriptEngine *engine)
424 {
425 if (!engine)
426 return 0;
427
428 return engine->pushContext();
429 }
430
~QScriptDeclarativeClass()431 QScriptDeclarativeClass::~QScriptDeclarativeClass()
432 {
433 }
434
engine() const435 QScriptEngine *QScriptDeclarativeClass::engine() const
436 {
437 return d_ptr->engine;
438 }
439
supportsCall() const440 bool QScriptDeclarativeClass::supportsCall() const
441 {
442 return d_ptr->supportsCall;
443 }
444
setSupportsCall(bool c)445 void QScriptDeclarativeClass::setSupportsCall(bool c)
446 {
447 d_ptr->supportsCall = c;
448 }
449
450 QScriptDeclarativeClass::PersistentIdentifier
createPersistentIdentifier(const QString & str)451 QScriptDeclarativeClass::createPersistentIdentifier(const QString &str)
452 {
453 QScriptEnginePrivate *p =
454 static_cast<QScriptEnginePrivate *>(QObjectPrivate::get(d_ptr->engine));
455 QScript::APIShim shim(p);
456 JSC::ExecState* exec = p->currentFrame;
457
458 PersistentIdentifier rv(p);
459 new (&rv.d) JSC::Identifier(exec, (UChar *)str.constData(), str.size());
460 rv.identifier = (void *)((JSC::Identifier &)rv.d).ustring().rep();
461 return rv;
462 }
463
464 QScriptDeclarativeClass::PersistentIdentifier
createPersistentIdentifier(const Identifier & id)465 QScriptDeclarativeClass::createPersistentIdentifier(const Identifier &id)
466 {
467 QScriptEnginePrivate *p =
468 static_cast<QScriptEnginePrivate *>(QObjectPrivate::get(d_ptr->engine));
469 QScript::APIShim shim(p);
470 JSC::ExecState* exec = p->currentFrame;
471
472 PersistentIdentifier rv(p);
473 new (&rv.d) JSC::Identifier(exec, (JSC::UString::Rep *)id);
474 rv.identifier = (void *)((JSC::Identifier &)rv.d).ustring().rep();
475 return rv;
476 }
477
toString(const Identifier & identifier)478 QString QScriptDeclarativeClass::toString(const Identifier &identifier)
479 {
480 JSC::UString::Rep *r = (JSC::UString::Rep *)identifier;
481 return QString((QChar *)r->data(), r->size());
482 }
483
startsWithUpper(const Identifier & identifier)484 bool QScriptDeclarativeClass::startsWithUpper(const Identifier &identifier)
485 {
486 JSC::UString::Rep *r = (JSC::UString::Rep *)identifier;
487 if (r->size() < 1)
488 return false;
489 return QChar::category((ushort)(r->data()[0])) == QChar::Letter_Uppercase;
490 }
491
toArrayIndex(const Identifier & identifier,bool * ok)492 quint32 QScriptDeclarativeClass::toArrayIndex(const Identifier &identifier, bool *ok)
493 {
494 JSC::UString::Rep *r = (JSC::UString::Rep *)identifier;
495 JSC::UString s(r);
496 return s.toArrayIndex(ok);
497 }
498
499 QScriptClass::QueryFlags
queryProperty(Object * object,const Identifier & name,QScriptClass::QueryFlags flags)500 QScriptDeclarativeClass::queryProperty(Object *object, const Identifier &name,
501 QScriptClass::QueryFlags flags)
502 {
503 Q_UNUSED(object);
504 Q_UNUSED(name);
505 Q_UNUSED(flags);
506 return {};
507 }
508
509 QScriptDeclarativeClass::Value
property(Object * object,const Identifier & name)510 QScriptDeclarativeClass::property(Object *object, const Identifier &name)
511 {
512 Q_UNUSED(object);
513 Q_UNUSED(name);
514 return Value();
515 }
516
setProperty(Object * object,const Identifier & name,const QScriptValue & value)517 void QScriptDeclarativeClass::setProperty(Object *object, const Identifier &name,
518 const QScriptValue &value)
519 {
520 Q_UNUSED(object);
521 Q_UNUSED(name);
522 Q_UNUSED(value);
523 }
524
525 QScriptValue::PropertyFlags
propertyFlags(Object * object,const Identifier & name)526 QScriptDeclarativeClass::propertyFlags(Object *object, const Identifier &name)
527 {
528 Q_UNUSED(object);
529 Q_UNUSED(name);
530 return {};
531 }
532
call(Object * object,QScriptContext * ctxt)533 QScriptDeclarativeClass::Value QScriptDeclarativeClass::call(Object *object,
534 QScriptContext *ctxt)
535 {
536 Q_UNUSED(object);
537 Q_UNUSED(ctxt);
538 return Value();
539 }
540
compare(Object * o,Object * o2)541 bool QScriptDeclarativeClass::compare(Object *o, Object *o2)
542 {
543 return o == o2;
544 }
545
propertyNames(Object * object)546 QStringList QScriptDeclarativeClass::propertyNames(Object *object)
547 {
548 Q_UNUSED(object);
549 return QStringList();
550 }
551
isQObject() const552 bool QScriptDeclarativeClass::isQObject() const
553 {
554 return false;
555 }
556
toQObject(Object *,bool * ok)557 QObject *QScriptDeclarativeClass::toQObject(Object *, bool *ok)
558 {
559 if (ok) *ok = false;
560 return 0;
561 }
562
toVariant(Object *,bool * ok)563 QVariant QScriptDeclarativeClass::toVariant(Object *, bool *ok)
564 {
565 if (ok) *ok = false;
566 return QVariant();
567 }
568
context() const569 QScriptContext *QScriptDeclarativeClass::context() const
570 {
571 return d_ptr->context;
572 }
573
574 /*!
575 Creates a scope object with a fixed set of undeletable properties.
576 */
newStaticScopeObject(QScriptEngine * engine,int propertyCount,const QString * names,const QScriptValue * values,const QScriptValue::PropertyFlags * flags)577 QScriptValue QScriptDeclarativeClass::newStaticScopeObject(
578 QScriptEngine *engine, int propertyCount, const QString *names,
579 const QScriptValue *values, const QScriptValue::PropertyFlags *flags)
580 {
581 QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(engine);
582 QScript::APIShim shim(eng_p);
583 JSC::ExecState *exec = eng_p->currentFrame;
584 QScriptStaticScopeObject::PropertyInfo *props = new QScriptStaticScopeObject::PropertyInfo[propertyCount];
585 for (int i = 0; i < propertyCount; ++i) {
586 unsigned attribs = QScriptEnginePrivate::propertyFlagsToJSCAttributes(flags[i]);
587 Q_ASSERT_X(attribs & JSC::DontDelete, Q_FUNC_INFO, "All properties must be undeletable");
588 JSC::Identifier id = JSC::Identifier(exec, names[i]);
589 JSC::JSValue jsval = eng_p->scriptValueToJSCValue(values[i]);
590 props[i] = QScriptStaticScopeObject::PropertyInfo(id, jsval, attribs);
591 }
592 QScriptValue result = eng_p->scriptValueFromJSCValue(new (exec)QScriptStaticScopeObject(eng_p->staticScopeObjectStructure,
593 propertyCount, props));
594 delete[] props;
595 return result;
596 }
597
598 /*!
599 Creates a static scope object that's initially empty, but to which new
600 properties can be added.
601 */
newStaticScopeObject(QScriptEngine * engine)602 QScriptValue QScriptDeclarativeClass::newStaticScopeObject(QScriptEngine *engine)
603 {
604 QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(engine);
605 QScript::APIShim shim(eng_p);
606 return eng_p->scriptValueFromJSCValue(new (eng_p->currentFrame)QScriptStaticScopeObject(eng_p->staticScopeObjectStructure));
607 }
608
609 QT_END_NAMESPACE
610