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 | |
65 | QScriptDeclarativeClass::Value::Value() |
66 | { |
67 | new (this) JSC::JSValue(JSC::jsUndefined()); |
68 | } |
69 | |
70 | QScriptDeclarativeClass::Value::Value(const Value &other) |
71 | { |
72 | new (this) JSC::JSValue((JSC::JSValue &)other); |
73 | } |
74 | |
75 | static QScriptDeclarativeClass::Value jscToValue(const JSC::JSValue &val) |
76 | { |
77 | return QScriptDeclarativeClass::Value((QScriptDeclarativeClass::Value &)val); |
78 | } |
79 | |
80 | QScriptDeclarativeClass::Value::Value(QScriptContext *ctxt, int value) |
81 | { |
82 | new (this) JSC::JSValue(QScriptEnginePrivate::frameForContext(context: ctxt), value); |
83 | } |
84 | |
85 | QScriptDeclarativeClass::Value::Value(QScriptContext *ctxt, uint value) |
86 | { |
87 | new (this) JSC::JSValue(QScriptEnginePrivate::frameForContext(context: ctxt), value); |
88 | } |
89 | |
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 | |
98 | QScriptDeclarativeClass::Value::Value(QScriptContext *ctxt, double value) |
99 | { |
100 | new (this) JSC::JSValue(QScriptEnginePrivate::frameForContext(context: ctxt), value); |
101 | } |
102 | |
103 | QScriptDeclarativeClass::Value::Value(QScriptContext *ctxt, float value) |
104 | { |
105 | new (this) JSC::JSValue(QScriptEnginePrivate::frameForContext(context: ctxt), value); |
106 | } |
107 | |
108 | QScriptDeclarativeClass::Value::Value(QScriptContext *ctxt, const QString &value) |
109 | { |
110 | new (this) JSC::JSValue(JSC::jsString(exec: QScriptEnginePrivate::frameForContext(context: ctxt), s: value)); |
111 | } |
112 | |
113 | QScriptDeclarativeClass::Value::Value(QScriptContext *ctxt, const QScriptValue &value) |
114 | { |
115 | new (this) JSC::JSValue(QScriptEnginePrivate::get(q: ctxt->engine())->scriptValueToJSCValue(value)); |
116 | } |
117 | |
118 | QScriptDeclarativeClass::Value::Value(QScriptEngine *eng, int value) |
119 | { |
120 | new (this) JSC::JSValue(QScriptEnginePrivate::get(q: eng)->currentFrame, value); |
121 | } |
122 | |
123 | QScriptDeclarativeClass::Value::Value(QScriptEngine *eng, uint value) |
124 | { |
125 | new (this) JSC::JSValue(QScriptEnginePrivate::get(q: eng)->currentFrame, value); |
126 | } |
127 | |
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 | |
136 | QScriptDeclarativeClass::Value::Value(QScriptEngine *eng, double value) |
137 | { |
138 | new (this) JSC::JSValue(QScriptEnginePrivate::get(q: eng)->currentFrame, value); |
139 | } |
140 | |
141 | QScriptDeclarativeClass::Value::Value(QScriptEngine *eng, float value) |
142 | { |
143 | new (this) JSC::JSValue(QScriptEnginePrivate::get(q: eng)->currentFrame, value); |
144 | } |
145 | |
146 | QScriptDeclarativeClass::Value::Value(QScriptEngine *eng, const QString &value) |
147 | { |
148 | new (this) JSC::JSValue(JSC::jsString(exec: QScriptEnginePrivate::get(q: eng)->currentFrame, s: value)); |
149 | } |
150 | |
151 | QScriptDeclarativeClass::Value::Value(QScriptEngine *eng, const QScriptValue &value) |
152 | { |
153 | new (this) JSC::JSValue(QScriptEnginePrivate::get(q: eng)->scriptValueToJSCValue(value)); |
154 | } |
155 | |
156 | QScriptDeclarativeClass::Value::~Value() |
157 | { |
158 | ((JSC::JSValue *)(this))->~JSValue(); |
159 | } |
160 | |
161 | QScriptValue QScriptDeclarativeClass::Value::toScriptValue(QScriptEngine *engine) const |
162 | { |
163 | return QScriptEnginePrivate::get(q: engine)->scriptValueFromJSCValue(value: (JSC::JSValue &)*this); |
164 | } |
165 | |
166 | QScriptDeclarativeClass::PersistentIdentifier::PersistentIdentifier() |
167 | : identifier(0), engine(0) |
168 | { |
169 | new (&d) JSC::Identifier(); |
170 | } |
171 | |
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 | |
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 & |
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 | |
198 | QString QScriptDeclarativeClass::PersistentIdentifier::toString() const |
199 | { |
200 | return ((JSC::Identifier &)d).ustring(); |
201 | } |
202 | |
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 | |
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(o: 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(value: result); |
225 | } |
226 | |
227 | QScriptDeclarativeClass::Value |
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(o: 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 | |
244 | QScriptDeclarativeClass *QScriptDeclarativeClass::scriptClass(const QScriptValue &v) |
245 | { |
246 | QScriptValuePrivate *d = QScriptValuePrivate::get(q: v); |
247 | if (!d || !d->isJSC()) |
248 | return 0; |
249 | return QScriptEnginePrivate::declarativeClass(v: d->jscValue); |
250 | } |
251 | |
252 | QScriptDeclarativeClass::Object *QScriptDeclarativeClass::object(const QScriptValue &v) |
253 | { |
254 | QScriptValuePrivate *d = QScriptValuePrivate::get(q: v); |
255 | if (!d || !d->isJSC()) |
256 | return 0; |
257 | return QScriptEnginePrivate::declarativeObject(v: d->jscValue); |
258 | } |
259 | |
260 | QScriptValue QScriptDeclarativeClass::function(const QScriptValue &v, const Identifier &name) |
261 | { |
262 | QScriptValuePrivate *d = QScriptValuePrivate::get(q: 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, propertyName: id, slot)) { |
276 | result = slot.getValue(exec, propertyName: id); |
277 | if (QScript::isFunction(value: result)) |
278 | return d->engine->scriptValueFromJSCValue(value: result); |
279 | } |
280 | |
281 | return QScriptValue(); |
282 | } |
283 | |
284 | QScriptValue QScriptDeclarativeClass::property(const QScriptValue &v, const Identifier &name) |
285 | { |
286 | QScriptValuePrivate *d = QScriptValuePrivate::get(q: 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, propertyName: id, slot)) { |
300 | result = slot.getValue(exec, propertyName: id); |
301 | return d->engine->scriptValueFromJSCValue(value: result); |
302 | } |
303 | |
304 | return QScriptValue(); |
305 | } |
306 | |
307 | QScriptDeclarativeClass::Value |
308 | QScriptDeclarativeClass::functionValue(const QScriptValue &v, const Identifier &name) |
309 | { |
310 | QScriptValuePrivate *d = QScriptValuePrivate::get(q: 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, propertyName: id, slot)) { |
324 | result = slot.getValue(exec, propertyName: id); |
325 | if (QScript::isFunction(value: result)) |
326 | return jscToValue(val: result); |
327 | } |
328 | |
329 | return Value(); |
330 | } |
331 | |
332 | QScriptDeclarativeClass::Value |
333 | QScriptDeclarativeClass::propertyValue(const QScriptValue &v, const Identifier &name) |
334 | { |
335 | QScriptValuePrivate *d = QScriptValuePrivate::get(q: 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, propertyName: id, slot)) { |
349 | result = slot.getValue(exec, propertyName: id); |
350 | return jscToValue(val: 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 | */ |
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(exec: 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(t: 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(info: &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(value: 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 | */ |
423 | QScriptContext * QScriptDeclarativeClass::pushCleanContext(QScriptEngine *engine) |
424 | { |
425 | if (!engine) |
426 | return 0; |
427 | |
428 | return engine->pushContext(); |
429 | } |
430 | |
431 | QScriptDeclarativeClass::~QScriptDeclarativeClass() |
432 | { |
433 | } |
434 | |
435 | QScriptEngine *QScriptDeclarativeClass::engine() const |
436 | { |
437 | return d_ptr->engine; |
438 | } |
439 | |
440 | bool QScriptDeclarativeClass::supportsCall() const |
441 | { |
442 | return d_ptr->supportsCall; |
443 | } |
444 | |
445 | void QScriptDeclarativeClass::setSupportsCall(bool c) |
446 | { |
447 | d_ptr->supportsCall = c; |
448 | } |
449 | |
450 | QScriptDeclarativeClass::PersistentIdentifier |
451 | QScriptDeclarativeClass::createPersistentIdentifier(const QString &str) |
452 | { |
453 | QScriptEnginePrivate *p = |
454 | static_cast<QScriptEnginePrivate *>(QObjectPrivate::get(o: 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 |
465 | QScriptDeclarativeClass::createPersistentIdentifier(const Identifier &id) |
466 | { |
467 | QScriptEnginePrivate *p = |
468 | static_cast<QScriptEnginePrivate *>(QObjectPrivate::get(o: 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 | |
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 | |
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(ucs4: (ushort)(r->data()[0])) == QChar::Letter_Uppercase; |
490 | } |
491 | |
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 |
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 |
510 | QScriptDeclarativeClass::property(Object *object, const Identifier &name) |
511 | { |
512 | Q_UNUSED(object); |
513 | Q_UNUSED(name); |
514 | return Value(); |
515 | } |
516 | |
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 |
526 | QScriptDeclarativeClass::propertyFlags(Object *object, const Identifier &name) |
527 | { |
528 | Q_UNUSED(object); |
529 | Q_UNUSED(name); |
530 | return {}; |
531 | } |
532 | |
533 | QScriptDeclarativeClass::Value QScriptDeclarativeClass::call(Object *object, |
534 | QScriptContext *ctxt) |
535 | { |
536 | Q_UNUSED(object); |
537 | Q_UNUSED(ctxt); |
538 | return Value(); |
539 | } |
540 | |
541 | bool QScriptDeclarativeClass::compare(Object *o, Object *o2) |
542 | { |
543 | return o == o2; |
544 | } |
545 | |
546 | QStringList QScriptDeclarativeClass::propertyNames(Object *object) |
547 | { |
548 | Q_UNUSED(object); |
549 | return QStringList(); |
550 | } |
551 | |
552 | bool QScriptDeclarativeClass::isQObject() const |
553 | { |
554 | return false; |
555 | } |
556 | |
557 | QObject *QScriptDeclarativeClass::toQObject(Object *, bool *ok) |
558 | { |
559 | if (ok) *ok = false; |
560 | return 0; |
561 | } |
562 | |
563 | QVariant QScriptDeclarativeClass::toVariant(Object *, bool *ok) |
564 | { |
565 | if (ok) *ok = false; |
566 | return QVariant(); |
567 | } |
568 | |
569 | 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 | */ |
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(q: 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: 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(value: values[i]); |
590 | props[i] = QScriptStaticScopeObject::PropertyInfo(id, jsval, attribs); |
591 | } |
592 | QScriptValue result = eng_p->scriptValueFromJSCValue(value: 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 | */ |
602 | QScriptValue QScriptDeclarativeClass::newStaticScopeObject(QScriptEngine *engine) |
603 | { |
604 | QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(q: engine); |
605 | QScript::APIShim shim(eng_p); |
606 | return eng_p->scriptValueFromJSCValue(value: new (eng_p->currentFrame)QScriptStaticScopeObject(eng_p->staticScopeObjectStructure)); |
607 | } |
608 | |
609 | QT_END_NAMESPACE |
610 | |