source: trunk/src/script/bridge/qscriptdeclarativeclass.cpp@ 573

Last change on this file since 573 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

  • Property svn:eol-style set to native
File size: 10.8 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtDeclarative module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL-ONLY$
10** GNU Lesser General Public License Usage
11** This file may be used under the terms of the GNU Lesser
12** General Public License version 2.1 as published by the Free Software
13** Foundation and appearing in the file LICENSE.LGPL included in the
14** packaging of this file. Please review the following information to
15** ensure the GNU Lesser General Public License version 2.1 requirements
16** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17**
18** If you have questions regarding the use of this file, please contact
19** Nokia at [email protected].
20** $QT_END_LICENSE$
21**
22****************************************************************************/
23
24#include "qscriptdeclarativeclass_p.h"
25#include "qscriptdeclarativeobject_p.h"
26#include "qscriptobject_p.h"
27#include <QtScript/qscriptstring.h>
28#include <QtScript/qscriptengine.h>
29#include <QtScript/qscriptengineagent.h>
30#include <private/qscriptengine_p.h>
31#include <private/qscriptvalue_p.h>
32#include <private/qscriptqobject_p.h>
33#include <private/qscriptactivationobject_p.h>
34#include <QtCore/qstringlist.h>
35
36QT_BEGIN_NAMESPACE
37
38QScriptDeclarativeClass::PersistentIdentifier::PersistentIdentifier()
39{
40 new (&d) JSC::Identifier();
41}
42
43QScriptDeclarativeClass::PersistentIdentifier::~PersistentIdentifier()
44{
45 ((JSC::Identifier &)d).JSC::Identifier::~Identifier();
46}
47
48QScriptDeclarativeClass::PersistentIdentifier::PersistentIdentifier(const PersistentIdentifier &other)
49{
50 identifier = other.identifier;
51 new (&d) JSC::Identifier((JSC::Identifier &)(other.d));
52}
53
54QScriptDeclarativeClass::PersistentIdentifier &
55QScriptDeclarativeClass::PersistentIdentifier::operator=(const PersistentIdentifier &other)
56{
57 identifier = other.identifier;
58 ((JSC::Identifier &)d) = (JSC::Identifier &)(other.d);
59 return *this;
60}
61
62QScriptDeclarativeClass::QScriptDeclarativeClass(QScriptEngine *engine)
63: d_ptr(new QScriptDeclarativeClassPrivate)
64{
65 Q_ASSERT(sizeof(void*) == sizeof(JSC::Identifier));
66 d_ptr->q_ptr = this;
67 d_ptr->engine = engine;
68}
69
70QScriptValue QScriptDeclarativeClass::newObject(QScriptEngine *engine,
71 QScriptDeclarativeClass *scriptClass,
72 Object *object)
73{
74 Q_ASSERT(engine);
75 Q_ASSERT(scriptClass);
76
77 QScriptEnginePrivate *p = static_cast<QScriptEnginePrivate *>(QObjectPrivate::get(engine));
78
79 JSC::ExecState* exec = p->currentFrame;
80 QScriptObject *result = new (exec) QScriptObject(p->scriptObjectStructure);
81 result->setDelegate(new QScript::DeclarativeObjectDelegate(scriptClass, object));
82 return p->scriptValueFromJSCValue(result);
83}
84
85QScriptDeclarativeClass *QScriptDeclarativeClass::scriptClass(const QScriptValue &v)
86{
87 QScriptValuePrivate *d = QScriptValuePrivate::get(v);
88 if (!d || !d->isJSC() || !d->jscValue.inherits(&QScriptObject::info))
89 return 0;
90 QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(d->jscValue));
91 QScriptObjectDelegate *delegate = scriptObject->delegate();
92 if (!delegate || (delegate->type() != QScriptObjectDelegate::DeclarativeClassObject))
93 return 0;
94 return static_cast<QScript::DeclarativeObjectDelegate*>(delegate)->scriptClass();
95}
96
97QScriptDeclarativeClass::Object *QScriptDeclarativeClass::object(const QScriptValue &v)
98{
99 QScriptValuePrivate *d = QScriptValuePrivate::get(v);
100 if (!d || !d->isJSC() || !d->jscValue.inherits(&QScriptObject::info))
101 return 0;
102 QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(d->jscValue));
103 QScriptObjectDelegate *delegate = scriptObject->delegate();
104 if (!delegate || (delegate->type() != QScriptObjectDelegate::DeclarativeClassObject))
105 return 0;
106 return static_cast<QScript::DeclarativeObjectDelegate*>(delegate)->object();
107}
108
109QScriptValue QScriptDeclarativeClass::function(const QScriptValue &v, const Identifier &name)
110{
111 QScriptValuePrivate *d = QScriptValuePrivate::get(v);
112
113 if (!d->isObject())
114 return QScriptValue();
115
116 JSC::ExecState *exec = d->engine->currentFrame;
117 JSC::JSObject *object = d->jscValue.getObject();
118 JSC::PropertySlot slot(const_cast<JSC::JSObject*>(object));
119 JSC::JSValue result;
120
121 JSC::Identifier id(exec, (JSC::UString::Rep *)name);
122
123 if (const_cast<JSC::JSObject*>(object)->getOwnPropertySlot(exec, id, slot)) {
124 result = slot.getValue(exec, id);
125 if (QScript::isFunction(result))
126 return d->engine->scriptValueFromJSCValue(result);
127 }
128
129 return QScriptValue();
130}
131
132QScriptValue QScriptDeclarativeClass::property(const QScriptValue &v, const Identifier &name)
133{
134 QScriptValuePrivate *d = QScriptValuePrivate::get(v);
135
136 if (!d->isObject())
137 return QScriptValue();
138
139 JSC::ExecState *exec = d->engine->currentFrame;
140 JSC::JSObject *object = d->jscValue.getObject();
141 JSC::PropertySlot slot(const_cast<JSC::JSObject*>(object));
142 JSC::JSValue result;
143
144 JSC::Identifier id(exec, (JSC::UString::Rep *)name);
145
146 if (const_cast<JSC::JSObject*>(object)->getOwnPropertySlot(exec, id, slot)) {
147 result = slot.getValue(exec, id);
148 return d->engine->scriptValueFromJSCValue(result);
149 }
150
151 return QScriptValue();
152}
153
154/*
155Returns the scope chain entry at \a index. If index is less than 0, returns
156entries starting at the end. For example, scopeChainValue(context, -1) will return
157the value last in the scope chain.
158*/
159QScriptValue QScriptDeclarativeClass::scopeChainValue(QScriptContext *context, int index)
160{
161 context->activationObject(); //ensure the creation of the normal scope for native context
162 const JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(context);
163 QScriptEnginePrivate *engine = QScript::scriptEngineFromExec(frame);
164
165 JSC::ScopeChainNode *node = frame->scopeChain();
166 JSC::ScopeChainIterator it(node);
167
168 if (index < 0) {
169 int count = 0;
170 for (it = node->begin(); it != node->end(); ++it)
171 ++count;
172
173 index = qAbs(index);
174 if (index > count)
175 return QScriptValue();
176 else
177 index = count - index;
178 }
179
180 for (it = node->begin(); it != node->end(); ++it) {
181
182 if (index == 0) {
183
184 JSC::JSObject *object = *it;
185 if (!object) return QScriptValue();
186
187 if (object->inherits(&QScript::QScriptActivationObject::info)
188 && (static_cast<QScript::QScriptActivationObject*>(object)->delegate() != 0)) {
189 // Return the object that property access is being delegated to
190 object = static_cast<QScript::QScriptActivationObject*>(object)->delegate();
191 }
192 return engine->scriptValueFromJSCValue(object);
193
194 } else {
195 --index;
196 }
197
198 }
199
200 return QScriptValue();
201}
202
203/*!
204 Enters a new execution context and returns the associated
205 QScriptContext object.
206
207 Once you are done with the context, you should call popContext() to
208 restore the old context.
209
210 By default, the `this' object of the new context is the Global Object.
211 The context's \l{QScriptContext::callee()}{callee}() will be invalid.
212
213 Unlike pushContext(), the default scope chain is reset to include
214 only the global object and the QScriptContext's activation object.
215
216 \sa QScriptEngine::popContext()
217*/
218QScriptContext * QScriptDeclarativeClass::pushCleanContext(QScriptEngine *engine)
219{
220 if (!engine)
221 return 0;
222
223 QScriptEnginePrivate *d = QScriptEnginePrivate::get(engine);
224
225 JSC::CallFrame* newFrame = d->pushContext(d->currentFrame,
226 d->currentFrame->globalData().dynamicGlobalObject,
227 JSC::ArgList(), /*callee = */0, false, true);
228
229 if (engine->agent())
230 engine->agent()->contextPush();
231
232 return d->contextForFrame(newFrame);
233}
234
235QScriptDeclarativeClass::~QScriptDeclarativeClass()
236{
237}
238
239QScriptEngine *QScriptDeclarativeClass::engine() const
240{
241 return d_ptr->engine;
242}
243
244QScriptDeclarativeClass::PersistentIdentifier
245QScriptDeclarativeClass::createPersistentIdentifier(const QString &str)
246{
247 QScriptEnginePrivate *p =
248 static_cast<QScriptEnginePrivate *>(QObjectPrivate::get(d_ptr->engine));
249 JSC::ExecState* exec = p->currentFrame;
250
251 PersistentIdentifier rv(true);
252 new (&rv.d) JSC::Identifier(exec, (UChar *)str.constData(), str.size());
253 rv.identifier = (void *)((JSC::Identifier &)rv.d).ustring().rep();
254 return rv;
255}
256
257QScriptDeclarativeClass::PersistentIdentifier
258QScriptDeclarativeClass::createPersistentIdentifier(const Identifier &id)
259{
260 QScriptEnginePrivate *p =
261 static_cast<QScriptEnginePrivate *>(QObjectPrivate::get(d_ptr->engine));
262 JSC::ExecState* exec = p->currentFrame;
263
264 PersistentIdentifier rv(true);
265 new (&rv.d) JSC::Identifier(exec, (JSC::UString::Rep *)id);
266 rv.identifier = (void *)((JSC::Identifier &)rv.d).ustring().rep();
267 return rv;
268}
269
270QString QScriptDeclarativeClass::toString(const Identifier &identifier)
271{
272 JSC::UString::Rep *r = (JSC::UString::Rep *)identifier;
273 return QString((QChar *)r->data(), r->size());
274}
275
276quint32 QScriptDeclarativeClass::toArrayIndex(const Identifier &identifier, bool *ok)
277{
278 JSC::UString::Rep *r = (JSC::UString::Rep *)identifier;
279 JSC::UString s(r);
280 return s.toArrayIndex(ok);
281}
282
283QScriptClass::QueryFlags
284QScriptDeclarativeClass::queryProperty(Object *object, const Identifier &name,
285 QScriptClass::QueryFlags flags)
286{
287 Q_UNUSED(object);
288 Q_UNUSED(name);
289 Q_UNUSED(flags);
290 return 0;
291}
292
293QScriptValue QScriptDeclarativeClass::property(Object *object, const Identifier &name)
294{
295 Q_UNUSED(object);
296 Q_UNUSED(name);
297 return QScriptValue();
298}
299
300void QScriptDeclarativeClass::setProperty(Object *object, const Identifier &name,
301 const QScriptValue &value)
302{
303 Q_UNUSED(object);
304 Q_UNUSED(name);
305 Q_UNUSED(value);
306}
307
308QScriptValue::PropertyFlags
309QScriptDeclarativeClass::propertyFlags(Object *object, const Identifier &name)
310{
311 Q_UNUSED(object);
312 Q_UNUSED(name);
313 return 0;
314}
315
316QStringList QScriptDeclarativeClass::propertyNames(Object *object)
317{
318 Q_UNUSED(object);
319 return QStringList();
320}
321
322bool QScriptDeclarativeClass::isQObject() const
323{
324 return false;
325}
326
327QObject *QScriptDeclarativeClass::toQObject(Object *, bool *ok)
328{
329 if (ok) *ok = false;
330 return 0;
331}
332
333QVariant QScriptDeclarativeClass::toVariant(Object *, bool *ok)
334{
335 if (ok) *ok = false;
336 return QVariant();
337}
338
339QScriptContext *QScriptDeclarativeClass::context() const
340{
341 return d_ptr->context;
342}
343
344QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.