26 #include "identifier.h"
29 #include "interpreter.h"
108 static int find(
const struct HashTable *table,
109 const UChar *c,
unsigned int len);
119 const UChar *c,
unsigned int len);
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);
135 template <
class FuncImp>
137 const ObjectImp *thisObj,
int token,
int params,
int attr)
140 ValueImp * cachedVal = thisObj->ObjectImp::getDirect(propertyName);
144 return Value(cachedVal);
146 ObjectImp* func =
new FuncImp( exec, token, params );
148 func->setFunctionName( propertyName );
149 ObjectImp *thatObj =
const_cast<ObjectImp *
>(thisObj);
150 thatObj->ObjectImp::put(exec, propertyName, val, attr);
174 template <
class FuncImp,
class ThisImp,
class ParentImp>
175 inline Value lookupGet(ExecState *exec,
const Identifier &propertyName,
176 const HashTable* table,
const ThisImp* thisObj)
181 return thisObj->ParentImp::get(exec, propertyName);
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);
193 template <
class FuncImp,
class ParentImp>
194 inline Value lookupGetFunction(ExecState *exec,
const Identifier &propertyName,
195 const HashTable* table,
const ObjectImp* thisObj)
200 return static_cast<const ParentImp *
>(thisObj)->ParentImp::get(exec, propertyName);
202 if (entry->attr & Function)
203 return lookupOrCreateFunction<FuncImp>(exec, propertyName, thisObj, entry->value, entry->params, entry->attr);
205 fprintf(stderr,
"Function bit not set! Shouldn't happen in lookupGetFunction!\n" );
213 template <
class ThisImp,
class ParentImp>
214 inline Value lookupGetValue(ExecState *exec,
const Identifier &propertyName,
215 const HashTable* table,
const ThisImp* thisObj)
220 return thisObj->ParentImp::get(exec, propertyName);
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);
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)
239 thisObj->ParentImp::put(exec, propertyName, value, attr);
240 else if (entry->attr & Function)
241 thisObj->ObjectImp::put(exec, propertyName, value, attr);
242 else if (entry->attr & ReadOnly)
244 fprintf(stderr,
"WARNING: Attempt to change value of readonly property '%s'\n",propertyName.ascii());
249 thisObj->putValueProperty(exec, entry->value, value, attr);
260 template <
class ClassCtor>
261 inline KJS::Object cacheGlobalObject(ExecState *exec,
const Identifier &propertyName)
263 ValueImp *obj =
static_cast<KJS::ObjectImp*
>(exec->interpreter()->globalObject().imp())->getDirect(propertyName);
269 exec->interpreter()->globalObject().put(exec, propertyName, newObject, Internal);
293 #define PUBLIC_DEFINE_PROTOTYPE(ClassName,ClassProto) \
295 class ClassProto : public KJS::ObjectImp { \
296 friend KJS::Object cacheGlobalObject<ClassProto>(KJS::ExecState *exec, const KJS::Identifier &propertyName); \
298 static KJS::Object self(KJS::ExecState *exec) \
300 return cacheGlobalObject<ClassProto>( exec, "[[" ClassName ".prototype]]" ); \
303 ClassProto( KJS::ExecState *exec ) \
304 : KJS::ObjectImp( exec->interpreter()->builtinObjectPrototype() ) {} \
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; \
314 #define IMPLEMENT_CLASSINFO(ClassName,ClassProto) \
316 const KJS::ClassInfo ClassProto::info = { ClassName, 0, &ClassProto##Table, 0 }; \
319 #define DEFINE_PROTOTYPE(ClassName,ClassProto) \
320 PUBLIC_DEFINE_PROTOTYPE(ClassName,ClassProto) \
321 IMPLEMENT_CLASSINFO(ClassName,ClassProto)
323 #define IMPLEMENT_PROTOTYPE(ClassProto,ClassFunc) \
324 KJS::Value KJS::ClassProto::get(KJS::ExecState *exec, const KJS::Identifier &propertyName) const \
327 return lookupGetFunction<ClassFunc,KJS::ObjectImp>(exec, propertyName, &ClassProto##Table, this ); \
329 bool KJS::ClassProto::hasProperty(KJS::ExecState *exec, const KJS::Identifier &propertyName) const \
331 return KJS::ObjectImp::hasProperty(exec, propertyName); \
334 #define PUBLIC_IMPLEMENT_PROTOTYPE(ClassProto,ClassName,ClassFunc) \
335 IMPLEMENT_PROTOTYPE(ClassProto,ClassFunc)\
336 IMPLEMENT_CLASSINFO(ClassName,ClassProto)
338 #define IMPLEMENT_PROTOTYPE_WITH_PARENT(ClassProto,ClassFunc,ParentProto) \
339 KJS::Value KJS::ClassProto::get(KJS::ExecState *exec, const KJS::Identifier &propertyName) const \
342 KJS::Value val = lookupGetFunction<ClassFunc,KJS::ObjectImp>(exec, propertyName, &ClassProto##Table, this ); \
343 if ( val.type() != UndefinedType ) return val; \
345 return ParentProto::self(exec).get( exec, propertyName ); \
347 bool KJS::ClassProto::hasProperty(KJS::ExecState *exec, const KJS::Identifier &propertyName) const \
349 if (KJS::ObjectImp::hasProperty(exec, propertyName)) \
351 return ParentProto::self(exec).hasProperty(exec, propertyName); \
354 #define PUBLIC_IMPLEMENT_PROTOTYPE_WITH_PARENT(ClassProto,ClassName,ClassFunc,ParentProto) \
355 IMPLEMENT_PROTOTYPE_WITH_PARENT(ClassProto,ClassFunc,ParentProto) \
356 IMPLEMENT_CLASSINFO(ClassName,ClassProto)
358 #define IMPLEMENT_PROTOFUNC(ClassFunc) \
360 class ClassFunc : public ObjectImp { \
362 ClassFunc(KJS::ExecState *exec, int i, int len) \
363 : ObjectImp( ), id(i) { \
364 KJS::Value protect(this); \
365 put(exec,lengthPropertyName,Number(len),DontDelete|ReadOnly|DontEnum); \
367 virtual bool implementsCall() const { return true; } \
369 virtual KJS::Value call(KJS::ExecState *exec, KJS::Object &thisObj, const KJS::List &args); \
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); \
Value objects are act as wrappers ("smart pointers") around ValueImp objects and their descendents...
const char *const sbase
pointer to the string table.
short int value
value is the result value (usually an enum value)
int type
type is a version number.
int size
size is the total number of entries in the hashtable, including the null entries, i...
An entry in a hash table.
int hashSize
the maximum value for the hash.
A hash table Usually the hashtable is generated by the create_hash_table script, from a ...
unsigned char attr
attr is a set for flags (e.g.
unsigned short soffset
s is the offset to the string key (e.g.
short next
next is the index to the next entry for the same hash value
unsigned char params
params is another number.
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...
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...
const HashEntry *const entries
pointer to the array of entries Mind that some entries in the array are null (0,0,0,0).
Represents the current state of script execution.
Represents an Identifier for a Javascript object.