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); \