JavaScriptCore:
authormjs <mjs@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 25 Jul 2005 22:17:20 +0000 (22:17 +0000)
committermjs <mjs@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 25 Jul 2005 22:17:20 +0000 (22:17 +0000)
        Reviewed by Darin.

- http://bugzilla.opendarwin.org/show_bug.cgi?id=4124
(change JavaScript property access to avoid double lookup)

- 10% speedup on JavaScript iBench
- 5% speedup on 24fun BenchJS benchmark

Changed all get methods to getOwnProperty - they are no longer
responsible for prototype lookup, and determine if the property
was found as a side efect.

get() is now a nonvirtual ObjectImp method which calls the virtual
getOwnProperty and walks the prototype chain. A few selected
methods were inlined.

Changed ResolveNode::evaluate plus some other places to use
getProperty which does get() and hasProperty() in one lookup.

Also miscellaneous code cleanup.

* bindings/objc/objc_runtime.h:
        * bindings/objc/objc_runtime.mm:
        (ObjcFallbackObjectImp::ObjcFallbackObjectImp):
        (ObjcFallbackObjectImp::getOwnProperty):
        * bindings/runtime_array.cpp:
        (RuntimeArrayImp::RuntimeArrayImp):
        (RuntimeArrayImp::getOwnProperty):
        * bindings/runtime_array.h:
        * bindings/runtime_method.cpp:
        (RuntimeMethodImp::getOwnProperty):
        * bindings/runtime_method.h:
        * bindings/runtime_object.cpp:
        (RuntimeObjectImp::getOwnProperty):
        * bindings/runtime_object.h:
        * kjs/array_instance.h:
        * kjs/array_object.cpp:
        (ArrayInstanceImp::getOwnProperty):
        (ArrayPrototypeImp::getOwnProperty):
        (ArrayProtoFuncImp::call):
        * kjs/array_object.h:
        * kjs/date_object.cpp:
        (DatePrototypeImp::getOwnProperty):
        * kjs/date_object.h:
        * kjs/function.cpp:
        (KJS::FunctionImp::getOwnProperty):
        (KJS::ArgumentsImp::getOwnProperty):
        (KJS::ActivationImp::getOwnProperty):
        * kjs/function.h:
        * kjs/lookup.h:
        (KJS::lookupGetOwnProperty):
        (KJS::lookupGetOwnFunction):
        (KJS::lookupGetOwnValue):
        * kjs/math_object.cpp:
        (MathObjectImp::getOwnProperty):
        (MathObjectImp::getValueProperty):
        * kjs/math_object.h:
        * kjs/nodes.cpp:
        (ResolveNode::evaluate):
        * kjs/number_object.cpp:
        (NumberObjectImp::getOwnProperty):
        * kjs/number_object.h:
        * kjs/object.cpp:
        (KJS::ObjectImp::get):
        (KJS::ObjectImp::getOwnProperty):
        (KJS::ObjectImp::getProperty):
        * kjs/object.h:
        (KJS::ObjectImp::getProperty):
        (KJS::ObjectImp::getOwnProperty):
        * kjs/object_object.cpp:
        (ObjectProtoFuncImp::call):
        * kjs/regexp_object.cpp:
        (RegExpObjectImp::getOwnProperty):
        * kjs/regexp_object.h:
        * kjs/string_object.cpp:
        (StringInstanceImp::getOwnProperty):
        (StringPrototypeImp::getOwnProperty):
        * kjs/string_object.h:

WebCore:

        Reviewed by Darin.

- http://bugzilla.opendarwin.org/show_bug.cgi?id=4124
(change JavaScript property access to avoid double lookup)

- 10% speedup on JavaScript iBench
- 5% speedup on 24fun BenchJS benchmark

Changed all get methods to getOwnProperty - they are no longer responsible for
prototype lookup, and determine if the property was found as a side efect.

Also miscellaneous code cleanup.

        * khtml/ecma/kjs_css.cpp:
        (KJS::DOMCSSStyleDeclaration::getOwnProperty):
        (KJS::DOMStyleSheet::getOwnProperty):
        (KJS::DOMStyleSheetList::getOwnProperty):
        (KJS::DOMMediaList::getOwnProperty):
        (KJS::DOMCSSStyleSheet::getOwnProperty):
        (KJS::DOMCSSRuleList::getOwnProperty):
        (KJS::DOMCSSRule::getOwnProperty):
        (KJS::DOMCSSRule::getValueProperty):
        (KJS::CSSRuleConstructor::getOwnProperty):
        (KJS::DOMCSSValue::getOwnProperty):
        (KJS::CSSValueConstructor::getOwnProperty):
        (KJS::DOMCSSPrimitiveValue::getOwnProperty):
        (KJS::CSSPrimitiveValueConstructor::getOwnProperty):
        (KJS::DOMCSSValueList::getOwnProperty):
        (KJS::DOMRGBColor::getOwnProperty):
        (KJS::DOMRect::getOwnProperty):
        (KJS::DOMCounter::getOwnProperty):
        * khtml/ecma/kjs_css.h:
        * khtml/ecma/kjs_dom.cpp:
        (KJS::DOMNode::getOwnProperty):
        (KJS::DOMNodeList::getOwnProperty):
        (KJS::DOMAttr::getOwnProperty):
        (KJS::DOMDocument::getOwnProperty):
        (KJS::DOMElement::getOwnProperty):
        (KJS::DOMDocumentType::getOwnProperty):
        (KJS::DOMNamedNodeMap::getOwnProperty):
        (KJS::DOMProcessingInstruction::getOwnProperty):
        (KJS::DOMNotation::getOwnProperty):
        (KJS::DOMEntity::getOwnProperty):
        (KJS::NodeConstructor::getOwnProperty):
        (KJS::DOMExceptionConstructor::getOwnProperty):
        (KJS::DOMNamedNodesCollection::getOwnProperty):
        (KJS::DOMCharacterData::getOwnProperty):
        * khtml/ecma/kjs_dom.h:
        * khtml/ecma/kjs_events.cpp:
        (KJS::EventConstructor::getOwnProperty):
        (KJS::DOMEvent::getOwnProperty):
        (KJS::EventExceptionConstructor::getOwnProperty):
        (KJS::DOMUIEvent::getOwnProperty):
        (KJS::DOMMouseEvent::getOwnProperty):
        (KJS::DOMKeyboardEvent::getOwnProperty):
        (KJS::MutationEventConstructor::getOwnProperty):
        (KJS::DOMMutationEvent::getOwnProperty):
        (KJS::DOMWheelEvent::getOwnProperty):
        (KJS::Clipboard::getOwnProperty):
        * khtml/ecma/kjs_events.h:
        * khtml/ecma/kjs_html.cpp:
        (KJS::HTMLDocument::getOwnProperty):
        (KJS::KJS::HTMLElement::getOwnProperty):
        (KJS::KJS::HTMLCollection::getOwnProperty):
        (KJS::KJS::HTMLSelectCollection::getOwnProperty):
        (KJS::Image::getOwnProperty):
        (KJS::Context2D::getOwnProperty):
        (KJS::Gradient::getOwnProperty):
        (KJS::ImagePattern::getOwnProperty):
        * khtml/ecma/kjs_html.h:
        * khtml/ecma/kjs_navigator.cpp:
        (KJS::Plugin::Plugin):
        (KJS::Navigator::getOwnProperty):
        (KJS::Plugins::getOwnProperty):
        (KJS::MimeTypes::getOwnProperty):
        (KJS::Plugin::getOwnProperty):
        (KJS::MimeType::getOwnProperty):
        * khtml/ecma/kjs_navigator.h:
        * khtml/ecma/kjs_range.cpp:
        (KJS::DOMRange::getOwnProperty):
        (KJS::RangeConstructor::getOwnProperty):
        * khtml/ecma/kjs_range.h:
        * khtml/ecma/kjs_traversal.cpp:
        (KJS::DOMNodeIterator::getOwnProperty):
        (KJS::NodeFilterConstructor::getOwnProperty):
        (KJS::DOMTreeWalker::getOwnProperty):
        * khtml/ecma/kjs_traversal.h:
        * khtml/ecma/kjs_views.cpp:
        (KJS::DOMAbstractView::getOwnProperty):
        * khtml/ecma/kjs_views.h:
        * khtml/ecma/kjs_window.cpp:
        (KJS::Screen::getOwnProperty):
        (KJS::Window::~Window):
        (KJS::Window::getOwnProperty):
        (KJS::Window::put):
        (KJS::FrameArray::getOwnProperty):
        (KJS::Location::Location):
        (KJS::Location::getOwnProperty):
        (KJS::Location::put):
        (KJS::Selection::Selection):
        (KJS::Selection::getOwnProperty):
        (KJS::BarInfo::getOwnProperty):
        (KJS::History::getOwnProperty):
        * khtml/ecma/kjs_window.h:
        * khtml/ecma/xmlhttprequest.cpp:
        (KJS::XMLHttpRequest::getOwnProperty):
        * khtml/ecma/xmlhttprequest.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@9889 268f45cc-cd09-0410-ab3c-d52691b4dbfc

50 files changed:
JavaScriptCore/ChangeLog
JavaScriptCore/bindings/objc/objc_runtime.h
JavaScriptCore/bindings/objc/objc_runtime.mm
JavaScriptCore/bindings/runtime_array.cpp
JavaScriptCore/bindings/runtime_array.h
JavaScriptCore/bindings/runtime_method.cpp
JavaScriptCore/bindings/runtime_method.h
JavaScriptCore/bindings/runtime_object.cpp
JavaScriptCore/bindings/runtime_object.h
JavaScriptCore/kjs/array_instance.h
JavaScriptCore/kjs/array_object.cpp
JavaScriptCore/kjs/array_object.h
JavaScriptCore/kjs/date_object.cpp
JavaScriptCore/kjs/date_object.h
JavaScriptCore/kjs/function.cpp
JavaScriptCore/kjs/function.h
JavaScriptCore/kjs/lookup.h
JavaScriptCore/kjs/math_object.cpp
JavaScriptCore/kjs/math_object.h
JavaScriptCore/kjs/nodes.cpp
JavaScriptCore/kjs/number_object.cpp
JavaScriptCore/kjs/number_object.h
JavaScriptCore/kjs/object.cpp
JavaScriptCore/kjs/object.h
JavaScriptCore/kjs/object_object.cpp
JavaScriptCore/kjs/regexp_object.cpp
JavaScriptCore/kjs/regexp_object.h
JavaScriptCore/kjs/string_object.cpp
JavaScriptCore/kjs/string_object.h
WebCore/ChangeLog-2005-08-23
WebCore/khtml/ecma/kjs_css.cpp
WebCore/khtml/ecma/kjs_css.h
WebCore/khtml/ecma/kjs_dom.cpp
WebCore/khtml/ecma/kjs_dom.h
WebCore/khtml/ecma/kjs_events.cpp
WebCore/khtml/ecma/kjs_events.h
WebCore/khtml/ecma/kjs_html.cpp
WebCore/khtml/ecma/kjs_html.h
WebCore/khtml/ecma/kjs_navigator.cpp
WebCore/khtml/ecma/kjs_navigator.h
WebCore/khtml/ecma/kjs_range.cpp
WebCore/khtml/ecma/kjs_range.h
WebCore/khtml/ecma/kjs_traversal.cpp
WebCore/khtml/ecma/kjs_traversal.h
WebCore/khtml/ecma/kjs_views.cpp
WebCore/khtml/ecma/kjs_views.h
WebCore/khtml/ecma/kjs_window.cpp
WebCore/khtml/ecma/kjs_window.h
WebCore/khtml/ecma/xmlhttprequest.cpp
WebCore/khtml/ecma/xmlhttprequest.h

index 4f86c10..1e48303 100644 (file)
@@ -1,3 +1,84 @@
+2005-07-24  Maciej Stachowiak  <mjs@apple.com>
+
+        Reviewed by Darin.
+
+       - http://bugzilla.opendarwin.org/show_bug.cgi?id=4124
+       (change JavaScript property access to avoid double lookup)
+
+       - 10% speedup on JavaScript iBench
+       - 5% speedup on 24fun BenchJS benchmark
+
+       Changed all get methods to getOwnProperty - they are no longer
+       responsible for prototype lookup, and determine if the property
+       was found as a side efect. 
+
+       get() is now a nonvirtual ObjectImp method which calls the virtual
+       getOwnProperty and walks the prototype chain. A few selected
+       methods were inlined.
+
+       Changed ResolveNode::evaluate plus some other places to use
+       getProperty which does get() and hasProperty() in one lookup.
+
+       Also miscellaneous code cleanup.
+        
+       * bindings/objc/objc_runtime.h:
+        * bindings/objc/objc_runtime.mm:
+        (ObjcFallbackObjectImp::ObjcFallbackObjectImp):
+        (ObjcFallbackObjectImp::getOwnProperty):
+        * bindings/runtime_array.cpp:
+        (RuntimeArrayImp::RuntimeArrayImp):
+        (RuntimeArrayImp::getOwnProperty):
+        * bindings/runtime_array.h:
+        * bindings/runtime_method.cpp:
+        (RuntimeMethodImp::getOwnProperty):
+        * bindings/runtime_method.h:
+        * bindings/runtime_object.cpp:
+        (RuntimeObjectImp::getOwnProperty):
+        * bindings/runtime_object.h:
+        * kjs/array_instance.h:
+        * kjs/array_object.cpp:
+        (ArrayInstanceImp::getOwnProperty):
+        (ArrayPrototypeImp::getOwnProperty):
+        (ArrayProtoFuncImp::call):
+        * kjs/array_object.h:
+        * kjs/date_object.cpp:
+        (DatePrototypeImp::getOwnProperty):
+        * kjs/date_object.h:
+        * kjs/function.cpp:
+        (KJS::FunctionImp::getOwnProperty):
+        (KJS::ArgumentsImp::getOwnProperty):
+        (KJS::ActivationImp::getOwnProperty):
+        * kjs/function.h:
+        * kjs/lookup.h:
+        (KJS::lookupGetOwnProperty):
+        (KJS::lookupGetOwnFunction):
+        (KJS::lookupGetOwnValue):
+        * kjs/math_object.cpp:
+        (MathObjectImp::getOwnProperty):
+        (MathObjectImp::getValueProperty):
+        * kjs/math_object.h:
+        * kjs/nodes.cpp:
+        (ResolveNode::evaluate):
+        * kjs/number_object.cpp:
+        (NumberObjectImp::getOwnProperty):
+        * kjs/number_object.h:
+        * kjs/object.cpp:
+        (KJS::ObjectImp::get):
+        (KJS::ObjectImp::getOwnProperty):
+        (KJS::ObjectImp::getProperty):
+        * kjs/object.h:
+        (KJS::ObjectImp::getProperty):
+        (KJS::ObjectImp::getOwnProperty):
+        * kjs/object_object.cpp:
+        (ObjectProtoFuncImp::call):
+        * kjs/regexp_object.cpp:
+        (RegExpObjectImp::getOwnProperty):
+        * kjs/regexp_object.h:
+        * kjs/string_object.cpp:
+        (StringInstanceImp::getOwnProperty):
+        (StringPrototypeImp::getOwnProperty):
+        * kjs/string_object.h:
+
 2005-07-25  Geoffrey Garen  <ggaren@apple.com>
 
         - fixed http://bugzilla.opendarwin.org/show_bug.cgi?id=3971
index 8a4e741..744e01e 100644 (file)
@@ -169,7 +169,7 @@ public:
 
     const ClassInfo *classInfo() const { return &info; }
 
-    virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
 
     virtual void put(ExecState *exec, const Identifier &propertyName,
                      const Value &value, int attr = None);
index 060554a..1168934 100644 (file)
@@ -261,15 +261,18 @@ ObjcFallbackObjectImp::ObjcFallbackObjectImp(ObjectImp *proto)
     _instance = 0;
 }
 
-ObjcFallbackObjectImp::ObjcFallbackObjectImp(ObjcInstance *i, const KJS::Identifier propertyName) : ObjectImp ((ObjectImp *)0)
+ObjcFallbackObjectImp::ObjcFallbackObjectImp(ObjcInstance *i, const KJS::Identifier propertyName)
+    : ObjectImp ((ObjectImp *)0)
 {
     _instance = i;
     _item = propertyName;
 }
 
-Value ObjcFallbackObjectImp::get(ExecState *exec, const Identifier &propertyName) const
+bool ObjcFallbackObjectImp::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
 {
-    return Undefined();
+    // keep the prototype from getting called instead of just returning false
+    result = Undefined();
+    return true;
 }
 
 void ObjcFallbackObjectImp::put(ExecState *exec, const Identifier &propertyName,
index 2feae39..113be46 100644 (file)
@@ -31,7 +31,8 @@ using namespace KJS;
 
 const ClassInfo RuntimeArrayImp::info = {"RuntimeArray", &ArrayInstanceImp::info, 0, 0};
 
-RuntimeArrayImp::RuntimeArrayImp(ExecState *exec, Bindings::Array *a) : ArrayInstanceImp (exec->lexicalInterpreter()->builtinArrayPrototype().imp(), a->getLength())
+RuntimeArrayImp::RuntimeArrayImp(ExecState *exec, Bindings::Array *a)
+    : ArrayInstanceImp (exec->lexicalInterpreter()->builtinArrayPrototype().imp(), a->getLength())
 {
     // Always takes ownership of concrete array.
     _array = a;
@@ -42,28 +43,34 @@ RuntimeArrayImp::~RuntimeArrayImp()
     delete _array;
 }
 
-
-Value RuntimeArrayImp::get(ExecState *exec, const Identifier &propertyName) const
+bool RuntimeArrayImp::getOwnProperty(ExecState *exec, const Identifier &propertyName, Value& result) const
 {
-    if (propertyName == lengthPropertyName)
-        return Number(getLength());
+    if (propertyName == lengthPropertyName) {
+        result = Number(getLength());
+        return true;
+    }
     
     bool ok;
     unsigned index = propertyName.toArrayIndex(&ok);
     if (ok) {
         if (index >= getLength())
-            return Undefined();
-        return getConcreteArray()->valueAt(exec, index);
+            result =  Undefined();
+        else
+            result = getConcreteArray()->valueAt(exec, index);
+        return true;
     }
     
-    return ObjectImp::get(exec, propertyName);
+    return ArrayInstanceImp::getOwnProperty(exec, propertyName, result);
 }
 
-Value RuntimeArrayImp::get(ExecState *exec, unsigned index) const
+bool RuntimeArrayImp::getOwnProperty(ExecState *exec, unsigned index, Value& result) const
 {
     if (index >= getLength())
-        return Undefined();
-    return getConcreteArray()->valueAt(exec, index);
+        result = Undefined();
+    else
+        result = getConcreteArray()->valueAt(exec, index);
+    
+    return true;
 }
 
 void RuntimeArrayImp::put(ExecState *exec, const Identifier &propertyName, const Value &value, int attr)
index a56b142..324a379 100644 (file)
@@ -37,8 +37,8 @@ public:
     RuntimeArrayImp(ExecState *exec, Bindings::Array *i);
     ~RuntimeArrayImp();
     
-    virtual Value get(ExecState *exec, const Identifier &propertyName) const;
-    virtual Value get(ExecState *exec, unsigned index) const ;
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
+    virtual bool getOwnProperty(ExecState *exec, unsigned index, Value& result) const ;
     virtual void put(ExecState *exec, const Identifier &propertyName, const Value &value, int attr = None);
     virtual void put(ExecState *exec, unsigned propertyName, const Value &value, int attr = None);
     
index 1d8e71c..74c2866 100644 (file)
@@ -40,30 +40,19 @@ RuntimeMethodImp::~RuntimeMethodImp()
 {
 }
 
-Value RuntimeMethodImp::get(ExecState *exec, const Identifier &propertyName) const
+bool RuntimeMethodImp::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
 {
-    // Find the arguments from the closest context.
-    if (propertyName == argumentsPropertyName) {
-        ContextImp *context = exec->_context;
-        while (context) {
-            if (context->function() == this)
-                return static_cast<ActivationImp *>
-                    (context->activationObject())->get(exec, propertyName);
-            context = context->callingContext();
-        }
-        return Undefined();
-    }
-    
     // Compute length of parameters.
     if (propertyName == lengthPropertyName) {
         // Ick!  There may be more than one method with this name.  Arbitrarily
         // just pick the first method.  The fundamental problem here is that 
         // JavaScript doesn't have the notion of method overloading and
         // Java does.
-        return Number(_methodList.methodAt(0)->numParameters());
+        result = Number(_methodList.methodAt(0)->numParameters());
+        return result;
     }
     
-    return FunctionImp::get(exec, propertyName);
+    return FunctionImp::getOwnProperty(exec, propertyName, result);
 }
 
 bool RuntimeMethodImp::implementsCall() const
index 6cfc5a5..3fc4dbb 100644 (file)
@@ -38,7 +38,7 @@ public:
     
     virtual ~RuntimeMethodImp();
 
-    virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
 
     virtual bool implementsCall() const;
     virtual Value call(ExecState *exec, Object &thisObj, const List &args);
@@ -53,4 +53,4 @@ private:
 
 } // namespace KJS
 
-#endif
\ No newline at end of file
+#endif
index 2531d3e..3a54e77 100644 (file)
@@ -60,40 +60,39 @@ RuntimeObjectImp::RuntimeObjectImp(Bindings::Instance *i, bool oi) : ObjectImp (
     instance = i;
 }
 
