• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • kjs
 

kjs

  • kjs
lookup.h
1 // -*- c-basic-offset: 2 -*-
2 /*
3  * This file is part of the KDE libraries
4  * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
5  * Copyright (C) 2003 Apple Computer, Inc.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  *
21  */
22 
23 #ifndef _KJSLOOKUP_H_
24 #define _KJSLOOKUP_H_
25 
26 #include "identifier.h"
27 #include "value.h"
28 #include "object.h"
29 #include "interpreter.h"
30 #include <stdio.h>
31 
32 namespace KJS {
33 
37  struct HashEntry {
41  unsigned short soffset;
45  short int value;
49  unsigned char attr;
54  unsigned char params;
58  short next;
59  };
60 
72  struct HashTable {
76  int type;
82  int size;
87  const HashEntry *const entries;
91  int hashSize;
92 
96  const char* const sbase;
97  };
98 
102  class KJS_EXPORT Lookup {
103  public:
107  static int find(const struct HashTable *table, const Identifier &s);
108  static int find(const struct HashTable *table,
109  const UChar *c, unsigned int len);
110 
116  static const HashEntry* findEntry(const struct HashTable *table,
117  const Identifier &s);
118  static const HashEntry* findEntry(const struct HashTable *table,
119  const UChar *c, unsigned int len);
120 
124  static unsigned int hash(const Identifier &key);
125  static unsigned int hash(const UChar *c, unsigned int len);
126  static unsigned int hash(const char *s);
127  };
128 
129  class ExecState;
130  class UString;
135  template <class FuncImp>
136  inline Value lookupOrCreateFunction(ExecState *exec, const Identifier &propertyName,
137  const ObjectImp *thisObj, int token, int params, int attr)
138  {
139  // Look for cached value in dynamic map of properties (in ObjectImp)
140  ValueImp * cachedVal = thisObj->ObjectImp::getDirect(propertyName);
141  /*if (cachedVal)
142  fprintf(stderr, "lookupOrCreateFunction: Function -> looked up in ObjectImp, found type=%d\n", cachedVal->type());*/
143  if (cachedVal)
144  return Value(cachedVal);
145 
146  ObjectImp* func = new FuncImp( exec, token, params );
147  Value val( func );
148  func->setFunctionName( propertyName );
149  ObjectImp *thatObj = const_cast<ObjectImp *>(thisObj);
150  thatObj->ObjectImp::put(exec, propertyName, val, attr);
151  return val;
152  }
153 
174  template <class FuncImp, class ThisImp, class ParentImp>
175  inline Value lookupGet(ExecState *exec, const Identifier &propertyName,
176  const HashTable* table, const ThisImp* thisObj)
177  {
178  const HashEntry* entry = Lookup::findEntry(table, propertyName);
179 
180  if (!entry) // not found, forward to parent
181  return thisObj->ParentImp::get(exec, propertyName);
182 
183  //fprintf(stderr, "lookupGet: found value=%d attr=%d\n", entry->value, entry->attr);
184  if (entry->attr & Function)
185  return lookupOrCreateFunction<FuncImp>(exec, propertyName, thisObj, entry->value, entry->params, entry->attr);
186  return thisObj->getValueProperty(exec, entry->value);
187  }
188 
193  template <class FuncImp, class ParentImp>
194  inline Value lookupGetFunction(ExecState *exec, const Identifier &propertyName,
195  const HashTable* table, const ObjectImp* thisObj)
196  {
197  const HashEntry* entry = Lookup::findEntry(table, propertyName);
198 
199  if (!entry) // not found, forward to parent
200  return static_cast<const ParentImp *>(thisObj)->ParentImp::get(exec, propertyName);
201 
202  if (entry->attr & Function)
203  return lookupOrCreateFunction<FuncImp>(exec, propertyName, thisObj, entry->value, entry->params, entry->attr);
204 
205  fprintf(stderr, "Function bit not set! Shouldn't happen in lookupGetFunction!\n" );
206  return Undefined();
207  }
208 
213  template <class ThisImp, class ParentImp>
214  inline Value lookupGetValue(ExecState *exec, const Identifier &propertyName,
215  const HashTable* table, const ThisImp* thisObj)
216  {
217  const HashEntry* entry = Lookup::findEntry(table, propertyName);
218 
219  if (!entry) // not found, forward to parent
220  return thisObj->ParentImp::get(exec, propertyName);
221 
222  if (entry->attr & Function)
223  fprintf(stderr, "Function bit set! Shouldn't happen in lookupGetValue! propertyName was %s\n", propertyName.ascii() );
224  return thisObj->getValueProperty(exec, entry->value);
225  }
226 
231  template <class ThisImp, class ParentImp>
232  inline void lookupPut(ExecState *exec, const Identifier &propertyName,
233  const Value& value, int attr,
234  const HashTable* table, ThisImp* thisObj)
235  {
236  const HashEntry* entry = Lookup::findEntry(table, propertyName);
237 
238  if (!entry) // not found: forward to parent
239  thisObj->ParentImp::put(exec, propertyName, value, attr);
240  else if (entry->attr & Function) // function: put as override property
241  thisObj->ObjectImp::put(exec, propertyName, value, attr);
242  else if (entry->attr & ReadOnly) // readonly! Can't put!
243 #ifdef KJS_VERBOSE
244  fprintf(stderr,"WARNING: Attempt to change value of readonly property '%s'\n",propertyName.ascii());
245 #else
246  ; // do nothing
247 #endif
248  else
249  thisObj->putValueProperty(exec, entry->value, value, attr);
250  }
251 
252 
260  template <class ClassCtor>
261  inline KJS::Object cacheGlobalObject(ExecState *exec, const Identifier &propertyName)
262  {
263  ValueImp *obj = static_cast<KJS::ObjectImp*>(exec->interpreter()->globalObject().imp())->getDirect(propertyName);
264  if (obj)
265  return KJS::Object::dynamicCast(Value(obj));
266  else
267  {
268  KJS::Object newObject(new ClassCtor(exec));
269  exec->interpreter()->globalObject().put(exec, propertyName, newObject, Internal);
270  return newObject;
271  }
272  }
273 
274 
293 #define PUBLIC_DEFINE_PROTOTYPE(ClassName,ClassProto) \
294  namespace KJS { \
295  class ClassProto : public KJS::ObjectImp { \
296  friend KJS::Object cacheGlobalObject<ClassProto>(KJS::ExecState *exec, const KJS::Identifier &propertyName); \
297  public: \
298  static KJS::Object self(KJS::ExecState *exec) \
299  { \
300  return cacheGlobalObject<ClassProto>( exec, "[[" ClassName ".prototype]]" ); \
301  } \
302  protected: \
303  ClassProto( KJS::ExecState *exec ) \
304  : KJS::ObjectImp( exec->interpreter()->builtinObjectPrototype() ) {} \
305  \
306  public: \
307  virtual const KJS::ClassInfo *classInfo() const { return &info; } \
308  static const KJS::ClassInfo info; \
309  KJS::Value get(KJS::ExecState *exec, const KJS::Identifier &propertyName) const; \
310  bool hasProperty(KJS::ExecState *exec, const KJS::Identifier &propertyName) const; \
311  }; \
312  }
313 
314 #define IMPLEMENT_CLASSINFO(ClassName,ClassProto) \
315  namespace KJS {\
316  const KJS::ClassInfo ClassProto::info = { ClassName, 0, &ClassProto##Table, 0 }; \
317  }
318 
319 #define DEFINE_PROTOTYPE(ClassName,ClassProto) \
320  PUBLIC_DEFINE_PROTOTYPE(ClassName,ClassProto) \
321  IMPLEMENT_CLASSINFO(ClassName,ClassProto)
322 
323 #define IMPLEMENT_PROTOTYPE(ClassProto,ClassFunc) \
324  KJS::Value KJS::ClassProto::get(KJS::ExecState *exec, const KJS::Identifier &propertyName) const \
325  { \
326  /*fprintf( stderr, "%sProto::get(%s) [in macro, no parent]\n", info.className, propertyName.ascii());*/ \
327  return lookupGetFunction<ClassFunc,KJS::ObjectImp>(exec, propertyName, &ClassProto##Table, this ); \
328  } \
329  bool KJS::ClassProto::hasProperty(KJS::ExecState *exec, const KJS::Identifier &propertyName) const \
330  { /*stupid but we need this to have a common macro for the declaration*/ \
331  return KJS::ObjectImp::hasProperty(exec, propertyName); \
332  }
333 
334 #define PUBLIC_IMPLEMENT_PROTOTYPE(ClassProto,ClassName,ClassFunc) \
335  IMPLEMENT_PROTOTYPE(ClassProto,ClassFunc)\
336  IMPLEMENT_CLASSINFO(ClassName,ClassProto)
337 
338 #define IMPLEMENT_PROTOTYPE_WITH_PARENT(ClassProto,ClassFunc,ParentProto) \
339  KJS::Value KJS::ClassProto::get(KJS::ExecState *exec, const KJS::Identifier &propertyName) const \
340  { \
341  /*fprintf( stderr, "%sProto::get(%s) [in macro]\n", info.className, propertyName.ascii());*/ \
342  KJS::Value val = lookupGetFunction<ClassFunc,KJS::ObjectImp>(exec, propertyName, &ClassProto##Table, this ); \
343  if ( val.type() != UndefinedType ) return val; \
344  /* Not found -> forward request to "parent" prototype */ \
345  return ParentProto::self(exec).get( exec, propertyName ); \
346  } \
347  bool KJS::ClassProto::hasProperty(KJS::ExecState *exec, const KJS::Identifier &propertyName) const \
348  { \
349  if (KJS::ObjectImp::hasProperty(exec, propertyName)) \
350  return true; \
351  return ParentProto::self(exec).hasProperty(exec, propertyName); \
352  }
353 
354 #define PUBLIC_IMPLEMENT_PROTOTYPE_WITH_PARENT(ClassProto,ClassName,ClassFunc,ParentProto) \
355  IMPLEMENT_PROTOTYPE_WITH_PARENT(ClassProto,ClassFunc,ParentProto) \
356  IMPLEMENT_CLASSINFO(ClassName,ClassProto)
357 
358 #define IMPLEMENT_PROTOFUNC(ClassFunc) \
359  namespace KJS { \
360  class ClassFunc : public ObjectImp { \
361  public: \
362  ClassFunc(KJS::ExecState *exec, int i, int len) \
363  : ObjectImp( /*proto? */ ), id(i) { \
364  KJS::Value protect(this); \
365  put(exec,lengthPropertyName,Number(len),DontDelete|ReadOnly|DontEnum); \
366  } \
367  virtual bool implementsCall() const { return true; } \
368  \
369  virtual KJS::Value call(KJS::ExecState *exec, KJS::Object &thisObj, const KJS::List &args); \
370  private: \
371  int id; \
372  }; \
373  }
374 
375  // To be used in all call() implementations, before casting the type of thisObj
376 #define KJS_CHECK_THIS( ClassName, theObj ) \
377  if (!theObj.isValid() || !theObj.inherits(&ClassName::info)) { \
378  KJS::UString errMsg = "Attempt at calling a function that expects a "; \
379  errMsg += ClassName::info.className; \
380  errMsg += " on a "; \
381  errMsg += thisObj.className(); \
382  KJS::Object err = KJS::Error::create(exec, KJS::TypeError, errMsg.ascii()); \
383  exec->setException(err); \
384  return err; \
385  }
386 
387  /*
388  * List of things to do when porting an objectimp to the 'static hashtable' mechanism:
389  * - write the hashtable source, between @begin and @end
390  * - add a rule to build the .lut.h
391  * - include the .lut.h
392  * - mention the table in the classinfo (add a classinfo if necessary)
393  * - write/update the class enum (for the tokens)
394  * - turn get() into getValueProperty(), put() into putValueProperty(), using a switch and removing funcs
395  * - write get() and/or put() using a template method
396  * - cleanup old stuff (e.g. hasProperty)
397  * - compile, test, commit ;)
398  */
399 } // namespace
400 
401 #endif

kjs

Skip menu "kjs"
  • Main Page
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

kjs

Skip menu "kjs"
  • arts
  • dcop
  • dnssd
  • interfaces
  •     interface
  •     library
  •   kspeech
  •   ktexteditor
  • kabc
  • kate
  • kcmshell
  • kdecore
  • kded
  • kdefx
  • kdeprint
  • kdesu
  • kdeui
  • kdoctools
  • khtml
  • kimgio
  • kinit
  • kio
  •   bookmarks
  •   httpfilter
  •   kfile
  •   kio
  •   kioexec
  •   kpasswdserver
  •   kssl
  • kioslave
  •   http
  • kjs
  • kmdi
  •   kmdi
  • knewstuff
  • kparts
  • krandr
  • kresources
  • kspell2
  • kunittest
  • kutils
  • kwallet
  • libkmid
  • libkscreensaver
Generated for kjs by doxygen 1.8.3.1
This website is maintained by Timothy Pearson.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. |