25 #include "identifier.h"
28 #include "interpreter.h"
107 static int find(
const struct HashTable *table,
108 const UChar *c,
unsigned int len);
118 const UChar *c,
unsigned int len);
123 static unsigned int hash(
const Identifier &key);
124 static unsigned int hash(
const UChar *c,
unsigned int len);
125 static unsigned int hash(
const char *s);
134 template <
class FuncImp>
136 const ObjectImp *thisObj,
int token,
int params,
int attr)
139 ValueImp * cachedVal = thisObj->ObjectImp::getDirect(propertyName);
143 return Value(cachedVal);
145 ObjectImp* func =
new FuncImp( exec, token, params );
147 func->setFunctionName( propertyName );
148 ObjectImp *thatObj =
const_cast<ObjectImp *
>(thisObj);
149 thatObj->ObjectImp::put(exec, propertyName, val, attr);
173 template <
class FuncImp,
class ThisImp,
class ParentImp>
174 inline Value lookupGet(ExecState *exec,
const Identifier &propertyName,
175 const HashTable* table,
const ThisImp* thisObj)
180 return thisObj->ParentImp::get(exec, propertyName);
183 if (entry->attr & Function)
184 return lookupOrCreateFunction<FuncImp>(exec, propertyName, thisObj, entry->value, entry->params, entry->attr);
185 return thisObj->getValueProperty(exec, entry->value);
192 template <
class FuncImp,
class ParentImp>
193 inline Value lookupGetFunction(ExecState *exec,
const Identifier &propertyName,
194 const HashTable* table,
const ObjectImp* thisObj)
199 return static_cast<const ParentImp *
>(thisObj)->ParentImp::get(exec, propertyName);
201 if (entry->attr & Function)
202 return lookupOrCreateFunction<FuncImp>(exec, propertyName, thisObj, entry->value, entry->params, entry->attr);
204 fprintf(stderr,
"Function bit not set! Shouldn't happen in lookupGetFunction!\n" );
212 template <
class ThisImp,
class ParentImp>
213 inline Value lookupGetValue(ExecState *exec,
const Identifier &propertyName,
214 const HashTable* table,
const ThisImp* thisObj)
219 return thisObj->ParentImp::get(exec, propertyName);
221 if (entry->attr & Function)
222 fprintf(stderr,
"Function bit set! Shouldn't happen in lookupGetValue! propertyName was %s\n", propertyName.ascii() );
223 return thisObj->getValueProperty(exec, entry->value);
230 template <
class ThisImp,
class ParentImp>
231 inline void lookupPut(ExecState *exec,
const Identifier &propertyName,
232 const Value& value,
int attr,
233 const HashTable* table, ThisImp* thisObj)
238 thisObj->ParentImp::put(exec, propertyName, value, attr);
239 else if (entry->attr & Function)
240 thisObj->ObjectImp::put(exec, propertyName, value, attr);
241 else if (entry->attr & ReadOnly)
243 fprintf(stderr,
"WARNING: Attempt to change value of readonly property '%s'\n",propertyName.ascii());
248 thisObj->putValueProperty(exec, entry->value, value, attr);
259 template <
class ClassCtor>
260 inline KJS::Object cacheGlobalObject(ExecState *exec,
const Identifier &propertyName)
262 ValueImp *obj =
static_cast<KJS::ObjectImp*
>(exec->interpreter()->globalObject().imp())->getDirect(propertyName);
268 exec->interpreter()->globalObject().put(exec, propertyName, newObject, Internal);
292 #define PUBLIC_DEFINE_PROTOTYPE(ClassName,ClassProto) \
294 class ClassProto : public KJS::ObjectImp { \
295 friend KJS::Object cacheGlobalObject<ClassProto>(KJS::ExecState *exec, const KJS::Identifier &propertyName); \
297 static KJS::Object self(KJS::ExecState *exec) \
299 return cacheGlobalObject<ClassProto>( exec, "[[" ClassName ".prototype]]" ); \
302 ClassProto( KJS::ExecState *exec ) \
303 : KJS::ObjectImp( exec->interpreter()->builtinObjectPrototype() ) {} \
306 virtual const KJS::ClassInfo *classInfo() const { return &info; } \
307 static const KJS::ClassInfo info; \
308 KJS::Value get(KJS::ExecState *exec, const KJS::Identifier &propertyName) const; \
309 bool hasProperty(KJS::ExecState *exec, const KJS::Identifier &propertyName) const; \
313 #define IMPLEMENT_CLASSINFO(ClassName,ClassProto) \
315 const KJS::ClassInfo ClassProto::info = { ClassName, 0, &ClassProto##Table, 0 }; \
318 #define DEFINE_PROTOTYPE(ClassName,ClassProto) \
319 PUBLIC_DEFINE_PROTOTYPE(ClassName,ClassProto) \
320 IMPLEMENT_CLASSINFO(ClassName,ClassProto)
322 #define IMPLEMENT_PROTOTYPE(ClassProto,ClassFunc) \
323 KJS::Value KJS::ClassProto::get(KJS::ExecState *exec, const KJS::Identifier &propertyName) const \
326 return lookupGetFunction<ClassFunc,KJS::ObjectImp>(exec, propertyName, &ClassProto##Table, this ); \
328 bool KJS::ClassProto::hasProperty(KJS::ExecState *exec, const KJS::Identifier &propertyName) const \
330 return KJS::ObjectImp::hasProperty(exec, propertyName); \
333 #define PUBLIC_IMPLEMENT_PROTOTYPE(ClassProto,ClassName,ClassFunc) \
334 IMPLEMENT_PROTOTYPE(ClassProto,ClassFunc)\
335 IMPLEMENT_CLASSINFO(ClassName,ClassProto)
337 #define IMPLEMENT_PROTOTYPE_WITH_PARENT(ClassProto,ClassFunc,ParentProto) \
338 KJS::Value KJS::ClassProto::get(KJS::ExecState *exec, const KJS::Identifier &propertyName) const \
341 KJS::Value val = lookupGetFunction<ClassFunc,KJS::ObjectImp>(exec, propertyName, &ClassProto##Table, this ); \
342 if ( val.type() != UndefinedType ) return val; \
344 return ParentProto::self(exec).get( exec, propertyName ); \
346 bool KJS::ClassProto::hasProperty(KJS::ExecState *exec, const KJS::Identifier &propertyName) const \
348 if (KJS::ObjectImp::hasProperty(exec, propertyName)) \
350 return ParentProto::self(exec).hasProperty(exec, propertyName); \
353 #define PUBLIC_IMPLEMENT_PROTOTYPE_WITH_PARENT(ClassProto,ClassName,ClassFunc,ParentProto) \
354 IMPLEMENT_PROTOTYPE_WITH_PARENT(ClassProto,ClassFunc,ParentProto) \
355 IMPLEMENT_CLASSINFO(ClassName,ClassProto)
357 #define IMPLEMENT_PROTOFUNC(ClassFunc) \
359 class ClassFunc : public ObjectImp { \
361 ClassFunc(KJS::ExecState *exec, int i, int len) \
362 : ObjectImp( ), id(i) { \
363 KJS::Value protect(this); \
364 put(exec,lengthPropertyName,Number(len),DontDelete|ReadOnly|DontEnum); \
366 virtual bool implementsCall() const { return true; } \
368 virtual KJS::Value call(KJS::ExecState *exec, KJS::Object &thisObj, const KJS::List &args); \
375 #define KJS_CHECK_THIS( ClassName, theObj ) \
376 if (!theObj.isValid() || !theObj.inherits(&ClassName::info)) { \
377 KJS::UString errMsg = "Attempt at calling a function that expects a "; \
378 errMsg += ClassName::info.className; \
379 errMsg += " on a "; \
380 errMsg += thisObj.className(); \
381 KJS::Object err = KJS::Error::create(exec, KJS::TypeError, errMsg.ascii()); \
382 exec->setException(err); \
Represents the current state of script execution.
Represents an Identifier for a Javascript object.
static const HashEntry * findEntry(const struct HashTable *table, const Identifier &s)
Find an entry in the table, and return the entry This variant gives access to the other attributes of...
static Object dynamicCast(const Value &v)
Converts a Value into an Object.
ValueImp is the base type for all primitives (Undefined, Null, Boolean, String, Number) and objects i...
Value objects are act as wrappers ("smart pointers") around ValueImp objects and their descendents.
An entry in a hash table.
unsigned char attr
attr is a set for flags (e.g.
unsigned char params
params is another number.
short next
next is the index to the next entry for the same hash value
short int value
value is the result value (usually an enum value)
unsigned short soffset
s is the offset to the string key (e.g.
A hash table Usually the hashtable is generated by the create_hash_table script, from a ....
const char *const sbase
pointer to the string table.
const HashEntry *const entries
pointer to the array of entries Mind that some entries in the array are null (0,0,...
int size
size is the total number of entries in the hashtable, including the null entries, i....
int hashSize
the maximum value for the hash.
int type
type is a version number.