• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.14.8 API Reference
  • KDE Home
  • Contact Us
 

KJS-API

  • kjs
  • api
kjsprototype.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of the KDE libraries
3  * Copyright (C) 2008 Harri Porten (porten@kde.org)
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public License
16  * along with this library; see the file COPYING.LIB. If not, write to
17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  *
20  */
21 
22 #include "kjsprototype.h"
23 #include "kjsinterpreter.h"
24 #include "kjsarguments.h"
25 #include "kjsprivate.h"
26 
27 #include "kjs/object.h"
28 #include "kjs/JSVariableObject.h"
29 #include "kjs/context.h"
30 #include "kjs/interpreter.h"
31 
32 #include <QMap>
33 
34 using namespace KJS;
35 
36 class KJSCustomProperty
37 {
38 public:
39  KJSCustomProperty(KJSPrototype::PropertyGetter g,
40  KJSPrototype::PropertySetter s)
41  : getter(g), setter(s)
42  {
43  }
44 
45  JSValue* read(ExecState* exec, void* object);
46  void write(ExecState* exec, void* object, JSValue* value);
47 
48 private:
49  KJSPrototype::PropertyGetter getter;
50  KJSPrototype::PropertySetter setter;
51 };
52 
53 class CustomObjectInfo {
54 public:
55  CustomObjectInfo(void* v): iv(v) {}
56  virtual ~CustomObjectInfo() {}
57  void* internalValue() { return iv; }
58 protected:
59  void* iv;
60 };
61 
62 template<class Base>
63 class CustomObject : public Base, public CustomObjectInfo {
64 public:
65  CustomObject(JSValue* proto, void* v)
66  : Base(proto),
67  CustomObjectInfo(v)
68  {}
69 
70  using Base::put;
71  void put(ExecState* exec, const Identifier& id,
72  JSValue *value, int attr = None);
73 
74 
75  // rtti
76  static const ClassInfo info;
77  const ClassInfo* classInfo() const { return &info; }
78 };
79 
80 template<>
81 const ClassInfo CustomObject<JSObject>::info = { "CustomObject", 0, 0, 0 };
82 
83 template<>
84 const ClassInfo CustomObject<JSGlobalObject>::info = { "CustomGlobalObject", 0, 0, 0 };
85 
86 class KJSCustomFunction : public JSObject {
87 public:
88  KJSCustomFunction(ExecState* exec, KJSPrototype::FunctionCall f)
89  : callback(f)
90  {
91  setPrototype(exec->lexicalInterpreter()->builtinObjectPrototype());
92  }
93 
94  JSValue* callAsFunction(ExecState* exec, JSObject* thisObj,
95  const List &args);
96  bool implementsCall() const { return true; }
97 
98 private:
99  KJSPrototype::FunctionCall callback;
100 };
101 
102 JSValue* KJSCustomFunction::callAsFunction(ExecState* exec, JSObject* thisObj,
103  const List &args)
104 {
105  // FIXME: does not protect against mixing custom objects
106  CustomObjectInfo* inf = dynamic_cast<CustomObjectInfo*>(thisObj);
107 
108  if (!inf) {
109  const char* errMsg = "Attempt at calling a function with an invalid receiver";
110  KJS::JSObject *err = KJS::Error::create(exec, KJS::TypeError, errMsg);
111  exec->setException(err);
112  return err;
113  }
114 
115  void* thisValue = inf->internalValue();
116 
117  KJSContext ctx(EXECSTATE_HANDLE(exec));
118  KJSArguments a(LIST_HANDLE(&args));
119  KJSObject res = (*callback)(&ctx, thisValue, a);
120  return JSVALUE(&res);
121 }
122 
123 JSValue* KJSCustomProperty::read(ExecState* exec, void* object)
124 {
125  assert(getter);
126 
127  KJSContext ctx(EXECSTATE_HANDLE(exec));
128  KJSObject res = (*getter)(&ctx, object);
129  return JSVALUE(&res);
130 }
131 
132 void KJSCustomProperty::write(ExecState* exec, void* object, JSValue* value)
133 {
134  KJSContext ctx(EXECSTATE_HANDLE(exec));
135 
136  if (setter) {
137  KJSObject vo(JSVALUE_HANDLE(value));
138  (*setter)(&ctx, object, vo);
139  } else {
140  JSObject *e = Error::create(exec, GeneralError,
141  "Property is read-only");
142  exec->setException(e);
143  }
144 }
145 
146 static JSValue* getPropertyValue(ExecState* exec, JSObject *originalObject,
147  const Identifier&, const PropertySlot& sl)
148 {
149  CustomObjectInfo* inf = dynamic_cast<CustomObjectInfo*>(originalObject);
150  if (!inf)
151  return jsUndefined();
152 
153  KJSCustomProperty* p =
154  reinterpret_cast<KJSCustomProperty*>(sl.customValue());
155 
156  return p->read(exec, inf->internalValue());
157 }
158 
159 // FIXME: or use Identifier?
160 // FIXME: use values
161 typedef QMap<UString, KJSCustomProperty*> CustomPropertyMap;
162 
163 class CustomPrototype : public JSObject {
164 public:
165  CustomPrototype()
166  {
167  }
168  ~CustomPrototype()
169  {
170  qDeleteAll(properties);
171  }
172 
173  using KJS::JSObject::getOwnPropertySlot;
174  bool getOwnPropertySlot(ExecState *exec, const Identifier& id,
175  PropertySlot& sl)
176  {
177  CustomPropertyMap::iterator it = properties.find(id.ustring());
178  if (it == properties.end())
179  return JSObject::getOwnPropertySlot(exec, id, sl);
180 
181  sl.setCustomValue(0, *it, getPropertyValue);
182 
183  return true;
184  }
185 
186  void registerProperty(const QString& name,
187  KJSPrototype::PropertyGetter g,
188  KJSPrototype::PropertySetter s)
189  {
190  properties.insert(toUString(name), new KJSCustomProperty(g, s));
191  }
192 
193  void registerFunction(ExecState* exec,
194  const QString& name, KJSPrototype::FunctionCall f)
195  {
196  putDirect(toIdentifier(name), new KJSCustomFunction(exec, f));
197  }
198 
199  template<typename Base>
200  bool setProperty(ExecState* exec, CustomObject<Base>* obj,
201  const Identifier& id, JSValue* value)
202  {
203  CustomPropertyMap::iterator it = properties.find(id.ustring());
204  if (it == properties.end())
205  return false;
206 
207  (*it)->write(exec, obj->internalValue(), value);
208 
209  return true;
210  }
211 
212 private:
213  CustomPropertyMap properties;
214 };
215 
216 template<class Base>
217 void CustomObject<Base>::put(ExecState* exec, const Identifier& id,
218  JSValue* value, int attr)
219 {
220  CustomPrototype* p = static_cast<CustomPrototype*>(this->prototype());
221 
222  if (!p->setProperty(exec, this, id, value))
223  Base::put(exec, id, value, attr);
224 }
225 
226 KJSPrototype::KJSPrototype()
227 {
228  CustomPrototype* p = new CustomPrototype;
229  gcProtect(p);
230 
231  hnd = PROTOTYPE_HANDLE(p);
232 }
233 
234 KJSPrototype::~KJSPrototype()
235 {
236  gcUnprotect(PROTOTYPE(this));
237 }
238 
239 void KJSPrototype::defineConstant(const QString& name, double value)
240 {
241  CustomPrototype* p = PROTOTYPE(this);
242 
243  p->putDirect(toIdentifier(name), jsNumber(value),
244  DontEnum|DontDelete|ReadOnly);
245 }
246 
247 void KJSPrototype::defineConstant(const QString& name, const QString& value)
248 {
249  CustomPrototype* p = PROTOTYPE(this);
250 
251  p->putDirect(toIdentifier(name), jsString(toUString(value)),
252  DontEnum|DontDelete|ReadOnly);
253 }
254 
255 void KJSPrototype::defineConstant(const QString& name, const KJSObject& value)
256 {
257  CustomPrototype* p = PROTOTYPE(this);
258 
259  p->putDirect(toIdentifier(name), JSVALUE(&value),
260  DontEnum|DontDelete|ReadOnly);
261 }
262 
263 KJSObject KJSPrototype::constructObject(KJSContext* ctx, void *internalValue)
264 {
265  CustomPrototype* p = PROTOTYPE(this);
266 
267  if (ctx && !p->prototype()) {
268  ExecState* exec = EXECSTATE(ctx);
269  KJS::Interpreter* i = exec->lexicalInterpreter();
270  JSObject* objectProto = i->builtinObjectPrototype();
271  p->setPrototype(objectProto);
272  }
273 
274  CustomObject<JSObject>* newObj = new CustomObject<JSObject>(p, internalValue);
275  return KJSObject(JSVALUE_HANDLE(newObj));
276 }
277 
278 KJSGlobalObject KJSPrototype::constructGlobalObject(void *internalValue)
279 {
280  CustomPrototype* p = PROTOTYPE(this);
281 
282  CustomObject<JSGlobalObject>* newObj = new CustomObject<JSGlobalObject>(p, internalValue);
283  return KJSGlobalObject(JSVALUE_HANDLE(newObj));
284 }
285 
286 void KJSPrototype::defineProperty(KJSContext* ctx,
287  const QString& name,
288  PropertyGetter getter,
289  PropertySetter setter)
290 {
291  Q_UNUSED(ctx);
292  assert(getter);
293 
294  CustomPrototype* p = PROTOTYPE(this);
295 
296  p->registerProperty(name, getter, setter);
297 }
298 
299 void KJSPrototype::defineFunction(KJSContext* ctx,
300  const QString& name, FunctionCall callback)
301 {
302  assert(callback);
303 
304  CustomPrototype* p = PROTOTYPE(this);
305  ExecState* exec = EXECSTATE(ctx);
306 
307  p->registerFunction(exec, name, callback);
308 }
309 
310 
311 // kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on;
KJSPrototype::PropertyGetter
KJSObject(* PropertyGetter)(KJSContext *context, void *object)
Function signature for a property getter function.
Definition: kjsprototype.h:70
KJSPrototype::defineProperty
void defineProperty(KJSContext *ctx, const QString &name, PropertyGetter getter, PropertySetter setter=0)
Defines a property of this prototype with C++ callback functions for getting and setting the property...
Definition: kjsprototype.cpp:286
KJSPrototype::constructGlobalObject
KJSGlobalObject constructGlobalObject(void *internalValue=0)
Similar to constructObject() but specialized on the construction of global objects.
Definition: kjsprototype.cpp:278
KJSPrototype::~KJSPrototype
~KJSPrototype()
Destructs this prototype object.
Definition: kjsprototype.cpp:234
JSVALUE
#define JSVALUE(h)
Definition: kjsprivate.h:31
toUString
static KJS::UString toUString(const QString &s)
Definition: kjsprivate.h:45
KJSGlobalObject
A class representing a global object of an execution environment.
Definition: kjsobject.h:280
KJSPrototype::PropertySetter
void(* PropertySetter)(KJSContext *context, void *object, KJSObject value)
Function signature for a property setter function.
Definition: kjsprototype.h:75
EXECSTATE
#define EXECSTATE(ctx)
Definition: kjsprivate.h:34
KJSContext
A class representing a JavaScript execution context.
Definition: kjscontext.h:39
KJSPrototype::defineFunction
void defineFunction(KJSContext *ctx, const QString &name, FunctionCall callback)
Define a function.
Definition: kjsprototype.cpp:299
EXECSTATE_HANDLE
#define EXECSTATE_HANDLE(c)
Definition: kjsprivate.h:33
kjsinterpreter.h
LIST_HANDLE
#define LIST_HANDLE(l)
Definition: kjsprivate.h:42
KJSArguments
A class representing a list of JavaScript arguments.
Definition: kjsarguments.h:36
KJSPrototype::defineConstant
void defineConstant(const QString &name, double value)
Add a read-only numerical property to this object.
Definition: kjsprototype.cpp:239
toIdentifier
static KJS::Identifier toIdentifier(const QString &s)
Definition: kjsprivate.h:53
KJSObject
A class representing a JavaScript value.
Definition: kjsobject.h:48
KJSPrototype::KJSPrototype
KJSPrototype()
Constructs a prototype object with its own prototype property set to the Object prototype.
Definition: kjsprototype.cpp:226
CustomPropertyMap
QMap< UString, KJSCustomProperty * > CustomPropertyMap
Definition: kjsprototype.cpp:161
PROTOTYPE
#define PROTOTYPE(h)
Definition: kjsprivate.h:40
getPropertyValue
static JSValue * getPropertyValue(ExecState *exec, JSObject *originalObject, const Identifier &, const PropertySlot &sl)
Definition: kjsprototype.cpp:146
kjsprototype.h
PROTOTYPE_HANDLE
#define PROTOTYPE_HANDLE(p)
Definition: kjsprivate.h:39
kjsarguments.h
JSVALUE_HANDLE
#define JSVALUE_HANDLE(v)
Definition: kjsprivate.h:30
kjsprivate.h
KJSPrototype::FunctionCall
KJSObject(* FunctionCall)(KJSContext *context, void *object, const KJSArguments &arguments)
Signature for function call callback function.
Definition: kjsprototype.h:92
KJSPrototype::constructObject
KJSObject constructObject(KJSContext *ctx, void *internalValue=0)
Construct an object with this prototype and the specified internal value.
Definition: kjsprototype.cpp:263
This file is part of the KDE documentation.
Documentation copyright © 1996-2019 The KDE developers.
Generated on Fri Aug 9 2019 17:22:48 by doxygen 1.8.5 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KJS-API

Skip menu "KJS-API"
  • Main Page
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdelibs-4.14.8 API Reference

Skip menu "kdelibs-4.14.8 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal