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