-Value RuntimeObjectImp::get(ExecState *exec, const Identifier &propertyName) const
+bool RuntimeObjectImp::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
 {
-    Value result = Undefined();
-
     instance->begin();
     
     Class *aClass = instance->getClass();
     
     if (aClass) {
-        
         // See if the instance have a field with the specified name.
         Field *aField = aClass->fieldNamed(propertyName.ascii(), instance);
         if (aField) {
-            result = instance->getValueOfField (exec, aField); 
-        }
-        else {
+            result = instance->getValueOfField(exec, aField); 
+            return true;
+        else {
             // Now check if a method with specified name exists, if so return a function object for
             // that method.
             MethodList methodList = aClass->methodsNamed(propertyName.ascii(), instance);
             if (methodList.length() > 0) {
-                result = Object (new RuntimeMethodImp(exec, propertyName, methodList));
+                result = Object(new RuntimeMethodImp(exec, propertyName, methodList));
+                return true;
             }
         }
        
         if (result.type() == UndefinedType) {
             // Try a fallback object.
-            result = aClass->fallbackObject (exec, instance, propertyName);
+            result = aClass->fallbackObject(exec, instance, propertyName);
+            return true;
         }
     }
         
     instance->end();
 
-    
-    return result;
+    // don't call superclass, because runtime objects can't have custom properties or a prototype
+    return false;
 }
 
 void RuntimeObjectImp::put(ExecState *exec, const Identifier &propertyName,
index 799dffb..07bf9ab 100644 (file)
@@ -41,7 +41,7 @@ public:
 
     const ClassInfo *classInfo() const { return &info; }
 
-    virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
 
     virtual void put(ExecState *exec, const Identifier &propertyName,
                      const Value &value, int attr = None);
index 880e800..72ed6e2 100644 (file)
@@ -33,8 +33,8 @@ namespace KJS {
     ArrayInstanceImp(ObjectImp *proto, const List &initialValues);
     ~ArrayInstanceImp();
 
-    virtual Value get(ExecState *exec, const Identifier &propertyName) const;
-    virtual Value get(ExecState *exec, unsigned propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
+    virtual bool getOwnProperty(ExecState *exec, unsigned index, Value& result) const;
     virtual void put(ExecState *exec, const Identifier &propertyName, const Value &value, int attr = None);
     virtual void put(ExecState *exec, unsigned propertyName, const Value &value, int attr = None);
     virtual bool hasOwnProperty(ExecState *exec, const Identifier &propertyName) const;
index 65db697..baa3861 100644 (file)
@@ -70,35 +70,45 @@ ArrayInstanceImp::~ArrayInstanceImp()
   free(storage);
 }
 
-Value ArrayInstanceImp::get(ExecState *exec, const Identifier &propertyName) const
+bool ArrayInstanceImp::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
 {
-  if (propertyName == lengthPropertyName)
-    return Number(length);
+  if (propertyName == lengthPropertyName) {
+    result = Number(length);
+    return true;
+  }
 
   bool ok;
   unsigned index = propertyName.toArrayIndex(&ok);
   if (ok) {
     if (index >= length)
-      return Undefined();
+      return false;
     if (index < storageLength) {
       ValueImp *v = storage[index];
-      return v ? Value(v) : Undefined();
+      if (!v || v == UndefinedImp::staticUndefined)
+        return false;
+
+      result = Value(v);
+      return true;
     }
   }
 
-  return ObjectImp::get(exec, propertyName);
+  return ObjectImp::getOwnProperty(exec, propertyName, result);
 }
 
-Value ArrayInstanceImp::get(ExecState *exec, unsigned index) const
+bool ArrayInstanceImp::getOwnProperty(ExecState *exec, unsigned index, Value& result) const
 {
   if (index >= length)
-    return Undefined();
+    return false;
   if (index < storageLength) {
     ValueImp *v = storage[index];
-    return v ? Value(v) : Undefined();
+    if (!v || v == UndefinedImp::staticUndefined)
+      return false;
+
+    result = Value(v);
+    return true;
   }
   
-  return ObjectImp::get(exec, Identifier::from(index));
+  return ObjectImp::getOwnProperty(exec, Identifier::from(index), result);
 }
 
 // Special implementation of [[Put]] - see ECMA 15.4.5.1
@@ -418,10 +428,9 @@ ArrayPrototypeImp::ArrayPrototypeImp(ExecState *exec,
   setInternalValue(Null());
 }
 
-Value ArrayPrototypeImp::get(ExecState *exec, const Identifier &propertyName) const
+bool ArrayPrototypeImp::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
 {
-  //fprintf( stderr, "ArrayPrototypeImp::get(%s)\n", propertyName.ascii() );
-  return lookupGetFunction<ArrayProtoFuncImp, ArrayInstanceImp>( exec, propertyName, &arrayTable, this );
+  return lookupGetOwnFunction<ArrayProtoFuncImp, ArrayInstanceImp>(exec, propertyName, &arrayTable, this, result);
 }
 
 // ------------------------------ ArrayProtoFuncImp ----------------------------
@@ -444,6 +453,7 @@ bool ArrayProtoFuncImp::implementsCall() const
 Value ArrayProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &args)
 {
   unsigned int length = thisObj.get(exec,lengthPropertyName).toUInt32(exec);
+  ObjectImp *thisImp = thisObj.imp();
 
   Value result;
   
@@ -501,8 +511,9 @@ Value ArrayProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &args
         // by checking for n != 0, but that doesn't work if thisObj is an empty array.
         length = curObj.get(exec,lengthPropertyName).toUInt32(exec);
         while (k < length) {
-          if (curObj.hasProperty(exec,k))
-            arr.put(exec, n, curObj.get(exec, k));
+          Value v;
+          if (curObj.imp()->getProperty(exec, k, v))
+            arr.put(exec, n, v);
           n++;
           k++;
         }
@@ -544,26 +555,20 @@ Value ArrayProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &args
 
     for (unsigned int k = 0; k < middle; k++) {
       unsigned lk1 = length - k - 1;
-      Value obj = thisObj.get(exec,k);
-      Value obj2 = thisObj.get(exec,lk1);
-      if (thisObj.hasProperty(exec,lk1)) {
-        if (thisObj.hasProperty(exec,k)) {
-          thisObj.put(exec, k, obj2);
-          thisObj.put(exec, lk1, obj);
-        } else {
-          thisObj.put(exec, k, obj2);
-          thisObj.deleteProperty(exec, lk1);
-        }
-      } else {
-        if (thisObj.hasProperty(exec, k)) {
-          thisObj.deleteProperty(exec, k);
-          thisObj.put(exec, lk1, obj);
-        } else {
-          // why delete something that's not there ? Strange.
-          thisObj.deleteProperty(exec, k);
-          thisObj.deleteProperty(exec, lk1);
-        }
-      }
+      Value obj;
+      Value obj2;
+      bool has2 = thisImp->getProperty(exec, lk1, obj2);
+      bool has1 = thisImp->getProperty(exec, k, obj);
+
+      if (has2) 
+        thisObj.put(exec, k, obj2);
+      else
+        thisObj.deleteProperty(exec, k);
+
+      if (has1)
+        thisObj.put(exec, lk1, obj);
+      else
+        thisObj.deleteProperty(exec, lk1);
     }
     result = thisObj;
     break;
@@ -575,10 +580,10 @@ Value ArrayProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &args
     } else {
       result = thisObj.get(exec, 0);
       for(unsigned int k = 1; k < length; k++) {
-        if (thisObj.hasProperty(exec, k)) {
-          Value obj = thisObj.get(exec, k);
+        Value obj;
+        if (thisImp->getProperty(exec, k, obj))
           thisObj.put(exec, k-1, obj);
-        else
+        else
           thisObj.deleteProperty(exec, k-1);
       }
       thisObj.deleteProperty(exec, length - 1);
@@ -622,10 +627,9 @@ Value ArrayProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &args
     int b = static_cast<int>(begin);
     int e = static_cast<int>(end);
     for(int k = b; k < e; k++, n++) {
-      if (thisObj.hasProperty(exec, k)) {
-        Value obj = thisObj.get(exec, k);
+      Value obj;
+      if (thisImp->getProperty(exec, k, obj))
         resObj.put(exec, n, obj);
-      }
     }
     resObj.put(exec, lengthPropertyName, Number(n), DontEnum | DontDelete);
     break;
@@ -645,11 +649,11 @@ Value ArrayProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &args
           useSortFunction = false;
       }
     
-    if (thisObj.imp()->classInfo() == &ArrayInstanceImp::info) {
+    if (thisImp->classInfo() == &ArrayInstanceImp::info) {
       if (useSortFunction)
-        ((ArrayInstanceImp *)thisObj.imp())->sort(exec, sortFunction);
+        ((ArrayInstanceImp *)thisImp)->sort(exec, sortFunction);
       else
-        ((ArrayInstanceImp *)thisObj.imp())->sort(exec);
+        ((ArrayInstanceImp *)thisImp)->sort(exec);
       result = thisObj;
       break;
     }
@@ -718,10 +722,9 @@ Value ArrayProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &args
 
     //printf( "Splicing from %d, deleteCount=%d \n", begin, deleteCount );
     for(unsigned int k = 0; k < deleteCount; k++) {
-      if (thisObj.hasProperty(exec,k+begin)) {
-        Value obj = thisObj.get(exec, k+begin);
+      Value obj;
+      if (thisImp->getProperty(exec, k+begin, obj))
         resObj.put(exec, k, obj);
-      }
     }
     resObj.put(exec, lengthPropertyName, Number(deleteCount), DontEnum | DontDelete);
 
@@ -732,10 +735,9 @@ Value ArrayProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &args
       {
         for ( unsigned int k = begin; k < length - deleteCount; ++k )
         {
-          if (thisObj.hasProperty(exec,k+deleteCount)) {
-            Value obj = thisObj.get(exec, k+deleteCount);
+          Value obj;
+          if (thisImp->getProperty(exec, k+deleteCount, obj))
             thisObj.put(exec, k+additionalArgs, obj);
-          }
           else
             thisObj.deleteProperty(exec, k+additionalArgs);
         }
@@ -746,10 +748,9 @@ Value ArrayProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &args
       {
         for ( unsigned int k = length - deleteCount; (int)k > begin; --k )
         {
-          if (thisObj.hasProperty(exec,k+deleteCount-1)) {
-            Value obj = thisObj.get(exec, k+deleteCount-1);
-            thisObj.put(exec, k+additionalArgs-1, obj);
-          }
+          Value obj;
+          if (thisImp->getProperty(exec, k + deleteCount - 1, obj))
+            thisObj.put(exec, k + additionalArgs - 1, obj);
           else
             thisObj.deleteProperty(exec, k+additionalArgs-1);
         }
@@ -766,12 +767,11 @@ Value ArrayProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &args
     unsigned int nrArgs = args.size();
     for ( unsigned int k = length; k > 0; --k )
     {
-      if (thisObj.hasProperty(exec,k-1)) {
-        Value obj = thisObj.get(exec, k-1);
+      Value obj;
+      if (thisImp->getProperty(exec, k - 1, obj))
         thisObj.put(exec, k+nrArgs-1, obj);
-      } else {
+      else
         thisObj.deleteProperty(exec, k+nrArgs-1);
-      }
     }
     for ( unsigned int k = 0; k < nrArgs; ++k )
       thisObj.put(exec, k, args[k]);
index 7555d28..8dec59e 100644 (file)
@@ -31,7 +31,7 @@ namespace KJS {
   public:
     ArrayPrototypeImp(ExecState *exec,
                       ObjectPrototypeImp *objProto);
-    Value get(ExecState *exec, const Identifier &p) const;
+    bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     virtual const ClassInfo *classInfo() const { return &info; }
     static const ClassInfo info;
   };
index 512d9c0..49f51d9 100644 (file)
@@ -466,9 +466,9 @@ DatePrototypeImp::DatePrototypeImp(ExecState *,
   // The constructor will be added later, after DateObjectImp has been built
 }
 
-Value DatePrototypeImp::get(ExecState *exec, const Identifier &propertyName) const
+bool DatePrototypeImp::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
 {
-  return lookupGetFunction<DateProtoFuncImp, ObjectImp>( exec, propertyName, &dateTable, this );
+  return lookupGetOwnFunction<DateProtoFuncImp, ObjectImp>(exec, propertyName, &dateTable, this, result);
 }
 
 // ------------------------------ DateProtoFuncImp -----------------------------
index be46f30..0dbc0cd 100644 (file)
@@ -46,7 +46,7 @@ namespace KJS {
   class DatePrototypeImp : public DateInstanceImp {
   public:
     DatePrototypeImp(ExecState *exec, ObjectPrototypeImp *objectProto);
-    Value get(ExecState *exec, const Identifier &p) const;
+    bool getOwnProperty(ExecState *exec, const Identifier& p, Value& result) const;
     virtual const ClassInfo *classInfo() const { return &info; }
     static const ClassInfo info;
   };
index 3049694..6b0c8fa 100644 (file)
@@ -202,18 +202,20 @@ void FunctionImp::processVarDecls(ExecState */*exec*/)
 {
 }
 
-Value FunctionImp::get(ExecState *exec, const Identifier &propertyName) const
+bool FunctionImp::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
 {
     // Find the arguments from the closest context.
     if (propertyName == argumentsPropertyName) {
         ContextImp *context = exec->_context;
         while (context) {
-            if (context->function() == this)
-                return static_cast<ActivationImp *>
-                    (context->activationObject())->get(exec, propertyName);
-            context = context->callingContext();
+          if (context->function() == this) {
+            result = static_cast<ActivationImp *>(context->activationObject())->get(exec, propertyName);
+            return true;
+          }
+          context = context->callingContext();
         }
-        return Null();
+        result = Null();
+        return true;
     }
     
     // Compute length of parameters.
@@ -224,10 +226,11 @@ Value FunctionImp::get(ExecState *exec, const Identifier &propertyName) const
             ++count;
             p = p->next;
         }
-        return Number(count);
+        result = Number(count);
+        return true;
     }
     
-    return InternalFunctionImp::get(exec, propertyName);
+    return InternalFunctionImp::getOwnProperty(exec, propertyName, result);
 }
 
 void FunctionImp::put(ExecState *exec, const Identifier &propertyName, const Value &value, int attr)
@@ -440,13 +443,14 @@ void ArgumentsImp::mark()
     _activationObject->mark();
 }
 
-Value ArgumentsImp::get(ExecState *exec, const Identifier &propertyName) const
+bool ArgumentsImp::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
 {
   if (indexToNameMap.isMapped(propertyName)) {
-    return _activationObject->get(exec, indexToNameMap[propertyName]);
-  } else {
-    return ObjectImp::get(exec, propertyName);
+    result = _activationObject->get(exec, indexToNameMap[propertyName]);
+    return true;
   }
+
+  return ObjectImp::getOwnProperty(exec, propertyName, result);
 }
 
 void ArgumentsImp::put(ExecState *exec, const Identifier &propertyName, const Value &value, int attr)
@@ -488,20 +492,22 @@ ActivationImp::ActivationImp(FunctionImp *function, const List &arguments)
   // FIXME: Do we need to support enumerating the arguments property?
 }
 
-Value ActivationImp::get(ExecState *exec, const Identifier &propertyName) const
+bool ActivationImp::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
 {
-    if (propertyName == argumentsPropertyName) {
-        // check for locally declared arguments property
-        ValueImp *v = getDirect(propertyName);
-        if (v)
-            return Value(v);
+    // do this first so property map arguments property wins over the below
+    if (ObjectImp::getOwnProperty(exec, propertyName, result))
+        return true;
 
+    if (propertyName == argumentsPropertyName) {
         // default: return builtin arguments array
         if (!_argumentsObject)
-                createArgumentsObject(exec);
-        return Value(_argumentsObject);
+            createArgumentsObject(exec);
+
+        result = Value(_argumentsObject);
+        return true;
     }
-    return ObjectImp::get(exec, propertyName);
+
+    return false;
 }
 
 bool ActivationImp::hasOwnProperty(ExecState *exec, const Identifier &propertyName) const
index 5198e68..3ae8d78 100644 (file)
@@ -41,7 +41,7 @@ namespace KJS {
     FunctionImp(ExecState *exec, const Identifier &n = Identifier::null());
     virtual ~FunctionImp();
 
-    virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     virtual void put(ExecState *exec, const Identifier &propertyName, const Value &value, int attr = None);
     virtual bool hasOwnProperty(ExecState *exec, const Identifier &propertyName) const;
     virtual bool deleteProperty(ExecState *exec, const Identifier &propertyName);
@@ -108,7 +108,7 @@ namespace KJS {
   public:
     ArgumentsImp(ExecState *exec, FunctionImp *func, const List &args, ActivationImp *act);
     virtual void mark();
-    virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     virtual void put(ExecState *exec, const Identifier &propertyName,
                      const Value &value, int attr = None);
     virtual bool hasOwnProperty(ExecState *exec, const Identifier &propertyName) const;
@@ -124,7 +124,7 @@ namespace KJS {
   public:
     ActivationImp(FunctionImp *function, const List &arguments);
 
-    virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     virtual bool hasOwnProperty(ExecState *exec, const Identifier &propertyName) const;
     virtual bool deleteProperty(ExecState *exec, const Identifier &propertyName);
 
index 210d1e0..08cac76 100644 (file)
@@ -164,18 +164,20 @@ namespace KJS {
    * @param thisObj "this"
    */
   template <class FuncImp, class ThisImp, class ParentImp>
-  inline Value lookupGet(ExecState *exec, const Identifier &propertyName,
-                         const HashTable* table, const ThisImp* thisObj)
+  inline bool lookupGetOwnProperty(ExecState *exec, const Identifier &propertyName,
+                                   const HashTable* table, const ThisImp* thisObj, Value& result)
   {
     const HashEntry* entry = Lookup::findEntry(table, propertyName);
 
     if (!entry) // not found, forward to parent
-      return thisObj->ParentImp::get(exec, propertyName);
+      return thisObj->ParentImp::getOwnProperty(exec, propertyName, result);
 
-    //fprintf(stderr, "lookupGet: found value=%d attr=%d\n", entry->value, entry->attr);
     if (entry->attr & Function)
-      return lookupOrCreateFunction<FuncImp>(exec, propertyName, thisObj, entry->value, entry->params, entry->attr);
-    return thisObj->getValueProperty(exec, entry->value);
+      result = lookupOrCreateFunction<FuncImp>(exec, propertyName, thisObj, entry->value, entry->params, entry->attr);
+    else 
+      result = thisObj->getValueProperty(exec, entry->value);
+
+    return true;
   }
 
   /**
@@ -183,19 +185,18 @@ namespace KJS {
    * Using this instead of lookupGet prevents 'this' from implementing a dummy getValueProperty.
    */
   template <class FuncImp, class ParentImp>
-  inline Value lookupGetFunction(ExecState *exec, const Identifier &propertyName,
-                         const HashTable* table, const ObjectImp* thisObj)
+  inline bool lookupGetOwnFunction(ExecState *exec, const Identifier &propertyName,
+                                   const HashTable* table, const ObjectImp* thisObj, Value& result)
   {
     const HashEntry* entry = Lookup::findEntry(table, propertyName);
 
     if (!entry) // not found, forward to parent
-      return static_cast<const ParentImp *>(thisObj)->ParentImp::get(exec, propertyName);
+      return static_cast<const ParentImp *>(thisObj)->ParentImp::getOwnProperty(exec, propertyName, result);
 
-    if (entry->attr & Function)
-      return lookupOrCreateFunction<FuncImp>(exec, propertyName, thisObj, entry->value, entry->params, entry->attr);
+    assert(entry->attr & Function);
 
-    fprintf(stderr, "Function bit not set! Shouldn't happen in lookupGetFunction!\n" );
-    return Undefined();
+    result = lookupOrCreateFunction<FuncImp>(exec, propertyName, thisObj, entry->value, entry->params, entry->attr);
+    return true;
   }
 
   /**
@@ -203,17 +204,18 @@ namespace KJS {
    * Using this instead of lookupGet removes the need for a FuncImp class.
    */
   template <class ThisImp, class ParentImp>
-  inline Value lookupGetValue(ExecState *exec, const Identifier &propertyName,
-                           const HashTable* table, const ThisImp* thisObj)
+  inline bool lookupGetOwnValue(ExecState *exec, const Identifier &propertyName,
+                                const HashTable* table, const ThisImp* thisObj, Value& result)
   {
     const HashEntry* entry = Lookup::findEntry(table, propertyName);
 
     if (!entry) // not found, forward to parent
-      return thisObj->ParentImp::get(exec, propertyName);
+      return thisObj->ParentImp::getOwnProperty(exec, propertyName, result);
 
-    if (entry->attr & Function)
-      fprintf(stderr, "Function bit set! Shouldn't happen in lookupGetValue! propertyName was %s\n", propertyName.ascii() );
-    return thisObj->getValueProperty(exec, entry->value);
+    assert(!entry->attr & Function);
+
+    result = thisObj->getValueProperty(exec, entry->value);
+    return true;
   }
 
   /**
@@ -293,16 +295,15 @@ namespace KJS {
   public: \
     virtual const ClassInfo *classInfo() const { return &info; } \
     static const ClassInfo info; \
-    Value get(ExecState *exec, const Identifier &propertyName) const; \
+    bool getOwnProperty(ExecState *exec, const Identifier &propertyName, Value& result) const; \
     bool hasOwnProperty(ExecState *exec, const Identifier &propertyName) const; \
   }; \
   const ClassInfo ClassProto::info = { ClassName, 0, &ClassProto##Table, 0 };
 
 #define IMPLEMENT_PROTOTYPE(ClassProto,ClassFunc) \
-    Value ClassProto::get(ExecState *exec, const Identifier &propertyName) const \
+    bool ClassProto::getOwnProperty(ExecState *exec, const Identifier &propertyName, Value& result) const \
     { \
-      /*fprintf( stderr, "%sProto::get(%s) [in macro, no parent]\n", info.className, propertyName.ascii());*/ \
-      return lookupGetFunction<ClassFunc,ObjectImp>(exec, propertyName, &ClassProto##Table, this ); \
+      return lookupGetOwnFunction<ClassFunc,ObjectImp>(exec, propertyName, &ClassProto##Table, this, result); \
     } \
     bool ClassProto::hasOwnProperty(ExecState *exec, const Identifier &propertyName) const \
     { /*stupid but we need this to have a common macro for the declaration*/ \
@@ -310,13 +311,11 @@ namespace KJS {
     }
 
 #define IMPLEMENT_PROTOTYPE_WITH_PARENT(ClassProto,ClassFunc,ParentProto)  \
-    Value ClassProto::get(ExecState *exec, const Identifier &propertyName) const \
+    bool ClassProto::getOwnProperty(ExecState *exec, const Identifier &propertyName, Value& result) const \
     { \
-      /*fprintf( stderr, "%sProto::get(%s) [in macro]\n", info.className, propertyName.ascii());*/ \
-      Value val = lookupGetFunction<ClassFunc,ObjectImp>(exec, propertyName, &ClassProto##Table, this ); \
-      if ( val.type() != UndefinedType ) return val; \
-      /* Not found -> forward request to "parent" prototype */ \
-      return ParentProto::self(exec)->get( exec, propertyName ); \
+      if (lookupGetOwnFunction<ClassFunc,ObjectImp>(exec, propertyName, &ClassProto##Table, this, result)) \
+          return true; \
+      return ParentProto::self(exec)->getOwnProperty(exec, propertyName, result); \
     } \
     bool ClassProto::hasOwnProperty(ExecState *exec, const Identifier &propertyName) const \
     { \
index 3041de0..9c18119 100644 (file)
@@ -21,7 +21,6 @@
 
 #include <math.h>
 #include <stdlib.h>
-#include <stdio.h>
 #include <assert.h>
 
 #include "value.h"
@@ -81,9 +80,10 @@ MathObjectImp::MathObjectImp(ExecState * /*exec*/,
 }
 
 // ECMA 15.8
-Value MathObjectImp::get(ExecState *exec, const Identifier &propertyName) const
+
+bool MathObjectImp::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
 {
-  return lookupGet<MathFuncImp, MathObjectImp, ObjectImp>( exec, propertyName, &mathTable, this );
+  return lookupGetOwnProperty<MathFuncImp, MathObjectImp, ObjectImp>(exec, propertyName, &mathTable, this, result);
 }
 
 Value MathObjectImp::getValueProperty(ExecState *, int token) const
@@ -115,8 +115,7 @@ Value MathObjectImp::getValueProperty(ExecState *, int token) const
     d = sqrt(2.0);
     break;
   default:
-    fprintf( stderr, "Internal error in MathObjectImp: unhandled token %d\n", token );
-    break;
+    assert(0);
   }
 
   return Number(d);
index 9d5a319..92eef64 100644 (file)
@@ -31,7 +31,7 @@ namespace KJS {
   public:
     MathObjectImp(ExecState *exec,
                   ObjectPrototypeImp *objProto);
-    Value get(ExecState *exec, const Identifier &p) const;
+    bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     Value getValueProperty(ExecState *exec, int token) const;
     virtual const ClassInfo *classInfo() const { return &info; }
     static const ClassInfo info;
index cf42ba2..3771fd9 100644 (file)
@@ -284,7 +284,22 @@ Value ThisNode::evaluate(ExecState *exec)
 // ECMA 11.1.2 & 10.1.4
 Value ResolveNode::evaluate(ExecState *exec)
 {
-  return evaluateReference(exec).getValue(exec);
+  ScopeChain chain = exec->context().imp()->scopeChain();
+
+  Value result;
+  while (!chain.isEmpty()) {
+    ObjectImp *o = chain.top();
+
+    if (o->getProperty(exec, ident, result))
+      return result;
+    
+    chain.pop();
+  }
+
+  UString m = I18N_NOOP("Can't find variable: ") + ident.ustring();
+  Object err = Error::create(exec, ReferenceError, m.ascii());
+  exec->setException(err);
+  return err;
 }
 
 Reference ResolveNode::evaluateReference(ExecState *exec)
index 9fff1fd..3fe0954 100644 (file)
@@ -402,9 +402,9 @@ NumberObjectImp::NumberObjectImp(ExecState *exec,
   putDirect(lengthPropertyName, NumberImp::one(), ReadOnly|DontDelete|DontEnum);
 }
 
-Value NumberObjectImp::get(ExecState *exec, const Identifier &propertyName) const
+bool NumberObjectImp::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
 {
-  return lookupGetValue<NumberObjectImp, InternalFunctionImp>( exec, propertyName, &numberTable, this );
+  return lookupGetOwnValue<NumberObjectImp, InternalFunctionImp>(exec, propertyName, &numberTable, this, result);
 }
 
 Value NumberObjectImp::getValueProperty(ExecState *, int token) const
index b846e87..dddbb1d 100644 (file)
@@ -84,7 +84,7 @@ namespace KJS {
     virtual bool implementsCall() const;
     virtual Value call(ExecState *exec, Object &thisObj, const List &args);
 
-    Value get(ExecState *exec, const Identifier &p) const;
+    bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     Value getValueProperty(ExecState *exec, int token) const;
     virtual const ClassInfo *classInfo() const { return &info; }
     static const ClassInfo info;
index c9d48cb..322c846 100644 (file)
@@ -208,24 +208,65 @@ UString ObjectImp::className() const
 
 Value ObjectImp::get(ExecState *exec, const Identifier &propertyName) const
 {
-  ValueImp *imp = getDirect(propertyName);
-  if (imp)
-    return Value(imp);
+  Value result;
 
-  // non-standard netscape extension
-  if (propertyName == specialPrototypePropertyName)
-    return Value(_proto);
+  const ObjectImp *imp = this;
 
-  if (_proto->dispatchType() != ObjectType) {
-    return Undefined();
+  while (true) {
+    if (imp->getOwnProperty(exec, propertyName, result))
+      return result;
+
+    const ValueImp *proto = imp->_proto;
+    if (proto->dispatchType() != ObjectType)
+      break;
+
+    imp = static_cast<const ObjectImp *>(proto);
   }
 
-  return static_cast<ObjectImp *>(_proto)->get(exec, propertyName);
+  return Undefined();
+}
+
+bool ObjectImp::getOwnProperty(ExecState *exec, unsigned propertyName, Value& result) const
+{
+  return getOwnProperty(exec, Identifier::from(propertyName), result);
 }
 
 Value ObjectImp::get(ExecState *exec, unsigned propertyName) const
 {
-  return get(exec, Identifier::from(propertyName));
+  Value result;
+
+  const ObjectImp *imp = this;
+
+  while (imp) {
+    if (imp->getOwnProperty(exec, propertyName, result))
+      return result;
+
+    const ValueImp *proto = imp->_proto;
+    if (proto->dispatchType() != ObjectType)
+      break;
+
+    imp = static_cast<const ObjectImp *>(proto);
+  }
+
+  return Undefined();
+}
+
+bool ObjectImp::getProperty(ExecState *exec, unsigned propertyName, Value& result) const
+{
+  const ObjectImp *imp = this;
+  
+  while (true) {
+    if (imp->getOwnProperty(exec, propertyName, result))
+      return true;
+    
+    const ValueImp *proto = imp->_proto;
+      if (proto->dispatchType() != ObjectType)
+        break;
+      
+      imp = static_cast<const ObjectImp *>(proto);
+  }
+  
+  return false;
 }
 
 // ECMA 8.6.2.2
index 5a9ee99..596ecea 100644 (file)
@@ -503,8 +503,14 @@ namespace KJS {
      * @see Object::get()
      */
     // [[Get]] - must be implemented by all Objects
-    virtual Value get(ExecState *exec, const Identifier &propertyName) const;
-    virtual Value get(ExecState *exec, unsigned propertyName) const;
+    Value get(ExecState *exec, const Identifier &propertyName) const;
+    Value get(ExecState *exec, unsigned propertyName) const;
+
+    bool getProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
+    bool getProperty(ExecState *exec, unsigned propertyName, Value& result) const;
+
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
+    virtual bool getOwnProperty(ExecState *exec, unsigned propertyName, Value& result) const;
 
     /**
      * Implementation of the [[Put]] internal property (implemented by all
@@ -632,6 +638,47 @@ namespace KJS {
     ScopeChain _scope;
   };
 
+
+  // it may seem crazy to inline a function this large but it makes a big difference
+  // since this is function very hot in variable lookup
+  inline bool ObjectImp::getProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
+  {
+    const ObjectImp *imp = this;
+
+    while (true) {
+      if (imp->getOwnProperty(exec, propertyName, result))
+        return true;
+      
+      const ValueImp *proto = imp->_proto;
+      if (proto->dispatchType() != ObjectType)
+        break;
+      
+      imp = static_cast<const ObjectImp *>(proto);
+    }
+    
+    return false;
+  }
+
+  // it may seem crazy to inline a function this large, especially a virtual function,
+  // but it makes a big difference to property lookup if subclasses can inline their
+  // superclass call to this
+  inline bool ObjectImp::getOwnProperty(ExecState *exec, const Identifier &propertyName, Value &result) const
+  {
+      ValueImp *imp = getDirect(propertyName);
+      if (imp) {
+        result = Value(imp);
+        return true;
+      }
+
+      // non-standard netscape extension
+      if (propertyName == specialPrototypePropertyName) {
+        result = Value(_proto);
+        return true;
+      }
+
+      return false;
+  }
+
   /**
    * Types of Native Errors available. For custom errors, GeneralError
    * should be used.
index 660c3ee..0e4fb13 100644 (file)
@@ -70,7 +70,7 @@ Value ObjectProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &arg
         case ValueOf:
             return thisObj;
         case HasOwnProperty: {
-            // Same as hasProperty() but without checking the prototype
+            // Same as the in operator but without checking the prototype
             Identifier propertyName(args[0].toString(exec));
             bool exists = thisObj.hasOwnProperty(exec, propertyName);
             return Value(exists ? BooleanImp::staticTrue : BooleanImp::staticFalse);
index ee6fc00..193f9fe 100644 (file)
@@ -216,7 +216,7 @@ Object RegExpObjectImp::arrayOfMatches(ExecState *exec, const UString &result) c
   return arr;
 }
 
-Value RegExpObjectImp::get(ExecState *exec, const Identifier &p) const
+bool RegExpObjectImp::getOwnProperty(ExecState *exec, const Identifier& p, Value& result) const
 {
   UString s = p.ustring();
   if (s[0] == '$' && lastOvector)
@@ -228,12 +228,15 @@ Value RegExpObjectImp::get(ExecState *exec, const Identifier &p) const
       if (i < lastNrSubPatterns + 1)
       {
         UString substring = lastString.substr( lastOvector[2*i], lastOvector[2*i+1] - lastOvector[2*i] );
-        return String(substring);
-      }
-      return String("");
+        result = String(substring);
+      } else
+        result = String("");
+      
+      return true;
     }
   }
-  return InternalFunctionImp::get(exec, p);
+
+  return InternalFunctionImp::getOwnProperty(exec, p, result);
 }
 
 bool RegExpObjectImp::implementsConstruct() const
index 560e238..e890d94 100644 (file)
@@ -74,7 +74,7 @@ namespace KJS {
     virtual bool implementsCall() const;
     virtual Value call(ExecState *exec, Object &thisObj, const List &args);
 
-    Value get(ExecState *exec, const Identifier &p) const;
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     int ** registerRegexp( const RegExp* re, const UString& s );
     void setSubPatterns(int num) { lastNrSubPatterns = num; }
     Object arrayOfMatches(ExecState *exec, const UString &result) const;
index 0b1aa05..f484051 100644 (file)
@@ -50,10 +50,12 @@ StringInstanceImp::StringInstanceImp(ObjectImp *proto, const UString &string)
   setInternalValue(String(string));
 }
 
-Value StringInstanceImp::get(ExecState *exec, const Identifier &propertyName) const
+bool StringInstanceImp::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
 {
-  if (propertyName == lengthPropertyName)
-    return Number(internalValue().toString(exec).size());
+  if (propertyName == lengthPropertyName) {
+    result = Value(internalValue().toString(exec).size());
+    return true;
+  }
 
   bool ok;
   const unsigned index = propertyName.toArrayIndex(&ok);
@@ -63,10 +65,11 @@ Value StringInstanceImp::get(ExecState *exec, const Identifier &propertyName) co
     if (index >= length)
       return Undefined();
     const UChar c = s[index];
-    return String(UString(&c, 1));
+    result = Value(UString(&c, 1));
+    return true;
   }
 
-  return ObjectImp::get(exec, propertyName);
+  return ObjectImp::getOwnProperty(exec, propertyName, result);
 }
 
 void StringInstanceImp::put(ExecState *exec, const Identifier &propertyName, const Value &value, int attr)
@@ -151,9 +154,9 @@ StringPrototypeImp::StringPrototypeImp(ExecState *exec,
 
 }
 
-Value StringPrototypeImp::get(ExecState *exec, const Identifier &propertyName) const
+bool StringPrototypeImp::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
 {
-  return lookupGetFunction<StringProtoFuncImp, StringInstanceImp>( exec, propertyName, &stringTable, this );
+  return lookupGetOwnFunction<StringProtoFuncImp, StringInstanceImp>(exec, propertyName, &stringTable, this, result);
 }
 
 // ------------------------------ StringProtoFuncImp ---------------------------
index 6f574a6..d2a4a9f 100644 (file)
@@ -32,7 +32,7 @@ namespace KJS {
     StringInstanceImp(ObjectImp *proto);
     StringInstanceImp(ObjectImp *proto, const UString &string);
 
-    virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     virtual void put(ExecState *exec, const Identifier &propertyName, const Value &value, int attr = None);
     virtual bool hasOwnProperty(ExecState *exec, const Identifier &propertyName) const;
     virtual bool deleteProperty(ExecState *exec, const Identifier &propertyName);
@@ -51,7 +51,7 @@ namespace KJS {
   public:
     StringPrototypeImp(ExecState *exec,
                        ObjectPrototypeImp *objProto);
-    Value get(ExecState *exec, const Identifier &p) const;
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     virtual const ClassInfo *classInfo() const { return &info; }
     static const ClassInfo info;
   };
index ba39f5a..2ce66bc 100644 (file)
@@ -1,3 +1,113 @@
+2005-07-24  Maciej Stachowiak  <mjs@apple.com>
+
+        Reviewed by Darin.
+
+       - http://bugzilla.opendarwin.org/show_bug.cgi?id=4124
+       (change JavaScript property access to avoid double lookup)
+
+       - 10% speedup on JavaScript iBench
+       - 5% speedup on 24fun BenchJS benchmark
+
+       Changed all get methods to getOwnProperty - they are no longer responsible for
+       prototype lookup, and determine if the property was found as a side efect.
+
+       Also miscellaneous code cleanup.
+       
+        * khtml/ecma/kjs_css.cpp:
+        (KJS::DOMCSSStyleDeclaration::getOwnProperty):
+        (KJS::DOMStyleSheet::getOwnProperty):
+        (KJS::DOMStyleSheetList::getOwnProperty):
+        (KJS::DOMMediaList::getOwnProperty):
+        (KJS::DOMCSSStyleSheet::getOwnProperty):
+        (KJS::DOMCSSRuleList::getOwnProperty):
+        (KJS::DOMCSSRule::getOwnProperty):
+        (KJS::DOMCSSRule::getValueProperty):
+        (KJS::CSSRuleConstructor::getOwnProperty):
+        (KJS::DOMCSSValue::getOwnProperty):
+        (KJS::CSSValueConstructor::getOwnProperty):
+        (KJS::DOMCSSPrimitiveValue::getOwnProperty):
+        (KJS::CSSPrimitiveValueConstructor::getOwnProperty):
+        (KJS::DOMCSSValueList::getOwnProperty):
+        (KJS::DOMRGBColor::getOwnProperty):
+        (KJS::DOMRect::getOwnProperty):
+        (KJS::DOMCounter::getOwnProperty):
+        * khtml/ecma/kjs_css.h:
+        * khtml/ecma/kjs_dom.cpp:
+        (KJS::DOMNode::getOwnProperty):
+        (KJS::DOMNodeList::getOwnProperty):
+        (KJS::DOMAttr::getOwnProperty):
+        (KJS::DOMDocument::getOwnProperty):
+        (KJS::DOMElement::getOwnProperty):
+        (KJS::DOMDocumentType::getOwnProperty):
+        (KJS::DOMNamedNodeMap::getOwnProperty):
+        (KJS::DOMProcessingInstruction::getOwnProperty):
+        (KJS::DOMNotation::getOwnProperty):
+        (KJS::DOMEntity::getOwnProperty):
+        (KJS::NodeConstructor::getOwnProperty):
+        (KJS::DOMExceptionConstructor::getOwnProperty):
+        (KJS::DOMNamedNodesCollection::getOwnProperty):
+        (KJS::DOMCharacterData::getOwnProperty):
+        * khtml/ecma/kjs_dom.h:
+        * khtml/ecma/kjs_events.cpp:
+        (KJS::EventConstructor::getOwnProperty):
+        (KJS::DOMEvent::getOwnProperty):
+        (KJS::EventExceptionConstructor::getOwnProperty):
+        (KJS::DOMUIEvent::getOwnProperty):
+        (KJS::DOMMouseEvent::getOwnProperty):
+        (KJS::DOMKeyboardEvent::getOwnProperty):
+        (KJS::MutationEventConstructor::getOwnProperty):
+        (KJS::DOMMutationEvent::getOwnProperty):
+        (KJS::DOMWheelEvent::getOwnProperty):
+        (KJS::Clipboard::getOwnProperty):
+        * khtml/ecma/kjs_events.h:
+        * khtml/ecma/kjs_html.cpp:
+        (KJS::HTMLDocument::getOwnProperty):
+        (KJS::KJS::HTMLElement::getOwnProperty):
+        (KJS::KJS::HTMLCollection::getOwnProperty):
+        (KJS::KJS::HTMLSelectCollection::getOwnProperty):
+        (KJS::Image::getOwnProperty):
+        (KJS::Context2D::getOwnProperty):
+        (KJS::Gradient::getOwnProperty):
+        (KJS::ImagePattern::getOwnProperty):
+        * khtml/ecma/kjs_html.h:
+        * khtml/ecma/kjs_navigator.cpp:
+        (KJS::Plugin::Plugin):
+        (KJS::Navigator::getOwnProperty):
+        (KJS::Plugins::getOwnProperty):
+        (KJS::MimeTypes::getOwnProperty):
+        (KJS::Plugin::getOwnProperty):
+        (KJS::MimeType::getOwnProperty):
+        * khtml/ecma/kjs_navigator.h:
+        * khtml/ecma/kjs_range.cpp:
+        (KJS::DOMRange::getOwnProperty):
+        (KJS::RangeConstructor::getOwnProperty):
+        * khtml/ecma/kjs_range.h:
+        * khtml/ecma/kjs_traversal.cpp:
+        (KJS::DOMNodeIterator::getOwnProperty):
+        (KJS::NodeFilterConstructor::getOwnProperty):
+        (KJS::DOMTreeWalker::getOwnProperty):
+        * khtml/ecma/kjs_traversal.h:
+        * khtml/ecma/kjs_views.cpp:
+        (KJS::DOMAbstractView::getOwnProperty):
+        * khtml/ecma/kjs_views.h:
+        * khtml/ecma/kjs_window.cpp:
+        (KJS::Screen::getOwnProperty):
+        (KJS::Window::~Window):
+        (KJS::Window::getOwnProperty):
+        (KJS::Window::put):
+        (KJS::FrameArray::getOwnProperty):
+        (KJS::Location::Location):
+        (KJS::Location::getOwnProperty):
+        (KJS::Location::put):
+        (KJS::Selection::Selection):
+        (KJS::Selection::getOwnProperty):
+        (KJS::BarInfo::getOwnProperty):
+        (KJS::History::getOwnProperty):
+        * khtml/ecma/kjs_window.h:
+        * khtml/ecma/xmlhttprequest.cpp:
+        (KJS::XMLHttpRequest::getOwnProperty):
+        * khtml/ecma/xmlhttprequest.h:
+
 2005-07-25  Justin Garcia  <justin.garcia@apple.com>
 
         Reviewed by hyatt
index 7e45444..0570948 100644 (file)
@@ -143,34 +143,42 @@ bool DOMCSSStyleDeclaration::hasOwnProperty(ExecState *exec, const Identifier &p
   return ObjectImp::hasOwnProperty(exec, p);
 }
 
-Value DOMCSSStyleDeclaration::get(ExecState *exec, const Identifier &propertyName) const
+bool DOMCSSStyleDeclaration::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
 {
 #ifdef KJS_VERBOSE
   kdDebug(6070) << "DOMCSSStyleDeclaration::get " << propertyName.qstring() << endl;
 #endif
   const HashEntry* entry = Lookup::findEntry(&DOMCSSStyleDeclarationTable, propertyName);
   CSSStyleDeclarationImpl &styleDecl = *m_impl;
-  if (entry)
+  if (entry) {
     switch (entry->value) {
     case CssText:
-      return getStringOrNull(styleDecl.cssText());
+      result = getStringOrNull(styleDecl.cssText());
+      return true;
     case Length:
-      return Number(styleDecl.length());
+      result = Value(styleDecl.length());
+      return true;
     case ParentRule:
-      return getDOMCSSRule(exec,styleDecl.parentRule());
+      result = getDOMCSSRule(exec,styleDecl.parentRule());
+      return true;
     default:
-      break;
+      assert(0);
     }
+  }
 
   // Look in the prototype (for functions) before assuming it's a name
+  // FIXME: is this really needed? do any property names conflict with names
+  // of functions from the prototype?
   Object proto = Object::dynamicCast(prototype());
   if (!proto.isNull() && proto.hasProperty(exec,propertyName))
-    return proto.get(exec,propertyName);
+    return false;
 
   bool ok;
   long unsigned int u = propertyName.toULong(&ok);
-  if (ok)
-    return getStringOrNull(styleDecl.item(u));
+  if (ok) {
+    result = getStringOrNull(styleDecl.item(u));
+    return true;
+  }
 
 #ifdef KJS_VERBOSE
   kdDebug(6070) << "DOMCSSStyleDeclaration: converting to css property name: " << cssPropertyName(propertyName) << endl;
@@ -187,13 +195,15 @@ Value DOMCSSStyleDeclaration::get(ExecState *exec, const Identifier &propertyNam
     CSSValueImpl *v = styleDecl.getPropertyCSSValue(prop);
     if (v) {
       if (pixelOrPos && v->cssValueType() == CSSValue::CSS_PRIMITIVE_VALUE)
-        return Number(static_cast<CSSPrimitiveValueImpl *>(v)->getFloatValue(CSSPrimitiveValue::CSS_PX));
-      return getStringOrNull(v->cssText());
-    }
-    return String("");
+        result = Number(static_cast<CSSPrimitiveValueImpl *>(v)->getFloatValue(CSSPrimitiveValue::CSS_PX));
+      else
+        result =  getStringOrNull(v->cssText());
+    } else
+      result = String("");
+    return true;
   }
 
-  return DOMObject::get(exec, propertyName);
+  return DOMObject::getOwnProperty(exec, propertyName, result);
 }
 
 
@@ -290,9 +300,9 @@ DOMStyleSheet::~DOMStyleSheet()
   ScriptInterpreter::forgetDOMObject(m_impl.get());
 }
 
-Value DOMStyleSheet::get(ExecState *exec, const Identifier &propertyName) const
+bool DOMStyleSheet::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
 {
-  return lookupGetValue<DOMStyleSheet,DOMObject>(exec,propertyName,&DOMStyleSheetTable,this);
+  return lookupGetOwnValue<DOMStyleSheet, DOMObject>(exec, propertyName, &DOMStyleSheetTable, this, result);
 }
 
 Value DOMStyleSheet::getValueProperty(ExecState *exec, int token) const
@@ -361,22 +371,27 @@ DOMStyleSheetList::~DOMStyleSheetList()
   ScriptInterpreter::forgetDOMObject(m_impl.get());
 }
 
-Value DOMStyleSheetList::get(ExecState *exec, const Identifier &p) const
+bool DOMStyleSheetList::getOwnProperty(ExecState *exec, const Identifier& p, Value& result) const
 {
 #ifdef KJS_VERBOSE
   kdDebug(6070) << "DOMStyleSheetList::get " << p.qstring() << endl;
 #endif
   StyleSheetListImpl &styleSheetList = *m_impl;
-  if (p == lengthPropertyName)
-    return Number(styleSheetList.length());
-  else if (p == "item")
-    return lookupOrCreateFunction<DOMStyleSheetListFunc>(exec,p,this,DOMStyleSheetList::Item,1,DontDelete|Function);
+  if (p == lengthPropertyName) {
+    result = Number(styleSheetList.length());
+    return true;
+  } else if (p == "item") {
+    result = lookupOrCreateFunction<DOMStyleSheetListFunc>(exec, p, this, DOMStyleSheetList::Item, 1, DontDelete|Function);
+    return true;
+  }
 
   // Retrieve stylesheet by index
   bool ok;
   long unsigned int u = p.toULong(&ok);
-  if (ok)
-    return getDOMStyleSheet(exec, styleSheetList.item(u));
+  if (ok) {
+    result = getDOMStyleSheet(exec, styleSheetList.item(u));
+    return true;
+  }
 
   // IE also supports retrieving a stylesheet by name, using the name/id of the <style> tag
   // (this is consistent with all the other collections)
@@ -405,10 +420,12 @@ Value DOMStyleSheetList::get(ExecState *exec, const Identifier &p) const
   // and doesn't look for name attribute (see implementation above).
   // But unicity of stylesheet ids is good practice anyway ;)
   ElementImpl *element = m_doc->getElementById(p.string());
-  if (element && element->hasTagName(HTMLTags::style()))
-    return getDOMStyleSheet(exec, static_cast<HTMLStyleElementImpl *>(element)->sheet());
+  if (element && element->hasTagName(HTMLTags::style())) {
+    result = getDOMStyleSheet(exec, static_cast<HTMLStyleElementImpl *>(element)->sheet());
+    return true;
+  }
 
-  return DOMObject::get(exec, p);
+  return DOMObject::getOwnProperty(exec, p, result);
 }
 
 ValueImp *getDOMStyleSheetList(ExecState *exec, StyleSheetListImpl *ssl, DocumentImpl *doc)
@@ -470,20 +487,25 @@ DOMMediaList::~DOMMediaList()
   ScriptInterpreter::forgetDOMObject(m_impl.get());
 }
 
-Value DOMMediaList::get(ExecState *exec, const Identifier &p) const
+bool DOMMediaList::getOwnProperty(ExecState *exec, const Identifier& p, Value& result) const
 {
   MediaListImpl &mediaList = *m_impl;
-  if (p == "mediaText")
-    return getStringOrNull(mediaList.mediaText());
-  else if (p == lengthPropertyName)
-    return Number(mediaList.length());
+  if (p == "mediaText") {
+    result = getStringOrNull(mediaList.mediaText());
+    return true;
+  } else if (p == lengthPropertyName) {
+    result = Number(mediaList.length());
+    return true;
+  }
 
   bool ok;
   long unsigned int u = p.toULong(&ok);
-  if (ok)
-    return getStringOrNull(mediaList.item(u));
+  if (ok) {
+    result = getStringOrNull(mediaList.item(u));
+    return true;
+  }
 
-  return DOMObject::get(exec, p);
+  return DOMObject::getOwnProperty(exec, p, result);
 }
 
 void DOMMediaList::put(ExecState *exec, const Identifier &propertyName, const Value& value, int attr)
@@ -554,14 +576,17 @@ DOMCSSStyleSheet::~DOMCSSStyleSheet()
 {
 }
 
-Value DOMCSSStyleSheet::get(ExecState *exec, const Identifier &p) const
+bool DOMCSSStyleSheet::getOwnProperty(ExecState *exec, const Identifier& p, Value& result) const
 {
   CSSStyleSheetImpl &cssStyleSheet = *static_cast<CSSStyleSheetImpl *>(impl());
-  if (p == "ownerRule")
-    return getDOMCSSRule(exec,cssStyleSheet.ownerRule());
-  else if (p == "cssRules" || p == "rules" /* MSIE extension */)
-    return getDOMCSSRuleList(exec,cssStyleSheet.cssRules());
-  return DOMStyleSheet::get(exec,p);
+  if (p == "ownerRule") {
+    result = getDOMCSSRule(exec,cssStyleSheet.ownerRule());
+    return true;
+  } else if (p == "cssRules" || p == "rules" /* MSIE extension */) {
+    result =  getDOMCSSRuleList(exec,cssStyleSheet.cssRules());
+    return true;
+  }
+  return DOMStyleSheet::getOwnProperty(exec, p, result);
 }
 
 Value DOMCSSStyleSheetProtoFunc::call(ExecState *exec, Object &thisObj, const List &args)
@@ -607,20 +632,25 @@ DOMCSSRuleList::~DOMCSSRuleList()
   ScriptInterpreter::forgetDOMObject(m_impl.get());
 }
 
-Value DOMCSSRuleList::get(ExecState *exec, const Identifier &p) const
+bool DOMCSSRuleList::getOwnProperty(ExecState *exec, const Identifier& p, Value& result) const
 {
   CSSRuleListImpl &cssRuleList = *m_impl;
-  if (p == lengthPropertyName)
-    return Number(cssRuleList.length());
-  else if (p == "item")
-    return lookupOrCreateFunction<DOMCSSRuleListFunc>(exec, p, this, DOMCSSRuleList::Item, 1, DontDelete|Function);
+  if (p == lengthPropertyName) {
+    result = Number(cssRuleList.length());
+    return true;
+  } else if (p == "item") {
+    result = lookupOrCreateFunction<DOMCSSRuleListFunc>(exec, p, this, DOMCSSRuleList::Item, 1, DontDelete|Function);
+    return true;
+  }
 
   bool ok;
   long unsigned int u = p.toULong(&ok);
-  if (ok)
-    return getDOMCSSRule(exec, cssRuleList.item(u));
+  if (ok) {
+    result = getDOMCSSRule(exec, cssRuleList.item(u));
+    return true;
+  }
 
-  return DOMObject::get(exec, p);
+  return DOMObject::getOwnProperty(exec, p, result);
 }
 
 Value DOMCSSRuleListFunc::call(ExecState *exec, Object &thisObj, const List &args)
@@ -715,20 +745,17 @@ const ClassInfo* DOMCSSRule::classInfo() const
   encoding             DOMCSSRule::Charset_Encoding    DontDelete
 @end
 */
-Value DOMCSSRule::get(ExecState *exec, const Identifier &propertyName) const
+bool DOMCSSRule::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
 {
-#ifdef KJS_VERBOSE
-  kdDebug(6070) << "DOMCSSRule::get " << propertyName.qstring() << endl;
-#endif
-  const HashEntry *entry = Lookup::findEntry(classInfo()->propHashTable, propertyName);
+  // first try the properties specific to this rule type
+  const HashEntry* entry = Lookup::findEntry(classInfo()->propHashTable, propertyName);
   if (entry) {
-    if (entry->attr & Function)
-      return lookupOrCreateFunction<DOMCSSRuleFunc>(exec, propertyName, this, entry->value, entry->params, entry->attr);
-    return getValueProperty(exec, entry->value);
+    result = getValueProperty(exec, entry->value);
+    return true;
   }
-
-  // Base CSSRule stuff or parent class forward, as usual
-  return lookupGet<DOMCSSRuleFunc, DOMCSSRule, DOMObject>(exec, propertyName, &DOMCSSRuleTable, this);
+  
+  // now the stuff that applies to all rules
+  return lookupGetOwnProperty<DOMCSSRuleFunc, DOMCSSRule, DOMObject>(exec, propertyName, &DOMCSSRuleTable, this, result);
 }
 
 Value DOMCSSRule::getValueProperty(ExecState *exec, int token) const
@@ -779,7 +806,7 @@ Value DOMCSSRule::getValueProperty(ExecState *exec, int token) const
     return getStringOrNull(static_cast<CSSCharsetRuleImpl *>(m_impl.get())->encoding());
 
   default:
-    kdWarning() << "DOMCSSRule::getValueProperty unhandled token " << token << endl;
+    assert(0);
   }
   return Undefined();
 }
@@ -866,9 +893,9 @@ const ClassInfo CSSRuleConstructor::info = { "CSSRuleConstructor", 0, &CSSRuleCo
 @end
 */
 
-Value CSSRuleConstructor::get(ExecState *exec, const Identifier &p) const
+bool CSSRuleConstructor::getOwnProperty(ExecState *exec, const Identifier& p, Value& result) const
 {
-  return lookupGetValue<CSSRuleConstructor,DOMObject>(exec,p,&CSSRuleConstructorTable,this);
+  return lookupGetOwnValue<CSSRuleConstructor, DOMObject>(exec, p, &CSSRuleConstructorTable, this, result);
 }
 
 Value CSSRuleConstructor::getValueProperty(ExecState *, int token) const
@@ -912,14 +939,18 @@ DOMCSSValue::~DOMCSSValue()
   ScriptInterpreter::forgetDOMObject(m_impl.get());
 }
 
-Value DOMCSSValue::get(ExecState *exec, const Identifier &p) const
+bool DOMCSSValue::getOwnProperty(ExecState *exec, const Identifier& p, Value& result) const
 {
   CSSValueImpl &cssValue = *m_impl;
-  if (p == "cssText")
-    return getStringOrNull(cssValue.cssText());
-  else if (p == "cssValueType");
-    return Number(cssValue.cssValueType());
-  return DOMObject::get(exec,p);
+  if (p == "cssText") {
+    result = getStringOrNull(cssValue.cssText());
+    return true;
+  } else if (p == "cssValueType"); {
+    result = Number(cssValue.cssValueType());
+    return true;
+  }
+
+  return DOMObject::getOwnProperty(exec, p, result);
 }
 
 void DOMCSSValue::put(ExecState *exec, const Identifier &propertyName, const Value& value, int attr)
@@ -962,9 +993,9 @@ const ClassInfo CSSValueConstructor::info = { "CSSValueConstructor", 0, &CSSValu
   CSS_CUSTOM           CSSValueConstructor::CSS_CUSTOM                 DontDelete|ReadOnly
 @end
 */
-Value CSSValueConstructor::get(ExecState *exec, const Identifier &p) const
+bool CSSValueConstructor::getOwnProperty(ExecState *exec, const Identifier& p, Value& result) const
 {
-  return lookupGetValue<CSSValueConstructor,DOMObject>(exec,p,&CSSValueConstructorTable,this);
+  return lookupGetOwnValue<CSSValueConstructor, DOMObject>(exec, p, &CSSValueConstructorTable, this, result);
 }
 
 Value CSSValueConstructor::getValueProperty(ExecState *, int token) const
@@ -1014,11 +1045,14 @@ DOMCSSPrimitiveValue::DOMCSSPrimitiveValue(ExecState *exec, CSSPrimitiveValueImp
   setPrototype(DOMCSSPrimitiveValueProto::self(exec));
 }
 
-Value DOMCSSPrimitiveValue::get(ExecState *exec, const Identifier &p) const
+bool DOMCSSPrimitiveValue::getOwnProperty(ExecState *exec, const Identifier& p, Value& result) const
 {
-  if (p == "primitiveType")
-    return Number(static_cast<CSSPrimitiveValueImpl *>(impl())->primitiveType());
-  return DOMObject::get(exec,p);
+  if (p == "primitiveType") {
+    result = Number(static_cast<CSSPrimitiveValueImpl *>(impl())->primitiveType());
+    return result;
+  }
+
+  return DOMObject::getOwnProperty(exec, p, result);
 }
 
 Value DOMCSSPrimitiveValueProtoFunc::call(ExecState *exec, Object &thisObj, const List &args)
@@ -1087,9 +1121,9 @@ const ClassInfo CSSPrimitiveValueConstructor::info = { "CSSPrimitiveValueConstru
 @end
 */
 
-Value CSSPrimitiveValueConstructor::get(ExecState *exec, const Identifier &p) const
+bool CSSPrimitiveValueConstructor::getOwnProperty(ExecState *exec, const Identifier& p, Value& result) const
 {
-  return lookupGetValue<CSSPrimitiveValueConstructor,CSSValueConstructor>(exec,p,&CSSPrimitiveValueConstructorTable,this);
+  return lookupGetOwnValue<CSSPrimitiveValueConstructor, CSSValueConstructor>(exec, p, &CSSPrimitiveValueConstructorTable, this, result);
 }
 
 Value CSSPrimitiveValueConstructor::getValueProperty(ExecState *, int token) const
@@ -1120,21 +1154,26 @@ DOMCSSValueList::DOMCSSValueList(ExecState *exec, CSSValueListImpl *v)
 { 
 }
 
-Value DOMCSSValueList::get(ExecState *exec, const Identifier &p) const
+bool DOMCSSValueList::getOwnProperty(ExecState *exec, const Identifier& p, Value& result) const
 {
   CSSValueListImpl &valueList = *static_cast<CSSValueListImpl *>(impl());
 
-  if (p == lengthPropertyName)
-    return Number(valueList.length());
-  else if (p == "item")
-    return lookupOrCreateFunction<DOMCSSValueListFunc>(exec,p,this,DOMCSSValueList::Item,1,DontDelete|Function);
+  if (p == lengthPropertyName) {
+    result = Number(valueList.length());
+    return true;
+  } else if (p == "item") {
+    result = lookupOrCreateFunction<DOMCSSValueListFunc>(exec,p,this,DOMCSSValueList::Item,1,DontDelete|Function);
+    return true;
+  }
 
   bool ok;
   long unsigned int u = p.toULong(&ok);
-  if (ok)
-    return getDOMCSSValue(exec,valueList.item(u));
+  if (ok) {
+    result = getDOMCSSValue(exec,valueList.item(u));
+    return true;
+  }
 
-  return DOMCSSValue::get(exec,p);
+  return DOMCSSValue::getOwnProperty(exec, p, result);
 }
 
 Value DOMCSSValueListFunc::call(ExecState *exec, Object &thisObj, const List &args)
@@ -1169,11 +1208,9 @@ DOMRGBColor::~DOMRGBColor()
   //rgbColors.remove(rgbColor.handle());
 }
 
-Value DOMRGBColor::get(ExecState *exec, const Identifier &p) const
+bool DOMRGBColor::getOwnProperty(ExecState *exec, const Identifier& p, Value& result) const
 {
-  return lookupGetValue<DOMRGBColor,DOMObject>(exec, p,
-                                                      &DOMRGBColorTable,
-                                                      this);
+  return lookupGetOwnValue<DOMRGBColor, DOMObject>(exec, p, &DOMRGBColorTable, this, result);
 }
 
 Value DOMRGBColor::getValueProperty(ExecState *exec, int token) const
@@ -1215,10 +1252,9 @@ DOMRect::~DOMRect()
   ScriptInterpreter::forgetDOMObject(m_rect.get());
 }
 
-Value DOMRect::get(ExecState *exec, const Identifier &p) const
+bool DOMRect::getOwnProperty(ExecState *exec, const Identifier& p, Value& result) const
 {
-  return lookupGetValue<DOMRect,DOMObject>(exec, p,
-                                                   &DOMRectTable, this);
+  return lookupGetOwnValue<DOMRect, DOMObject>(exec, p, &DOMRectTable, this, result);
 }
 
 Value DOMRect::getValueProperty(ExecState *exec, int token) const
@@ -1259,10 +1295,9 @@ DOMCounter::~DOMCounter()
   ScriptInterpreter::forgetDOMObject(m_counter.get());
 }
 
-Value DOMCounter::get(ExecState *exec, const Identifier &p) const
+bool DOMCounter::getOwnProperty(ExecState *exec, const Identifier& p, Value& result) const
 {
-  return lookupGetValue<DOMCounter,DOMObject>(exec, p,
-                                                      &DOMCounterTable, this);
+  return lookupGetOwnValue<DOMCounter, DOMObject>(exec, p, &DOMCounterTable, this, result);
 }
 
 Value DOMCounter::getValueProperty(ExecState *, int token) const
index 1fe8a83..6b1b0c3 100644 (file)
@@ -49,7 +49,7 @@ namespace KJS {
   public:
     DOMCSSStyleDeclaration(ExecState *exec, DOM::CSSStyleDeclarationImpl *s);
     virtual ~DOMCSSStyleDeclaration();
-    virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     virtual void put(ExecState *exec, const Identifier &propertyName, const Value& value, int attr = None);
     virtual bool hasOwnProperty(ExecState *exec, const Identifier &propertyName) const;
     virtual const ClassInfo *classInfo() const { return &info; }
@@ -68,7 +68,7 @@ namespace KJS {
   public:
     DOMStyleSheet(ExecState *, DOM::StyleSheetImpl *ss) : m_impl(ss) { }
     virtual ~DOMStyleSheet();
-    virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     Value getValueProperty(ExecState *exec, int token) const;
     virtual void put(ExecState *exec, const Identifier &propertyName, const Value& value, int attr = None);
     virtual bool toBoolean(ExecState *) const { return true; }
@@ -90,7 +90,7 @@ namespace KJS {
     DOMStyleSheetList(ExecState *, DOM::StyleSheetListImpl *ssl, DOM::DocumentImpl *doc)
       : m_impl(ssl), m_doc(doc) { }
     virtual ~DOMStyleSheetList();
-    virtual Value get(ExecState *exec,const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec,const Identifier& propertyName, Value& result) const;
     // no put - all read-only
     virtual const ClassInfo* classInfo() const { return &info; }
     virtual bool toBoolean(ExecState* ) const { return true; }
@@ -109,7 +109,7 @@ namespace KJS {
   public:
     DOMMediaList(ExecState *, DOM::MediaListImpl *ml);
     virtual ~DOMMediaList();
-    virtual Value get(ExecState *exec,const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec,const Identifier& propertyName, Value& result) const;
     virtual void put(ExecState *exec, const Identifier &propertyName, const Value& value, int attr = None);
     virtual const ClassInfo* classInfo() const { return &info; }
     virtual bool toBoolean(ExecState* ) const { return true; }
@@ -127,7 +127,7 @@ namespace KJS {
   public:
     DOMCSSStyleSheet(ExecState *exec, DOM::CSSStyleSheetImpl *ss);
     virtual ~DOMCSSStyleSheet();
-    virtual Value get(ExecState *exec,const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec,const Identifier& propertyName, Value& result) const;
     // no put - all read-only
     virtual const ClassInfo* classInfo() const { return &info; }
     static const ClassInfo info;
@@ -139,7 +139,7 @@ namespace KJS {
   public:
     DOMCSSRuleList(ExecState *, DOM::CSSRuleListImpl *rl) : m_impl(rl) { }
     virtual ~DOMCSSRuleList();
-    virtual Value get(ExecState *exec,const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec,const Identifier& propertyName, Value& result) const;
     // no put - all read-only
     virtual const ClassInfo* classInfo() const { return &info; }
     static const ClassInfo info;
@@ -155,7 +155,7 @@ namespace KJS {
   public:
     DOMCSSRule(ExecState *, DOM::CSSRuleImpl *r) : m_impl(r) { }
     virtual ~DOMCSSRule();
-    virtual Value get(ExecState *exec,const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec,const Identifier& propertyName, Value& result) const;
     Value getValueProperty(ExecState *exec, int token) const;
     virtual void put(ExecState *exec, const Identifier &propertyName, const Value& value, int attr = None);
     void putValueProperty(ExecState *exec, int token, const Value& value, int attr);
@@ -178,7 +178,7 @@ namespace KJS {
   class CSSRuleConstructor : public DOMObject {
   public:
     CSSRuleConstructor(ExecState *) { }
-    virtual Value get(ExecState *exec,const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec,const Identifier& propertyName, Value& result) const;
     Value getValueProperty(ExecState *exec, int token) const;
     // no put - all read-only
     virtual const ClassInfo* classInfo() const { return &info; }
@@ -192,7 +192,7 @@ namespace KJS {
   public:
     DOMCSSValue(ExecState *, DOM::CSSValueImpl *v) : m_impl(v) { }
     virtual ~DOMCSSValue();
-    virtual Value get(ExecState *exec,const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec,const Identifier& propertyName, Value& result) const;
     virtual void put(ExecState *exec, const Identifier &propertyName, const Value& value, int attr = None);
     virtual const ClassInfo* classInfo() const { return &info; }
     static const ClassInfo info;
@@ -211,7 +211,7 @@ namespace KJS {
   class CSSValueConstructor : public DOMObject {
   public:
     CSSValueConstructor(ExecState *) { }
-    virtual Value get(ExecState *exec,const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec,const Identifier& propertyName, Value& result) const;
     Value getValueProperty(ExecState *exec, int token) const;
     // no put - all read-only
     virtual const ClassInfo* classInfo() const { return &info; }
@@ -224,7 +224,7 @@ namespace KJS {
   class DOMCSSPrimitiveValue : public DOMCSSValue {
   public:
     DOMCSSPrimitiveValue(ExecState *exec, DOM::CSSPrimitiveValueImpl *v);
-    virtual Value get(ExecState *exec,const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec,const Identifier& propertyName, Value& result) const;
     // no put - all read-only
     virtual const ClassInfo* classInfo() const { return &info; }
     static const ClassInfo info;
@@ -236,7 +236,7 @@ namespace KJS {
   class CSSPrimitiveValueConstructor : public CSSValueConstructor {
   public:
     CSSPrimitiveValueConstructor(ExecState *exec) : CSSValueConstructor(exec) { }
-    virtual Value get(ExecState *exec,const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec,const Identifier& propertyName, Value& result) const;
     Value getValueProperty(ExecState *exec, int token) const;
     // no put - all read-only
     virtual const ClassInfo* classInfo() const { return &info; }
@@ -248,7 +248,7 @@ namespace KJS {
   class DOMCSSValueList : public DOMCSSValue {
   public:
     DOMCSSValueList(ExecState *exec, DOM::CSSValueListImpl *l);
-    virtual Value get(ExecState *exec,const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec,const Identifier& propertyName, Value& result) const;
     // no put - all read-only
     virtual const ClassInfo* classInfo() const { return &info; }
     static const ClassInfo info;
@@ -259,7 +259,7 @@ namespace KJS {
   public:
     DOMRGBColor(unsigned color) : m_color(color) { }
     ~DOMRGBColor();
-    virtual Value get(ExecState *exec,const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec,const Identifier& propertyName, Value& result) const;
     Value getValueProperty(ExecState *exec, int token) const;
     // no put - all read-only
     virtual const ClassInfo* classInfo() const { return &info; }
@@ -275,7 +275,7 @@ namespace KJS {
   public:
     DOMRect(ExecState *, DOM::RectImpl *r) : m_rect(r) { }
     ~DOMRect();
-    virtual Value get(ExecState *exec,const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec,const Identifier& propertyName, Value& result) const;
     Value getValueProperty(ExecState *exec, int token) const;
     // no put - all read-only
     virtual const ClassInfo* classInfo() const { return &info; }
@@ -291,7 +291,7 @@ namespace KJS {
   public:
     DOMCounter(ExecState *, DOM::CounterImpl *c) : m_counter(c) { }
     ~DOMCounter();
-    virtual Value get(ExecState *exec,const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec,const Identifier& propertyName, Value& result) const;
     Value getValueProperty(ExecState *exec, int token) const;
     // no put - all read-only
     virtual const ClassInfo* classInfo() const { return &info; }
index 9315140..eb40a10 100644 (file)
@@ -271,12 +271,9 @@ bool DOMNode::toBoolean(ExecState *) const
   scrollHeight  DOMNode::ScrollHeight           DontDelete|ReadOnly
 @end
 */
-Value DOMNode::get(ExecState *exec, const Identifier &propertyName) const
+bool DOMNode::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
 {
-#ifdef KJS_VERBOSE
-  kdDebug(6070) << "DOMNode::get " << propertyName.qstring() << endl;
-#endif
-  return lookupGetValue<DOMNode, DOMObject>(exec, propertyName, &DOMNodeTable, this);
+  return lookupGetOwnValue<DOMNode, DOMObject>(exec, propertyName, &DOMNodeTable, this, result);
 }
 
 Value DOMNode::getValueProperty(ExecState *exec, int token) const
@@ -733,39 +730,35 @@ bool DOMNodeList::hasOwnProperty(ExecState *exec, const Identifier &p) const
   return ObjectImp::hasOwnProperty(exec, p);
 }
 
-Value DOMNodeList::get(ExecState *exec, const Identifier &p) const
+bool DOMNodeList::getOwnProperty(ExecState *exec, const Identifier &p, Value& result) const
 {
-#ifdef KJS_VERBOSE
-  kdDebug(6070) << "DOMNodeList::get " << p.ascii() << endl;
-#endif
-  Value result;
-
   NodeListImpl &list = *m_impl;
-  if (p == lengthPropertyName)
+  if (p == lengthPropertyName) {
     result = Number(list.length());
-  else if (p == "item") {
+    return true;
+  } else if (p == "item") {
     // No need for a complete hashtable for a single func, but we still want
     // to use the caching feature of lookupOrCreateFunction.
     result = lookupOrCreateFunction<DOMNodeListFunc>(exec, p, this, DOMNodeListFunc::Item, 1, DontDelete|Function);
-  }
-  else {
+    return true;
+  else {
     // array index ?
     bool ok;
     long unsigned int idx = p.toULong(&ok);
     if (ok) {
       result = getDOMNode(exec,list.item(idx));
+      return true;
     } else {
       NodeImpl *node = list.itemById(p.string());
 
       if (node) {
         result = getDOMNode(exec, node);
-      } else {
-        result = ObjectImp::get(exec, p);
-      }
+        return true;
+      } 
     }
   }
 
-  return result;
+  return DOMNodeList::getOwnProperty(exec, p, result);
 }
 
 // Need to support both get and call, so that list[0] and list(0) work.
@@ -823,13 +816,9 @@ DOMAttr::DOMAttr(ExecState *exec, AttrImpl *a)
 {
 }
 
-Value DOMAttr::get(ExecState *exec, const Identifier &propertyName) const
+bool DOMAttr::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
 {
-#ifdef KJS_VERBOSE
-  kdDebug(6070) << "DOMAttr::put " << propertyName.qstring() << endl;
-#endif
-  return lookupGetValue<DOMAttr,DOMNode>(exec, propertyName,
-                                                  &DOMAttrTable, this );
+  return lookupGetOwnValue<DOMAttr, DOMNode>(exec, propertyName, &DOMAttrTable, this, result);
 }
 
 Value DOMAttr::getValueProperty(ExecState *exec, int token) const
@@ -943,13 +932,9 @@ DOMDocument::~DOMDocument()
   ScriptInterpreter::forgetDOMObject(static_cast<DocumentImpl *>(m_impl.get()));
 }
 
-Value DOMDocument::get(ExecState *exec, const Identifier &propertyName) const
+bool DOMDocument::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
 {
-#ifdef KJS_VERBOSE
-  kdDebug(6070) << "DOMDocument::get " << propertyName.qstring() << endl;
-#endif
-  return lookupGetValue<DOMDocument, DOMNode>(
-    exec, propertyName, &DOMDocumentTable, this);
+  return lookupGetOwnValue<DOMDocument, DOMNode>(exec, propertyName, &DOMDocumentTable, this, result);
 }
 
 Value DOMDocument::getValueProperty(ExecState *exec, int token) const
@@ -1161,39 +1146,42 @@ DOMElement::DOMElement(ElementImpl *e)
 { 
 }
 
-Value DOMElement::get(ExecState *exec, const Identifier &propertyName) const
+bool DOMElement::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
 {
-#ifdef KJS_VERBOSE
-  kdDebug(6070) << "DOMElement::get " << propertyName.qstring() << endl;
-#endif
   ElementImpl &element = *static_cast<ElementImpl *>(impl());
 
   const HashEntry* entry = Lookup::findEntry(&DOMElementTable, propertyName);
   if (entry)
   {
-    switch( entry->value ) {
+    switch (entry->value) {
     case TagName:
-      return getStringOrNull(element.nodeName());
+      result = getStringOrNull(element.nodeName());
+      break;
     case Style:
-      return getDOMCSSStyleDeclaration(exec,element.style());
-    default:
-      kdWarning() << "Unhandled token in DOMElement::get : " << entry->value << endl;
+      result = getDOMCSSStyleDeclaration(exec,element.style());
       break;
+    default:
+      assert(0);
     }
+    return true;
   }
   // We have to check in DOMNode before giving access to attributes, otherwise
   // onload="..." would make onload return the string (attribute value) instead of
   // the listener object (function).
   ValueImp *proto = prototype().imp();
-  if (DOMNode::hasOwnProperty(exec, propertyName) || (proto->dispatchType() == ObjectType && static_cast<ObjectImp *>(proto)->hasProperty(exec, propertyName)))
-    return DOMNode::get(exec, propertyName);
+  if (DOMNode::hasOwnProperty(exec, propertyName))
+    return DOMNode::getOwnProperty(exec, propertyName, result);
+  if (proto->dispatchType() == ObjectType && static_cast<ObjectImp *>(proto)->hasProperty(exec, propertyName))
+    return false;
 
-  DOM::DOMString attr = element.getAttribute( propertyName.string() );
+  DOM::DOMString attr = element.getAttribute(propertyName.string());
   // Give access to attributes
-  if ( !attr.isNull() )
-    return getStringOrNull( attr );
+  if (!attr.isNull()) {
+    result = getStringOrNull(attr);
+    return true;
+  }
 
-  return Undefined();
+  return false;
 }
 
 Value DOMElementProtoFunc::call(ExecState *exec, Object &thisObj, const List &args)
@@ -1353,9 +1341,9 @@ const ClassInfo DOMDocumentType::info = { "DocumentType", &DOMNode::info, &DOMDo
 DOMDocumentType::DOMDocumentType(ExecState *exec, DocumentTypeImpl *dt)
   : DOMNode( /*### no proto yet*/exec, dt ) { }
 
-Value DOMDocumentType::get(ExecState *exec, const Identifier &propertyName) const
+bool DOMDocumentType::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
 {
-  return lookupGetValue<DOMDocumentType, DOMNode>(exec, propertyName, &DOMDocumentTypeTable, this);
+  return lookupGetOwnValue<DOMDocumentType, DOMNode>(exec, propertyName, &DOMDocumentTypeTable, this, result);
 }
 
 Value DOMDocumentType::getValueProperty(ExecState *exec, int token) const
@@ -1427,20 +1415,24 @@ bool DOMNamedNodeMap::hasOwnProperty(ExecState *exec, const Identifier &p) const
   return DOMObject::hasOwnProperty(exec, p);
 }
 
-Value DOMNamedNodeMap::get(ExecState* exec, const Identifier &p) const
+bool DOMNamedNodeMap::getOwnProperty(ExecState* exec, const Identifier& p, Value& result) const
 {
   NamedNodeMapImpl &map = *m_impl;
-  if (p == lengthPropertyName)
-    return Number(map.length());
+  if (p == lengthPropertyName) {
+    result = Number(map.length());
+    return true;
+  }
 
   // array index ?
   bool ok;
   long unsigned int idx = p.toULong(&ok);
-  if (ok)
-    return getDOMNode(exec,map.item(idx));
+  if (ok) {
+    result = getDOMNode(exec,map.item(idx));
+    return true;
+  }
 
   // Anything else (including functions, defined in the prototype)
-  return DOMObject::get(exec, p);
+  return DOMObject::getOwnProperty(exec, p, result);
 }
 
 Value DOMNamedNodeMapProtoFunc::call(ExecState *exec, Object &thisObj, const List &args)
@@ -1492,9 +1484,9 @@ DOMProcessingInstruction::DOMProcessingInstruction(ExecState *exec, ProcessingIn
 {
 }
 
-Value DOMProcessingInstruction::get(ExecState *exec, const Identifier &propertyName) const
+bool DOMProcessingInstruction::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
 {
-  return lookupGetValue<DOMProcessingInstruction, DOMNode>(exec, propertyName, &DOMProcessingInstructionTable, this);
+  return lookupGetOwnValue<DOMProcessingInstruction, DOMNode>(exec, propertyName, &DOMProcessingInstructionTable, this, result);
 }
 
 Value DOMProcessingInstruction::getValueProperty(ExecState *exec, int token) const
@@ -1540,9 +1532,9 @@ DOMNotation::DOMNotation(ExecState *exec, NotationImpl *n)
 {
 }
 
-Value DOMNotation::get(ExecState *exec, const Identifier &propertyName) const
+bool DOMNotation::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
 {
-  return lookupGetValue<DOMNotation, DOMNode>(exec, propertyName, &DOMNotationTable, this);
+  return lookupGetOwnValue<DOMNotation, DOMNode>(exec, propertyName, &DOMNotationTable, this, result);
 }
 
 Value DOMNotation::getValueProperty(ExecState *, int token) const
@@ -1575,9 +1567,9 @@ DOMEntity::DOMEntity(ExecState *exec, EntityImpl *e)
 {
 }
 
-Value DOMEntity::get(ExecState *exec, const Identifier &propertyName) const
+bool DOMEntity::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
 {
-  return lookupGetValue<DOMEntity, DOMNode>(exec, propertyName, &DOMEntityTable, this);
+  return lookupGetOwnValue<DOMEntity, DOMNode>(exec, propertyName, &DOMEntityTable, this, result);
 }
 
 Value DOMEntity::getValueProperty(ExecState *, int token) const
@@ -1749,9 +1741,9 @@ const ClassInfo NodeConstructor::info = { "NodeConstructor", 0, &NodeConstructor
   NOTATION_NODE                DOM::Node::NOTATION_NODE                DontDelete|ReadOnly
 @end
 */
-Value NodeConstructor::get(ExecState *exec, const Identifier &propertyName) const
+bool NodeConstructor::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
 {
-  return lookupGetValue<NodeConstructor, DOMObject>(exec, propertyName, &NodeConstructorTable, this);
+  return lookupGetOwnValue<NodeConstructor, DOMObject>(exec, propertyName, &NodeConstructorTable, this, result);
 }
 
 Value NodeConstructor::getValueProperty(ExecState *, int token) const
@@ -1820,9 +1812,9 @@ const ClassInfo DOMExceptionConstructor::info = { "DOMExceptionConstructor", 0,
 @end
 */
 
-Value DOMExceptionConstructor::get(ExecState *exec, const Identifier &propertyName) const
+bool DOMExceptionConstructor::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
 {
-  return lookupGetValue<DOMExceptionConstructor, DOMObject>(exec, propertyName, &DOMExceptionConstructorTable, this);
+  return lookupGetOwnValue<DOMExceptionConstructor, DOMObject>(exec, propertyName, &DOMExceptionConstructorTable, this, result);
 }
 
 Value DOMExceptionConstructor::getValueProperty(ExecState *, int token) const
@@ -1883,15 +1875,18 @@ DOMNamedNodesCollection::DOMNamedNodesCollection(ExecState *, const QValueList<
 {
 }
 
-Value DOMNamedNodesCollection::get(ExecState *exec, const Identifier &propertyName) const
+bool DOMNamedNodesCollection::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
 {
-  if (propertyName == lengthPropertyName)
-    return Number(m_nodes.count());
+  if (propertyName == lengthPropertyName) {
+    result = Number(m_nodes.count());
+    return true;
+  }
   // index?
   bool ok;
   unsigned int u = propertyName.toULong(&ok);
   if (ok && u < m_nodes.count()) {
-    return getDOMNode(exec, m_nodes[u].get());
+    result = getDOMNode(exec, m_nodes[u].get());
+    return true;
   }
   // For IE compatibility, we need to be able to look up elements in a
   // document.formName.name result by id as well as be index.
@@ -1911,12 +1906,13 @@ Value DOMNamedNodesCollection::get(ExecState *exec, const Identifier &propertyNa
       }
 
       if (idAttr->nodeValue() == propertyName.string()) {
-       return getDOMNode(exec,node);
+       result = getDOMNode(exec,node);
+        return true;
       }
     }
   }
 
-  return DOMObject::get(exec,propertyName);
+  return DOMObject::getOwnProperty(exec, propertyName, result);
 }
 
 // -------------------------------------------------------------------------
@@ -1951,12 +1947,9 @@ DOMCharacterData::DOMCharacterData(CharacterDataImpl *d)
 {
 }
 
-Value DOMCharacterData::get(ExecState *exec, const Identifier &p) const
+bool DOMCharacterData::getOwnProperty(ExecState *exec, const Identifier& p, Value& result) const
 {
-#ifdef KJS_VERBOSE
-  kdDebug(6070)<<"DOMCharacterData::get "<<p.string().string()<<endl;
-#endif
-  return lookupGetValue<DOMCharacterData,DOMNode>(exec,p,&DOMCharacterDataTable,this);
+  return lookupGetOwnValue<DOMCharacterData, DOMNode>(exec, p, &DOMCharacterDataTable, this, result);
 }
 
 Value DOMCharacterData::getValueProperty(ExecState *, int token) const
@@ -2045,14 +2038,6 @@ DOMText::DOMText(ExecState *exec, TextImpl *t)
   setPrototype(DOMTextProto::self(exec));
 }
 
-Value DOMText::get(ExecState *exec, const Identifier &p) const
-{
-  if (p == "")
-    return Undefined(); // ### TODO
-  else
-    return DOMCharacterData::get(exec, p);
-}
-
 Value DOMTextProtoFunc::call(ExecState *exec, Object &thisObj, const List &args)
 {
   if (!thisObj.inherits(&KJS::DOMText::info)) {
index 77e7879..d3c63ca 100644 (file)
@@ -49,7 +49,7 @@ namespace KJS {
     DOMNode(ExecState *exec, DOM::NodeImpl *n);
     virtual ~DOMNode();
     virtual bool toBoolean(ExecState *) const;
-    virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     Value getValueProperty(ExecState *exec, int token) const;
     virtual void mark();
     virtual void put(ExecState *exec, const Identifier &propertyName, const Value& value, int attr = None);
@@ -92,7 +92,7 @@ namespace KJS {
     DOMNodeList(ExecState *, DOM::NodeListImpl *l) : m_impl(l) { }
     ~DOMNodeList();
     virtual bool hasOwnProperty(ExecState *exec, const Identifier &p) const;
-    virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     virtual Value call(ExecState *exec, Object &thisObj, const List&args);
     virtual bool implementsCall() const { return true; }
     // no put - all read-only
@@ -111,7 +111,7 @@ namespace KJS {
   public:
     DOMDocument(ExecState *exec, DOM::DocumentImpl *d);
     ~DOMDocument();
-    virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     Value getValueProperty(ExecState *exec, int token) const;
     virtual void put(ExecState *exec, const Identifier &propertyName, const Value& value, int attr = None);
     void putValueProperty(ExecState *exec, int token, const Value& value, int attr);
@@ -137,7 +137,7 @@ namespace KJS {
   class DOMAttr : public DOMNode {
   public:
     DOMAttr(ExecState *exec, DOM::AttrImpl *a);
-    virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     virtual void put(ExecState *exec, const Identifier &propertyName, const Value& value, int attr = None);
     Value getValueProperty(ExecState *exec, int token) const;
     void putValueProperty(ExecState *exec, int token, const Value& value, int attr);
@@ -151,7 +151,7 @@ namespace KJS {
   class DOMElement : public DOMNode {
   public:
     DOMElement(ExecState *exec, DOM::ElementImpl *e);
-    virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     // no put - all read-only
     virtual const ClassInfo* classInfo() const { return &info; }
     static const ClassInfo info;
@@ -186,7 +186,7 @@ namespace KJS {
   class DOMDocumentType : public DOMNode {
   public:
     DOMDocumentType(ExecState *exec, DOM::DocumentTypeImpl *dt);
-    virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     Value getValueProperty(ExecState *exec, int token) const;
     // no put - all read-only
     virtual const ClassInfo* classInfo() const { return &info; }
@@ -201,7 +201,7 @@ namespace KJS {
     DOMNamedNodeMap(ExecState *, DOM::NamedNodeMapImpl *m);
     ~DOMNamedNodeMap();
     virtual bool hasOwnProperty(ExecState *exec, const Identifier &p) const;
-    virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     // no put - all read-only
     virtual const ClassInfo* classInfo() const { return &info; }
     virtual bool toBoolean(ExecState *) const { return true; }
@@ -216,7 +216,7 @@ namespace KJS {
   class DOMProcessingInstruction : public DOMNode {
   public:
     DOMProcessingInstruction(ExecState *exec, DOM::ProcessingInstructionImpl *pi);
-    virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     Value getValueProperty(ExecState *exec, int token) const;
     virtual void put(ExecState *exec, const Identifier &propertyName, const Value& value, int attr = None);
     virtual const ClassInfo* classInfo() const { return &info; }
@@ -227,7 +227,7 @@ namespace KJS {
   class DOMNotation : public DOMNode {
   public:
     DOMNotation(ExecState *exec, DOM::NotationImpl *n);
-    virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     Value getValueProperty(ExecState *exec, int token) const;
     // no put - all read-only
     virtual const ClassInfo* classInfo() const { return &info; }
@@ -238,7 +238,7 @@ namespace KJS {
   class DOMEntity : public DOMNode {
   public:
     DOMEntity(ExecState *exec, DOM::EntityImpl *e);
-    virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     Value getValueProperty(ExecState *exec, int token) const;
     // no put - all read-only
     virtual const ClassInfo* classInfo() const { return &info; }
@@ -250,7 +250,7 @@ namespace KJS {
   class NodeConstructor : public DOMObject {
   public:
     NodeConstructor(ExecState *) { }
-    virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     Value getValueProperty(ExecState *exec, int token) const;
     // no put - all read-only
     virtual const ClassInfo* classInfo() const { return &info; }
@@ -261,7 +261,7 @@ namespace KJS {
   class DOMExceptionConstructor : public DOMObject {
   public:
     DOMExceptionConstructor(ExecState *) { }
-    virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     Value getValueProperty(ExecState *exec, int token) const;
     // no put - all read-only
     virtual const ClassInfo* classInfo() const { return &info; }
@@ -283,7 +283,7 @@ namespace KJS {
   class DOMNamedNodesCollection : public DOMObject {
   public:
     DOMNamedNodesCollection(ExecState *exec, const QValueList< khtml::SharedPtr<DOM::NodeImpl> >& nodes );
-    virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
   private:
     QValueList< khtml::SharedPtr<DOM::NodeImpl> > m_nodes;
   };
@@ -291,7 +291,7 @@ namespace KJS {
   class DOMCharacterData : public DOMNode {
   public:
     DOMCharacterData(ExecState *exec, DOM::CharacterDataImpl *d);
-    virtual Value get(ExecState *exec,const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec,const Identifier& propertyName, Value& result) const;
     Value getValueProperty(ExecState *, int token) const;
     virtual void put(ExecState *exec, const Identifier &propertyName, const Value& value, int attr = None);
     virtual const ClassInfo* classInfo() const { return &info; }
@@ -307,8 +307,6 @@ namespace KJS {
   class DOMText : public DOMCharacterData {
   public:
     DOMText(ExecState *exec, DOM::TextImpl *t);
-    virtual Value get(ExecState *exec,const Identifier &propertyName) const;
-    Value getValueProperty(ExecState *, int token) const;
     virtual const ClassInfo* classInfo() const { return &info; }
     static const ClassInfo info;
     DOM::TextImpl *toText() const;
index 0163ea6..c12cbf0 100644 (file)
@@ -351,9 +351,9 @@ const ClassInfo EventConstructor::info = { "EventConstructor", 0, &EventConstruc
 @end
 */
 
-Value EventConstructor::get(ExecState *exec, const Identifier &p) const
+bool EventConstructor::getOwnProperty(ExecState *exec, const Identifier& p, Value& result) const
 {
-  return lookupGetValue<EventConstructor, DOMObject>(exec,p,&EventConstructorTable,this);
+  return lookupGetOwnValue<EventConstructor, DOMObject>(exec, p, &EventConstructorTable, this, result);
 }
 
 Value EventConstructor::getValueProperty(ExecState *, int token) const
@@ -414,12 +414,9 @@ void DOMMouseEvent::mark()
         clipboard->mark();
 }
 
-Value DOMEvent::get(ExecState *exec, const Identifier &p) const
+bool DOMEvent::getOwnProperty(ExecState *exec, const Identifier& p, Value& result) const
 {
-#ifdef KJS_VERBOSE
-  kdDebug() << "KJS::DOMEvent::get " << p.qstring() << endl;
-#endif
-  return lookupGetValue<DOMEvent,DOMObject>(exec, p, &DOMEventTable, this );
+  return lookupGetOwnValue<DOMEvent, DOMObject>(exec, p, &DOMEventTable, this, result);
 }
 
 Value DOMEvent::getValueProperty(ExecState *exec, int token) const
@@ -565,9 +562,9 @@ const ClassInfo EventExceptionConstructor::info = { "EventExceptionConstructor",
   UNSPECIFIED_EVENT_TYPE_ERR    DOM::EventException::UNSPECIFIED_EVENT_TYPE_ERR DontDelete|ReadOnly
 @end
 */
-Value EventExceptionConstructor::get(ExecState *exec, const Identifier &p) const
+bool EventExceptionConstructor::getOwnProperty(ExecState *exec, const Identifier& p, Value& result) const
 {
-  return lookupGetValue<EventExceptionConstructor, DOMObject>(exec,p,&EventExceptionConstructorTable,this);
+  return lookupGetOwnValue<EventExceptionConstructor, DOMObject>(exec, p, &EventExceptionConstructorTable, this, result);
 }
 
 Value EventExceptionConstructor::getValueProperty(ExecState *, int token) const
@@ -614,9 +611,9 @@ DOMUIEvent::~DOMUIEvent()
 {
 }
 
-Value DOMUIEvent::get(ExecState *exec, const Identifier &p) const
+bool DOMUIEvent::getOwnProperty(ExecState *exec, const Identifier& p, Value& result) const
 {
-  return lookupGetValue<DOMUIEvent,DOMEvent>(exec,p,&DOMUIEventTable,this);
+  return lookupGetOwnValue<DOMUIEvent,DOMEvent>(exec, p, &DOMUIEventTable, this, result);
 }
 
 Value DOMUIEvent::getValueProperty(ExecState *exec, int token) const
@@ -708,12 +705,9 @@ DOMMouseEvent::~DOMMouseEvent()
 {
 }
 
-Value DOMMouseEvent::get(ExecState *exec, const Identifier &p) const
+bool DOMMouseEvent::getOwnProperty(ExecState *exec, const Identifier& p, Value& result) const
 {
-#ifdef KJS_VERBOSE
-  kdDebug(6070) << "DOMMouseEvent::get " << p.qstring() << endl;
-#endif
-  return lookupGetValue<DOMMouseEvent,DOMUIEvent>(exec,p,&DOMMouseEventTable,this);
+  return lookupGetOwnValue<DOMMouseEvent, DOMUIEvent>(exec, p, &DOMMouseEventTable, this, result);
 }
 
 static QPoint offsetFromTarget(const MouseRelatedEventImpl *e)
@@ -859,12 +853,9 @@ const ClassInfo* DOMKeyboardEvent::classInfo() const
     return &info;
 }
 
-Value DOMKeyboardEvent::get(ExecState *exec, const Identifier &p) const
+bool DOMKeyboardEvent::getOwnProperty(ExecState *exec, const Identifier& p, Value& result) const
 {
-#ifdef KJS_VERBOSE
-  kdDebug(6070) << "DOMKeyboardEvent::get " << p.qstring() << endl;
-#endif
-  return lookupGetValue<DOMKeyboardEvent, DOMUIEvent>(exec, p, &DOMKeyboardEventTable, this);
+  return lookupGetOwnValue<DOMKeyboardEvent, DOMUIEvent>(exec, p, &DOMKeyboardEventTable, this, result);
 }
 
 Value DOMKeyboardEvent::getValueProperty(ExecState *exec, int token) const
@@ -927,9 +918,9 @@ const ClassInfo MutationEventConstructor::info = { "MutationEventConstructor", 0
   REMOVAL      DOM::MutationEvent::REMOVAL             DontDelete|ReadOnly
 @end
 */
-Value MutationEventConstructor::get(ExecState *exec, const Identifier &p) const
+bool MutationEventConstructor::getOwnProperty(ExecState *exec, const Identifier& p, Value& result) const
 {
-  return lookupGetValue<MutationEventConstructor,DOMObject>(exec,p,&MutationEventConstructorTable,this);
+  return lookupGetOwnValue<MutationEventConstructor,DOMObject>(exec, p, &MutationEventConstructorTable, this, result);
 }
 
 Value MutationEventConstructor::getValueProperty(ExecState *, int token) const
@@ -972,9 +963,9 @@ DOMMutationEvent::~DOMMutationEvent()
 {
 }
 
-Value DOMMutationEvent::get(ExecState *exec, const Identifier &p) const
+bool DOMMutationEvent::getOwnProperty(ExecState *exec, const Identifier& p, Value& result) const
 {
-  return lookupGetValue<DOMMutationEvent,DOMEvent>(exec,p,&DOMMutationEventTable,this);
+  return lookupGetOwnValue<DOMMutationEvent, DOMEvent>(exec, p, &DOMMutationEventTable, this, result);
 }
 
 Value DOMMutationEvent::getValueProperty(ExecState *exec, int token) const
@@ -1051,9 +1042,9 @@ DOMWheelEvent::DOMWheelEvent(ExecState *exec, DOM::WheelEventImpl *e)
 {
 }
 
-Value DOMWheelEvent::get(ExecState *exec, const Identifier &p) const
+bool DOMWheelEvent::getOwnProperty(ExecState *exec, const Identifier &p, Value& result) const
 {
-    return lookupGetValue<DOMWheelEvent,DOMEvent>(exec, p, &DOMWheelEventTable, this);
+    return lookupGetOwnValue<DOMWheelEvent,DOMEvent>(exec, p, &DOMWheelEventTable, this, result);
 }
 
 Value DOMWheelEvent::getValueProperty(ExecState *exec, int token) const
@@ -1144,9 +1135,9 @@ static Value stringOrUndefined(const DOM::DOMString &str)
     }
 }
 
-Value Clipboard::get(ExecState *exec, const Identifier &propertyName) const
+bool Clipboard::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
 {
-    return lookupGetValue<Clipboard,DOMObject>(exec, propertyName, &ClipboardTable, this);
+    return lookupGetOwnValue<Clipboard, DOMObject>(exec, propertyName, &ClipboardTable, this, result);
 }
 
 Value Clipboard::getValueProperty(ExecState *exec, int token) const
index de5d1bd..a6a038e 100644 (file)
@@ -99,7 +99,7 @@ namespace KJS {
   class EventConstructor : public DOMObject {
   public:
     EventConstructor(ExecState *) { }
-    virtual Value get(ExecState *exec,const Identifier &p) const;
+    virtual bool getOwnProperty(ExecState *exec,const Identifier& p, Value& result) const;
     Value getValueProperty(ExecState *, int token) const;
     // no put - all read-only
     virtual const ClassInfo* classInfo() const { return &info; }
@@ -112,7 +112,7 @@ namespace KJS {
   public:
     DOMEvent(ExecState *exec, DOM::EventImpl *e);
     ~DOMEvent();
-    virtual Value get(ExecState *exec,const Identifier &p) const;
+    virtual bool getOwnProperty(ExecState *exec,const Identifier& p, Value& result) const;
     Value getValueProperty(ExecState *, int token) const;
     virtual void put(ExecState *exec, const Identifier &propertyName,
                        const Value& value, int attr = None);
@@ -137,7 +137,7 @@ namespace KJS {
   class EventExceptionConstructor : public DOMObject {
   public:
     EventExceptionConstructor(ExecState *) { }
-    virtual Value get(ExecState *exec,const Identifier &p) const;
+    virtual bool getOwnProperty(ExecState *exec,const Identifier& p, Value& result) const;
     Value getValueProperty(ExecState *, int token) const;
     // no put - all read-only
     virtual const ClassInfo* classInfo() const { return &info; }
@@ -150,7 +150,7 @@ namespace KJS {
   public:
     DOMUIEvent(ExecState *exec, DOM::UIEventImpl *ue);
     ~DOMUIEvent();
-    virtual Value get(ExecState *exec,const Identifier &p) const;
+    virtual bool getOwnProperty(ExecState *exec,const Identifier& p, Value& result) const;
     Value getValueProperty(ExecState *, int token) const;
     // no put - all read-only
     virtual const ClassInfo* classInfo() const { return &info; }
@@ -162,7 +162,7 @@ namespace KJS {
   public:
     DOMMouseEvent(ExecState *exec, DOM::MouseEventImpl *me);
     ~DOMMouseEvent();
-    virtual Value get(ExecState *exec,const Identifier &p) const;
+    virtual bool getOwnProperty(ExecState *exec,const Identifier& p, Value& result) const;
     Value getValueProperty(ExecState *, int token) const;
     virtual void mark();
     // no put - all read-only
@@ -178,7 +178,7 @@ namespace KJS {
   public:
     DOMKeyboardEvent(ExecState *exec, DOM::KeyboardEventImpl *ke);
     ~DOMKeyboardEvent();
-    virtual Value get(ExecState *exec, const Identifier &p) const;
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& p, Value& result) const;
     Value getValueProperty(ExecState *, int token) const;
     // no put - all read-only
     virtual const ClassInfo* classInfo() const;
@@ -190,7 +190,7 @@ namespace KJS {
   class MutationEventConstructor : public DOMObject {
   public:
     MutationEventConstructor(ExecState *) { }
-    virtual Value get(ExecState *exec,const Identifier &p) const;
+    virtual bool getOwnProperty(ExecState *exec,const Identifier& p, Value& result) const;
     Value getValueProperty(ExecState *, int token) const;
     // no put - all read-only
     virtual const ClassInfo* classInfo() const { return &info; }
@@ -203,7 +203,7 @@ namespace KJS {
   public:
     DOMMutationEvent(ExecState *exec, DOM::MutationEventImpl *me);
     ~DOMMutationEvent();
-    virtual Value get(ExecState *exec,const Identifier &p) const;
+    virtual bool getOwnProperty(ExecState *exec,const Identifier& p, Value& result) const;
     Value getValueProperty(ExecState *, int token) const;
     // no put - all read-only
     virtual const ClassInfo* classInfo() const { return &info; }
@@ -215,7 +215,7 @@ namespace KJS {
     class DOMWheelEvent : public DOMUIEvent {
     public:
         DOMWheelEvent(ExecState *, DOM::WheelEventImpl *);
-        virtual Value get(ExecState *, const Identifier &p) const;
+        virtual bool getOwnProperty(ExecState *, const Identifier &p, Value& result) const;
         Value getValueProperty(ExecState *, int token) const;
         // no put - all read-only
         virtual const ClassInfo* classInfo() const { return &info; }
@@ -229,7 +229,7 @@ namespace KJS {
   public:
     Clipboard(ExecState *exec, DOM::ClipboardImpl *ds);
     ~Clipboard();
-    virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     Value getValueProperty(ExecState *exec, int token) const;
     virtual void put(ExecState *exec, const Identifier &propertyName, const Value& value, int attr = None);
     void putValueProperty(ExecState *exec, int token, const Value& value, int /*attr*/);
index ba636e0..93c1dc2 100644 (file)
@@ -282,11 +282,8 @@ bool HTMLDocument::hasOwnProperty(ExecState *exec, const Identifier &p) const
   return doc->hasNamedItem(name) || doc->hasDocExtraNamedItem(name);
 }
 
-Value HTMLDocument::get(ExecState *exec, const Identifier &propertyName) const
+bool HTMLDocument::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
 {
-#ifdef KJS_VERBOSE
-  kdDebug(6070) << "KJS::HTMLDocument::get " << propertyName.qstring() << endl;
-#endif
   HTMLDocumentImpl &doc = *static_cast<HTMLDocumentImpl *>(impl());
   HTMLElementImpl *body = doc.body();
 
@@ -298,63 +295,83 @@ Value HTMLDocument::get(ExecState *exec, const Identifier &propertyName) const
     SharedPtr<DOM::HTMLCollectionImpl> collection = doc.documentNamedItems(name);
     if (collection->length() == 1) {
       NodeImpl *node = collection->firstItem();
-      if (node->hasTagName(HTMLTags::iframe())) {
-        KHTMLPart *part = static_cast<DOM::HTMLIFrameElementImpl *>(node)->contentPart();
-        if (part)
-          return Window::retrieve(part);
-      }
-      return getDOMNode(exec, node);
+      KHTMLPart *part;
+      if (node->hasTagName(HTMLTags::iframe()) && 
+          (part = static_cast<DOM::HTMLIFrameElementImpl *>(node)->contentPart()))
+        result = Window::retrieve(part);
+      else
+        result = getDOMNode(exec, node);
     } else 
-      return getHTMLCollection(exec, collection.get());
+      result = getHTMLCollection(exec, collection.get());
+    return true;
   }
+
+  HTMLBodyElementImpl *bodyElement = (body && body->hasTagName(HTMLTags::body())) ? static_cast<HTMLBodyElementImpl *>(body) : 0;
     
   const HashEntry* entry = Lookup::findEntry(&HTMLDocumentTable, propertyName);
   if (entry) {
     switch (entry->value) {
     case Title:
-      return String(doc.title());
+      result = String(doc.title());
+      return true;
     case Referrer:
-      return String(doc.referrer());
+      result = String(doc.referrer());
+      return true;
     case Domain:
-      return String(doc.domain());
+      result = String(doc.domain());
+      return true;
     case URL:
-      return String(doc.URL());
+      result = String(doc.URL());
+      return true;
     case Body:
-      return getDOMNode(exec, body);
+      result = getDOMNode(exec, body);
+      return true;
     case Location:
       if (part) {
         Window* win = Window::retrieveWindow(part);
-        if (win)
-          return Value(win->location());
+        if (win) {
+          result = Value(win->location());
+          return true;
+        }
       }
-      return Undefined();
+      result = Undefined();
+      return true;
     case Cookie:
-      return String(doc.cookie());
+      result = String(doc.cookie());
+      return true;
     case Images:
-      return getHTMLCollection(exec, doc.images().get());
+      result = getHTMLCollection(exec, doc.images().get());
+      return true;
     case Embeds:
-      return getHTMLCollection(exec, doc.embeds().get());
+      result = getHTMLCollection(exec, doc.embeds().get());
+      return true;
     case Applets:
-      return getHTMLCollection(exec, doc.applets().get());
+      result = getHTMLCollection(exec, doc.applets().get());
+      return true;
     case Links:
-      return getHTMLCollection(exec, doc.links().get());
+      result = getHTMLCollection(exec, doc.links().get());
+      return true;
     case Forms:
-      return getHTMLCollection(exec, doc.forms().get());
+      result = getHTMLCollection(exec, doc.forms().get());
+      return true;
     case Anchors:
-      return getHTMLCollection(exec, doc.anchors().get());
+      result = getHTMLCollection(exec, doc.anchors().get());
+      return true;
     case Scripts: // TODO (IE-specific)
     {
       // To be implemented. Meanwhile, return an object with a length property set to 0
       kdWarning() << "KJS::HTMLDocument document.scripts called - not implemented" << endl;
-      Object obj( new ObjectImp() );
-      obj.put( exec, lengthPropertyName, Number(0) );
-      return obj;
+      Object obj(new ObjectImp());
+      obj.put(exec, lengthPropertyName, Number(0));
+      result = obj;
+      return true;
     }
     case All:
       // Disable document.all when we try to be Netscape-compatible
-      if ( exec->dynamicInterpreter()->compatMode() == Interpreter::NetscapeCompat )
-        return Undefined();
-      return getHTMLCollection(exec, doc.all().get());
+      if (exec->dynamicInterpreter()->compatMode() == Interpreter::NetscapeCompat)
+        result = Undefined();
+      result = getHTMLCollection(exec, doc.all().get());
+      return true;
     case Clear:
     case Open:
     case Close:
@@ -363,53 +380,62 @@ Value HTMLDocument::get(ExecState *exec, const Identifier &propertyName) const
     case GetElementsByName:
     case CaptureEvents:
     case ReleaseEvents:
-      return lookupOrCreateFunction<HTMLDocFunction>( exec, propertyName, this, entry->value, entry->params, entry->attr );
-    }
-  }
-  // Look for overrides
-  ValueImp *val = ObjectImp::getDirect(propertyName);
-  if (val)
-    return Value(val);
-
-  HTMLBodyElementImpl *bodyElement = (body && body->hasTagName(HTMLTags::body())) ? static_cast<HTMLBodyElementImpl *>(body) : 0;
-
-  if (entry) {
-    switch (entry->value) {
+      result = lookupOrCreateFunction<HTMLDocFunction>( exec, propertyName, this, entry->value, entry->params, entry->attr );
+      return true;
     case BgColor:
-      if (!bodyElement)
-        return Undefined();
-      return String(bodyElement->bgColor());
+      if (bodyElement)
+        result = String(bodyElement->bgColor());
+      else
+        result = Undefined();
+      return true;
     case FgColor:
-      if (!bodyElement)
-        return Undefined();
-      return String(bodyElement->text());
+      if (bodyElement)
+        result = String(bodyElement->text());
+      else
+        result = Undefined();
+      return true;
     case AlinkColor:
-      if (!bodyElement)
-        return Undefined();
-      return String(bodyElement->aLink());
+      if (bodyElement)
+        result = String(bodyElement->aLink());
+      else
+        result = Undefined();
+      return true;
     case LinkColor:
-      if (!bodyElement)
-        return Undefined();
-      return String(bodyElement->link());
+      if (bodyElement)
+        result = String(bodyElement->link());
+      else
+        result = Undefined();
+      return true;
     case VlinkColor:
-      if (!bodyElement)
-        return Undefined();
-      return String(bodyElement->vLink());
+      if (bodyElement)
+        result = String(bodyElement->vLink());
+      else
+        result = Undefined();
+      return true;
     case LastModified:
-      return String(doc.lastModified());
+      result = String(doc.lastModified());
+      return true;
     case Height:
-      return Number(view ? view->contentsHeight() : 0);
+      result = Number(view ? view->contentsHeight() : 0);
+      return true;
     case Width:
-      return Number(view ? view->contentsWidth() : 0);
+      result = Number(view ? view->contentsWidth() : 0);
+      return true;
     case Dir:
-        return Undefined();
-      return String(bodyElement->dir());
+      if (bodyElement)
+        result = String(bodyElement->dir());
+      else 
+        result = Undefined();
+      return true;
     case DesignMode:
-      return String(doc.inDesignMode() ? "on" : "off");
+      result = String(doc.inDesignMode() ? "on" : "off");
+      return true;
+    default:
+      assert(0);
     }
   }
 
-  return DOMDocument::get(exec, propertyName);
+  return DOMDocument::getOwnProperty(exec, propertyName, result);
 }
 
 void KJS::HTMLDocument::put(ExecState *exec, const Identifier &propertyName, const Value& value, int attr)
@@ -1274,30 +1300,36 @@ HTMLElement::HTMLElement(ExecState *exec, HTMLElementImpl *e)
 {
 }
 
-Value KJS::HTMLElement::get(ExecState *exec, const Identifier &propertyName) const
+bool KJS::HTMLElement::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
 {
     HTMLElementImpl &element = *static_cast<HTMLElementImpl *>(impl());
-#ifdef KJS_VERBOSE
-    kdDebug(6070) << "KJS::HTMLElement::tryGet " << propertyName.qstring() << " thisTag=" << element.tagName().string() << endl;
-#endif
+
     // First look at dynamic properties
     if (element.hasLocalName(HTMLTags::form())) {
         HTMLFormElementImpl &form = static_cast<HTMLFormElementImpl &>(element);
         // Check if we're retrieving an element (by index or by name)
         bool ok;
         uint u = propertyName.toULong(&ok);
-        if (ok)
-            return getDOMNode(exec, form.elements()->item(u));
+        if (ok) {
+            result = getDOMNode(exec, form.elements()->item(u));
+            return true;
+        }
+
         ValueImp *namedItems = HTMLCollection(exec, form.elements().get()).getNamedItems(exec, propertyName);
-        if (!namedItems->isUndefined())
-            return namedItems;
+        if (!namedItems->isUndefined()) {
+            result = namedItems;
+            return true;
+        }
     }
     else if (element.hasLocalName(HTMLTags::select())) {
         HTMLSelectElementImpl &select = static_cast<HTMLSelectElementImpl &>(element);
         bool ok;
         uint u = propertyName.toULong(&ok);
-        if (ok)
-            return getDOMNode(exec, select.optionsHTMLCollection()->item(u)); // not specified by DOM(?) but supported in netscape/IE
+        if (ok) {
+            // not specified by DOM(?) but supported in netscape/IE
+            result = getDOMNode(exec, select.optionsHTMLCollection()->item(u));
+            return true;
+        }
     }
     else if (element.hasLocalName(HTMLTags::frameset())) {
         NodeImpl *frame = element.children()->namedItem(propertyName.string());
@@ -1308,7 +1340,8 @@ Value KJS::HTMLElement::get(ExecState *exec, const Identifier &propertyName) con
                 if (part) {
                     Window *window = Window::retrieveWindow(part);
                     if (window) {
-                        return Value(window);
+                        result = Value(window);
+                        return true;
                     }
                 }
             }
@@ -1319,22 +1352,28 @@ Value KJS::HTMLElement::get(ExecState *exec, const Identifier &propertyName) con
         if (doc) {
             KHTMLPart* part = doc->part();
             if (part) {
-              Window *window = Window::retrieveWindow(part);
-             if (window && window->hasProperty(exec, propertyName))
-                return window->get(exec, propertyName);
+                Window *window = Window::retrieveWindow(part);
+                if (window && window->hasProperty(exec, propertyName)) {
+                    result = window->get(exec, propertyName);
+                    return result;
+                }
             }
         }
     }
 #if APPLE_CHANGES
     else if (element.hasLocalName(HTMLTags::embed()) || element.hasLocalName(HTMLTags::object()) ||
              element.hasLocalName(HTMLTags::applet())) {
-       if (propertyName == "__apple_runtime_object")
-           return getRuntimeObject(exec,&element);
+        if (propertyName == "__apple_runtime_object") {
+           result = getRuntimeObject(exec,&element);
+            return true;
+        }
        Value runtimeObject = getRuntimeObject(exec,&element);
        if (!runtimeObject.isNull()) {
            ObjectImp *imp = static_cast<ObjectImp *>(runtimeObject.imp());
-           if (imp->hasProperty(exec, propertyName))
-               return imp->get (exec, propertyName);
+           if (imp->hasProperty(exec, propertyName)) {
+               result = imp->get(exec, propertyName);
+                return true;
+            }
        }
     }
 #endif
@@ -1343,12 +1382,14 @@ Value KJS::HTMLElement::get(ExecState *exec, const Identifier &propertyName) con
     const HashEntry* entry = Lookup::findEntry(table, propertyName);
     if (entry) {
         if (entry->attr & Function)
-            return lookupOrCreateFunction<KJS::HTMLElementFunction>(exec, propertyName, this, entry->value, entry->params, entry->attr);
-        return getValueProperty(exec, entry->value);
+            result = lookupOrCreateFunction<KJS::HTMLElementFunction>(exec, propertyName, this, entry->value, entry->params, entry->attr);
+        else
+            result = getValueProperty(exec, entry->value);
+        return true;
     }
 
     // Base HTMLElement stuff or parent class forward, as usual
-    return lookupGet<KJS::HTMLElementFunction, KJS::HTMLElement, DOMElement>(exec, propertyName, &HTMLElementTable, this);
+    return lookupGetOwnProperty<KJS::HTMLElementFunction, KJS::HTMLElement, DOMElement>(exec, propertyName, &HTMLElementTable, this, result);
 }
 
 bool KJS::HTMLElement::implementsCall() const
@@ -3319,37 +3360,47 @@ bool KJS::HTMLCollection::hasOwnProperty(ExecState *exec, const Identifier &p) c
   return DOMObject::hasOwnProperty(exec, p);
 }
 
-Value KJS::HTMLCollection::get(ExecState *exec, const Identifier &propertyName) const
+bool KJS::HTMLCollection::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
 {
-#ifdef KJS_VERBOSE
-  kdDebug() << "KJS::HTMLCollection::get " << propertyName.ascii() << endl;
-#endif
   HTMLCollectionImpl &collection = *m_impl;
-  if (propertyName == lengthPropertyName)
-    return Number(collection.length());
-  else if (propertyName == "selectedIndex") {
+  if (propertyName == lengthPropertyName) {
+    result = Number(collection.length());
+    return true;
+  } else if (propertyName == "selectedIndex") {
+    // FIXME: should we really handle selectedIndex here, as well as in HTMLSelectCollection?
+
     // NON-STANDARD options.selectedIndex
     NodeImpl *option = collection.item(0);
     if (option->hasTagName(HTMLTags::option())) {
       NodeImpl *select = option;
       while ((select = select->parentNode()))
-        if (select->hasTagName(HTMLTags::select()))
-         return Number(static_cast<HTMLSelectElementImpl *>(select)->selectedIndex());
+        if (select->hasTagName(HTMLTags::select())) {
+         result =  Number(static_cast<HTMLSelectElementImpl *>(select)->selectedIndex());
+          return true;
+        }
     }
-    return Undefined();
   } else {
     // Look in the prototype (for functions) before assuming it's an item's name
     Object proto = Object::dynamicCast(prototype());
     if (!proto.isNull() && proto.hasProperty(exec,propertyName))
-      return proto.get(exec,propertyName);
+      return false;
 
     // name or index ?
     bool ok;
     unsigned int u = propertyName.toULong(&ok);
-    if (ok)
-      return getDOMNode(exec, collection.item(u));
-    return getNamedItems(exec, propertyName);
+    if (ok) {
+      result = getDOMNode(exec, collection.item(u));
+      return true;
+    }
+
+    Value items = getNamedItems(exec, propertyName);
+    if (!items.imp()->isUndefined()) {
+      result = items;
+      return true;
+    }
   }
+
+  return DOMObject::getOwnProperty(exec, propertyName, result);
 }
 
 // HTMLCollections are strange objects, they support both get and call,
@@ -3447,12 +3498,14 @@ HTMLSelectCollection::HTMLSelectCollection(ExecState *exec, HTMLCollectionImpl *
 {
 }
 
-Value KJS::HTMLSelectCollection::get(ExecState *exec, const Identifier &p) const
+bool KJS::HTMLSelectCollection::getOwnProperty(ExecState *exec, const Identifier &p, Value& result) const
 {
-  if (p == "selectedIndex")
-    return Number(m_element->selectedIndex());
+  if (p == "selectedIndex") {
+    result = Number(m_element->selectedIndex());
+    return true;
+  }
 
-  return  HTMLCollection::get(exec, p);
+  return HTMLCollection::getOwnProperty(exec, p, result);
 }
 
 void KJS::HTMLSelectCollection::put(ExecState *exec, const Identifier &propertyName, const Value& value, int)
@@ -3621,9 +3674,9 @@ const ClassInfo KJS::Image::info = { "Image", 0, &ImageTable, 0 };
 @end
 */
 
-Value Image::get(ExecState *exec, const Identifier &propertyName) const
+bool Image::getOwnProperty(ExecState *exec, const Identifier &propertyName, Value &result) const
 {
-  return lookupGetValue<Image,DOMObject>(exec, propertyName, &ImageTable, this);
+  return lookupGetOwnValue<Image,DOMObject>(exec, propertyName, &ImageTable, this, result);
 }
 
 Value Image::getValueProperty(ExecState *, int token) const
@@ -4643,17 +4696,10 @@ const ClassInfo Context2D::info = { "Context2D", 0, &Context2DTable, 0 };
 @end
 */
 
-Value Context2D::get(ExecState *exec, const Identifier &propertyName) const
+bool Context2D::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
 {
-    const HashTable* table = classInfo()->propHashTable; // get the right hashtable
-    const HashEntry* entry = Lookup::findEntry(table, propertyName);
-    if (entry) {
-        if (entry->attr & Function)
-            return lookupOrCreateFunction<KJS::Context2DFunction>(exec, propertyName, this, entry->value, entry->params, entry->attr);
-        return getValueProperty(exec, entry->value);
-    }
-
-    return lookupGetValue<Context2D,DOMObject>(exec, propertyName, &Context2DTable, this);
+    // FIXME: functions should be on the prototype, not in the object itself
+    return lookupGetOwnProperty<Context2DFunction, Context2D, DOMObject>(exec, propertyName, &Context2DTable, this, result);
 }
 
 Value Context2D::getValueProperty(ExecState *, int token) const
@@ -5212,17 +5258,9 @@ Gradient::Gradient(float x0, float y0, float r0, float x1, float y1, float r1)
     commonInit();
 }
 
-Value Gradient::get(ExecState *exec, const Identifier &propertyName) const
+bool Gradient::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
 {
-    const HashTable* table = classInfo()->propHashTable; // get the right hashtable
-    const HashEntry* entry = Lookup::findEntry(table, propertyName);
-    if (entry) {
-        if (entry->attr & Function)
-            return lookupOrCreateFunction<KJS::GradientFunction>(exec, propertyName, this, entry->value, entry->params, entry->attr);
-        return getValueProperty(exec, entry->value);
-    }
-
-    return lookupGetValue<Gradient,DOMObject>(exec, propertyName, &GradientTable, this);
+    return lookupGetOwnProperty<GradientFunction, Gradient, DOMObject>(exec, propertyName, &GradientTable, this, result);
 }
 
 Value Gradient::getValueProperty(ExecState *, int token) const
@@ -5416,17 +5454,9 @@ CGPatternRef ImagePattern::createPattern(CGAffineTransform transform)
     return CGPatternCreate(this, _bounds, patternTransform, _rw, _rh, kCGPatternTilingConstantSpacing, true, &patternCallbacks);
 }
 
-Value ImagePattern::get(ExecState *exec, const Identifier &propertyName) const
+bool ImagePattern::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
 {
-    const HashTable* table = classInfo()->propHashTable; // get the right hashtable
-    const HashEntry* entry = Lookup::findEntry(table, propertyName);
-    if (entry) {
-        if (entry->attr & Function)
-            return lookupOrCreateFunction<GradientFunction>(exec, propertyName, this, entry->value, entry->params, entry->attr);
-        return getValueProperty(exec, entry->value);
-    }
-
-    return lookupGetValue<ImagePattern,DOMObject>(exec, propertyName, &ImagePatternTable, this);
+    return lookupGetOwnValue<ImagePattern, DOMObject>(exec, propertyName, &ImagePatternTable, this, result);
 }
 
 Value ImagePattern::getValueProperty(ExecState *, int token) const
index f6c8292..956390e 100644 (file)
@@ -47,7 +47,7 @@ namespace KJS {
   class HTMLDocument : public DOMDocument {
   public:
     HTMLDocument(ExecState *exec, DOM::HTMLDocumentImpl *d);
-    virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     virtual void put(ExecState *exec, const Identifier &propertyName, const Value& value, int attr = None);
     void putValueProperty(ExecState *exec, int token, const Value& value, int /*attr*/);
     virtual bool hasOwnProperty(ExecState *exec, const Identifier &propertyName) const;
@@ -62,7 +62,7 @@ namespace KJS {
   class HTMLElement : public DOMElement {
   public:
     HTMLElement(ExecState *exec, DOM::HTMLElementImpl *e);
-    virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     Value getValueProperty(ExecState *exec, int token) const;
     virtual void put(ExecState *exec, const Identifier &propertyName, const Value& value, int attr = None);
     void putValueProperty(ExecState *exec, int token, const Value& value, int);
@@ -295,7 +295,7 @@ namespace KJS {
   public:
     HTMLCollection(ExecState *exec, DOM::HTMLCollectionImpl *c);
     ~HTMLCollection();
-    virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     virtual Value call(ExecState *exec, Object &thisObj, const List&args);
     virtual bool implementsCall() const { return true; }
     virtual bool toBoolean(ExecState *) const { return true; }
@@ -312,7 +312,7 @@ namespace KJS {
   class HTMLSelectCollection : public HTMLCollection {
   public:
     HTMLSelectCollection(ExecState *exec, DOM::HTMLCollectionImpl *c, DOM::HTMLSelectElementImpl *e);
-    virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     virtual void put(ExecState *exec, const Identifier &propertyName, const Value& value, int attr = None);
   private:
     khtml::SharedPtr<DOM::HTMLSelectElementImpl> m_element;
@@ -344,7 +344,7 @@ namespace KJS {
   public:
     Image(DOM::DocumentImpl *d, bool ws, int w, bool hs, int h);
     ~Image();
-    virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     Value getValueProperty(ExecState *exec, int token) const;
     virtual void put(ExecState *exec, const Identifier &propertyName, const Value& value, int attr = None);
     void putValueProperty(ExecState *exec, int token, const Value& value, int /*attr*/);
@@ -374,7 +374,7 @@ namespace KJS {
   public:
     Context2D(DOM::HTMLElementImpl *e);
     ~Context2D();
-    virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     Value getValueProperty(ExecState *exec, int token) const;
     virtual void put(ExecState *exec, const Identifier &propertyName, const Value& value, int attr = None);
     void putValueProperty(ExecState *exec, int token, const Value& value, int /*attr*/);
@@ -466,7 +466,7 @@ private:
     Gradient(float x0, float y0, float x1, float y1);
     Gradient(float x0, float y0, float r0, float x1, float y1, float r1);
     ~Gradient();
-    virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     Value getValueProperty(ExecState *exec, int token) const;
     virtual void put(ExecState *exec, const Identifier &propertyName, const Value& value, int attr = None);
     void putValueProperty(ExecState *exec, int token, const Value& value, int /*attr*/);
@@ -512,7 +512,7 @@ private:
   class ImagePattern : public DOMObject {
   public:
     ImagePattern(Image *i, int type);
-    virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     Value getValueProperty(ExecState *exec, int token) const;
     virtual void put(ExecState *exec, const Identifier &propertyName, const Value& value, int attr = None);
     void putValueProperty(ExecState *exec, int token, const Value& value, int /*attr*/);
index 72ba33a..8515625 100644 (file)
@@ -75,7 +75,7 @@ namespace KJS {
     class Plugins : public PluginBase {
     public:
         Plugins(ExecState *exec) : PluginBase(exec) {};
-        virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+        virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
         virtual const ClassInfo* classInfo() const { return &info; }
         static const ClassInfo info;
     private:
@@ -86,7 +86,7 @@ namespace KJS {
     class MimeTypes : public PluginBase {
     public:
         MimeTypes(ExecState *exec) : PluginBase(exec) { };
-        virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+        virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
         virtual const ClassInfo* classInfo() const { return &info; }
         static const ClassInfo info;
     private:
@@ -96,8 +96,8 @@ namespace KJS {
 
     class Plugin : public PluginBase {
     public:
-        Plugin( ExecState *exec, PluginInfo *info ) : PluginBase(exec), m_info(info) { }
-        virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+        Plugin(ExecState *exec, PluginInfo *info) : PluginBase(exec), m_info(info) { }
+        virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
         virtual const ClassInfo* classInfo() const { return &info; }
         static const ClassInfo info;
     private:
@@ -109,7 +109,7 @@ namespace KJS {
     class MimeType : public PluginBase {
     public:
         MimeType( ExecState *exec, MimeClassInfo *info ) : PluginBase(exec), m_info(info) { }
-        virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+        virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
         virtual const ClassInfo* classInfo() const { return &info; }
         static const ClassInfo info;
     private:
@@ -144,12 +144,9 @@ IMPLEMENT_PROTOFUNC(NavigatorFunc)
 Navigator::Navigator(ExecState *exec, KHTMLPart *p)
   : ObjectImp(exec->lexicalInterpreter()->builtinObjectPrototype()), m_part(p) { }
 
-Value Navigator::get(ExecState *exec, const Identifier &propertyName) const
+bool Navigator::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
 {
-#ifdef KJS_VERBOSE
-  kdDebug(6070) << "Navigator::get " << propertyName.ascii() << endl;
-#endif
-  return lookupGet<NavigatorFunc,Navigator,ObjectImp>(exec,propertyName,&NavigatorTable,this);
+  return lookupGetOwnProperty<NavigatorFunc, Navigator, ObjectImp>(exec, propertyName, &NavigatorTable, this, result);
 }
 
 Value Navigator::getValueProperty(ExecState *exec, int token) const
@@ -339,120 +336,126 @@ void PluginBase::refresh(bool reload)
 /*******************************************************************/
 IMPLEMENT_PROTOFUNC(PluginsFunc)
 
-Value Plugins::get(ExecState *exec, const Identifier &propertyName) const
+bool Plugins::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
 {
-#ifdef KJS_VERBOSE
-  kdDebug(6070) << "Plugins::get " << propertyName.qstring() << endl;
-#endif
-    if (propertyName == "refresh")
-      return lookupOrCreateFunction<PluginsFunc>(exec,propertyName,this,0,0,DontDelete|Function);
-    else if ( propertyName ==lengthPropertyName )
-      return Number(plugins->count());
-    else {
-
+    if (propertyName == "refresh") {
+        result = lookupOrCreateFunction<PluginsFunc>(exec, propertyName, this, 0, 0, DontDelete|Function);
+        return true;
+    } else if (propertyName == lengthPropertyName) {
+        result = Number(plugins->count());
+        return true;
+    } else {
         // plugins[#]
         bool ok;
         unsigned int i = propertyName.toULong(&ok);
-        if( ok && i<plugins->count() )
-            return Value( new Plugin( exec, plugins->at(i) ) );
+        if (ok && i < plugins->count()) {
+            result = Value(new Plugin(exec, plugins->at(i)));
+            return true;
+        }
 
         // plugin[name]
-        for ( PluginInfo *pl = plugins->first(); pl!=0; pl = plugins->next() ) {
-            if ( pl->name==propertyName.qstring() )
-                return Value( new Plugin( exec, pl ) );
+        for (PluginInfo *pl = plugins->first(); pl; pl = plugins->next()) {
+            if (pl->name==propertyName.qstring()) {
+                result = Value(new Plugin(exec, pl));
+                return true;
+            }
         }
     }
 
-    return PluginBase::get(exec, propertyName);
+    return PluginBase::getOwnProperty(exec, propertyName, result);
 }
 
 /*******************************************************************/
 
-Value MimeTypes::get(ExecState *exec, const Identifier &propertyName) const
+bool MimeTypes::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
 {
-#ifdef KJS_VERBOSE
-  kdDebug(6070) << "MimeTypes::get " << propertyName.qstring() << endl;
-#endif
-    if( propertyName==lengthPropertyName )
-        return Number( mimes->count() );
-    else {
-
+    if (propertyName == lengthPropertyName) {
+        result = Number(mimes->count());
+        return true;
+    } else {
         // mimeTypes[#]
         bool ok;
         unsigned int i = propertyName.toULong(&ok);
-        if( ok && i<mimes->count() )
-            return Value( new MimeType( exec, mimes->at(i) ) );
+        if (ok && i < mimes->count()) {
+            result = Value(new MimeType(exec, mimes->at(i)));
+            return true;
+        }
 
         // mimeTypes[name]
-        //kdDebug(6070) << "MimeTypes[" << propertyName.ascii() << "]" << endl;
-        for ( MimeClassInfo *m=mimes->first(); m!=0; m=mimes->next() ) {
-            //kdDebug(6070) << "m->type=" << m->type.ascii() << endl;
-            if ( m->type == propertyName.qstring() )
-                return Value( new MimeType( exec, m ) );
+        for (MimeClassInfo *m = mimes->first(); m; m = mimes->next()) {
+            if (m->type == propertyName.qstring()) {
+                result = Value(new MimeType(exec, m));
+                return true;
+            }
         }
     }
 
-    return PluginBase::get(exec, propertyName);
+    return PluginBase::getOwnProperty(exec, propertyName, result);
 }
 
 
 /************************************************************************/
 
-Value Plugin::get(ExecState *exec, const Identifier &propertyName) const
+bool Plugin::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
 {
-#ifdef KJS_VERBOSE
-  kdDebug(6070) << "Plugin::get " << propertyName.qstring() << endl;
-#endif
-    if ( propertyName=="name" )
-        return String( m_info->name );
-    else if ( propertyName == "filename" )
-        return String( m_info->file );
-    else if ( propertyName == "description" )
-        return String( m_info->desc );
-    else if ( propertyName == lengthPropertyName )
-        return Number( m_info->mimes.count() );
-    else {
-
+    // FIXME: should use the hashtable mechanism for properties
+
+    if (propertyName == "name") {
+        result = String(m_info->name);
+        return true;
+    } else if (propertyName == "filename") {
+        result = String(m_info->file);
+        return true;
+    } else if (propertyName == "description") {
+        result = String(m_info->desc);
+        return true;
+    } else if (propertyName == lengthPropertyName) {
+        result = Number(m_info->mimes.count());
+        return true;
+    } else {
         // plugin[#]
         bool ok;
         unsigned int i = propertyName.toULong(&ok);
-        //kdDebug(6070) << "Plugin::get plugin[" << i << "]" << endl;
-        if( ok && i<m_info->mimes.count() )
-        {
-            //kdDebug(6070) << "returning mimetype " << m_info->mimes.at(i)->type << endl;
-            return Value(new MimeType(exec, m_info->mimes.at(i)));
+        if (ok && i < m_info->mimes.count()) {
+            result = Value(new MimeType(exec, m_info->mimes.at(i)));
+            return result;
         }
 
         // plugin["name"]
-        for ( MimeClassInfo *m=m_info->mimes.first();
-              m!=0; m=m_info->mimes.next() ) {
-            if ( m->type==propertyName.qstring() )
-                return Value(new MimeType(exec, m));
+        for (MimeClassInfo *m=m_info->mimes.first(); m; m = m_info->mimes.next()) {
+            if (m->type==propertyName.qstring()) {
+                result = Value(new MimeType(exec, m));
+                return result;
+            }
         }
 
     }
 
-    return ObjectImp::get(exec,propertyName);
+    return ObjectImp::getOwnProperty(exec, propertyName, result);
 }
 
 
 /*****************************************************************************/
 
-Value MimeType::get(ExecState *exec, const Identifier &propertyName) const
+bool MimeType::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
 {
-#ifdef KJS_VERBOSE
-  kdDebug(6070) << "MimeType::get " << propertyName.qstring() << endl;
-#endif
-    if ( propertyName == "type" )
-        return String( m_info->type );
-    else if ( propertyName == "suffixes" )
-        return String( m_info->suffixes );
-    else if ( propertyName == "description" )
-        return String( m_info->desc );
-    else if ( propertyName == "enabledPlugin" )
-        return Value(new Plugin(exec, m_info->plugin));
-
-    return ObjectImp::get(exec,propertyName);
+    // FIXME: should use hashtable mechanism
+
+    if (propertyName == "type") {
+        result = String(m_info->type);
+        return true;
+    } else if (propertyName == "suffixes") {
+        result = String(m_info->suffixes);
+        return true;
+    } else if (propertyName == "description") {
+        result = String(m_info->desc);
+        return true;
+    } else if (propertyName == "enabledPlugin") {
+        result = Value(new Plugin(exec, m_info->plugin));
+        return true;
+    }
+
+    return ObjectImp::getOwnProperty(exec, propertyName, result);
 }
 
 
index bbb4940..f55e86a 100644 (file)
@@ -30,7 +30,7 @@ namespace KJS {
   class Navigator : public ObjectImp {
   public:
     Navigator(ExecState *exec, KHTMLPart *p);
-    virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     Value getValueProperty(ExecState *exec, int token) const;
     virtual const ClassInfo* classInfo() const { return &info; }
     static const ClassInfo info;
index 6e7ed4a..dd4a457 100644 (file)
@@ -83,9 +83,9 @@ DOMRange::~DOMRange()
   ScriptInterpreter::forgetDOMObject(m_impl.get());
 }
 
-Value DOMRange::get(ExecState *exec, const Identifier &p) const
+bool DOMRange::getOwnProperty(ExecState *exec, const Identifier& p, Value& result) const
 {
-  return lookupGetValue<DOMRange, DOMObject>(exec, p, &DOMRangeTable, this);
+  return lookupGetOwnValue<DOMRange, DOMObject>(exec, p, &DOMRangeTable, this, result);
 }
 
 Value DOMRange::getValueProperty(ExecState *exec, int token) const
@@ -204,9 +204,9 @@ const ClassInfo RangeConstructor::info = { "RangeConstructor", 0, &RangeConstruc
   END_TO_START         DOM::Range::END_TO_START        DontDelete|ReadOnly
 @end
 */
-Value RangeConstructor::get(ExecState *exec, const Identifier &p) const
+bool RangeConstructor::getOwnProperty(ExecState *exec, const Identifier& p, Value& result) const
 {
-  return lookupGetValue<RangeConstructor,DOMObject>(exec, p, &RangeConstructorTable, this);
+  return lookupGetOwnValue<RangeConstructor,DOMObject>(exec, p, &RangeConstructorTable, this, result);
 }
 
 Value RangeConstructor::getValueProperty(ExecState *, int token) const
index 88a26bc..103d88f 100644 (file)
@@ -33,7 +33,7 @@ namespace KJS {
   public:
     DOMRange(ExecState *exec, DOM::RangeImpl *r);
     ~DOMRange();
-    virtual Value get(ExecState *exec,const Identifier &p) const;
+    virtual bool getOwnProperty(ExecState *exec,const Identifier& p, Value& result) const;
     Value getValueProperty(ExecState *exec, int token) const;
     // no put - all read-only
     virtual const ClassInfo* classInfo() const { return &info; }
@@ -54,7 +54,7 @@ namespace KJS {
   class RangeConstructor : public DOMObject {
   public:
     RangeConstructor(ExecState *) { }
-    virtual Value get(ExecState *exec,const Identifier &p) const;
+    virtual bool getOwnProperty(ExecState *exec,const Identifier& p, Value& result) const;
     Value getValueProperty(ExecState *, int token) const;
     // no put - all read-only
     virtual const ClassInfo* classInfo() const { return &info; }
index 55b85af..8a57ffb 100644 (file)
@@ -68,9 +68,9 @@ DOMNodeIterator::~DOMNodeIterator()
   ScriptInterpreter::forgetDOMObject(m_impl.get());
 }
 
-Value DOMNodeIterator::get(ExecState *exec, const Identifier &p) const
+bool DOMNodeIterator::getOwnProperty(ExecState *exec, const Identifier& p, Value& result) const
 {
-  return lookupGetValue<DOMNodeIterator,DOMObject>(exec,p,&DOMNodeIteratorTable,this);
+  return lookupGetOwnValue<DOMNodeIterator, DOMObject>(exec, p, &DOMNodeIteratorTable, this, result);
 }
 
 Value DOMNodeIterator::getValueProperty(ExecState *exec, int token) const
@@ -145,9 +145,9 @@ const ClassInfo NodeFilterConstructor::info = { "NodeFilterConstructor", 0, &Nod
   SHOW_NOTATION                DOM::NodeFilter::SHOW_NOTATION  DontDelete|ReadOnly
 @end
 */
-Value NodeFilterConstructor::get(ExecState *exec, const Identifier &p) const
+bool NodeFilterConstructor::getOwnProperty(ExecState *exec, const Identifier& p, Value& result) const
 {
-  return lookupGetValue<NodeFilterConstructor,DOMObject>(exec,p,&NodeFilterConstructorTable,this);
+  return lookupGetOwnValue<NodeFilterConstructor, DOMObject>(exec, p, &NodeFilterConstructorTable, this, result);
 }
 
 Value NodeFilterConstructor::getValueProperty(ExecState *, int token) const
@@ -247,9 +247,9 @@ DOMTreeWalker::~DOMTreeWalker()
   ScriptInterpreter::forgetDOMObject(m_impl.get());
 }
 
-Value DOMTreeWalker::get(ExecState *exec, const Identifier &p) const
+bool DOMTreeWalker::getOwnProperty(ExecState *exec, const Identifier& p, Value& result) const
 {
-  return lookupGetValue<DOMTreeWalker,DOMObject>(exec,p,&DOMTreeWalkerTable,this);
+  return lookupGetOwnValue<DOMTreeWalker, DOMObject>(exec, p, &DOMTreeWalkerTable, this, result);
 }
 
 Value DOMTreeWalker::getValueProperty(ExecState *exec, int token) const
index 21ec584..6d37d42 100644 (file)
@@ -36,7 +36,7 @@ namespace KJS {
   public:
     DOMNodeIterator(ExecState *exec, DOM::NodeIteratorImpl *ni);
     ~DOMNodeIterator();
-    virtual Value get(ExecState *exec,const Identifier &p) const;
+    virtual bool getOwnProperty(ExecState *exec,const Identifier& p, Value& result) const;
     Value getValueProperty(ExecState *exec, int token) const;
     // no put - all read-only
     virtual const ClassInfo* classInfo() const { return &info; }
@@ -52,7 +52,7 @@ namespace KJS {
   class NodeFilterConstructor : public DOMObject {
   public:
     NodeFilterConstructor(ExecState *) { }
-    virtual Value get(ExecState *exec,const Identifier &p) const;
+    virtual bool getOwnProperty(ExecState *exec,const Identifier& p, Value& result) const;
     Value getValueProperty(ExecState *exec, int token) const;
     // no put - all read-only
     virtual const ClassInfo* classInfo() const { return &info; }
@@ -76,7 +76,7 @@ namespace KJS {
   public:
     DOMTreeWalker(ExecState *exec, DOM::TreeWalkerImpl *tw);
     ~DOMTreeWalker();
-    virtual Value get(ExecState *exec,const Identifier &p) const;
+    virtual bool getOwnProperty(ExecState *exec,const Identifier& p, Value& result) const;
     Value getValueProperty(ExecState *exec, int token) const;
     virtual void put(ExecState *exec, const Identifier &propertyName,
                         const Value& value, int attr = None);
index bfbb04b..169da00 100644 (file)
@@ -54,13 +54,17 @@ DOMAbstractView::~DOMAbstractView()
   ScriptInterpreter::forgetDOMObject(m_impl.get());
 }
 
-Value DOMAbstractView::get(ExecState *exec, const Identifier &p) const
+bool DOMAbstractView::getOwnProperty(ExecState *exec, const Identifier& p, Value& result) const
 {
-  if (p == "document")
-    return getDOMNode(exec, m_impl->document());
-  else if (p == "getComputedStyle")
-    return lookupOrCreateFunction<DOMAbstractViewFunc>(exec,p,this,DOMAbstractView::GetComputedStyle,2,DontDelete|Function);
-  return DOMObject::get(exec, p);
+    if (p == "document") {
+        result = getDOMNode(exec, m_impl->document());
+        return true;
+    } else if (p == "getComputedStyle") {
+        result = lookupOrCreateFunction<DOMAbstractViewFunc>(exec, p, this, DOMAbstractView::GetComputedStyle, 2, DontDelete|Function);
+        return true;
+    }
+
+    return DOMObject::getOwnProperty(exec, p, result);
 }
 
 Value DOMAbstractViewFunc::call(ExecState *exec, Object &thisObj, const List &args)
index b16891b..0f10f21 100644 (file)
@@ -33,7 +33,7 @@ namespace KJS {
   public:
     DOMAbstractView(ExecState *, DOM::AbstractViewImpl *av) : m_impl(av) { }
     ~DOMAbstractView();
-    virtual Value get(ExecState *exec,const Identifier &p) const;
+    virtual bool getOwnProperty(ExecState *exec,const Identifier& p, Value& result) const;
     // no put - all read-only
     virtual const ClassInfo* classInfo() const { return &info; }
     static const ClassInfo info;
index b1432a2..b19bd1f 100644 (file)
@@ -104,7 +104,7 @@ namespace KJS {
   public:
     History(ExecState *exec, KHTMLPart *p)
       : ObjectImp(exec->lexicalInterpreter()->builtinObjectPrototype()), part(p) { }
-    virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     Value getValueProperty(ExecState *exec, int token) const;
     virtual const ClassInfo* classInfo() const { return &info; }
     static const ClassInfo info;
@@ -118,7 +118,7 @@ namespace KJS {
   public:
     FrameArray(ExecState *exec, KHTMLPart *p)
       : ObjectImp(exec->lexicalInterpreter()->builtinObjectPrototype()), part(p) { }
-    virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     virtual UString toString(ExecState *exec) const;
   private:
     QGuardedPtr<KHTMLPart> part;
@@ -165,12 +165,9 @@ const ClassInfo Screen::info = { "Screen", 0, &ScreenTable, 0 };
 Screen::Screen(ExecState *exec)
   : ObjectImp(exec->lexicalInterpreter()->builtinObjectPrototype()) {}
 
-Value Screen::get(ExecState *exec, const Identifier &p) const
+bool Screen::getOwnProperty(ExecState *exec, const Identifier& p, Value& result) const
 {
-#ifdef KJS_VERBOSE
-  kdDebug(6070) << "Screen::get " << p.qstring() << endl;
-#endif
-  return lookupGetValue<Screen,ObjectImp>(exec,p,&ScreenTable,this);
+  return lookupGetOwnValue<Screen, ObjectImp>(exec, p, &ScreenTable, this, result);
 }
 
 Value Screen::getValueProperty(ExecState *exec, int token) const
@@ -347,7 +344,6 @@ Window::Window(KHTMLPart *p)
 
 Window::~Window()
 {
-  kdDebug(6070) << "Window::~Window this=" << this << " part=" << m_part << endl;
   delete winq;
 }
 
@@ -692,24 +688,27 @@ static ValueImp *showModalDialog(ExecState *exec, Window *openerWindow, const Li
     return returnValue;
 }
 
-Value Window::get(ExecState *exec, const Identifier &p) const
+bool Window::getOwnProperty(ExecState *exec, const Identifier& p, Value& result) const
 {
-#ifdef KJS_VERBOSE
-  kdDebug(6070) << "Window("<<this<<")::get " << p.qstring() << endl;
-#endif
-  if ( p == "closed" )
-    return Boolean(m_part.isNull());
+  if (p == "closed") {
+      result = Boolean(m_part.isNull());
+      return false;
+  }
 
   // we don't want any properties other than "closed" on a closed window
-  if (m_part.isNull())
-    return Undefined();
+  if (m_part.isNull()) {
+      result = Undefined();
+      return true;
+  }
 
   // Look for overrides first
   ValueImp * val = ObjectImp::getDirect(p);
   if (val) {
-    //kdDebug(6070) << "Window::get found dynamic property '" << p.ascii() << "'" << endl;
     if (isSafeScript(exec))
-      return Value(val);
+      result = Value(val);
+    else
+      result = Undefined();
+    return true;
   }
 
   // Check for child frames by name before built-in properties to
@@ -718,198 +717,244 @@ Value Window::get(ExecState *exec, const Identifier &p) const
   // are in Moz but not IE. Since we have some of these, we have to do
   // it the Moz way.
   KHTMLPart *childFrame = m_part->childFrameNamed(p.ustring().qstring());
-  if (childFrame) 
-    return retrieve(childFrame);
+  if (childFrame) {
+    result = retrieve(childFrame);
+    return true;
+  }
 
   const HashEntry* entry = Lookup::findEntry(&WindowTable, p);
-  if (entry)
-  {
-    //kdDebug(6070) << "token: " << entry->value << endl;
-    switch( entry->value ) {
+  if (entry) {
+    switch(entry->value) {
     case Crypto:
-      return Undefined(); // ###
+      result = Undefined(); // ###
+      return true;
     case DefaultStatus:
-      return String(UString(m_part->jsDefaultStatusBarText()));
+      result = String(UString(m_part->jsDefaultStatusBarText()));
+      return true;
     case Status:
-      return String(UString(m_part->jsStatusBarText()));
+      result = String(UString(m_part->jsStatusBarText()));
+      return true;
     case Document:
-      if (isSafeScript(exec))
-      {
+      if (isSafeScript(exec)) {
         if (!m_part->xmlDocImpl()) {
 #if APPLE_CHANGES
           KWQ(m_part)->createEmptyDocument();
 #endif
-          kdDebug(6070) << "Document.write: adding <HTML><BODY> to create document" << endl;
           m_part->begin();
           m_part->write("<HTML><BODY>");
           m_part->end();
         }
-        return getDOMNode(exec, m_part->xmlDocImpl());
-      }
-      else
-        return Undefined();
+        result = getDOMNode(exec, m_part->xmlDocImpl());
+      } else
+        result = Undefined();
+      return true;
     case Node:
-      return getNodeConstructor(exec);
+      result = getNodeConstructor(exec);
+      return true;
     case Range:
-      return getRangeConstructor(exec);
+      result = getRangeConstructor(exec);
+      return true;
     case NodeFilter:
-      return getNodeFilterConstructor(exec);
+      result = getNodeFilterConstructor(exec);
+      return true;
     case DOMException:
-      return getDOMExceptionConstructor(exec);
+      result = getDOMExceptionConstructor(exec);
+      return true;
     case CSSRule:
-      return getCSSRuleConstructor(exec);
+      result = getCSSRuleConstructor(exec);
+      return true;
     case EventCtor:
-      return getEventConstructor(exec);
+      result = getEventConstructor(exec);
+      return true;
     case Frames:
-      return Value(frames ? frames :
-                   (const_cast<Window*>(this)->frames = new FrameArray(exec,m_part)));
+      result = Value(frames ? frames :
+                     (const_cast<Window*>(this)->frames = new FrameArray(exec,m_part)));
+      return true;
     case _History:
-      return Value(history ? history :
-                   (const_cast<Window*>(this)->history = new History(exec,m_part)));
-
+      result = Value(history ? history :
+                     (const_cast<Window*>(this)->history = new History(exec,m_part)));
+      return true;
     case Event:
       if (m_evt)
-        return getDOMEvent(exec, m_evt);
-      else {
-#ifdef KJS_VERBOSE
-        kdWarning(6070) << "window(" << this << "," << m_part->name() << ").event, no event!" << endl;
-#endif
-        return Undefined();
-      }
+        result = getDOMEvent(exec, m_evt);
+      else
+        result = Undefined();
+      return true;
     case InnerHeight:
-      if (!m_part->view())
-        return Undefined();
-      return Number(m_part->view()->visibleHeight());
+      if (m_part->view())
+        result = Number(m_part->view()->visibleHeight());
+      else
+        result = Undefined();
+      return true;
     case InnerWidth:
-      if (!m_part->view())
-        return Undefined();
-      return Number(m_part->view()->visibleWidth());
+      if (m_part->view())
+        result = Number(m_part->view()->visibleWidth());
+      else
+        result = Undefined();
+      return true;
     case Length:
-      return Number(m_part->frames().count());
+      result = Number(m_part->frames().count());
+      return true;
     case _Location:
-      return Value(location());
+      result = Value(location());
+      return true;
     case Name:
-      return String(m_part->name());
+      result = String(m_part->name());
+      return true;
     case _Navigator:
     case ClientInformation: {
       // Store the navigator in the object so we get the same one each time.
       Navigator *n = new Navigator(exec, m_part);
       const_cast<Window *>(this)->putDirect("navigator", n, DontDelete|ReadOnly);
       const_cast<Window *>(this)->putDirect("clientInformation", n, DontDelete|ReadOnly);
-      return Value(n);
+      result = Value(n);
+      return true;
     }
 #ifdef Q_WS_QWS
     case _Konqueror:
-      return Value(new Konqueror(m_part));
+      result = Value(new Konqueror(m_part));
+      return true;
 #endif
     case Locationbar:
-      return Value(locationbar(exec));
+      result = Value(locationbar(exec));
+      return true;
     case Menubar:
-      return Value(menubar(exec));
+      result = Value(menubar(exec));
+      return true;
     case OffscreenBuffering:
-      return Boolean(true);
+      result = Boolean(true);
+      return true;
     case Opener:
-      if (!m_part->opener())
-        return Null();    // ### a null Window might be better, but == null
-      else                // doesn't work yet
-        return retrieve(m_part->opener());
+      if (m_part->opener())
+        result = retrieve(m_part->opener());
+      else
+        result = Null();
+      return true;
     case OuterHeight:
     case OuterWidth:
     {
-      if (!m_part->view())
-        return Number(0);
-      KWin::Info inf = KWin::info(m_part->view()->topLevelWidget()->winId());
-      return Number(entry->value == OuterHeight ?
-                    inf.geometry.height() : inf.geometry.width());
+      if (m_part->view()) {
+        KWin::Info inf = KWin::info(m_part->view()->topLevelWidget()->winId());
+        result = Number(entry->value == OuterHeight ?
+                        inf.geometry.height() : inf.geometry.width());
+      } else
+        result = Number(0);
+      return true;
     }
     case PageXOffset:
-      if (!m_part->view())
-        return Undefined();
-      updateLayout();
-      return Number(m_part->view()->contentsX());
+      if (m_part->view()) {
+        updateLayout();
+        result = Number(m_part->view()->contentsX());
+      } else
+        result = Undefined();
+      return true;
     case PageYOffset:
-      if (!m_part->view())
-        return Undefined();
-      updateLayout();
-      return Number(m_part->view()->contentsY());
+      if (m_part->view()) {
+        updateLayout();
+        result = Number(m_part->view()->contentsY());
+      } else
+        result = Undefined();
+      return true;
     case Parent:
-      return Value(retrieve(m_part->parentPart() ? m_part->parentPart() : (KHTMLPart*)m_part));
+      result = Value(retrieve(m_part->parentPart() ? m_part->parentPart() : (KHTMLPart*)m_part));
+      return true;
     case Personalbar:
-      return Value(personalbar(exec));
+      result = Value(personalbar(exec));
+      return true;
     case ScreenLeft:
     case ScreenX: {
-      if (!m_part->view())
-        return Undefined();
+      if (m_part->view()) {
 #if APPLE_CHANGES
-      // We want to use frameGeometry here instead of mapToGlobal because it goes through
-      // the windowFrame method of the WebKit's UI delegate. Also we don't want to try
-      // to do anything relative to the screen the window is on, so the code below is no
-      // good of us anyway.
-      return Number(m_part->view()->topLevelWidget()->frameGeometry().x());
+        // We want to use frameGeometry here instead of mapToGlobal because it goes through
+        // the windowFrame method of the WebKit's UI delegate. Also we don't want to try
+        // to do anything relative to the screen the window is on, so the code below is no
+        // good of us anyway.
+        result = Number(m_part->view()->topLevelWidget()->frameGeometry().x());
 #else
-      QRect sg = QApplication::desktop()->screenGeometry(QApplication::desktop()->screenNumber(m_part->view()));
-      return Number(m_part->view()->mapToGlobal(QPoint(0,0)).x() + sg.x());
+        QRect sg = QApplication::desktop()->screenGeometry(QApplication::desktop()->screenNumber(m_part->view()));
+        result = Number(m_part->view()->mapToGlobal(QPoint(0,0)).x() + sg.x());
 #endif
+      } else
+        result = Undefined();
+      return true;
     }
     case ScreenTop:
     case ScreenY: {
-      if (!m_part->view())
-        return Undefined();
+      if (m_part->view()) {
 #if APPLE_CHANGES
-      // See comment above in ScreenX.
-      return Number(m_part->view()->topLevelWidget()->frameGeometry().y());
+        // See comment above in ScreenX.
+        result = Number(m_part->view()->topLevelWidget()->frameGeometry().y());
 #else
-      QRect sg = QApplication::desktop()->screenGeometry(QApplication::desktop()->screenNumber(m_part->view()));
-      return Number(m_part->view()->mapToGlobal(QPoint(0,0)).y() + sg.y());
+        QRect sg = QApplication::desktop()->screenGeometry(QApplication::desktop()->screenNumber(m_part->view()));
+        result = Number(m_part->view()->mapToGlobal(QPoint(0,0)).y() + sg.y());
 #endif
+      } else 
+        result = Undefined();
+      return true;
     }
-    case ScrollX: {
-      if (!m_part->view())
-        return Undefined();
-      updateLayout();
-      return Number(m_part->view()->contentsX());
-    }
-    case ScrollY: {
-      if (!m_part->view())
-        return Undefined();
-      updateLayout();
-      return Number(m_part->view()->contentsY());
-    }
+    case ScrollX:
+      if (m_part->view()) {
+        updateLayout();
+        result = Number(m_part->view()->contentsX());
+      } else
+        result = Undefined();
+      return true;
+    case ScrollY:
+      if (m_part->view()) {
+        updateLayout();
+        result = Number(m_part->view()->contentsY());
+      } else
+        result = Undefined();
+      return true;
     case Scrollbars:
-      return Value(scrollbars(exec));
+      result = Value(scrollbars(exec));
+      return true;
     case Statusbar:
-      return Value(statusbar(exec));
+      result = Value(statusbar(exec));
+      return true;
     case Toolbar:
-      return Value(toolbar(exec));
+      result = Value(toolbar(exec));
+      return true;
     case Self:
     case _Window:
-      return Value(retrieve(m_part));
+      result = Value(retrieve(m_part));
+      return true;
     case Top: {
       KHTMLPart *p = m_part;
       while (p->parentPart())
         p = p->parentPart();
-      return Value(retrieve(p));
+      result = Value(retrieve(p));
+      return true;
     }
     case _Screen:
-      return Value(screen ? screen :
-                   (const_cast<Window*>(this)->screen = new Screen(exec)));
+      result = Value(screen ? screen :
+                     (const_cast<Window*>(this)->screen = new Screen(exec)));
+      return true;
     case Image:
-      return new ImageConstructorImp(exec, m_part->xmlDocImpl());
+      // FIXME: this property (and the few below) probably shouldn't create a new object every
+      // time
+      result = new ImageConstructorImp(exec, m_part->xmlDocImpl());
+      return true;
     case Option:
-      return new OptionConstructorImp(exec, m_part->xmlDocImpl());
+      result = new OptionConstructorImp(exec, m_part->xmlDocImpl());
+      return true;
     case XMLHttpRequest:
-      return new XMLHttpRequestConstructorImp(exec, m_part->xmlDocImpl());
+      result = new XMLHttpRequestConstructorImp(exec, m_part->xmlDocImpl());
+      return true;
     case XMLSerializer:
-      return new XMLSerializerConstructorImp(exec);
+      result = new XMLSerializerConstructorImp(exec);
+      return true;
     case DOMParser:
-      return new DOMParserConstructorImp(exec, m_part->xmlDocImpl());
+      result = new DOMParserConstructorImp(exec, m_part->xmlDocImpl());
+      return true;
     case Focus:
     case Blur:
     case Close:
-       return lookupOrCreateFunction<WindowFunc>(exec,p,this,entry->value,entry->params,entry->attr);
+      result = lookupOrCreateFunction<WindowFunc>(exec,p,this,entry->value,entry->params,entry->attr);
+      return true;
     case ShowModalDialog:
         if (!canShowModalDialog(this))
-            return Undefined();
+          return false;
         // fall through
     case Alert:
     case Confirm:
@@ -935,153 +980,185 @@ Value Window::get(ExecState *exec, const Identifier &p) const
     case ClearInterval:
     case GetSelection:
       if (isSafeScript(exec))
-        return lookupOrCreateFunction<WindowFunc>(exec,p,this,entry->value,entry->params,entry->attr);
+        result = lookupOrCreateFunction<WindowFunc>(exec, p, this, entry->value, entry->params, entry->attr);
       else
-        return Undefined();
+        result = Undefined();
+      return true;
     case Onabort:
       if (isSafeScript(exec))
-        return getListener(exec,DOM::EventImpl::ABORT_EVENT);
+        result = getListener(exec,DOM::EventImpl::ABORT_EVENT);
       else
-        return Undefined();
+        result = Undefined();
+      return true;
     case Onblur:
       if (isSafeScript(exec))
-        return getListener(exec,DOM::EventImpl::BLUR_EVENT);
+        result = getListener(exec,DOM::EventImpl::BLUR_EVENT);
       else
-        return Undefined();
+        result = Undefined();
+      return true;
     case Onchange:
       if (isSafeScript(exec))
-        return getListener(exec,DOM::EventImpl::CHANGE_EVENT);
+        result = getListener(exec,DOM::EventImpl::CHANGE_EVENT);
       else
-        return Undefined();
+        result = Undefined();
+      return true;
     case Onclick:
       if (isSafeScript(exec))
-        return getListener(exec,DOM::EventImpl::KHTML_CLICK_EVENT);
+        result = getListener(exec,DOM::EventImpl::KHTML_CLICK_EVENT);
       else
-        return Undefined();
+        result = Undefined();
+      return true;
     case Ondblclick:
       if (isSafeScript(exec))
-        return getListener(exec,DOM::EventImpl::KHTML_DBLCLICK_EVENT);
+        result = getListener(exec,DOM::EventImpl::KHTML_DBLCLICK_EVENT);
       else
-        return Undefined();
+        result = Undefined();
+      return true;
     case Ondragdrop:
       if (isSafeScript(exec))
-        return getListener(exec,DOM::EventImpl::KHTML_DRAGDROP_EVENT);
+        result = getListener(exec,DOM::EventImpl::KHTML_DRAGDROP_EVENT);
       else
-        return Undefined();
+        result = Undefined();
+      return true;
     case Onerror:
       if (isSafeScript(exec))
-        return getListener(exec,DOM::EventImpl::KHTML_ERROR_EVENT);
+        result = getListener(exec,DOM::EventImpl::KHTML_ERROR_EVENT);
       else
-        return Undefined();
+        result = Undefined();
+      return true;
     case Onfocus:
       if (isSafeScript(exec))
-        return getListener(exec,DOM::EventImpl::FOCUS_EVENT);
+        result = getListener(exec,DOM::EventImpl::FOCUS_EVENT);
       else
-        return Undefined();
+        result = Undefined();
+      return true;
     case Onkeydown:
       if (isSafeScript(exec))
-        return getListener(exec,DOM::EventImpl::KEYDOWN_EVENT);
+        result = getListener(exec,DOM::EventImpl::KEYDOWN_EVENT);
       else
-        return Undefined();
+        result = Undefined();
+      return true;
     case Onkeypress:
       if (isSafeScript(exec))
-        return getListener(exec,DOM::EventImpl::KEYPRESS_EVENT);
+        result = getListener(exec,DOM::EventImpl::KEYPRESS_EVENT);
       else
-        return Undefined();
+        result = Undefined();
+      return true;
     case Onkeyup:
       if (isSafeScript(exec))
-        return getListener(exec,DOM::EventImpl::KEYUP_EVENT);
+        result = getListener(exec,DOM::EventImpl::KEYUP_EVENT);
       else
-        return Undefined();
+        result = Undefined();
+      return true;
     case Onload:
       if (isSafeScript(exec))
-        return getListener(exec,DOM::EventImpl::LOAD_EVENT);
+        result = getListener(exec,DOM::EventImpl::LOAD_EVENT);
       else
-        return Undefined();
+        result = Undefined();
+      return true;
     case Onmousedown:
       if (isSafeScript(exec))
-        return getListener(exec,DOM::EventImpl::MOUSEDOWN_EVENT);
+        result = getListener(exec,DOM::EventImpl::MOUSEDOWN_EVENT);
       else
-        return Undefined();
+        result = Undefined();
+      return true;
     case Onmousemove:
       if (isSafeScript(exec))
-        return getListener(exec,DOM::EventImpl::MOUSEMOVE_EVENT);
+        result = getListener(exec,DOM::EventImpl::MOUSEMOVE_EVENT);
       else
-        return Undefined();
+        result = Undefined();
+      return true;
     case Onmouseout:
       if (isSafeScript(exec))
-        return getListener(exec,DOM::EventImpl::MOUSEOUT_EVENT);
+        result = getListener(exec,DOM::EventImpl::MOUSEOUT_EVENT);
       else
-        return Undefined();
+        result = Undefined();
+      return true;
     case Onmouseover:
       if (isSafeScript(exec))
-        return getListener(exec,DOM::EventImpl::MOUSEOVER_EVENT);
+        result = getListener(exec,DOM::EventImpl::MOUSEOVER_EVENT);
       else
-        return Undefined();
+        result = Undefined();
+      return true;
     case Onmouseup:
       if (isSafeScript(exec))
-        return getListener(exec,DOM::EventImpl::MOUSEUP_EVENT);
+        result = getListener(exec,DOM::EventImpl::MOUSEUP_EVENT);
       else
-        return Undefined();
+        result = Undefined();
+      return true;
     case OnWindowMouseWheel:
       if (isSafeScript(exec))
-        return getListener(exec, DOM::EventImpl::MOUSEWHEEL_EVENT);
+        result = getListener(exec, DOM::EventImpl::MOUSEWHEEL_EVENT);
       else
-        return Undefined();
+        result = Undefined();
+      return true;
     case Onmove:
       if (isSafeScript(exec))
-        return getListener(exec,DOM::EventImpl::KHTML_MOVE_EVENT);
+        result = getListener(exec,DOM::EventImpl::KHTML_MOVE_EVENT);
       else
-        return Undefined();
+        result = Undefined();
+      return true;
     case Onreset:
       if (isSafeScript(exec))
-        return getListener(exec,DOM::EventImpl::RESET_EVENT);
+        result = getListener(exec,DOM::EventImpl::RESET_EVENT);
       else
-        return Undefined();
+        result = Undefined();
+      return true;
     case Onresize:
       if (isSafeScript(exec))
-        return getListener(exec,DOM::EventImpl::RESIZE_EVENT);
+        result = getListener(exec,DOM::EventImpl::RESIZE_EVENT);
       else
-        return Undefined();
+        result = Undefined();
+      return true;
     case Onscroll:
-        if (isSafeScript(exec))
-            return getListener(exec,DOM::EventImpl::SCROLL_EVENT);
-        else
-            return Undefined();
+      if (isSafeScript(exec))
+        result = getListener(exec,DOM::EventImpl::SCROLL_EVENT);
+      else
+        result = Undefined();
+      return true;
 #if APPLE_CHANGES
     case Onsearch:
-        if (isSafeScript(exec))
-            return getListener(exec,DOM::EventImpl::SEARCH_EVENT);
-        else
-            return Undefined();
+      if (isSafeScript(exec))
+        result = getListener(exec,DOM::EventImpl::SEARCH_EVENT);
+      else
+        result = Undefined();
+      return true;
 #endif
     case Onselect:
       if (isSafeScript(exec))
-        return getListener(exec,DOM::EventImpl::SELECT_EVENT);
+        result = getListener(exec,DOM::EventImpl::SELECT_EVENT);
       else
-        return Undefined();
+        result = Undefined();
+      return true;
     case Onsubmit:
       if (isSafeScript(exec))
-        return getListener(exec,DOM::EventImpl::SUBMIT_EVENT);
+        result = getListener(exec,DOM::EventImpl::SUBMIT_EVENT);
       else
-        return Undefined();
+        result = Undefined();
+      return true;
     case Onunload:
       if (isSafeScript(exec))
-        return getListener(exec,DOM::EventImpl::UNLOAD_EVENT);
+        result = getListener(exec,DOM::EventImpl::UNLOAD_EVENT);
       else
-        return Undefined();
+        result = Undefined();
+      return true;
     case FrameElement:
       if (DocumentImpl *doc = m_part->xmlDocImpl())
         if (ElementImpl *fe = doc->ownerElement())
-          if (checkNodeSecurity(exec, fe))
-            return getDOMNode(exec, fe);
-      return Undefined();
+          if (checkNodeSecurity(exec, fe)) {
+            result = getDOMNode(exec, fe);
+            return true;
+          }
+      result = Undefined();
+      return true;
     }
   }
 
-  KHTMLPart *kp = m_part->findFrame( p.qstring() );
-  if (kp)
-    return Value(retrieve(kp));
+  KHTMLPart *kp = m_part->findFrame(p.qstring());
+  if (kp) {
+    result = Value(retrieve(kp));
+    return true;
+  }
 
   // allow window[1] or parent[1] etc. (#56983)
   bool ok;
@@ -1093,7 +1170,8 @@ Value Window::get(ExecState *exec, const Identifier &p) const
       KParts::ReadOnlyPart* frame = frames.at(i);
       if (frame && frame->inherits("KHTMLPart")) {
        KHTMLPart *khtml = static_cast<KHTMLPart*>(frame);
-       return Window::retrieve(khtml);
+       result = Window::retrieve(khtml);
+        return true;
       }
     }
   }
@@ -1102,26 +1180,22 @@ Value Window::get(ExecState *exec, const Identifier &p) const
   DocumentImpl *doc = m_part->xmlDocImpl();
   if (isSafeScript(exec) && doc && doc->isHTMLDocument()) {
     DOMString name = p.string();
-    if (static_cast<HTMLDocumentImpl *>(doc)->hasNamedItem(name) ||
-        doc->getElementById(name)) {
+    if (static_cast<HTMLDocumentImpl *>(doc)->hasNamedItem(name) || doc->getElementById(name)) {
       SharedPtr<DOM::HTMLCollectionImpl> collection = doc->windowNamedItems(name);
       if (collection->length() == 1)
-        return getDOMNode(exec, collection->firstItem());
+        result = getDOMNode(exec, collection->firstItem());
       else 
-        return getHTMLCollection(exec, collection.get());
+        result = getHTMLCollection(exec, collection.get());
+      return true;
     }
   }
 
-  // This isn't necessarily a bug. Some code uses if(!window.blah) window.blah=1
-  // But it can also mean something isn't loaded or implemented, hence the WARNING to help grepping.
-#ifdef KJS_VERBOSE
-  kdDebug(6070) << "WARNING: Window::get property not found: " << p.qstring() << endl;
-#endif
-
-  if (isSafeScript(exec))
-    return ObjectImp::get(exec, p);
+  if (!isSafeScript(exec)) {
+    result = Undefined();
+    return true;
+  }
 
-  return Undefined();
+  return ObjectImp::getOwnProperty(exec, p, result);
 }
 
 bool Window::hasOwnProperty(ExecState *exec, const Identifier &p) const
@@ -1167,9 +1241,6 @@ void Window::put(ExecState* exec, const Identifier &propertyName, const Value &v
   const HashEntry* entry = Lookup::findEntry(&WindowTable, propertyName);
   if (entry)
   {
-#ifdef KJS_VERBOSE
-    kdDebug(6070) << "Window("<<this<<")::put " << propertyName.qstring() << endl;
-#endif
     switch( entry->value ) {
     case Status: {
       String s = value.toString(exec);
@@ -1317,7 +1388,6 @@ void Window::put(ExecState* exec, const Identifier &propertyName, const Value &v
     }
   }
   if (isSafeScript(exec)) {
-    //kdDebug(6070) << "Window("<<this<<")::put storing " << propertyName.qstring() << endl;
     ObjectImp::put(exec, propertyName, value, attr);
   }
 }
@@ -2178,11 +2248,6 @@ void ScheduledAction::execute(Window *window)
   interpreter->setProcessingTimerCallback(false);
 }
 
-ScheduledAction::~ScheduledAction()
-{
-  //kdDebug(6070) << "ScheduledAction::~ScheduledAction " << this << endl;
-}
-
 ////////////////////// WindowQObject ////////////////////////
 
 WindowQObject::WindowQObject(Window *w)
@@ -2314,24 +2379,23 @@ bool WindowQObject::hasTimeouts()
 }
 #endif
 
-Value FrameArray::get(ExecState *exec, const Identifier &p) const
+bool FrameArray::getOwnProperty(ExecState *exec, const Identifier& p, Value& result) const
 {
-#ifdef KJS_VERBOSE
-  kdDebug(6070) << "FrameArray::get " << p.qstring() << " part=" << (void*)part << endl;
-#endif
   if (part.isNull())
     return Undefined();
 
   QPtrList<KParts::ReadOnlyPart> frames = part->frames();
   unsigned int len = frames.count();
-  if (p == lengthPropertyName)
-    return Number(len);
-  else if (p== "location") // non-standard property, but works in NS and IE
-  {
-    Object obj = Object::dynamicCast( Window::retrieve( part ) );
-    if ( !obj.isNull() )
-      return obj.get( exec, "location" );
-    return Undefined();
+  if (p == lengthPropertyName) {
+    result = Number(len);
+    return true;
+  } else if (p== "location") {
+    // non-standard property, but works in NS and IE
+    Object obj = Object::dynamicCast(Window::retrieve(part));
+    if (!obj.isNull()) {
+      result = obj.get(exec, "location");
+      return true;
+    }
   }
 
   // check for the name or number
@@ -2343,15 +2407,13 @@ Value FrameArray::get(ExecState *exec, const Identifier &p) const
       frame = frames.at(i);
   }
 
-  // we are potentially fetching a reference to a another Window object here.
-  // i.e. we may be accessing objects from another interpreter instance.
-  // Therefore we have to be a bit careful with memory managment.
   if (frame && frame->inherits("KHTMLPart")) {
     KHTMLPart *khtml = static_cast<KHTMLPart*>(frame);
-    return Window::retrieve(khtml);
+    result = Window::retrieve(khtml);
+    return true;
   }
 
-  return ObjectImp::get(exec, p);
+  return ObjectImp::getOwnProperty(exec, p, result);
 }
 
 UString FrameArray::toString(ExecState *) const
@@ -2382,84 +2444,74 @@ const ClassInfo Location::info = { "Location", 0, 0, 0 };
 IMPLEMENT_PROTOFUNC(LocationFunc)
 Location::Location(KHTMLPart *p) : m_part(p)
 {
-  //kdDebug(6070) << "Location::Location " << this << " m_part=" << (void*)m_part << endl;
 }
 
-Location::~Location()
+bool Location::getOwnProperty(ExecState *exec, const Identifier& p, Value& result) const
 {
-  //kdDebug(6070) << "Location::~Location " << this << " m_part=" << (void*)m_part << endl;
-}
-
-Value Location::get(ExecState *exec, const Identifier &p) const
-{
-#ifdef KJS_VERBOSE
-  kdDebug(6070) << "Location::get " << p.qstring() << " m_part=" << (void*)m_part << endl;
-#endif
-
   if (m_part.isNull())
-    return Undefined();
+    return false;
   
   const Window* window = Window::retrieveWindow(m_part);
-  if (!window || !window->isSafeScript(exec))
-      return Undefined();
+  if (!window || !window->isSafeScript(exec)) {
+      result = Undefined();
+      return true;
+  }
 
   KURL url = m_part->url();
   const HashEntry *entry = Lookup::findEntry(&LocationTable, p);
-  if (entry)
+  if (entry) {
     switch (entry->value) {
     case Hash:
-      return String( url.ref().isNull() ? QString("") : "#" + url.ref() );
+      result = String(url.ref().isNull() ? QString("") : "#" + url.ref());
+      return true;
     case Host: {
-      UString str = url.host();
-      if (url.port())
-        str += ":" + QString::number((int)url.port());
-      return String(str);
       // Note: this is the IE spec. The NS spec swaps the two, it says
       // "The hostname property is the concatenation of the host and port properties, separated by a colon."
       // Bleh.
+      UString str = url.host();
+      if (url.port())
+        str += ":" + QString::number((int)url.port());
+      result = String(str);
+      return true;
     }
     case Hostname:
-      return String( url.host() );
+      result = String(url.host());
+      return true;
     case Href:
       if (!url.hasPath())
-        return String( url.prettyURL()+"/" );
+        result = String(url.prettyURL() + "/");
       else
-        return String( url.prettyURL() );
+        result = String(url.prettyURL());
+      return true;
     case Pathname:
-      return String( url.path().isEmpty() ? QString("/") : url.path() );
+      result = String(url.path().isEmpty() ? QString("/") : url.path());
+      return true;
     case Port:
-      return String( url.port() ? QString::number((int)url.port()) : QString::fromLatin1("") );
+      result = String(url.port() ? QString::number((int)url.port()) : QString::fromLatin1(""));
+      return true;
     case Protocol:
-      return String( url.protocol()+":" );
+      result = String(url.protocol()+":");
+      return true;
     case Search:
-      return String( url.query() );
-    case EqualEqual: // [[==]]
-      return String(toString(exec));
+      result = String(url.query());
+      return true;
     case ToString:
-      return lookupOrCreateFunction<LocationFunc>(exec,p,this,entry->value,entry->params,entry->attr);
-    }
-  // Look for overrides
-  ValueImp * val = ObjectImp::getDirect(p);
-  if (val)
-    return Value(val);
-  if (entry)
-    switch (entry->value) {
+      result = String(toString(exec));
+      return true;
     case Replace:
-      return lookupOrCreateFunction<LocationFunc>(exec,p,this,entry->value,entry->params,entry->attr);
     case Reload:
-      return lookupOrCreateFunction<LocationFunc>(exec,p,this,entry->value,entry->params,entry->attr);
     case Assign:
-      return lookupOrCreateFunction<LocationFunc>(exec,p,this,entry->value,entry->params,entry->attr);
+    case EqualEqual: // [[==]]
+      result = lookupOrCreateFunction<LocationFunc>(exec, p, this, entry->value, entry->params, entry->attr);
+      return true;
     }
+  }
 
-  return Undefined();
+  return ObjectImp::getOwnProperty(exec, p, result);
 }
 
 void Location::put(ExecState *exec, const Identifier &p, const Value &v, int attr)
 {
-#ifdef KJS_VERBOSE
-  kdDebug(6070) << "Location::put " << p.qstring() << " m_part=" << (void*)m_part << endl;
-#endif
   if (m_part.isNull())
     return;
 
@@ -2627,85 +2679,81 @@ const ClassInfo Selection::info = { "Selection", 0, 0, 0 };
 IMPLEMENT_PROTOFUNC(SelectionFunc)
 Selection::Selection(KHTMLPart *p) : m_part(p)
 {
-  //kdDebug(6070) << "Selection::Selection " << this << " m_part=" << (void*)m_part << endl;
 }
 
-Selection::~Selection()
+bool Selection::getOwnProperty(ExecState *exec, const Identifier& p, Value& result) const
 {
-  //kdDebug(6070) << "Selection::~Selection " << this << " m_part=" << (void*)m_part << endl;
-}
-
-Value Selection::get(ExecState *exec, const Identifier &p) const
-{
-#ifdef KJS_VERBOSE
-  kdDebug(6070) << "Selection::get " << p.qstring() << " m_part=" << (void*)m_part << endl;
-#endif
-
   if (m_part.isNull())
-    return Undefined();
+    return false;
   
   const Window* window = Window::retrieveWindow(m_part);
-  if (!window || !window->isSafeScript(exec))
-      return Undefined();
+  if (!window || !window->isSafeScript(exec)) {
+      result = Undefined();
+      return true;
+  }
 
   DocumentImpl *docimpl = m_part->xmlDocImpl();
   if (docimpl)
     docimpl->updateLayoutIgnorePendingStylesheets();
 
+  // FIXME: should use lookupGetOwnProperty here...
   KURL url = m_part->url();
   const HashEntry *entry = Lookup::findEntry(&SelectionTable, p);
   if (entry)
     switch (entry->value) {
         case AnchorNode:
         case BaseNode:
-            return getDOMNode(exec, m_part->selection().base().node());
+            result = getDOMNode(exec, m_part->selection().base().node());
+            return true;
         case AnchorOffset:
         case BaseOffset:
-            return Number(m_part->selection().base().offset());
+             result = Number(m_part->selection().base().offset());
+             return true;
         case FocusNode:
         case ExtentNode:
-            return getDOMNode(exec, m_part->selection().extent().node());
+             result = getDOMNode(exec, m_part->selection().extent().node());
+             return true;
         case FocusOffset:
         case ExtentOffset:
-            return Number(m_part->selection().extent().offset());
+             result = Number(m_part->selection().extent().offset());
+             return true;
         case IsCollapsed:
-            return Boolean(!m_part->selection().isRange());
+             result = Boolean(!m_part->selection().isRange());
+             return true;
         case _Type: {
             switch (m_part->selection().state()) {
-                case khtml::Selection::NONE:
-                    return String("None");
-                case khtml::Selection::CARET:
-                    return String("Caret");
-                case khtml::Selection::RANGE:
-                    return String("Range");
+            case khtml::Selection::NONE:
+                result = String("None");
+                break;
+            case khtml::Selection::CARET:
+                result = String("Caret");
+                break;
+            case khtml::Selection::RANGE:
+                result = String("Range");
+                break;
+            default:
+                assert(0);
             }
+            return true;
         }
         case EqualEqual:
-            return String(toString(exec));
+            result = lookupOrCreateFunction<SelectionFunc>(exec, p, this, entry->value, entry->params, entry->attr);
+            return true;
         case ToString:
-          return lookupOrCreateFunction<SelectionFunc>(exec,p,this,entry->value,entry->params,entry->attr);
+            result = String(toString(exec));
+            return true;
+        case Collapse:
+        case CollapseToEnd:
+        case CollapseToStart:
+        case Empty:
+        case SetBaseAndExtent:
+        case SetPosition:
+        case Modify:
+            result = lookupOrCreateFunction<SelectionFunc>(exec,p,this,entry->value,entry->params,entry->attr);
+            return true;
     }
-    // Look for overrides
-    ValueImp * val = ObjectImp::getDirect(p);
-    if (val)
-        return Value(val);
-    if (entry)
-        switch (entry->value) {
-            case Collapse:
-            case CollapseToEnd:
-            case CollapseToStart:
-            case Empty:
-            case SetBaseAndExtent:
-            case SetPosition:
-            case Modify:
-                return lookupOrCreateFunction<SelectionFunc>(exec,p,this,entry->value,entry->params,entry->attr);
-        }
 
-    return Undefined();
-}
-
-void Selection::put(ExecState *exec, const Identifier &p, const Value &v, int attr)
-{
+    return ObjectImp::getOwnProperty(exec, p, result);
 }
 
 Value Selection::toPrimitive(ExecState *exec, Type) const
@@ -2810,52 +2858,42 @@ BarInfo::BarInfo(ExecState *exec, KHTMLPart *p, Type barType)
 {
 }
 
-BarInfo::~BarInfo()
-{
-}
-
-Value BarInfo::get(ExecState *exec, const Identifier &p) const
+bool BarInfo::getOwnProperty(ExecState *exec, const Identifier& p, Value& result) const
 {
   if (m_part.isNull())
-    return Undefined();
+    return false;
   
   const HashEntry *entry = Lookup::findEntry(&BarInfoTable, p);
   if (entry && entry->value == Visible) {
     switch (m_type) {
-    case Locationbar:
 #if APPLE_CHANGES
-      return Boolean(KWQ(m_part)->locationbarVisible());
-#endif
+    case Locationbar:
+      result = Boolean(KWQ(m_part)->locationbarVisible());
+      break;
     case Menubar: 
-#if APPLE_CHANGES
-      return Boolean(KWQ(m_part)->locationbarVisible());
-#endif
+      result = Boolean(KWQ(m_part)->locationbarVisible());
+      break;
     case Personalbar:
-#if APPLE_CHANGES
-      return Boolean(KWQ(m_part)->personalbarVisible());
-#endif
+      result = Boolean(KWQ(m_part)->personalbarVisible());
+      break;
     case Scrollbars: 
-#if APPLE_CHANGES
-      return Boolean(KWQ(m_part)->scrollbarsVisible());
-#endif
+      result = Boolean(KWQ(m_part)->scrollbarsVisible());
+      break;
     case Statusbar:
-#if APPLE_CHANGES
-      return Boolean(KWQ(m_part)->statusbarVisible());
-#endif
+      result =  Boolean(KWQ(m_part)->statusbarVisible());
+      break;
     case Toolbar:
-#if APPLE_CHANGES
-      return Boolean(KWQ(m_part)->toolbarVisible());
+      result = Boolean(KWQ(m_part)->toolbarVisible());
+      break;
 #endif
     default:
-      return Boolean(false);
+      result = Boolean(false);
     }
+    
+    return true;
   }
   
-  return Undefined();
-}
-
-void BarInfo::put(ExecState *exec, const Identifier &p, const Value &v, int attr)
-{
+  return ObjectImp::getOwnProperty(exec, p, result);
 }
 
 ////////////////////// History Object ////////////////////////
@@ -2871,9 +2909,9 @@ const ClassInfo History::info = { "History", 0, 0, 0 };
 */
 IMPLEMENT_PROTOFUNC(HistoryFunc)
 
-Value History::get(ExecState *exec, const Identifier &p) const
+bool History::getOwnProperty(ExecState *exec, const Identifier &p, Value& result) const
 {
-  return lookupGet<HistoryFunc,History,ObjectImp>(exec,p,&HistoryTable,this);
+  return lookupGetOwnProperty<HistoryFunc, History, ObjectImp>(exec, p, &HistoryTable, this, result);
 }
 
 Value History::getValueProperty(ExecState *, int token) const
index 4e7883e..c65af84 100644 (file)
@@ -57,7 +57,7 @@ namespace KJS {
       Height, Width, ColorDepth, PixelDepth, AvailLeft, AvailTop, AvailHeight,
       AvailWidth
     };
-    virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     Value getValueProperty(ExecState *exec, int token) const;
   private:
     KHTMLView *view;
@@ -92,7 +92,7 @@ namespace KJS {
     static Window *retrieveActive(ExecState *exec);
     QGuardedPtr<KHTMLPart> part() const { return m_part; }
     virtual void mark();
-    virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     virtual bool hasOwnProperty(ExecState *exec, const Identifier &propertyName) const;
     virtual void put(ExecState *exec, const Identifier &propertyName, const Value &value, int attr = None);
     virtual bool toBoolean(ExecState *exec) const;
@@ -182,7 +182,6 @@ namespace KJS {
   public:
     ScheduledAction(Object _func, List _args, bool _singleShot);
     ScheduledAction(const QString &_code, bool _singleShot);
-    ~ScheduledAction();
     void execute(Window *window);
 
     ProtectedObject func;
@@ -220,8 +219,7 @@ namespace KJS {
 
   class Location : public ObjectImp {
   public:
-    ~Location();
-    virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     virtual void put(ExecState *exec, const Identifier &propertyName, const Value &value, int attr = None);
     virtual Value toPrimitive(ExecState *exec, Type preferred) const;
     virtual UString toString(ExecState *exec) const;
@@ -238,9 +236,7 @@ namespace KJS {
 
   class Selection : public ObjectImp {
   public:
-    ~Selection();
-    virtual Value get(ExecState *exec, const Identifier &propertyName) const;
-    virtual void put(ExecState *exec, const Identifier &propertyName, const Value &value, int attr = None);
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     virtual Value toPrimitive(ExecState *exec, Type preferred) const;
     virtual UString toString(ExecState *exec) const;
     enum { AnchorNode, AnchorOffset, FocusNode, FocusOffset, BaseNode, BaseOffset, ExtentNode, ExtentOffset, 
@@ -257,9 +253,7 @@ namespace KJS {
 
   class BarInfo : public ObjectImp {
   public:
-    ~BarInfo();
-    virtual Value get(ExecState *exec, const Identifier &propertyName) const;
-    virtual void put(ExecState *exec, const Identifier &propertyName, const Value &value, int attr = None);
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     enum { Visible };
     enum Type { Locationbar, Menubar, Personalbar, Scrollbars, Statusbar, Toolbar };
     KHTMLPart *part() const { return m_part; }
@@ -277,7 +271,7 @@ namespace KJS {
     friend class KonquerorFunc;
   public:
     Konqueror(KHTMLPart *p) : part(p) { }
-    virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     virtual bool hasOwnProperty(ExecState *exec, const Identifier &p) const;
     virtual UString toString(ExecState *exec) const;
     virtual const ClassInfo* classInfo() const { return &info; }
index 085fc6f..dda633a 100644 (file)
@@ -127,9 +127,9 @@ const ClassInfo XMLHttpRequest::info = { "XMLHttpRequest", 0, &XMLHttpRequestTab
 @end
 */
 
-Value XMLHttpRequest::get(ExecState *exec, const Identifier &propertyName) const
+bool XMLHttpRequest::getOwnProperty(ExecState *exec, const Identifier &propertyName, Value& result) const
 {
-  return lookupGetValue<XMLHttpRequest,DOMObject>(exec, propertyName, &XMLHttpRequestTable, this);
+  return lookupGetOwnValue<XMLHttpRequest,DOMObject>(exec, propertyName, &XMLHttpRequestTable, this, result);
 }
 
 Value XMLHttpRequest::getValueProperty(ExecState *exec, int token) const
index b2d751b..457ee75 100644 (file)
@@ -65,7 +65,7 @@ namespace KJS {
   public:
     XMLHttpRequest(ExecState *, DOM::DocumentImpl *d);
     ~XMLHttpRequest();
-    virtual Value get(ExecState *exec, const Identifier &propertyName) const;
+    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     Value getValueProperty(ExecState *exec, int token) const;
     virtual void put(ExecState *exec, const Identifier &propertyName, const Value& value, int attr = None);
     void putValueProperty(ExecState *exec, int token, const Value& value, int /*attr*/);