Changeset 9889 in webkit for trunk/JavaScriptCore/kjs


Ignore:
Timestamp:
Jul 25, 2005, 3:17:20 PM (20 years ago)
Author:
mjs
Message:

JavaScriptCore:

Reviewed by Darin.

  • 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.

  • 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:
Location:
trunk/JavaScriptCore/kjs
Files:
20 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/kjs/array_instance.h

    r9768 r9889  
    3434    ~ArrayInstanceImp();
    3535
    36     virtual Value get(ExecState *exec, const Identifier &propertyName) const;
    37     virtual Value get(ExecState *exec, unsigned propertyName) const;
     36    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     37    virtual bool getOwnProperty(ExecState *exec, unsigned index, Value& result) const;
    3838    virtual void put(ExecState *exec, const Identifier &propertyName, const Value &value, int attr = None);
    3939    virtual void put(ExecState *exec, unsigned propertyName, const Value &value, int attr = None);
  • trunk/JavaScriptCore/kjs/array_object.cpp

    r9842 r9889  
    7171}
    7272
    73 Value ArrayInstanceImp::get(ExecState *exec, const Identifier &propertyName) const
    74 {
    75   if (propertyName == lengthPropertyName)
    76     return Number(length);
     73bool ArrayInstanceImp::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
     74{
     75  if (propertyName == lengthPropertyName) {
     76    result = Number(length);
     77    return true;
     78  }
    7779
    7880  bool ok;
     
    8082  if (ok) {
    8183    if (index >= length)
    82       return Undefined();
     84      return false;
    8385    if (index < storageLength) {
    8486      ValueImp *v = storage[index];
    85       return v ? Value(v) : Undefined();
    86     }
    87   }
    88 
    89   return ObjectImp::get(exec, propertyName);
    90 }
    91 
    92 Value ArrayInstanceImp::get(ExecState *exec, unsigned index) const
     87      if (!v || v == UndefinedImp::staticUndefined)
     88        return false;
     89
     90      result = Value(v);
     91      return true;
     92    }
     93  }
     94
     95  return ObjectImp::getOwnProperty(exec, propertyName, result);
     96}
     97
     98bool ArrayInstanceImp::getOwnProperty(ExecState *exec, unsigned index, Value& result) const
    9399{
    94100  if (index >= length)
    95     return Undefined();
     101    return false;
    96102  if (index < storageLength) {
    97103    ValueImp *v = storage[index];
    98     return v ? Value(v) : Undefined();
    99   }
    100  
    101   return ObjectImp::get(exec, Identifier::from(index));
     104    if (!v || v == UndefinedImp::staticUndefined)
     105      return false;
     106
     107    result = Value(v);
     108    return true;
     109  }
     110 
     111  return ObjectImp::getOwnProperty(exec, Identifier::from(index), result);
    102112}
    103113
     
    419429}
    420430
    421 Value ArrayPrototypeImp::get(ExecState *exec, const Identifier &propertyName) const
    422 {
    423   //fprintf( stderr, "ArrayPrototypeImp::get(%s)\n", propertyName.ascii() );
    424   return lookupGetFunction<ArrayProtoFuncImp, ArrayInstanceImp>( exec, propertyName, &arrayTable, this );
     431bool ArrayPrototypeImp::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
     432{
     433  return lookupGetOwnFunction<ArrayProtoFuncImp, ArrayInstanceImp>(exec, propertyName, &arrayTable, this, result);
    425434}
    426435
     
    445454{
    446455  unsigned int length = thisObj.get(exec,lengthPropertyName).toUInt32(exec);
     456  ObjectImp *thisImp = thisObj.imp();
    447457
    448458  Value result;
     
    502512        length = curObj.get(exec,lengthPropertyName).toUInt32(exec);
    503513        while (k < length) {
    504           if (curObj.hasProperty(exec,k))
    505             arr.put(exec, n, curObj.get(exec, k));
     514          Value v;
     515          if (curObj.imp()->getProperty(exec, k, v))
     516            arr.put(exec, n, v);
    506517          n++;
    507518          k++;
     
    545556    for (unsigned int k = 0; k < middle; k++) {
    546557      unsigned lk1 = length - k - 1;
    547       Value obj = thisObj.get(exec,k);
    548       Value obj2 = thisObj.get(exec,lk1);
    549       if (thisObj.hasProperty(exec,lk1)) {
    550         if (thisObj.hasProperty(exec,k)) {
    551           thisObj.put(exec, k, obj2);
    552           thisObj.put(exec, lk1, obj);
    553         } else {
    554           thisObj.put(exec, k, obj2);
    555           thisObj.deleteProperty(exec, lk1);
    556         }
    557       } else {
    558         if (thisObj.hasProperty(exec, k)) {
    559           thisObj.deleteProperty(exec, k);
    560           thisObj.put(exec, lk1, obj);
    561         } else {
    562           // why delete something that's not there ? Strange.
    563           thisObj.deleteProperty(exec, k);
    564           thisObj.deleteProperty(exec, lk1);
    565         }
    566       }
     558      Value obj;
     559      Value obj2;
     560      bool has2 = thisImp->getProperty(exec, lk1, obj2);
     561      bool has1 = thisImp->getProperty(exec, k, obj);
     562
     563      if (has2)
     564        thisObj.put(exec, k, obj2);
     565      else
     566        thisObj.deleteProperty(exec, k);
     567
     568      if (has1)
     569        thisObj.put(exec, lk1, obj);
     570      else
     571        thisObj.deleteProperty(exec, lk1);
    567572    }
    568573    result = thisObj;
     
    576581      result = thisObj.get(exec, 0);
    577582      for(unsigned int k = 1; k < length; k++) {
    578         if (thisObj.hasProperty(exec, k)) {
    579           Value obj = thisObj.get(exec, k);
     583        Value obj;
     584        if (thisImp->getProperty(exec, k, obj))
    580585          thisObj.put(exec, k-1, obj);
    581         } else
     586        else
    582587          thisObj.deleteProperty(exec, k-1);
    583588      }
     
    623628    int e = static_cast<int>(end);
    624629    for(int k = b; k < e; k++, n++) {
    625       if (thisObj.hasProperty(exec, k)) {
    626         Value obj = thisObj.get(exec, k);
     630      Value obj;
     631      if (thisImp->getProperty(exec, k, obj))
    627632        resObj.put(exec, n, obj);
    628       }
    629633    }
    630634    resObj.put(exec, lengthPropertyName, Number(n), DontEnum | DontDelete);
     
    646650      }
    647651   
    648     if (thisObj.imp()->classInfo() == &ArrayInstanceImp::info) {
     652    if (thisImp->classInfo() == &ArrayInstanceImp::info) {
    649653      if (useSortFunction)
    650         ((ArrayInstanceImp *)thisObj.imp())->sort(exec, sortFunction);
     654        ((ArrayInstanceImp *)thisImp)->sort(exec, sortFunction);
    651655      else
    652         ((ArrayInstanceImp *)thisObj.imp())->sort(exec);
     656        ((ArrayInstanceImp *)thisImp)->sort(exec);
    653657      result = thisObj;
    654658      break;
     
    719723    //printf( "Splicing from %d, deleteCount=%d \n", begin, deleteCount );
    720724    for(unsigned int k = 0; k < deleteCount; k++) {
    721       if (thisObj.hasProperty(exec,k+begin)) {
    722         Value obj = thisObj.get(exec, k+begin);
     725      Value obj;
     726      if (thisImp->getProperty(exec, k+begin, obj))
    723727        resObj.put(exec, k, obj);
    724       }
    725728    }
    726729    resObj.put(exec, lengthPropertyName, Number(deleteCount), DontEnum | DontDelete);
     
    733736        for ( unsigned int k = begin; k < length - deleteCount; ++k )
    734737        {
    735           if (thisObj.hasProperty(exec,k+deleteCount)) {
    736             Value obj = thisObj.get(exec, k+deleteCount);
     738          Value obj;
     739          if (thisImp->getProperty(exec, k+deleteCount, obj))
    737740            thisObj.put(exec, k+additionalArgs, obj);
    738           }
    739741          else
    740742            thisObj.deleteProperty(exec, k+additionalArgs);
     
    747749        for ( unsigned int k = length - deleteCount; (int)k > begin; --k )
    748750        {
    749           if (thisObj.hasProperty(exec,k+deleteCount-1)) {
    750             Value obj = thisObj.get(exec, k+deleteCount-1);
    751             thisObj.put(exec, k+additionalArgs-1, obj);
    752           }
     751          Value obj;
     752          if (thisImp->getProperty(exec, k + deleteCount - 1, obj))
     753            thisObj.put(exec, k + additionalArgs - 1, obj);
    753754          else
    754755            thisObj.deleteProperty(exec, k+additionalArgs-1);
     
    767768    for ( unsigned int k = length; k > 0; --k )
    768769    {
    769       if (thisObj.hasProperty(exec,k-1)) {
    770         Value obj = thisObj.get(exec, k-1);
     770      Value obj;
     771      if (thisImp->getProperty(exec, k - 1, obj))
    771772        thisObj.put(exec, k+nrArgs-1, obj);
    772       } else {
     773      else
    773774        thisObj.deleteProperty(exec, k+nrArgs-1);
    774       }
    775775    }
    776776    for ( unsigned int k = 0; k < nrArgs; ++k )
  • trunk/JavaScriptCore/kjs/array_object.h

    r9768 r9889  
    3232    ArrayPrototypeImp(ExecState *exec,
    3333                      ObjectPrototypeImp *objProto);
    34     Value get(ExecState *exec, const Identifier &p) const;
     34    bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
    3535    virtual const ClassInfo *classInfo() const { return &info; }
    3636    static const ClassInfo info;
  • trunk/JavaScriptCore/kjs/date_object.cpp

    r9875 r9889  
    467467}
    468468
    469 Value DatePrototypeImp::get(ExecState *exec, const Identifier &propertyName) const
    470 {
    471   return lookupGetFunction<DateProtoFuncImp, ObjectImp>( exec, propertyName, &dateTable, this );
     469bool DatePrototypeImp::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
     470{
     471  return lookupGetOwnFunction<DateProtoFuncImp, ObjectImp>(exec, propertyName, &dateTable, this, result);
    472472}
    473473
  • trunk/JavaScriptCore/kjs/date_object.h

    r9768 r9889  
    4747  public:
    4848    DatePrototypeImp(ExecState *exec, ObjectPrototypeImp *objectProto);
    49     Value get(ExecState *exec, const Identifier &p) const;
     49    bool getOwnProperty(ExecState *exec, const Identifier& p, Value& result) const;
    5050    virtual const ClassInfo *classInfo() const { return &info; }
    5151    static const ClassInfo info;
  • trunk/JavaScriptCore/kjs/function.cpp

    r9768 r9889  
    203203}
    204204
    205 Value FunctionImp::get(ExecState *exec, const Identifier &propertyName) const
     205bool FunctionImp::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
    206206{
    207207    // Find the arguments from the closest context.
     
    209209        ContextImp *context = exec->_context;
    210210        while (context) {
    211             if (context->function() == this)
    212                 return static_cast<ActivationImp *>
    213                     (context->activationObject())->get(exec, propertyName);
    214             context = context->callingContext();
     211          if (context->function() == this) {
     212            result = static_cast<ActivationImp *>(context->activationObject())->get(exec, propertyName);
     213            return true;
     214          }
     215          context = context->callingContext();
    215216        }
    216         return Null();
     217        result = Null();
     218        return true;
    217219    }
    218220   
     
    225227            p = p->next;
    226228        }
    227         return Number(count);
     229        result = Number(count);
     230        return true;
    228231    }
    229232   
    230     return InternalFunctionImp::get(exec, propertyName);
     233    return InternalFunctionImp::getOwnProperty(exec, propertyName, result);
    231234}
    232235
     
    441444}
    442445
    443 Value ArgumentsImp::get(ExecState *exec, const Identifier &propertyName) const
     446bool ArgumentsImp::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
    444447{
    445448  if (indexToNameMap.isMapped(propertyName)) {
    446     return _activationObject->get(exec, indexToNameMap[propertyName]);
    447   } else {
    448     return ObjectImp::get(exec, propertyName);
    449   }
     449    result = _activationObject->get(exec, indexToNameMap[propertyName]);
     450    return true;
     451  }
     452
     453  return ObjectImp::getOwnProperty(exec, propertyName, result);
    450454}
    451455
     
    489493}
    490494
    491 Value ActivationImp::get(ExecState *exec, const Identifier &propertyName) const
    492 {
     495bool ActivationImp::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
     496{
     497    // do this first so property map arguments property wins over the below
     498    if (ObjectImp::getOwnProperty(exec, propertyName, result))
     499        return true;
     500
    493501    if (propertyName == argumentsPropertyName) {
    494         // check for locally declared arguments property
    495         ValueImp *v = getDirect(propertyName);
    496         if (v)
    497             return Value(v);
    498 
    499502        // default: return builtin arguments array
    500503        if (!_argumentsObject)
    501                 createArgumentsObject(exec);
    502         return Value(_argumentsObject);
    503     }
    504     return ObjectImp::get(exec, propertyName);
     504            createArgumentsObject(exec);
     505
     506        result = Value(_argumentsObject);
     507        return true;
     508    }
     509
     510    return false;
    505511}
    506512
  • trunk/JavaScriptCore/kjs/function.h

    r9768 r9889  
    4242    virtual ~FunctionImp();
    4343
    44     virtual Value get(ExecState *exec, const Identifier &propertyName) const;
     44    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
    4545    virtual void put(ExecState *exec, const Identifier &propertyName, const Value &value, int attr = None);
    4646    virtual bool hasOwnProperty(ExecState *exec, const Identifier &propertyName) const;
     
    109109    ArgumentsImp(ExecState *exec, FunctionImp *func, const List &args, ActivationImp *act);
    110110    virtual void mark();
    111     virtual Value get(ExecState *exec, const Identifier &propertyName) const;
     111    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
    112112    virtual void put(ExecState *exec, const Identifier &propertyName,
    113113                     const Value &value, int attr = None);
     
    125125    ActivationImp(FunctionImp *function, const List &arguments);
    126126
    127     virtual Value get(ExecState *exec, const Identifier &propertyName) const;
     127    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
    128128    virtual bool hasOwnProperty(ExecState *exec, const Identifier &propertyName) const;
    129129    virtual bool deleteProperty(ExecState *exec, const Identifier &propertyName);
  • trunk/JavaScriptCore/kjs/lookup.h

    r9834 r9889  
    165165   */
    166166  template <class FuncImp, class ThisImp, class ParentImp>
    167   inline Value lookupGet(ExecState *exec, const Identifier &propertyName,
    168                          const HashTable* table, const ThisImp* thisObj)
     167  inline bool lookupGetOwnProperty(ExecState *exec, const Identifier &propertyName,
     168                                   const HashTable* table, const ThisImp* thisObj, Value& result)
    169169  {
    170170    const HashEntry* entry = Lookup::findEntry(table, propertyName);
    171171
    172172    if (!entry) // not found, forward to parent
    173       return thisObj->ParentImp::get(exec, propertyName);
    174 
    175     //fprintf(stderr, "lookupGet: found value=%d attr=%d\n", entry->value, entry->attr);
     173      return thisObj->ParentImp::getOwnProperty(exec, propertyName, result);
     174
    176175    if (entry->attr & Function)
    177       return lookupOrCreateFunction<FuncImp>(exec, propertyName, thisObj, entry->value, entry->params, entry->attr);
    178     return thisObj->getValueProperty(exec, entry->value);
     176      result = lookupOrCreateFunction<FuncImp>(exec, propertyName, thisObj, entry->value, entry->params, entry->attr);
     177    else
     178      result = thisObj->getValueProperty(exec, entry->value);
     179
     180    return true;
    179181  }
    180182
     
    184186   */
    185187  template <class FuncImp, class ParentImp>
    186   inline Value lookupGetFunction(ExecState *exec, const Identifier &propertyName,
    187                          const HashTable* table, const ObjectImp* thisObj)
     188  inline bool lookupGetOwnFunction(ExecState *exec, const Identifier &propertyName,
     189                                   const HashTable* table, const ObjectImp* thisObj, Value& result)
    188190  {
    189191    const HashEntry* entry = Lookup::findEntry(table, propertyName);
    190192
    191193    if (!entry) // not found, forward to parent
    192       return static_cast<const ParentImp *>(thisObj)->ParentImp::get(exec, propertyName);
    193 
    194     if (entry->attr & Function)
    195       return lookupOrCreateFunction<FuncImp>(exec, propertyName, thisObj, entry->value, entry->params, entry->attr);
    196 
    197     fprintf(stderr, "Function bit not set! Shouldn't happen in lookupGetFunction!\n" );
    198     return Undefined();
     194      return static_cast<const ParentImp *>(thisObj)->ParentImp::getOwnProperty(exec, propertyName, result);
     195
     196    assert(entry->attr & Function);
     197
     198    result = lookupOrCreateFunction<FuncImp>(exec, propertyName, thisObj, entry->value, entry->params, entry->attr);
     199    return true;
    199200  }
    200201
     
    204205   */
    205206  template <class ThisImp, class ParentImp>
    206   inline Value lookupGetValue(ExecState *exec, const Identifier &propertyName,
    207                            const HashTable* table, const ThisImp* thisObj)
     207  inline bool lookupGetOwnValue(ExecState *exec, const Identifier &propertyName,
     208                                const HashTable* table, const ThisImp* thisObj, Value& result)
    208209  {
    209210    const HashEntry* entry = Lookup::findEntry(table, propertyName);
    210211
    211212    if (!entry) // not found, forward to parent
    212       return thisObj->ParentImp::get(exec, propertyName);
    213 
    214     if (entry->attr & Function)
    215       fprintf(stderr, "Function bit set! Shouldn't happen in lookupGetValue! propertyName was %s\n", propertyName.ascii() );
    216     return thisObj->getValueProperty(exec, entry->value);
     213      return thisObj->ParentImp::getOwnProperty(exec, propertyName, result);
     214
     215    assert(!entry->attr & Function);
     216
     217    result = thisObj->getValueProperty(exec, entry->value);
     218    return true;
    217219  }
    218220
     
    294296    virtual const ClassInfo *classInfo() const { return &info; } \
    295297    static const ClassInfo info; \
    296     Value get(ExecState *exec, const Identifier &propertyName) const; \
     298    bool getOwnProperty(ExecState *exec, const Identifier &propertyName, Value& result) const; \
    297299    bool hasOwnProperty(ExecState *exec, const Identifier &propertyName) const; \
    298300  }; \
     
    300302
    301303#define IMPLEMENT_PROTOTYPE(ClassProto,ClassFunc) \
    302     Value ClassProto::get(ExecState *exec, const Identifier &propertyName) const \
    303     { \
    304       /*fprintf( stderr, "%sProto::get(%s) [in macro, no parent]\n", info.className, propertyName.ascii());*/ \
    305       return lookupGetFunction<ClassFunc,ObjectImp>(exec, propertyName, &ClassProto##Table, this ); \
     304    bool ClassProto::getOwnProperty(ExecState *exec, const Identifier &propertyName, Value& result) const \
     305    { \
     306      return lookupGetOwnFunction<ClassFunc,ObjectImp>(exec, propertyName, &ClassProto##Table, this, result); \
    306307    } \
    307308    bool ClassProto::hasOwnProperty(ExecState *exec, const Identifier &propertyName) const \
     
    311312
    312313#define IMPLEMENT_PROTOTYPE_WITH_PARENT(ClassProto,ClassFunc,ParentProto)  \
    313     Value ClassProto::get(ExecState *exec, const Identifier &propertyName) const \
    314     { \
    315       /*fprintf( stderr, "%sProto::get(%s) [in macro]\n", info.className, propertyName.ascii());*/ \
    316       Value val = lookupGetFunction<ClassFunc,ObjectImp>(exec, propertyName, &ClassProto##Table, this ); \
    317       if ( val.type() != UndefinedType ) return val; \
    318       /* Not found -> forward request to "parent" prototype */ \
    319       return ParentProto::self(exec)->get( exec, propertyName ); \
     314    bool ClassProto::getOwnProperty(ExecState *exec, const Identifier &propertyName, Value& result) const \
     315    { \
     316      if (lookupGetOwnFunction<ClassFunc,ObjectImp>(exec, propertyName, &ClassProto##Table, this, result)) \
     317          return true; \
     318      return ParentProto::self(exec)->getOwnProperty(exec, propertyName, result); \
    320319    } \
    321320    bool ClassProto::hasOwnProperty(ExecState *exec, const Identifier &propertyName) const \
  • trunk/JavaScriptCore/kjs/math_object.cpp

    r9768 r9889  
    2222#include <math.h>
    2323#include <stdlib.h>
    24 #include <stdio.h>
    2524#include <assert.h>
    2625
     
    8281
    8382// ECMA 15.8
    84 Value MathObjectImp::get(ExecState *exec, const Identifier &propertyName) const
    85 {
    86   return lookupGet<MathFuncImp, MathObjectImp, ObjectImp>( exec, propertyName, &mathTable, this );
     83
     84bool MathObjectImp::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
     85{
     86  return lookupGetOwnProperty<MathFuncImp, MathObjectImp, ObjectImp>(exec, propertyName, &mathTable, this, result);
    8787}
    8888
     
    116116    break;
    117117  default:
    118     fprintf( stderr, "Internal error in MathObjectImp: unhandled token %d\n", token );
    119     break;
     118    assert(0);
    120119  }
    121120
  • trunk/JavaScriptCore/kjs/math_object.h

    r9768 r9889  
    3232    MathObjectImp(ExecState *exec,
    3333                  ObjectPrototypeImp *objProto);
    34     Value get(ExecState *exec, const Identifier &p) const;
     34    bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
    3535    Value getValueProperty(ExecState *exec, int token) const;
    3636    virtual const ClassInfo *classInfo() const { return &info; }
  • trunk/JavaScriptCore/kjs/nodes.cpp

    r9768 r9889  
    285285Value ResolveNode::evaluate(ExecState *exec)
    286286{
    287   return evaluateReference(exec).getValue(exec);
     287  ScopeChain chain = exec->context().imp()->scopeChain();
     288
     289  Value result;
     290  while (!chain.isEmpty()) {
     291    ObjectImp *o = chain.top();
     292
     293    if (o->getProperty(exec, ident, result))
     294      return result;
     295   
     296    chain.pop();
     297  }
     298
     299  UString m = I18N_NOOP("Can't find variable: ") + ident.ustring();
     300  Object err = Error::create(exec, ReferenceError, m.ascii());
     301  exec->setException(err);
     302  return err;
    288303}
    289304
  • trunk/JavaScriptCore/kjs/number_object.cpp

    r9768 r9889  
    403403}
    404404
    405 Value NumberObjectImp::get(ExecState *exec, const Identifier &propertyName) const
    406 {
    407   return lookupGetValue<NumberObjectImp, InternalFunctionImp>( exec, propertyName, &numberTable, this );
     405bool NumberObjectImp::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
     406{
     407  return lookupGetOwnValue<NumberObjectImp, InternalFunctionImp>(exec, propertyName, &numberTable, this, result);
    408408}
    409409
  • trunk/JavaScriptCore/kjs/number_object.h

    r9768 r9889  
    8585    virtual Value call(ExecState *exec, Object &thisObj, const List &args);
    8686
    87     Value get(ExecState *exec, const Identifier &p) const;
     87    bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
    8888    Value getValueProperty(ExecState *exec, int token) const;
    8989    virtual const ClassInfo *classInfo() const { return &info; }
  • trunk/JavaScriptCore/kjs/object.cpp

    r9768 r9889  
    209209Value ObjectImp::get(ExecState *exec, const Identifier &propertyName) const
    210210{
    211   ValueImp *imp = getDirect(propertyName);
    212   if (imp)
    213     return Value(imp);
    214 
    215   // non-standard netscape extension
    216   if (propertyName == specialPrototypePropertyName)
    217     return Value(_proto);
    218 
    219   if (_proto->dispatchType() != ObjectType) {
    220     return Undefined();
    221   }
    222 
    223   return static_cast<ObjectImp *>(_proto)->get(exec, propertyName);
     211  Value result;
     212
     213  const ObjectImp *imp = this;
     214
     215  while (true) {
     216    if (imp->getOwnProperty(exec, propertyName, result))
     217      return result;
     218
     219    const ValueImp *proto = imp->_proto;
     220    if (proto->dispatchType() != ObjectType)
     221      break;
     222
     223    imp = static_cast<const ObjectImp *>(proto);
     224  }
     225
     226  return Undefined();
     227}
     228
     229bool ObjectImp::getOwnProperty(ExecState *exec, unsigned propertyName, Value& result) const
     230{
     231  return getOwnProperty(exec, Identifier::from(propertyName), result);
    224232}
    225233
    226234Value ObjectImp::get(ExecState *exec, unsigned propertyName) const
    227235{
    228   return get(exec, Identifier::from(propertyName));
     236  Value result;
     237
     238  const ObjectImp *imp = this;
     239
     240  while (imp) {
     241    if (imp->getOwnProperty(exec, propertyName, result))
     242      return result;
     243
     244    const ValueImp *proto = imp->_proto;
     245    if (proto->dispatchType() != ObjectType)
     246      break;
     247
     248    imp = static_cast<const ObjectImp *>(proto);
     249  }
     250
     251  return Undefined();
     252}
     253
     254bool ObjectImp::getProperty(ExecState *exec, unsigned propertyName, Value& result) const
     255{
     256  const ObjectImp *imp = this;
     257 
     258  while (true) {
     259    if (imp->getOwnProperty(exec, propertyName, result))
     260      return true;
     261   
     262    const ValueImp *proto = imp->_proto;
     263      if (proto->dispatchType() != ObjectType)
     264        break;
     265     
     266      imp = static_cast<const ObjectImp *>(proto);
     267  }
     268 
     269  return false;
    229270}
    230271
  • trunk/JavaScriptCore/kjs/object.h

    r9795 r9889  
    504504     */
    505505    // [[Get]] - must be implemented by all Objects
    506     virtual Value get(ExecState *exec, const Identifier &propertyName) const;
    507     virtual Value get(ExecState *exec, unsigned propertyName) const;
     506    Value get(ExecState *exec, const Identifier &propertyName) const;
     507    Value get(ExecState *exec, unsigned propertyName) const;
     508
     509    bool getProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     510    bool getProperty(ExecState *exec, unsigned propertyName, Value& result) const;
     511
     512    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     513    virtual bool getOwnProperty(ExecState *exec, unsigned propertyName, Value& result) const;
    508514
    509515    /**
     
    633639  };
    634640
     641
     642  // it may seem crazy to inline a function this large but it makes a big difference
     643  // since this is function very hot in variable lookup
     644  inline bool ObjectImp::getProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
     645  {
     646    const ObjectImp *imp = this;
     647
     648    while (true) {
     649      if (imp->getOwnProperty(exec, propertyName, result))
     650        return true;
     651     
     652      const ValueImp *proto = imp->_proto;
     653      if (proto->dispatchType() != ObjectType)
     654        break;
     655     
     656      imp = static_cast<const ObjectImp *>(proto);
     657    }
     658   
     659    return false;
     660  }
     661
     662  // it may seem crazy to inline a function this large, especially a virtual function,
     663  // but it makes a big difference to property lookup if subclasses can inline their
     664  // superclass call to this
     665  inline bool ObjectImp::getOwnProperty(ExecState *exec, const Identifier &propertyName, Value &result) const
     666  {
     667      ValueImp *imp = getDirect(propertyName);
     668      if (imp) {
     669        result = Value(imp);
     670        return true;
     671      }
     672
     673      // non-standard netscape extension
     674      if (propertyName == specialPrototypePropertyName) {
     675        result = Value(_proto);
     676        return true;
     677      }
     678
     679      return false;
     680  }
     681
    635682  /**
    636683   * Types of Native Errors available. For custom errors, GeneralError
  • trunk/JavaScriptCore/kjs/object_object.cpp

    r9768 r9889  
    7171            return thisObj;
    7272        case HasOwnProperty: {
    73             // Same as hasProperty() but without checking the prototype
     73            // Same as the in operator but without checking the prototype
    7474            Identifier propertyName(args[0].toString(exec));
    7575            bool exists = thisObj.hasOwnProperty(exec, propertyName);
  • trunk/JavaScriptCore/kjs/regexp_object.cpp

    r9768 r9889  
    217217}
    218218
    219 Value RegExpObjectImp::get(ExecState *exec, const Identifier &p) const
     219bool RegExpObjectImp::getOwnProperty(ExecState *exec, const Identifier& p, Value& result) const
    220220{
    221221  UString s = p.ustring();
     
    229229      {
    230230        UString substring = lastString.substr( lastOvector[2*i], lastOvector[2*i+1] - lastOvector[2*i] );
    231         return String(substring);
    232       }
    233       return String("");
    234     }
    235   }
    236   return InternalFunctionImp::get(exec, p);
     231        result = String(substring);
     232      } else
     233        result = String("");
     234     
     235      return true;
     236    }
     237  }
     238
     239  return InternalFunctionImp::getOwnProperty(exec, p, result);
    237240}
    238241
  • trunk/JavaScriptCore/kjs/regexp_object.h

    r9768 r9889  
    7575    virtual Value call(ExecState *exec, Object &thisObj, const List &args);
    7676
    77     Value get(ExecState *exec, const Identifier &p) const;
     77    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
    7878    int ** registerRegexp( const RegExp* re, const UString& s );
    7979    void setSubPatterns(int num) { lastNrSubPatterns = num; }
  • trunk/JavaScriptCore/kjs/string_object.cpp

    r9768 r9889  
    5151}
    5252
    53 Value StringInstanceImp::get(ExecState *exec, const Identifier &propertyName) const
    54 {
    55   if (propertyName == lengthPropertyName)
    56     return Number(internalValue().toString(exec).size());
     53bool StringInstanceImp::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
     54{
     55  if (propertyName == lengthPropertyName) {
     56    result = Value(internalValue().toString(exec).size());
     57    return true;
     58  }
    5759
    5860  bool ok;
     
    6466      return Undefined();
    6567    const UChar c = s[index];
    66     return String(UString(&c, 1));
    67   }
    68 
    69   return ObjectImp::get(exec, propertyName);
     68    result = Value(UString(&c, 1));
     69    return true;
     70  }
     71
     72  return ObjectImp::getOwnProperty(exec, propertyName, result);
    7073}
    7174
     
    152155}
    153156
    154 Value StringPrototypeImp::get(ExecState *exec, const Identifier &propertyName) const
    155 {
    156   return lookupGetFunction<StringProtoFuncImp, StringInstanceImp>( exec, propertyName, &stringTable, this );
     157bool StringPrototypeImp::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
     158{
     159  return lookupGetOwnFunction<StringProtoFuncImp, StringInstanceImp>(exec, propertyName, &stringTable, this, result);
    157160}
    158161
  • trunk/JavaScriptCore/kjs/string_object.h

    r9768 r9889  
    3333    StringInstanceImp(ObjectImp *proto, const UString &string);
    3434
    35     virtual Value get(ExecState *exec, const Identifier &propertyName) const;
     35    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
    3636    virtual void put(ExecState *exec, const Identifier &propertyName, const Value &value, int attr = None);
    3737    virtual bool hasOwnProperty(ExecState *exec, const Identifier &propertyName) const;
     
    5252    StringPrototypeImp(ExecState *exec,
    5353                       ObjectPrototypeImp *objProto);
    54     Value get(ExecState *exec, const Identifier &p) const;
     54    virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
    5555    virtual const ClassInfo *classInfo() const { return &info; }
    5656    static const ClassInfo info;
Note: See TracChangeset for help on using the changeset viewer.