source: trunk/src/script/qscriptecmaobject.cpp@ 397

Last change on this file since 397 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 8.2 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtScript module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qscriptecmaobject_p.h"
43
44#ifndef QT_NO_SCRIPT
45
46#include "qscriptengine_p.h"
47#include "qscriptvalueimpl_p.h"
48#include "qscriptcontext_p.h"
49#include "qscriptmember_p.h"
50#include "qscriptobject_p.h"
51
52#include <QtCore/QtDebug>
53
54QT_BEGIN_NAMESPACE
55
56namespace QScript { namespace Ecma {
57
58Object::Object(QScriptEnginePrivate *eng, QScriptClassInfo *classInfo):
59 Core(eng, classInfo)
60{
61 newObject(&publicPrototype, eng->nullValue());
62}
63
64Object::~Object()
65{
66}
67
68void Object::initialize()
69{
70 QScriptEnginePrivate *eng = engine();
71
72 eng->newConstructor(&ctor, this, publicPrototype);
73
74 addPrototypeFunction(QLatin1String("toString"), method_toString, 1);
75 addPrototypeFunction(QLatin1String("toLocaleString"), method_toLocaleString, 1);
76 addPrototypeFunction(QLatin1String("valueOf"), method_valueOf, 0);
77 addPrototypeFunction(QLatin1String("hasOwnProperty"), method_hasOwnProperty, 1);
78 addPrototypeFunction(QLatin1String("isPrototypeOf"), method_isPrototypeOf, 1);
79 addPrototypeFunction(QLatin1String("propertyIsEnumerable"), method_propertyIsEnumerable, 1);
80 addPrototypeFunction(QLatin1String("__defineGetter__"), method_defineGetter, 2);
81 addPrototypeFunction(QLatin1String("__defineSetter__"), method_defineSetter, 2);
82}
83
84void Object::execute(QScriptContextPrivate *context)
85{
86#ifndef Q_SCRIPT_NO_EVENT_NOTIFY
87 engine()->notifyFunctionEntry(context);
88#endif
89 QScriptValueImpl value;
90
91 if (context->argumentCount() > 0)
92 value = engine()->toObject(context->argument(0));
93 else
94 value.invalidate();
95
96 if (! value.isValid())
97 newObject(&value);
98
99 context->setReturnValue(value);
100#ifndef Q_SCRIPT_NO_EVENT_NOTIFY
101 engine()->notifyFunctionExit(context);
102#endif
103}
104
105void Object::newObject(QScriptValueImpl *result, const QScriptValueImpl &proto)
106{
107 engine()->newObject(result, proto, classInfo());
108}
109
110QScriptValueImpl Object::method_toString(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *)
111{
112 QScriptValueImpl glo = eng->globalObject();
113 QString s = QLatin1String("[object ");
114 QScriptValueImpl self = context->thisObject();
115 s += self.classInfo()->name();
116 s += QLatin1String("]");
117 return (QScriptValueImpl(eng, s));
118}
119
120QScriptValueImpl Object::method_toLocaleString(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo)
121{
122 return method_toString(context, eng, classInfo);
123}
124
125QScriptValueImpl Object::method_valueOf(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *)
126{
127 return (context->thisObject());
128}
129
130QScriptValueImpl Object::method_hasOwnProperty(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *)
131{
132 bool result = false;
133
134 if (context->thisObject().isObject() && (context->argumentCount() > 0)) {
135 QScriptValueImpl arg = context->argument(0);
136
137 QScriptNameIdImpl *id = 0;
138 if (arg.isString())
139 id = arg.stringValue();
140
141 if (! id || ! id->unique) {
142 QString str = arg.toString();
143 id = eng->nameId(str);
144 }
145
146 QScript::Member member;
147 QScriptValueImpl base;
148 QScriptValueImpl self = context->thisObject();
149 if (self.resolve(id, &member, &base, QScriptValue::ResolveLocal, QScript::Read))
150 result = true;
151 }
152
153 return (QScriptValueImpl(result));
154}
155
156QScriptValueImpl Object::method_isPrototypeOf(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *)
157{
158 bool result = false;
159
160 if (context->thisObject().isObject() && (context->argumentCount() > 0)) {
161 QScriptValueImpl arg = context->argument(0);
162
163 if (arg.isObject()) {
164 QScriptValueImpl proto = arg.prototype();
165
166 if (proto.isObject()) {
167 QScriptValueImpl self = context->thisObject();
168 result = self.objectValue() == proto.objectValue();
169 }
170 }
171 }
172
173 return (QScriptValueImpl(result));
174}
175
176QScriptValueImpl Object::method_propertyIsEnumerable(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *)
177{
178 bool result = false;
179
180 if (context->thisObject().isObject() && (context->argumentCount() > 0)) {
181 QScriptValueImpl arg = context->argument(0);
182
183 QScriptNameIdImpl *id = 0;
184 if (arg.isString())
185 id = arg.stringValue();
186
187 if (! id || ! id->unique) {
188 QString str = arg.toString();
189 id = eng->nameId(str);
190 }
191
192 QScript::Member member;
193 QScriptValueImpl base;
194 QScriptValueImpl self = context->thisObject();
195 if (self.resolve(id, &member, &base, QScriptValue::ResolveLocal, QScript::Read)) {
196 result = ! member.dontEnum();
197 if (result) {
198 QScriptValueImpl tmp;
199 base.get(member, &tmp);
200 result = tmp.isValid();
201 }
202 }
203 }
204
205 return (QScriptValueImpl(result));
206}
207
208QScriptValueImpl Object::method_defineGetter(QScriptContextPrivate *context, QScriptEnginePrivate *eng,
209 QScriptClassInfo *)
210{
211 QString propertyName = context->argument(0).toString();
212 if (context->thisObject().propertyFlags(propertyName) & QScriptValue::ReadOnly)
213 return context->throwError(QLatin1String("cannot redefine read-only property"));
214 QScriptValueImpl getter = context->argument(1);
215 if (!getter.isFunction())
216 return context->throwError(QLatin1String("getter must be a function"));
217 context->thisObject().setProperty(propertyName, getter, QScriptValue::PropertyGetter);
218 return eng->undefinedValue();
219}
220
221QScriptValueImpl Object::method_defineSetter(QScriptContextPrivate *context, QScriptEnginePrivate *eng,
222 QScriptClassInfo *)
223{
224 QString propertyName = context->argument(0).toString();
225 if (context->thisObject().propertyFlags(propertyName) & QScriptValue::ReadOnly)
226 return context->throwError(QLatin1String("cannot redefine read-only property"));
227 QScriptValueImpl setter = context->argument(1);
228 if (!setter.isFunction())
229 return context->throwError(QLatin1String("setter must be a function"));
230 context->thisObject().setProperty(propertyName, setter, QScriptValue::PropertySetter);
231 return eng->undefinedValue();
232}
233
234} } // namespace QScript::Ecma
235
236QT_END_NAMESPACE
237
238#endif // QT_NO_SCRIPT
Note: See TracBrowser for help on using the repository browser.