Changeset 10076 in webkit for trunk/JavaScriptCore


Ignore:
Timestamp:
Aug 6, 2005, 11:17:49 PM (20 years ago)
Author:
mjs
Message:

JavaScriptCore:

Reviewed by Darin.

Change over to the new PropertySlot mechanism for property
lookup. This allows the elimination of hasOwnProperty
methods. Also did some of the performance tuning enabled by this
(but not yet all the possible improvements for function calls,
assignment, ++, and so forth). And also much code cleanup.

Net result is about a 2% speedup on the JS iBench.

Also redid Geoff's fix for the chrashing applet by avoiding a NULL
prototype in the bindings code and using the default of Null()
instead.

  • JavaScriptCore.xcodeproj/project.pbxproj:
  • bindings/objc/objc_runtime.h:
  • bindings/objc/objc_runtime.mm: (ObjcFallbackObjectImp::ObjcFallbackObjectImp): (ObjcFallbackObjectImp::getOwnPropertySlot):
  • bindings/runtime_array.cpp: (RuntimeArrayImp::lengthGetter): (RuntimeArrayImp::indexGetter): (RuntimeArrayImp::getOwnPropertySlot):
  • bindings/runtime_array.h:
  • bindings/runtime_method.cpp: (RuntimeMethodImp::lengthGetter): (RuntimeMethodImp::getOwnPropertySlot):
  • bindings/runtime_method.h:
  • bindings/runtime_object.cpp: (RuntimeObjectImp::RuntimeObjectImp): (RuntimeObjectImp::fallbackObjectGetter): (RuntimeObjectImp::fieldGetter): (RuntimeObjectImp::methodGetter): (RuntimeObjectImp::getOwnPropertySlot):
  • bindings/runtime_object.h:
  • bindings/runtime_root.h:
  • kjs/array_instance.h:
  • kjs/array_object.cpp: (ArrayInstanceImp::lengthGetter): (ArrayInstanceImp::getOwnPropertySlot): (ArrayPrototypeImp::getOwnPropertySlot):
  • kjs/array_object.h:
  • kjs/date_object.cpp: (DatePrototypeImp::getOwnPropertySlot):
  • kjs/date_object.h:
  • kjs/function.cpp: (KJS::FunctionImp::argumentsGetter): (KJS::FunctionImp::lengthGetter): (KJS::FunctionImp::getOwnPropertySlot): (KJS::FunctionImp::put): (KJS::FunctionImp::deleteProperty): (KJS::ArgumentsImp::mappedIndexGetter): (KJS::ArgumentsImp::getOwnPropertySlot): (KJS::ActivationImp::argumentsGetter): (KJS::ActivationImp::getArgumentsGetter): (KJS::ActivationImp::getOwnPropertySlot): (KJS::ActivationImp::deleteProperty):
  • kjs/function.h:
  • kjs/internal.cpp: (InterpreterImp::InterpreterImp): (InterpreterImp::initGlobalObject): (InterpreterImp::~InterpreterImp): (InterpreterImp::evaluate):
  • kjs/internal.h: (KJS::InterpreterImp::globalExec):
  • kjs/interpreter.cpp: (Interpreter::Interpreter): (Interpreter::createLanguageInstanceForValue):
  • kjs/interpreter.h: (KJS::Interpreter::argumentsIdentifier): (KJS::Interpreter::specialPrototypeIdentifier):
  • kjs/lookup.h: (KJS::staticFunctionGetter): (KJS::staticValueGetter): (KJS::getStaticPropertySlot): (KJS::getStaticFunctionSlot): (KJS::getStaticValueSlot):
  • kjs/math_object.cpp: (MathObjectImp::getOwnPropertySlot):
  • kjs/math_object.h:
  • kjs/nodes.cpp: (ResolveNode::evaluate): (ResolveNode::evaluateReference): (AccessorNode1::evaluate): (AccessorNode2::evaluate):
  • kjs/number_object.cpp: (NumberObjectImp::getOwnPropertySlot):
  • kjs/number_object.h:
  • kjs/object.cpp: (KJS::ObjectImp::get): (KJS::ObjectImp::getProperty): (KJS::ObjectImp::getPropertySlot): (KJS::ObjectImp::getOwnPropertySlot): (KJS::ObjectImp::put): (KJS::ObjectImp::hasProperty): (KJS::ObjectImp::hasOwnProperty):
  • kjs/object.h: (KJS::ObjectImp::getDirectLocation): (KJS::ObjectImp::getPropertySlot): (KJS::ObjectImp::getOwnPropertySlot):
  • kjs/object_wrapper.h: Added. (KJS::): (KJS::Object::Object): (KJS::Object::operator ObjectImp *):
  • kjs/property_map.cpp: (KJS::PropertyMap::getLocation):
  • kjs/property_map.h:
  • kjs/property_slot.cpp: Added. (KJS::PropertySlot::undefinedGetter):
  • kjs/property_slot.h: Added. (KJS::PropertySlot::isSet): (KJS::PropertySlot::getValue): (KJS::PropertySlot::setValueSlot): (KJS::PropertySlot::setStaticEntry): (KJS::PropertySlot::setCustom): (KJS::PropertySlot::setCustomIndex): (KJS::PropertySlot::setUndefined): (KJS::PropertySlot::slotBase): (KJS::PropertySlot::staticEntry): (KJS::PropertySlot::index): (KJS::PropertySlot::):
  • kjs/protect.h:
  • kjs/protected_object.h: Added. (KJS::ProtectedObject::ProtectedObject): (KJS::ProtectedObject::~ProtectedObject): (KJS::ProtectedObject::operator=): (KJS::ProtectedReference::ProtectedReference): (KJS::ProtectedReference::~ProtectedReference): (KJS::ProtectedReference::operator=):
  • kjs/reference.h:
  • kjs/reference_list.cpp:
  • kjs/regexp_object.cpp: (RegExpObjectImp::backrefGetter): (RegExpObjectImp::getOwnPropertySlot):
  • kjs/regexp_object.h:
  • kjs/string_object.cpp: (StringInstanceImp::lengthGetter): (StringInstanceImp::indexGetter): (StringInstanceImp::getOwnPropertySlot): (StringPrototypeImp::getOwnPropertySlot):
  • kjs/string_object.h:

WebCore:

Reviewed by Darin.

Change over to the new PropertySlot mechanism for property
lookup. This allows the elimination of hasOwnProperty methods. I
also did a bunch of code cleanup and regularization of the various
property lookup methods.

Test cases added: Added a test case for a bug I found along the way.

  • layout-tests/fast/js/string-index-overflow.html:
  • layout-tests/fast/js/string-index-overflow-expected.txt:
  • khtml/ecma/kjs_binding.cpp: (KJS::ScriptInterpreter::createLanguageInstanceForValue):
  • khtml/ecma/kjs_binding.h:
  • khtml/ecma/kjs_css.cpp: (KJS::DOMCSSStyleDeclaration::indexGetter): (KJS::DOMCSSStyleDeclaration::cssPropertyGetter): (KJS::DOMCSSStyleDeclaration::getOwnPropertySlot): (KJS::DOMCSSStyleDeclaration::getValueProperty): (KJS::DOMStyleSheet::getOwnPropertySlot): (KJS::DOMStyleSheetList::getValueProperty): (KJS::DOMStyleSheetList::indexGetter): (KJS::DOMStyleSheetList::nameGetter): (KJS::DOMStyleSheetList::getOwnPropertySlot): (KJS::DOMMediaList::getValueProperty): (KJS::DOMMediaList::indexGetter): (KJS::DOMMediaList::getOwnPropertySlot): (KJS::DOMCSSStyleSheet::getValueProperty): (KJS::DOMCSSStyleSheet::getOwnPropertySlot): (KJS::DOMCSSRuleList::getValueProperty): (KJS::DOMCSSRuleList::indexGetter): (KJS::DOMCSSRuleList::getOwnPropertySlot): (KJS::DOMCSSRule::getOwnPropertySlot): (KJS::CSSRuleConstructor::getOwnPropertySlot): (KJS::DOMCSSValue::getValueProperty): (KJS::DOMCSSValue::getOwnPropertySlot): (KJS::CSSValueConstructor::getOwnPropertySlot): (KJS::DOMCSSPrimitiveValue::getValueProperty): (KJS::DOMCSSPrimitiveValue::getOwnPropertySlot): (KJS::CSSPrimitiveValueConstructor::getOwnPropertySlot): (KJS::DOMCSSValueList::getValueProperty): (KJS::DOMCSSValueList::indexGetter): (KJS::DOMCSSValueList::getOwnPropertySlot): (KJS::DOMRGBColor::getOwnPropertySlot): (KJS::DOMRect::getOwnPropertySlot): (KJS::DOMCounter::getOwnPropertySlot):
  • khtml/ecma/kjs_css.h: (KJS::DOMCSSStyleDeclaration::): (KJS::DOMCSSStyleSheet::): (KJS::DOMCSSRule::): (KJS::DOMCSSValueList::):
  • khtml/ecma/kjs_dom.cpp: (KJS::DOMNode::getOwnPropertySlot): (KJS::): (KJS::DOMNodeList::getValueProperty): (KJS::DOMNodeList::indexGetter): (KJS::DOMNodeList::nameGetter): (KJS::DOMNodeList::getOwnPropertySlot): (KJS::DOMNodeList::call): (KJS::DOMAttr::getOwnPropertySlot): (KJS::DOMDocument::getOwnPropertySlot): (KJS::DOMElement::getValueProperty): (KJS::DOMElement::attributeGetter): (KJS::DOMElement::getOwnPropertySlot): (KJS::DOMDocumentType::getOwnPropertySlot): (KJS::DOMNamedNodeMap::lengthGetter): (KJS::DOMNamedNodeMap::indexGetter): (KJS::DOMNamedNodeMap::getOwnPropertySlot): (KJS::DOMProcessingInstruction::getOwnPropertySlot): (KJS::DOMNotation::getOwnPropertySlot): (KJS::DOMEntity::getOwnPropertySlot): (KJS::NodeConstructor::getOwnPropertySlot): (KJS::DOMExceptionConstructor::getOwnPropertySlot): (KJS::DOMNamedNodesCollection::lengthGetter): (KJS::DOMNamedNodesCollection::indexGetter): (KJS::DOMNamedNodesCollection::getOwnPropertySlot): (KJS::DOMCharacterData::getOwnPropertySlot):
  • khtml/ecma/kjs_dom.h:
  • khtml/ecma/kjs_events.cpp: (KJS::EventConstructor::getOwnPropertySlot): (KJS::DOMEvent::getOwnPropertySlot): (KJS::EventExceptionConstructor::getOwnPropertySlot): (KJS::DOMUIEvent::getOwnPropertySlot): (KJS::DOMMouseEvent::getOwnPropertySlot): (KJS::DOMKeyboardEvent::getOwnPropertySlot): (KJS::MutationEventConstructor::getOwnPropertySlot): (KJS::DOMMutationEvent::getOwnPropertySlot): (KJS::DOMWheelEvent::getOwnPropertySlot): (KJS::Clipboard::getOwnPropertySlot):
  • khtml/ecma/kjs_events.h:
  • khtml/ecma/kjs_html.cpp: (KJS::HTMLDocument::namedItemGetter): (KJS::HTMLDocument::getValueProperty): (KJS::HTMLDocument::getOwnPropertySlot): (KJS::HTMLElement::formIndexGetter): (KJS::HTMLElement::formNameGetter): (KJS::HTMLElement::selectIndexGetter): (KJS::HTMLElement::framesetNameGetter): (KJS::HTMLElement::frameWindowPropertyGetter): (KJS::HTMLElement::runtimeObjectGetter): (KJS::HTMLElement::runtimeObjectPropertyGetter): (KJS::HTMLElement::getOwnPropertySlot): (KJS::HTMLCollection::lengthGetter): (KJS::HTMLCollection::indexGetter): (KJS::HTMLCollection::nameGetter): (KJS::HTMLCollection::getOwnPropertySlot): (KJS::HTMLSelectCollection::selectedIndexGetter): (KJS::HTMLSelectCollection::getOwnPropertySlot): (KJS::Image::getOwnPropertySlot): (KJS::Context2D::getOwnPropertySlot): (KJS::Gradient::getOwnPropertySlot): (KJS::ImagePattern::getOwnPropertySlot):
  • khtml/ecma/kjs_html.h: (KJS::HTMLCollection::toBoolean):
  • khtml/ecma/kjs_navigator.cpp: (KJS::Plugins::): (KJS::MimeTypes::): (KJS::Plugin::): (KJS::MimeType::): (KJS::): (KJS::Navigator::getOwnPropertySlot): (KJS::Plugins::getValueProperty): (KJS::Plugins::indexGetter): (KJS::Plugins::nameGetter): (KJS::Plugins::getOwnPropertySlot): (KJS::MimeTypes::getValueProperty): (KJS::MimeTypes::indexGetter): (KJS::MimeTypes::nameGetter): (KJS::MimeTypes::getOwnPropertySlot): (KJS::Plugin::getValueProperty): (KJS::Plugin::indexGetter): (KJS::Plugin::nameGetter): (KJS::Plugin::getOwnPropertySlot): (KJS::MimeType::getValueProperty): (KJS::MimeType::getOwnPropertySlot):
  • khtml/ecma/kjs_navigator.h:
  • khtml/ecma/kjs_range.cpp: (KJS::DOMRange::getOwnPropertySlot): (KJS::RangeConstructor::getOwnPropertySlot):
  • khtml/ecma/kjs_range.h:
  • khtml/ecma/kjs_traversal.cpp: (KJS::DOMNodeIterator::getOwnPropertySlot): (KJS::NodeFilterConstructor::getOwnPropertySlot): (KJS::DOMTreeWalker::getOwnPropertySlot):
  • khtml/ecma/kjs_traversal.h:
  • khtml/ecma/kjs_views.cpp: (KJS::DOMAbstractView::~DOMAbstractView): (KJS::DOMAbstractView::getValueProperty): (KJS::DOMAbstractView::getOwnPropertySlot):
  • khtml/ecma/kjs_views.h:
  • khtml/ecma/kjs_window.cpp: (KJS::FrameArray::): (KJS::FrameArray::classInfo): (KJS::Screen::getOwnPropertySlot): (KJS::Window::getValueProperty): (KJS::Window::childFrameGetter): (KJS::Window::namedFrameGetter): (KJS::Window::indexGetter): (KJS::Window::namedItemGetter): (KJS::Window::getOwnPropertySlot): (KJS::): (KJS::FrameArray::getValueProperty): (KJS::FrameArray::indexGetter): (KJS::FrameArray::nameGetter): (KJS::FrameArray::getOwnPropertySlot): (KJS::Location::getValueProperty): (KJS::Location::getOwnPropertySlot): (KJS::Selection::getValueProperty): (KJS::Selection::getOwnPropertySlot): (KJS::BarInfo::getValueProperty): (KJS::BarInfo::getOwnPropertySlot): (KJS::History::getOwnPropertySlot):
  • khtml/ecma/kjs_window.h:
  • khtml/ecma/xmlhttprequest.cpp: (KJS::XMLHttpRequest::getOwnPropertySlot):
  • khtml/ecma/xmlhttprequest.h:
Location:
trunk/JavaScriptCore
Files:
4 added
39 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r10075 r10076  
     12005-08-06  Maciej Stachowiak  <[email protected]>
     2
     3        Reviewed by Darin.
     4
     5        Change over to the new PropertySlot mechanism for property
     6        lookup. This allows the elimination of hasOwnProperty
     7        methods. Also did some of the performance tuning enabled by this
     8        (but not yet all the possible improvements for function calls,
     9        assignment, ++, and so forth). And also much code cleanup.
     10
     11        Net result is about a 2% speedup on the JS iBench.
     12       
     13        Also redid Geoff's fix for the chrashing applet by avoiding a NULL
     14        prototype in the bindings code and using the default of Null()
     15        instead.
     16       
     17        * JavaScriptCore.xcodeproj/project.pbxproj:
     18        * bindings/objc/objc_runtime.h:
     19        * bindings/objc/objc_runtime.mm:
     20        (ObjcFallbackObjectImp::ObjcFallbackObjectImp):
     21        (ObjcFallbackObjectImp::getOwnPropertySlot):
     22        * bindings/runtime_array.cpp:
     23        (RuntimeArrayImp::lengthGetter):
     24        (RuntimeArrayImp::indexGetter):
     25        (RuntimeArrayImp::getOwnPropertySlot):
     26        * bindings/runtime_array.h:
     27        * bindings/runtime_method.cpp:
     28        (RuntimeMethodImp::lengthGetter):
     29        (RuntimeMethodImp::getOwnPropertySlot):
     30        * bindings/runtime_method.h:
     31        * bindings/runtime_object.cpp:
     32        (RuntimeObjectImp::RuntimeObjectImp):
     33        (RuntimeObjectImp::fallbackObjectGetter):
     34        (RuntimeObjectImp::fieldGetter):
     35        (RuntimeObjectImp::methodGetter):
     36        (RuntimeObjectImp::getOwnPropertySlot):
     37        * bindings/runtime_object.h:
     38        * bindings/runtime_root.h:
     39        * kjs/array_instance.h:
     40        * kjs/array_object.cpp:
     41        (ArrayInstanceImp::lengthGetter):
     42        (ArrayInstanceImp::getOwnPropertySlot):
     43        (ArrayPrototypeImp::getOwnPropertySlot):
     44        * kjs/array_object.h:
     45        * kjs/date_object.cpp:
     46        (DatePrototypeImp::getOwnPropertySlot):
     47        * kjs/date_object.h:
     48        * kjs/function.cpp:
     49        (KJS::FunctionImp::argumentsGetter):
     50        (KJS::FunctionImp::lengthGetter):
     51        (KJS::FunctionImp::getOwnPropertySlot):
     52        (KJS::FunctionImp::put):
     53        (KJS::FunctionImp::deleteProperty):
     54        (KJS::ArgumentsImp::mappedIndexGetter):
     55        (KJS::ArgumentsImp::getOwnPropertySlot):
     56        (KJS::ActivationImp::argumentsGetter):
     57        (KJS::ActivationImp::getArgumentsGetter):
     58        (KJS::ActivationImp::getOwnPropertySlot):
     59        (KJS::ActivationImp::deleteProperty):
     60        * kjs/function.h:
     61        * kjs/internal.cpp:
     62        (InterpreterImp::InterpreterImp):
     63        (InterpreterImp::initGlobalObject):
     64        (InterpreterImp::~InterpreterImp):
     65        (InterpreterImp::evaluate):
     66        * kjs/internal.h:
     67        (KJS::InterpreterImp::globalExec):
     68        * kjs/interpreter.cpp:
     69        (Interpreter::Interpreter):
     70        (Interpreter::createLanguageInstanceForValue):
     71        * kjs/interpreter.h:
     72        (KJS::Interpreter::argumentsIdentifier):
     73        (KJS::Interpreter::specialPrototypeIdentifier):
     74        * kjs/lookup.h:
     75        (KJS::staticFunctionGetter):
     76        (KJS::staticValueGetter):
     77        (KJS::getStaticPropertySlot):
     78        (KJS::getStaticFunctionSlot):
     79        (KJS::getStaticValueSlot):
     80        * kjs/math_object.cpp:
     81        (MathObjectImp::getOwnPropertySlot):
     82        * kjs/math_object.h:
     83        * kjs/nodes.cpp:
     84        (ResolveNode::evaluate):
     85        (ResolveNode::evaluateReference):
     86        (AccessorNode1::evaluate):
     87        (AccessorNode2::evaluate):
     88        * kjs/number_object.cpp:
     89        (NumberObjectImp::getOwnPropertySlot):
     90        * kjs/number_object.h:
     91        * kjs/object.cpp:
     92        (KJS::ObjectImp::get):
     93        (KJS::ObjectImp::getProperty):
     94        (KJS::ObjectImp::getPropertySlot):
     95        (KJS::ObjectImp::getOwnPropertySlot):
     96        (KJS::ObjectImp::put):
     97        (KJS::ObjectImp::hasProperty):
     98        (KJS::ObjectImp::hasOwnProperty):
     99        * kjs/object.h:
     100        (KJS::ObjectImp::getDirectLocation):
     101        (KJS::ObjectImp::getPropertySlot):
     102        (KJS::ObjectImp::getOwnPropertySlot):
     103        * kjs/object_wrapper.h: Added.
     104        (KJS::):
     105        (KJS::Object::Object):
     106        (KJS::Object::operator ObjectImp *):
     107        * kjs/property_map.cpp:
     108        (KJS::PropertyMap::getLocation):
     109        * kjs/property_map.h:
     110        * kjs/property_slot.cpp: Added.
     111        (KJS::PropertySlot::undefinedGetter):
     112        * kjs/property_slot.h: Added.
     113        (KJS::PropertySlot::isSet):
     114        (KJS::PropertySlot::getValue):
     115        (KJS::PropertySlot::setValueSlot):
     116        (KJS::PropertySlot::setStaticEntry):
     117        (KJS::PropertySlot::setCustom):
     118        (KJS::PropertySlot::setCustomIndex):
     119        (KJS::PropertySlot::setUndefined):
     120        (KJS::PropertySlot::slotBase):
     121        (KJS::PropertySlot::staticEntry):
     122        (KJS::PropertySlot::index):
     123        (KJS::PropertySlot::):
     124        * kjs/protect.h:
     125        * kjs/protected_object.h: Added.
     126        (KJS::ProtectedObject::ProtectedObject):
     127        (KJS::ProtectedObject::~ProtectedObject):
     128        (KJS::ProtectedObject::operator=):
     129        (KJS::ProtectedReference::ProtectedReference):
     130        (KJS::ProtectedReference::~ProtectedReference):
     131        (KJS::ProtectedReference::operator=):
     132        * kjs/reference.h:
     133        * kjs/reference_list.cpp:
     134        * kjs/regexp_object.cpp:
     135        (RegExpObjectImp::backrefGetter):
     136        (RegExpObjectImp::getOwnPropertySlot):
     137        * kjs/regexp_object.h:
     138        * kjs/string_object.cpp:
     139        (StringInstanceImp::lengthGetter):
     140        (StringInstanceImp::indexGetter):
     141        (StringInstanceImp::getOwnPropertySlot):
     142        (StringPrototypeImp::getOwnPropertySlot):
     143        * kjs/string_object.h:
     144
    11452005-08-05  Adele Peterson  <[email protected]>
    2146
  • trunk/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r10066 r10076  
    2626
    2727/* Begin PBXBuildFile section */
     28                65305EAF08A58DDE00F31E73 /* protected_object.h in Headers */ = {isa = PBXBuildFile; fileRef = 65305EAE08A58DDE00F31E73 /* protected_object.h */; settings = {ATTRIBUTES = (Private, ); }; };
     29                65305EB008A58E0900F31E73 /* protected_object.h in Headers */ = {isa = PBXBuildFile; fileRef = 65305EAE08A58DDE00F31E73 /* protected_object.h */; settings = {ATTRIBUTES = (Private, ); }; };
     30                6539AACB08A3225A00223EE2 /* object_wrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 6539AACA08A3225A00223EE2 /* object_wrapper.h */; settings = {ATTRIBUTES = (Private, ); }; };
     31                65621E6D089E859700760F35 /* property_slot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65621E6B089E859700760F35 /* property_slot.cpp */; };
     32                65621E6E089E859700760F35 /* property_slot.h in Headers */ = {isa = PBXBuildFile; fileRef = 65621E6C089E859700760F35 /* property_slot.h */; settings = {ATTRIBUTES = (Private, ); }; };
     33                65621E6F089E85D300760F35 /* property_slot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65621E6B089E859700760F35 /* property_slot.cpp */; };
     34                65621E70089E85D300760F35 /* property_slot.h in Headers */ = {isa = PBXBuildFile; fileRef = 65621E6C089E859700760F35 /* property_slot.h */; settings = {ATTRIBUTES = (Private, ); }; };
     35                65BBAEE008A329B300357728 /* object_wrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 6539AACA08A3225A00223EE2 /* object_wrapper.h */; settings = {ATTRIBUTES = (Private, ); }; };
    2836                932F5B400822A1C700736975 /* array_object.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A84E0255597D01FF60F7 /* array_object.h */; settings = {ATTRIBUTES = (Private, ); }; };
    2937                932F5B420822A1C700736975 /* collector.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A8530255597D01FF60F7 /* collector.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    450458                651F6412039D5B5F0078395C /* dtoa.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = dtoa.cpp; sourceTree = "<group>"; };
    451459                651F6413039D5B5F0078395C /* dtoa.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = dtoa.h; sourceTree = "<group>"; };
     460                65305EAE08A58DDE00F31E73 /* protected_object.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = protected_object.h; sourceTree = "<group>"; };
     461                6539AACA08A3225A00223EE2 /* object_wrapper.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = object_wrapper.h; sourceTree = "<group>"; };
    452462                65417205039E02E70058BFEB /* get.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = get.c; path = pcre/get.c; sourceTree = "<group>"; };
    453463                65417206039E02E70058BFEB /* maketables.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = maketables.c; path = pcre/maketables.c; sourceTree = "<group>"; };
     
    459469                6560A4CF04B3B3E7008AE952 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = "<absolute>"; };
    460470                6560A63D04B3B69F008AE952 /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = /System/Library/Frameworks/CoreServices.framework; sourceTree = "<absolute>"; };
     471                65621E6B089E859700760F35 /* property_slot.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = property_slot.cpp; sourceTree = "<group>"; };
     472                65621E6C089E859700760F35 /* property_slot.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = property_slot.h; sourceTree = "<group>"; };
    461473                65AB004806261CBA0076DE63 /* interpreter_map.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = interpreter_map.cpp; sourceTree = "<group>"; };
    462474                65AB004906261CBA0076DE63 /* interpreter_map.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = interpreter_map.h; sourceTree = "<group>"; };
     
    633645                        isa = PBXGroup;
    634646                        children = (
     647                                65305EAE08A58DDE00F31E73 /* protected_object.h */,
     648                                6539AACA08A3225A00223EE2 /* object_wrapper.h */,
     649                                65621E6B089E859700760F35 /* property_slot.cpp */,
     650                                65621E6C089E859700760F35 /* property_slot.h */,
    635651                                938772E5038BFE19008635CE /* array_instance.h */,
    636652                                650B68D80639033F009D42DE /* protected_values.cpp */,
     
    829845                        buildActionMask = 2147483647;
    830846                        files = (
     847                                65305EAF08A58DDE00F31E73 /* protected_object.h in Headers */,
    831848                                932F5B400822A1C700736975 /* array_object.h in Headers */,
    832849                                932F5B420822A1C700736975 /* collector.h in Headers */,
     
    901918                                932F5B8F0822A1C700736975 /* fast_malloc.h in Headers */,
    902919                                932FC11D0824A6A3005B3C75 /* create_hash_table in Headers */,
     920                                65621E6E089E859700760F35 /* property_slot.h in Headers */,
     921                                6539AACB08A3225A00223EE2 /* object_wrapper.h in Headers */,
    903922                        );
    904923                        runOnlyForDeploymentPostprocessing = 0;
     
    908927                        buildActionMask = 2147483647;
    909928                        files = (
     929                                65305EB008A58E0900F31E73 /* protected_object.h in Headers */,
    910930                                A85D81F8087B2822006A9172 /* array_object.h in Headers */,
    911931                                A85D81F9087B2822006A9172 /* collector.h in Headers */,
     
    923943                                A85D8205087B2822006A9172 /* number_object.h in Headers */,
    924944                                A85D8206087B2822006A9172 /* object_object.h in Headers */,
     945                                65BBAEE008A329B300357728 /* object_wrapper.h in Headers */,
    925946                                A85D8207087B2822006A9172 /* object.h in Headers */,
    926947                                A85D8208087B2822006A9172 /* operations.h in Headers */,
     
    9791000                                A85D823D087B2822006A9172 /* npruntime_impl.h in Headers */,
    9801001                                A85D823E087B2822006A9172 /* fast_malloc.h in Headers */,
     1002                                65621E70089E85D300760F35 /* property_slot.h in Headers */,
    9811003                                A85D823F087B2822006A9172 /* create_hash_table in Headers */,
    9821004                        );
     
    15301552                                932F5BD00822A1C700736975 /* softlinking.c in Sources */,
    15311553                                932F5BD10822A1C700736975 /* fast_malloc.cpp in Sources */,
     1554                                65621E6D089E859700760F35 /* property_slot.cpp in Sources */,
    15321555                        );
    15331556                        runOnlyForDeploymentPostprocessing = 0;
     
    16171640                                A85D827F087B2822006A9172 /* softlinking.c in Sources */,
    16181641                                A85D8280087B2822006A9172 /* fast_malloc.cpp in Sources */,
     1642                                65621E6F089E85D300760F35 /* property_slot.cpp in Sources */,
    16191643                        );
    16201644                        runOnlyForDeploymentPostprocessing = 0;
  • trunk/JavaScriptCore/bindings/objc/objc_runtime.h

    r9889 r10076  
    170170    const ClassInfo *classInfo() const { return &info; }
    171171
    172     virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     172    virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&);
    173173
    174174    virtual void put(ExecState *exec, const Identifier &propertyName,
     
    180180    virtual Value call(ExecState *exec, Object &thisObj, const List &args);
    181181
    182     virtual bool hasOwnProperty(ExecState *exec,
    183                              const Identifier &propertyName) const;
    184 
    185 
    186     virtual bool deleteProperty(ExecState *exec,
    187                                 const Identifier &propertyName);
     182    virtual bool deleteProperty(ExecState *exec, const Identifier &propertyName);
    188183
    189184    virtual Value defaultValue(ExecState *exec, Type hint) const;
  • trunk/JavaScriptCore/bindings/objc/objc_runtime.mm

    r9889 r10076  
    263263
    264264ObjcFallbackObjectImp::ObjcFallbackObjectImp(ObjcInstance *i, const KJS::Identifier propertyName)
    265     : ObjectImp ((ObjectImp *)0)
    266265{
    267266    _instance = i;
     
    269268}
    270269
    271 bool ObjcFallbackObjectImp::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
     270bool ObjcFallbackObjectImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
    272271{
    273272    // keep the prototype from getting called instead of just returning false
    274     result = Undefined();
     273    slot.setUndefined(this);
    275274    return true;
    276275}
     
    336335}
    337336
    338 bool ObjcFallbackObjectImp::hasOwnProperty(ExecState *exec,
    339                          const Identifier &propertyName) const
    340 {
    341     return false;
    342 }
    343 
    344337bool ObjcFallbackObjectImp::deleteProperty(ExecState *exec,
    345338                            const Identifier &propertyName)
  • trunk/JavaScriptCore/bindings/runtime_array.cpp

    r9889 r10076  
    4444}
    4545
    46 bool RuntimeArrayImp::getOwnProperty(ExecState *exec, const Identifier &propertyName, Value& result) const
     46Value RuntimeArrayImp::lengthGetter(ExecState *exec, const Identifier& propertyName, const PropertySlot& slot)
     47{
     48    RuntimeArrayImp *thisObj = static_cast<RuntimeArrayImp *>(slot.slotBase());
     49    return Number(thisObj->getLength());
     50}
     51
     52Value RuntimeArrayImp::indexGetter(ExecState *exec, const Identifier& propertyName, const PropertySlot& slot)
     53{
     54    RuntimeArrayImp *thisObj = static_cast<RuntimeArrayImp *>(slot.slotBase());
     55    return thisObj->getConcreteArray()->valueAt(exec, slot.index());
     56}
     57
     58bool RuntimeArrayImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
    4759{
    4860    if (propertyName == lengthPropertyName) {
    49         result = Number(getLength());
     61        slot.setCustom(this, lengthGetter);
    5062        return true;
    5163    }
     
    5466    unsigned index = propertyName.toArrayIndex(&ok);
    5567    if (ok) {
    56         if (index >= getLength())
    57             result =  Undefined();
    58         else
    59             result = getConcreteArray()->valueAt(exec, index);
     68        if (index < getLength()) {
     69            slot.setCustomIndex(this, index, indexGetter);
     70            return true;
     71        }
     72    }
     73   
     74    return ArrayInstanceImp::getOwnPropertySlot(exec, propertyName, slot);
     75}
     76
     77bool RuntimeArrayImp::getOwnPropertySlot(ExecState *exec, unsigned index, PropertySlot& slot)
     78{
     79    if (index < getLength()) {
     80        slot.setCustomIndex(this, index, indexGetter);
    6081        return true;
    6182    }
    6283   
    63     return ArrayInstanceImp::getOwnProperty(exec, propertyName, result);
    64 }
    65 
    66 bool RuntimeArrayImp::getOwnProperty(ExecState *exec, unsigned index, Value& result) const
    67 {
    68     if (index >= getLength())
    69         result = Undefined();
    70     else
    71         result = getConcreteArray()->valueAt(exec, index);
    72    
    73     return true;
     84    return ArrayInstanceImp::getOwnPropertySlot(exec, index, slot);
    7485}
    7586
     
    103114}
    104115
    105 
    106 bool RuntimeArrayImp::hasOwnProperty(ExecState *exec, const Identifier &propertyName) const
    107 {
    108     if (propertyName == lengthPropertyName)
    109         return true;
    110    
    111     bool ok;
    112     unsigned index = propertyName.toArrayIndex(&ok);
    113     if (ok) {
    114         if (index >= getLength())
    115             return false;
    116         return true;
    117     }
    118    
    119     return ObjectImp::hasOwnProperty(exec, propertyName);
    120 }
    121 
    122 bool RuntimeArrayImp::hasOwnProperty(ExecState *exec, unsigned index) const
    123 {
    124     if (index >= getLength())
    125         return false;
    126     return true;
    127 }
    128 
    129116bool RuntimeArrayImp::deleteProperty(ExecState *exec, const Identifier &propertyName)
    130117{
  • trunk/JavaScriptCore/bindings/runtime_array.h

    r9889 r10076  
    3838    ~RuntimeArrayImp();
    3939   
    40     virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
    41     virtual bool getOwnProperty(ExecState *exec, unsigned index, Value& result) const ;
     40    virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&);
     41    virtual bool getOwnPropertySlot(ExecState *, unsigned, PropertySlot&);
    4242    virtual void put(ExecState *exec, const Identifier &propertyName, const Value &value, int attr = None);
    4343    virtual void put(ExecState *exec, unsigned propertyName, const Value &value, int attr = None);
    4444   
    45     virtual bool hasOwnProperty(ExecState *exec, const Identifier &propertyName) const;
    46     virtual bool hasOwnProperty(ExecState *exec, unsigned propertyName) const;
    4745    virtual bool deleteProperty(ExecState *exec, const Identifier &propertyName);
    4846    virtual bool deleteProperty(ExecState *exec, unsigned propertyName);
     
    5755
    5856private:
     57    static Value lengthGetter(ExecState *, const Identifier&, const PropertySlot&);
     58    static Value indexGetter(ExecState *, const Identifier&, const PropertySlot&);
     59
    5960    Bindings::Array *_array;
    6061};
  • trunk/JavaScriptCore/bindings/runtime_method.cpp

    r9889 r10076  
    4141}
    4242
    43 bool RuntimeMethodImp::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
     43Value RuntimeMethodImp::lengthGetter(ExecState *exec, const Identifier& propertyName, const PropertySlot& slot)
    4444{
    45     // Compute length of parameters.
     45    RuntimeMethodImp *thisObj = static_cast<RuntimeMethodImp *>(slot.slotBase());
     46
     47    // Ick!  There may be more than one method with this name.  Arbitrarily
     48    // just pick the first method.  The fundamental problem here is that
     49    // JavaScript doesn't have the notion of method overloading and
     50    // Java does.
     51    // FIXME: a better solution might be to give the maximum number of parameters
     52    // of any method
     53    return Number(thisObj->_methodList.methodAt(0)->numParameters());
     54}
     55
     56bool RuntimeMethodImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot &slot)
     57{
    4658    if (propertyName == lengthPropertyName) {
    47         // Ick!  There may be more than one method with this name.  Arbitrarily
    48         // just pick the first method.  The fundamental problem here is that
    49         // JavaScript doesn't have the notion of method overloading and
    50         // Java does.
    51         result = Number(_methodList.methodAt(0)->numParameters());
    52         return result;
     59        slot.setCustom(this, lengthGetter);
     60        return true;
    5361    }
    5462   
    55     return FunctionImp::getOwnProperty(exec, propertyName, result);
     63    return FunctionImp::getOwnPropertySlot(exec, propertyName, slot);
    5664}
    5765
  • trunk/JavaScriptCore/bindings/runtime_method.h

    r9889 r10076  
    3939    virtual ~RuntimeMethodImp();
    4040
    41     virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     41    virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&);
    4242
    4343    virtual bool implementsCall() const;
     
    4949
    5050private:
     51    static Value lengthGetter(ExecState *, const Identifier&, const PropertySlot&);
     52
    5153    Bindings::MethodList _methodList;
    5254};
  • trunk/JavaScriptCore/bindings/runtime_object.cpp

    r9889 r10076  
    5555}
    5656
    57 RuntimeObjectImp::RuntimeObjectImp(Bindings::Instance *i, bool oi) : ObjectImp ((ObjectImp *)0)
     57RuntimeObjectImp::RuntimeObjectImp(Bindings::Instance *i, bool oi)
    5858{
    5959    ownsInstance = oi;
     
    6161}
    6262
    63 bool RuntimeObjectImp::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
     63Value RuntimeObjectImp::fallbackObjectGetter(ExecState *exec, const Identifier& propertyName, const PropertySlot& slot)
     64{
     65    RuntimeObjectImp *thisObj = static_cast<RuntimeObjectImp *>(slot.slotBase());
     66    Bindings::Instance *instance = thisObj->instance;
     67
     68    instance->begin();
     69
     70    Class *aClass = instance->getClass();
     71    Value result = aClass->fallbackObject(exec, instance, propertyName);
     72
     73    instance->end();
     74           
     75    return result;
     76}
     77
     78Value RuntimeObjectImp::fieldGetter(ExecState *exec, const Identifier& propertyName, const PropertySlot& slot)
     79{
     80    RuntimeObjectImp *thisObj = static_cast<RuntimeObjectImp *>(slot.slotBase());
     81    Bindings::Instance *instance = thisObj->instance;
     82
     83    instance->begin();
     84
     85    Class *aClass = instance->getClass();
     86    Field *aField = aClass->fieldNamed(propertyName.ascii(), instance);
     87    Value result = instance->getValueOfField(exec, aField);
     88   
     89    instance->end();
     90           
     91    return result;
     92}
     93
     94Value RuntimeObjectImp::methodGetter(ExecState *exec, const Identifier& propertyName, const PropertySlot& slot)
     95{
     96    RuntimeObjectImp *thisObj = static_cast<RuntimeObjectImp *>(slot.slotBase());
     97    Bindings::Instance *instance = thisObj->instance;
     98
     99    instance->begin();
     100
     101    Class *aClass = instance->getClass();
     102    MethodList methodList = aClass->methodsNamed(propertyName.ascii(), instance);
     103    Value result = Object(new RuntimeMethodImp(exec, propertyName, methodList));
     104
     105    instance->end();
     106           
     107    return result;
     108}
     109
     110bool RuntimeObjectImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
    64111{
    65112    instance->begin();
     
    68115   
    69116    if (aClass) {
    70         // See if the instance have a field with the specified name.
     117        // See if the instance has a field with the specified name.
    71118        Field *aField = aClass->fieldNamed(propertyName.ascii(), instance);
    72119        if (aField) {
    73             result = instance->getValueOfField(exec, aField);
     120            slot.setCustom(this, fieldGetter);
     121            instance->end();
    74122            return true;
    75123        } else {
     
    78126            MethodList methodList = aClass->methodsNamed(propertyName.ascii(), instance);
    79127            if (methodList.length() > 0) {
    80                 result = Object(new RuntimeMethodImp(exec, propertyName, methodList));
     128                slot.setCustom(this, methodGetter);
     129                instance->end();
    81130                return true;
    82131            }
    83132        }
    84133       
    85         if (result.type() == UndefinedType) {
    86             // Try a fallback object.
    87             result = aClass->fallbackObject(exec, instance, propertyName);
     134        // Try a fallback object.
     135        if (!aClass->fallbackObject(exec, instance, propertyName).type() != UndefinedType) {
     136            slot.setCustom(this, fallbackObjectGetter);
     137            instance->end();
    88138            return true;
    89139        }
     
    131181}
    132182
    133 bool RuntimeObjectImp::hasOwnProperty(ExecState *exec,
    134                             const Identifier &propertyName) const
    135 {
    136     bool result = false;
    137    
    138     instance->begin();
    139 
    140     Field *aField = instance->getClass()->fieldNamed(propertyName.ascii(), instance);
    141     if (aField) {
    142         instance->end();
    143         return true;
    144     }
    145        
    146     MethodList methodList = instance->getClass()->methodsNamed(propertyName.ascii(), instance);
    147 
    148     instance->end();
    149 
    150     if (methodList.length() > 0)
    151         return true;
    152 
    153     return result;
    154 }
    155 
    156183bool RuntimeObjectImp::deleteProperty(ExecState *exec,
    157184                            const Identifier &propertyName)
  • trunk/JavaScriptCore/bindings/runtime_object.h

    r9889 r10076  
    4242    const ClassInfo *classInfo() const { return &info; }
    4343
    44     virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     44    virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&);
    4545
    4646    virtual void put(ExecState *exec, const Identifier &propertyName,
     
    4848
    4949    virtual bool canPut(ExecState *exec, const Identifier &propertyName) const;
    50 
    51     virtual bool hasOwnProperty(ExecState *exec,
    52                              const Identifier &propertyName) const;
    53 
    5450
    5551    virtual bool deleteProperty(ExecState *exec,
     
    6763
    6864private:
     65    static Value fallbackObjectGetter(ExecState *, const Identifier&, const PropertySlot&);
     66    static Value fieldGetter(ExecState *, const Identifier&, const PropertySlot&);
     67    static Value methodGetter(ExecState *, const Identifier&, const PropertySlot&);
     68
    6969    Bindings::Instance *instance;
    7070    bool ownsInstance;
  • trunk/JavaScriptCore/bindings/runtime_root.h

    r9145 r10076  
    2828#include <JavaScriptCore/interpreter.h>
    2929#include <JavaScriptCore/object.h>
     30#include <JavaScriptCore/protect.h>
    3031#include <JavaScriptCore/jni_jsobject.h>
    3132
  • trunk/JavaScriptCore/kjs/array_instance.h

    r9889 r10076  
    3434    ~ArrayInstanceImp();
    3535
    36     virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
    37     virtual bool getOwnProperty(ExecState *exec, unsigned index, Value& result) const;
     36    virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&);
     37    virtual bool getOwnPropertySlot(ExecState *, unsigned, PropertySlot&);
    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);
    40     virtual bool hasOwnProperty(ExecState *exec, const Identifier &propertyName) const;
    41     virtual bool hasOwnProperty(ExecState *exec, unsigned propertyName) const;
    4240    virtual bool deleteProperty(ExecState *exec, const Identifier &propertyName);
    4341    virtual bool deleteProperty(ExecState *exec, unsigned propertyName);
     
    5553   
    5654  private:
     55    static Value lengthGetter(ExecState *, const Identifier&, const PropertySlot&);
     56
    5757    void setLength(unsigned newLength, ExecState *exec);
    5858   
  • trunk/JavaScriptCore/kjs/array_object.cpp

    r9932 r10076  
    7171}
    7272
    73 bool ArrayInstanceImp::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
     73Value ArrayInstanceImp::lengthGetter(ExecState *exec, const Identifier& propertyName, const PropertySlot& slot)
     74{
     75  return Number(static_cast<ArrayInstanceImp *>(slot.slotBase())->length);
     76}
     77
     78bool ArrayInstanceImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
    7479{
    7580  if (propertyName == lengthPropertyName) {
    76     result = Number(length);
     81    slot.setCustom(this, lengthGetter);
    7782    return true;
    7883  }
     
    8792      if (!v || v == UndefinedImp::staticUndefined)
    8893        return false;
    89 
    90       result = Value(v);
     94     
     95      slot.setValueSlot(this, &storage[index]);
    9196      return true;
    9297    }
    9398  }
    9499
    95   return ObjectImp::getOwnProperty(exec, propertyName, result);
    96 }
    97 
    98 bool ArrayInstanceImp::getOwnProperty(ExecState *exec, unsigned index, Value& result) const
     100  return ObjectImp::getOwnPropertySlot(exec, propertyName, slot);
     101}
     102
     103bool ArrayInstanceImp::getOwnPropertySlot(ExecState *exec, unsigned index, PropertySlot& slot)
    99104{
    100105  if (index >= length)
     
    104109    if (!v || v == UndefinedImp::staticUndefined)
    105110      return false;
    106 
    107     result = Value(v);
     111   
     112    slot.setValueSlot(this, &storage[index]);
    108113    return true;
    109114  }
    110  
    111   return ObjectImp::getOwnProperty(exec, Identifier::from(index), result);
     115
     116  return ObjectImp::getOwnPropertySlot(exec, index, slot);
    112117}
    113118
     
    147152  assert(index >= sparseArrayCutoff);
    148153  ObjectImp::put(exec, Identifier::from(index), value, attr);
    149 }
    150 
    151 bool ArrayInstanceImp::hasOwnProperty(ExecState *exec, const Identifier &propertyName) const
    152 {
    153   if (propertyName == lengthPropertyName)
    154     return true;
    155  
    156   bool ok;
    157   unsigned index = propertyName.toArrayIndex(&ok);
    158   if (ok) {
    159     if (index >= length)
    160       return false;
    161     if (index < storageLength) {
    162       ValueImp *v = storage[index];
    163       return v && v != UndefinedImp::staticUndefined;
    164     }
    165   }
    166  
    167   return ObjectImp::hasOwnProperty(exec, propertyName);
    168 }
    169 
    170 bool ArrayInstanceImp::hasOwnProperty(ExecState *exec, unsigned index) const
    171 {
    172   if (index >= length)
    173     return false;
    174   if (index < storageLength) {
    175     ValueImp *v = storage[index];
    176     return v && v != UndefinedImp::staticUndefined;
    177   }
    178  
    179   return ObjectImp::hasOwnProperty(exec, Identifier::from(index));
    180154}
    181155
     
    429403}
    430404
    431 bool ArrayPrototypeImp::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
    432 {
    433   return lookupGetOwnFunction<ArrayProtoFuncImp, ArrayInstanceImp>(exec, propertyName, &arrayTable, this, result);
     405bool ArrayPrototypeImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
     406{
     407  return getStaticFunctionSlot<ArrayProtoFuncImp, ArrayInstanceImp>(exec, &arrayTable, this, propertyName, slot);
    434408}
    435409
  • trunk/JavaScriptCore/kjs/array_object.h

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

    r9924 r10076  
    491491}
    492492
    493 bool DatePrototypeImp::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
    494 {
    495   return lookupGetOwnFunction<DateProtoFuncImp, ObjectImp>(exec, propertyName, &dateTable, this, result);
     493bool DatePrototypeImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
     494{
     495  return getStaticFunctionSlot<DateProtoFuncImp, ObjectImp>(exec, &dateTable, this, propertyName, slot);
    496496}
    497497
  • trunk/JavaScriptCore/kjs/date_object.h

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

    r9929 r10076  
    209209}
    210210
    211 bool FunctionImp::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
     211Value FunctionImp::argumentsGetter(ExecState *exec, const Identifier& propertyName, const PropertySlot& slot)
     212{
     213  FunctionImp *thisObj = static_cast<FunctionImp *>(slot.slotBase());
     214  ContextImp *context = exec->_context;
     215  while (context) {
     216    if (context->function() == thisObj) {
     217      return static_cast<ActivationImp *>(context->activationObject())->get(exec, propertyName);
     218    }
     219    context = context->callingContext();
     220  }
     221  return Null();
     222}
     223
     224Value FunctionImp::lengthGetter(ExecState *exec, const Identifier& propertyName, const PropertySlot& slot)
     225{
     226  FunctionImp *thisObj = static_cast<FunctionImp *>(slot.slotBase());
     227  const Parameter *p = thisObj->param;
     228  int count = 0;
     229  while (p) {
     230    ++count;
     231    p = p->next;
     232  }
     233  return Number(count);
     234}
     235
     236bool FunctionImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
    212237{
    213238    // Find the arguments from the closest context.
    214     if (propertyName == argumentsPropertyName) {
    215         ContextImp *context = exec->_context;
    216         while (context) {
    217           if (context->function() == this) {
    218             result = static_cast<ActivationImp *>(context->activationObject())->get(exec, propertyName);
    219             return true;
    220           }
    221           context = context->callingContext();
    222         }
    223         result = Null();
     239    if (propertyName == exec->dynamicInterpreter()->argumentsIdentifier()) {
     240        slot.setCustom(this, argumentsGetter);
    224241        return true;
    225242    }
     
    227244    // Compute length of parameters.
    228245    if (propertyName == lengthPropertyName) {
    229         const Parameter * p = param;
    230         int count = 0;
    231         while (p) {
    232             ++count;
    233             p = p->next;
    234         }
    235         result = Number(count);
     246        slot.setCustom(this, lengthGetter);
    236247        return true;
    237248    }
    238249   
    239     return InternalFunctionImp::getOwnProperty(exec, propertyName, result);
     250    return InternalFunctionImp::getOwnPropertySlot(exec, propertyName, slot);
    240251}
    241252
    242253void FunctionImp::put(ExecState *exec, const Identifier &propertyName, const Value &value, int attr)
    243254{
    244     if (propertyName == argumentsPropertyName || propertyName == lengthPropertyName)
     255    if (propertyName == exec->dynamicInterpreter()->argumentsIdentifier() || propertyName == lengthPropertyName)
    245256        return;
    246257    InternalFunctionImp::put(exec, propertyName, value, attr);
    247258}
    248259
    249 bool FunctionImp::hasOwnProperty(ExecState *exec, const Identifier &propertyName) const
    250 {
    251     if (propertyName == argumentsPropertyName || propertyName == lengthPropertyName)
    252         return true;
    253     return InternalFunctionImp::hasOwnProperty(exec, propertyName);
    254 }
    255 
    256260bool FunctionImp::deleteProperty(ExecState *exec, const Identifier &propertyName)
    257261{
    258     if (propertyName == argumentsPropertyName || propertyName == lengthPropertyName)
     262    if (propertyName == exec->dynamicInterpreter()->argumentsIdentifier() || propertyName == lengthPropertyName)
    259263        return false;
    260264    return InternalFunctionImp::deleteProperty(exec, propertyName);
     
    450454}
    451455
    452 bool ArgumentsImp::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
     456Value ArgumentsImp::mappedIndexGetter(ExecState *exec, const Identifier& propertyName, const PropertySlot& slot)
     457{
     458  ArgumentsImp *thisObj = static_cast<ArgumentsImp *>(slot.slotBase());
     459  return thisObj->_activationObject->get(exec, thisObj->indexToNameMap[propertyName]);
     460}
     461
     462bool ArgumentsImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
    453463{
    454464  if (indexToNameMap.isMapped(propertyName)) {
    455     result = _activationObject->get(exec, indexToNameMap[propertyName]);
     465    slot.setCustom(this, mappedIndexGetter);
    456466    return true;
    457467  }
    458468
    459   return ObjectImp::getOwnProperty(exec, propertyName, result);
     469  return ObjectImp::getOwnPropertySlot(exec, propertyName, slot);
    460470}
    461471
     
    479489}
    480490
    481 bool ArgumentsImp::hasOwnProperty(ExecState *exec, const Identifier &propertyName) const
    482 {
    483   if (indexToNameMap.isMapped(propertyName))
    484     return true;
    485  
    486   return ObjectImp::hasOwnProperty(exec, propertyName);
    487 }
    488 
    489491// ------------------------------ ActivationImp --------------------------------
    490492
     
    499501}
    500502
    501 bool ActivationImp::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
     503Value ActivationImp::argumentsGetter(ExecState *exec, const Identifier& propertyName, const PropertySlot& slot)
     504{
     505  ActivationImp *thisObj = static_cast<ActivationImp *>(slot.slotBase());
     506
     507  // default: return builtin arguments array
     508  if (!thisObj->_argumentsObject)
     509    thisObj->createArgumentsObject(exec);
     510 
     511  return Value(thisObj->_argumentsObject);
     512}
     513
     514PropertySlot::GetValueFunc ActivationImp::getArgumentsGetter()
     515{
     516  return ActivationImp::argumentsGetter;
     517}
     518
     519bool ActivationImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
    502520{
    503521    // do this first so property map arguments property wins over the below
    504     if (ObjectImp::getOwnProperty(exec, propertyName, result))
     522    if (ObjectImp::getOwnPropertySlot(exec, propertyName, slot))
    505523        return true;
    506524
    507     if (propertyName == argumentsPropertyName) {
    508         // default: return builtin arguments array
    509         if (!_argumentsObject)
    510             createArgumentsObject(exec);
    511 
    512         result = Value(_argumentsObject);
     525    if (propertyName == exec->dynamicInterpreter()->argumentsIdentifier()) {
     526        slot.setCustom(this, getArgumentsGetter());
    513527        return true;
    514528    }
     
    517531}
    518532
    519 bool ActivationImp::hasOwnProperty(ExecState *exec, const Identifier &propertyName) const
    520 {
    521     if (propertyName == argumentsPropertyName)
    522         return true;
    523     return ObjectImp::hasOwnProperty(exec, propertyName);
    524 }
    525 
    526533bool ActivationImp::deleteProperty(ExecState *exec, const Identifier &propertyName)
    527534{
    528     if (propertyName == argumentsPropertyName)
     535    if (propertyName == exec->dynamicInterpreter()->argumentsIdentifier())
    529536        return false;
    530537    return ObjectImp::deleteProperty(exec, propertyName);
  • trunk/JavaScriptCore/kjs/function.h

    r9917 r10076  
    4343    virtual ~FunctionImp();
    4444
    45     virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     45    virtual bool getOwnPropertySlot(ExecState *, const Identifier &, PropertySlot&);
    4646    virtual void put(ExecState *exec, const Identifier &propertyName, const Value &value, int attr = None);
    47     virtual bool hasOwnProperty(ExecState *exec, const Identifier &propertyName) const;
    4847    virtual bool deleteProperty(ExecState *exec, const Identifier &propertyName);
    4948
     
    6766
    6867  private:
     68    static Value argumentsGetter(ExecState *, const Identifier &, const PropertySlot&);
     69    static Value lengthGetter(ExecState *, const Identifier &, const PropertySlot&);
     70
    6971    void processParameters(ExecState *exec, const List &);
    7072    virtual void processVarDecls(ExecState *exec);
     
    110112    ArgumentsImp(ExecState *exec, FunctionImp *func, const List &args, ActivationImp *act);
    111113    virtual void mark();
    112     virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     114    virtual bool getOwnPropertySlot(ExecState *, const Identifier &, PropertySlot&);
    113115    virtual void put(ExecState *exec, const Identifier &propertyName,
    114116                     const Value &value, int attr = None);
    115     virtual bool hasOwnProperty(ExecState *exec, const Identifier &propertyName) const;
    116117    virtual bool deleteProperty(ExecState *exec, const Identifier &propertyName);
    117118    virtual const ClassInfo *classInfo() const { return &info; }
    118119    static const ClassInfo info;
    119120  private:
     121    static Value mappedIndexGetter(ExecState *exec, const Identifier &, const PropertySlot& slot);
     122
    120123    ActivationImp *_activationObject;
    121124    mutable IndexToNameMap indexToNameMap;
     
    126129    ActivationImp(FunctionImp *function, const List &arguments);
    127130
    128     virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
    129     virtual bool hasOwnProperty(ExecState *exec, const Identifier &propertyName) const;
     131    virtual bool getOwnPropertySlot(ExecState *exec, const Identifier &, PropertySlot&);
    130132    virtual bool deleteProperty(ExecState *exec, const Identifier &propertyName);
    131133
     
    136138
    137139  private:
     140    static PropertySlot::GetValueFunc getArgumentsGetter();
     141    static Value argumentsGetter(ExecState *exec, const Identifier &, const PropertySlot& slot);
    138142    void createArgumentsObject(ExecState *exec) const;
    139143   
  • trunk/JavaScriptCore/kjs/internal.cpp

    r9929 r10076  
    498498
    499499InterpreterImp::InterpreterImp(Interpreter *interp, const Object &glob)
    500     : _context(0)
     500  : globExec(interp, 0)
     501  , _context(0)
    501502{
    502503  // add this interpreter to the global chain
     
    518519
    519520  global = glob;
    520   globExec = new ExecState(m_interpreter,0);
    521521  dbg = 0;
    522522  m_compatMode = Interpreter::NativeMode;
     
    550550  // Contructor prototype objects (Object.prototype, Array.prototype etc)
    551551
    552   FunctionPrototypeImp *funcProto = new FunctionPrototypeImp(globExec);
     552  FunctionPrototypeImp *funcProto = new FunctionPrototypeImp(&globExec);
    553553  b_FunctionPrototype = Object(funcProto);
    554   ObjectPrototypeImp *objProto = new ObjectPrototypeImp(globExec,funcProto);
     554  ObjectPrototypeImp *objProto = new ObjectPrototypeImp(&globExec, funcProto);
    555555  b_ObjectPrototype = Object(objProto);
    556556  funcProto->setPrototype(b_ObjectPrototype);
    557557
    558   ArrayPrototypeImp *arrayProto = new ArrayPrototypeImp(globExec,objProto);
     558  ArrayPrototypeImp *arrayProto = new ArrayPrototypeImp(&globExec, objProto);
    559559  b_ArrayPrototype = Object(arrayProto);
    560   StringPrototypeImp *stringProto = new StringPrototypeImp(globExec,objProto);
     560  StringPrototypeImp *stringProto = new StringPrototypeImp(&globExec, objProto);
    561561  b_StringPrototype = Object(stringProto);
    562   BooleanPrototypeImp *booleanProto = new BooleanPrototypeImp(globExec,objProto,funcProto);
     562  BooleanPrototypeImp *booleanProto = new BooleanPrototypeImp(&globExec, objProto, funcProto);
    563563  b_BooleanPrototype = Object(booleanProto);
    564   NumberPrototypeImp *numberProto = new NumberPrototypeImp(globExec,objProto,funcProto);
     564  NumberPrototypeImp *numberProto = new NumberPrototypeImp(&globExec, objProto, funcProto);
    565565  b_NumberPrototype = Object(numberProto);
    566   DatePrototypeImp *dateProto = new DatePrototypeImp(globExec,objProto);
     566  DatePrototypeImp *dateProto = new DatePrototypeImp(&globExec, objProto);
    567567  b_DatePrototype = Object(dateProto);
    568   RegExpPrototypeImp *regexpProto = new RegExpPrototypeImp(globExec,objProto,funcProto);
     568  RegExpPrototypeImp *regexpProto = new RegExpPrototypeImp(&globExec, objProto, funcProto);
    569569  b_RegExpPrototype = Object(regexpProto);
    570   ErrorPrototypeImp *errorProto = new ErrorPrototypeImp(globExec,objProto,funcProto);
     570  ErrorPrototypeImp *errorProto = new ErrorPrototypeImp(&globExec, objProto, funcProto);
    571571  b_ErrorPrototype = Object(errorProto);
    572572
     
    574574
    575575  // Constructors (Object, Array, etc.)
    576   b_Object = Object(new ObjectObjectImp(globExec, objProto, funcProto));
    577   b_Function = Object(new FunctionObjectImp(globExec, funcProto));
    578   b_Array = Object(new ArrayObjectImp(globExec, funcProto, arrayProto));
    579   b_String = Object(new StringObjectImp(globExec, funcProto, stringProto));
    580   b_Boolean = Object(new BooleanObjectImp(globExec, funcProto, booleanProto));
    581   b_Number = Object(new NumberObjectImp(globExec, funcProto, numberProto));
    582   b_Date = Object(new DateObjectImp(globExec, funcProto, dateProto));
    583   b_RegExp = Object(new RegExpObjectImp(globExec, funcProto, regexpProto));
    584   b_Error = Object(new ErrorObjectImp(globExec, funcProto, errorProto));
     576  b_Object = Object(new ObjectObjectImp(&globExec, objProto, funcProto));
     577  b_Function = Object(new FunctionObjectImp(&globExec, funcProto));
     578  b_Array = Object(new ArrayObjectImp(&globExec, funcProto, arrayProto));
     579  b_String = Object(new StringObjectImp(&globExec, funcProto, stringProto));
     580  b_Boolean = Object(new BooleanObjectImp(&globExec, funcProto, booleanProto));
     581  b_Number = Object(new NumberObjectImp(&globExec, funcProto, numberProto));
     582  b_Date = Object(new DateObjectImp(&globExec, funcProto, dateProto));
     583  b_RegExp = Object(new RegExpObjectImp(&globExec, funcProto, regexpProto));
     584  b_Error = Object(new ErrorObjectImp(&globExec, funcProto, errorProto));
    585585
    586586  // Error object prototypes
    587   b_evalErrorPrototype = Object(new NativeErrorPrototypeImp(globExec,errorProto,EvalError,
    588                                                             "EvalError","EvalError"));
    589   b_rangeErrorPrototype = Object(new NativeErrorPrototypeImp(globExec,errorProto,RangeError,
    590                                                             "RangeError","RangeError"));
    591   b_referenceErrorPrototype = Object(new NativeErrorPrototypeImp(globExec,errorProto,ReferenceError,
    592                                                             "ReferenceError","ReferenceError"));
    593   b_syntaxErrorPrototype = Object(new NativeErrorPrototypeImp(globExec,errorProto,SyntaxError,
    594                                                             "SyntaxError","SyntaxError"));
    595   b_typeErrorPrototype = Object(new NativeErrorPrototypeImp(globExec,errorProto,TypeError,
    596                                                             "TypeError","TypeError"));
    597   b_uriErrorPrototype = Object(new NativeErrorPrototypeImp(globExec,errorProto,URIError,
    598                                                             "URIError","URIError"));
     587  b_evalErrorPrototype = Object(new NativeErrorPrototypeImp(&globExec, errorProto, EvalError,
     588                                                            "EvalError", "EvalError"));
     589  b_rangeErrorPrototype = Object(new NativeErrorPrototypeImp(&globExec, errorProto, RangeError,
     590                                                            "RangeError", "RangeError"));
     591  b_referenceErrorPrototype = Object(new NativeErrorPrototypeImp(&globExec, errorProto, ReferenceError,
     592                                                            "ReferenceError", "ReferenceError"));
     593  b_syntaxErrorPrototype = Object(new NativeErrorPrototypeImp(&globExec, errorProto, SyntaxError,
     594                                                            "SyntaxError", "SyntaxError"));
     595  b_typeErrorPrototype = Object(new NativeErrorPrototypeImp(&globExec, errorProto, TypeError,
     596                                                            "TypeError", "TypeError"));
     597  b_uriErrorPrototype = Object(new NativeErrorPrototypeImp(&globExec, errorProto, URIError,
     598                                                            "URIError", "URIError"));
    599599
    600600  // Error objects
    601   b_evalError = Object(new NativeErrorImp(globExec,funcProto,b_evalErrorPrototype));
    602   b_rangeError = Object(new NativeErrorImp(globExec,funcProto,b_rangeErrorPrototype));
    603   b_referenceError = Object(new NativeErrorImp(globExec,funcProto,b_referenceErrorPrototype));
    604   b_syntaxError = Object(new NativeErrorImp(globExec,funcProto,b_syntaxErrorPrototype));
    605   b_typeError = Object(new NativeErrorImp(globExec,funcProto,b_typeErrorPrototype));
    606   b_uriError = Object(new NativeErrorImp(globExec,funcProto,b_uriErrorPrototype));
     601  b_evalError = Object(new NativeErrorImp(&globExec, funcProto, b_evalErrorPrototype));
     602  b_rangeError = Object(new NativeErrorImp(&globExec, funcProto, b_rangeErrorPrototype));
     603  b_referenceError = Object(new NativeErrorImp(&globExec, funcProto, b_referenceErrorPrototype));
     604  b_syntaxError = Object(new NativeErrorImp(&globExec, funcProto, b_syntaxErrorPrototype));
     605  b_typeError = Object(new NativeErrorImp(&globExec, funcProto, b_typeErrorPrototype));
     606  b_uriError = Object(new NativeErrorImp(&globExec, funcProto, b_uriErrorPrototype));
    607607
    608608  // ECMA 15.3.4.1
    609   funcProto->put(globExec,"constructor", b_Function, DontEnum);
    610 
    611   global.put(globExec,"Object", b_Object, DontEnum);
    612   global.put(globExec,"Function", b_Function, DontEnum);
    613   global.put(globExec,"Array", b_Array, DontEnum);
    614   global.put(globExec,"Boolean", b_Boolean, DontEnum);
    615   global.put(globExec,"String", b_String, DontEnum);
    616   global.put(globExec,"Number", b_Number, DontEnum);
    617   global.put(globExec,"Date", b_Date, DontEnum);
    618   global.put(globExec,"RegExp", b_RegExp, DontEnum);
    619   global.put(globExec,"Error", b_Error, DontEnum);
     609  funcProto->put(&globExec, "constructor", b_Function, DontEnum);
     610
     611  global.put(&globExec, "Object", b_Object, DontEnum);
     612  global.put(&globExec, "Function", b_Function, DontEnum);
     613  global.put(&globExec, "Array", b_Array, DontEnum);
     614  global.put(&globExec, "Boolean", b_Boolean, DontEnum);
     615  global.put(&globExec, "String", b_String, DontEnum);
     616  global.put(&globExec, "Number", b_Number, DontEnum);
     617  global.put(&globExec, "Date", b_Date, DontEnum);
     618  global.put(&globExec, "RegExp", b_RegExp, DontEnum);
     619  global.put(&globExec, "Error", b_Error, DontEnum);
    620620  // Using Internal for those to have something != 0
    621621  // (see kjs_window). Maybe DontEnum would be ok too ?
    622   global.put(globExec,"EvalError",b_evalError, Internal);
    623   global.put(globExec,"RangeError",b_rangeError, Internal);
    624   global.put(globExec,"ReferenceError",b_referenceError, Internal);
    625   global.put(globExec,"SyntaxError",b_syntaxError, Internal);
    626   global.put(globExec,"TypeError",b_typeError, Internal);
    627   global.put(globExec,"URIError",b_uriError, Internal);
     622  global.put(&globExec, "EvalError",b_evalError, Internal);
     623  global.put(&globExec, "RangeError",b_rangeError, Internal);
     624  global.put(&globExec, "ReferenceError",b_referenceError, Internal);
     625  global.put(&globExec, "SyntaxError",b_syntaxError, Internal);
     626  global.put(&globExec, "TypeError",b_typeError, Internal);
     627  global.put(&globExec, "URIError",b_uriError, Internal);
    628628
    629629  // Set the "constructor" property of all builtin constructors
    630   objProto->put(globExec, "constructor", b_Object, DontEnum | DontDelete | ReadOnly);
    631   funcProto->put(globExec, "constructor", b_Function, DontEnum | DontDelete | ReadOnly);
    632   arrayProto->put(globExec, "constructor", b_Array, DontEnum | DontDelete | ReadOnly);
    633   booleanProto->put(globExec, "constructor", b_Boolean, DontEnum | DontDelete | ReadOnly);
    634   stringProto->put(globExec, "constructor", b_String, DontEnum | DontDelete | ReadOnly);
    635   numberProto->put(globExec, "constructor", b_Number, DontEnum | DontDelete | ReadOnly);
    636   dateProto->put(globExec, "constructor", b_Date, DontEnum | DontDelete | ReadOnly);
    637   regexpProto->put(globExec, "constructor", b_RegExp, DontEnum | DontDelete | ReadOnly);
    638   errorProto->put(globExec, "constructor", b_Error, DontEnum | DontDelete | ReadOnly);
    639   b_evalErrorPrototype.put(globExec, "constructor", b_evalError, DontEnum | DontDelete | ReadOnly);
    640   b_rangeErrorPrototype.put(globExec, "constructor", b_rangeError, DontEnum | DontDelete | ReadOnly);
    641   b_referenceErrorPrototype.put(globExec, "constructor", b_referenceError, DontEnum | DontDelete | ReadOnly);
    642   b_syntaxErrorPrototype.put(globExec, "constructor", b_syntaxError, DontEnum | DontDelete | ReadOnly);
    643   b_typeErrorPrototype.put(globExec, "constructor", b_typeError, DontEnum | DontDelete | ReadOnly);
    644   b_uriErrorPrototype.put(globExec, "constructor", b_uriError, DontEnum | DontDelete | ReadOnly);
     630  objProto->put(&globExec, "constructor", b_Object, DontEnum | DontDelete | ReadOnly);
     631  funcProto->put(&globExec, "constructor", b_Function, DontEnum | DontDelete | ReadOnly);
     632  arrayProto->put(&globExec, "constructor", b_Array, DontEnum | DontDelete | ReadOnly);
     633  booleanProto->put(&globExec, "constructor", b_Boolean, DontEnum | DontDelete | ReadOnly);
     634  stringProto->put(&globExec, "constructor", b_String, DontEnum | DontDelete | ReadOnly);
     635  numberProto->put(&globExec, "constructor", b_Number, DontEnum | DontDelete | ReadOnly);
     636  dateProto->put(&globExec, "constructor", b_Date, DontEnum | DontDelete | ReadOnly);
     637  regexpProto->put(&globExec, "constructor", b_RegExp, DontEnum | DontDelete | ReadOnly);
     638  errorProto->put(&globExec, "constructor", b_Error, DontEnum | DontDelete | ReadOnly);
     639  b_evalErrorPrototype.put(&globExec, "constructor", b_evalError, DontEnum | DontDelete | ReadOnly);
     640  b_rangeErrorPrototype.put(&globExec, "constructor", b_rangeError, DontEnum | DontDelete | ReadOnly);
     641  b_referenceErrorPrototype.put(&globExec, "constructor", b_referenceError, DontEnum | DontDelete | ReadOnly);
     642  b_syntaxErrorPrototype.put(&globExec, "constructor", b_syntaxError, DontEnum | DontDelete | ReadOnly);
     643  b_typeErrorPrototype.put(&globExec, "constructor", b_typeError, DontEnum | DontDelete | ReadOnly);
     644  b_uriErrorPrototype.put(&globExec, "constructor", b_uriError, DontEnum | DontDelete | ReadOnly);
    645645
    646646  // built-in values
    647   global.put(globExec, "NaN",        Number(NaN), DontEnum|DontDelete);
    648   global.put(globExec, "Infinity",   Number(Inf), DontEnum|DontDelete);
    649   global.put(globExec, "undefined",  Undefined(), DontEnum|DontDelete);
     647  global.put(&globExec, "NaN",        Number(NaN), DontEnum|DontDelete);
     648  global.put(&globExec, "Infinity",   Number(Inf), DontEnum|DontDelete);
     649  global.put(&globExec, "undefined",  Undefined(), DontEnum|DontDelete);
    650650
    651651  // built-in functions
    652   global.put(globExec,"eval",       Object(new GlobalFuncImp(globExec,funcProto,GlobalFuncImp::Eval,      1)), DontEnum);
    653   global.put(globExec,"parseInt",   Object(new GlobalFuncImp(globExec,funcProto,GlobalFuncImp::ParseInt,  2)), DontEnum);
    654   global.put(globExec,"parseFloat", Object(new GlobalFuncImp(globExec,funcProto,GlobalFuncImp::ParseFloat, 1)), DontEnum);
    655   global.put(globExec,"isNaN",      Object(new GlobalFuncImp(globExec,funcProto,GlobalFuncImp::IsNaN,      1)), DontEnum);
    656   global.put(globExec,"isFinite",   Object(new GlobalFuncImp(globExec,funcProto,GlobalFuncImp::IsFinite,  1)), DontEnum);
    657   global.put(globExec,"escape",     Object(new GlobalFuncImp(globExec,funcProto,GlobalFuncImp::Escape,    1)), DontEnum);
    658   global.put(globExec,"unescape",   Object(new GlobalFuncImp(globExec,funcProto,GlobalFuncImp::UnEscape,  1)), DontEnum);
    659   global.put(globExec,"decodeURI",  Object(new GlobalFuncImp(globExec,funcProto,GlobalFuncImp::DecodeURI, 1)), DontEnum);
    660   global.put(globExec,"decodeURIComponent", Object(new GlobalFuncImp(globExec,funcProto,GlobalFuncImp::DecodeURIComponent, 1)), DontEnum);
    661   global.put(globExec,"encodeURI",  Object(new GlobalFuncImp(globExec,funcProto,GlobalFuncImp::EncodeURI, 1)), DontEnum);
    662   global.put(globExec,"encodeURIComponent", Object(new GlobalFuncImp(globExec,funcProto,GlobalFuncImp::EncodeURIComponent, 1)), DontEnum);
     652  global.put(&globExec, "eval",       Object(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::Eval, 1)), DontEnum);
     653  global.put(&globExec, "parseInt",   Object(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::ParseInt, 2)), DontEnum);
     654  global.put(&globExec, "parseFloat", Object(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::ParseFloat, 1)), DontEnum);
     655  global.put(&globExec, "isNaN",      Object(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::IsNaN, 1)), DontEnum);
     656  global.put(&globExec, "isFinite",   Object(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::IsFinite, 1)), DontEnum);
     657  global.put(&globExec, "escape",     Object(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::Escape, 1)), DontEnum);
     658  global.put(&globExec, "unescape",   Object(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::UnEscape, 1)), DontEnum);
     659  global.put(&globExec, "decodeURI",  Object(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::DecodeURI, 1)), DontEnum);
     660  global.put(&globExec, "decodeURIComponent", Object(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::DecodeURIComponent, 1)), DontEnum);
     661  global.put(&globExec, "encodeURI",  Object(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::EncodeURI, 1)), DontEnum);
     662  global.put(&globExec, "encodeURIComponent", Object(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::EncodeURIComponent, 1)), DontEnum);
    663663#ifndef NDEBUG
    664   global.put(globExec,"kjsprint",   Object(new GlobalFuncImp(globExec,funcProto,GlobalFuncImp::KJSPrint,  1)), DontEnum);
     664  global.put(&globExec, "kjsprint",   Object(new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::KJSPrint, 1)), DontEnum);
    665665#endif
    666666
    667667  // built-in objects
    668   global.put(globExec,"Math", Object(new MathObjectImp(globExec,objProto)), DontEnum);
     668  global.put(&globExec, "Math", Object(new MathObjectImp(&globExec, objProto)), DontEnum);
    669669}
    670670
     
    673673  if (dbg)
    674674    dbg->detach(m_interpreter);
    675   delete globExec;
    676   globExec = 0L;
    677675  clear();
    678676}
     
    746744  if (recursion >= 20) {
    747745#if APPLE_CHANGES
    748     Completion result = Completion(Throw,Error::create(globExec,GeneralError,"Recursion too deep"));
     746    Completion result = Completion(Throw, Error::create(&globExec, GeneralError, "Recursion too deep"));
    749747    unlockInterpreter();
    750748    return result;
    751749#else
    752     return Completion(Throw,Error::create(globExec,GeneralError,"Recursion too deep"));
     750    return Completion(Throw,Error::create(&globExec, GeneralError, "Recursion too deep"));
    753751#endif
    754752  }
     
    762760  // notify debugger that source has been parsed
    763761  if (dbg) {
    764     bool cont = dbg->sourceParsed(globExec,sid,sourceURL,code,errLine);
     762    bool cont = dbg->sourceParsed(&globExec, sid, sourceURL, code, errLine);
    765763    if (!cont)
    766764#if APPLE_CHANGES
     
    776774  // no program node means a syntax error occurred
    777775  if (!progNode) {
    778     Object err = Error::create(globExec,SyntaxError,errMsg.ascii(),errLine, -1, &sourceURL);
    779     err.put(globExec,"sid",Number(sid));
     776    Object err = Error::create(&globExec, SyntaxError, errMsg.ascii(), errLine, -1, &sourceURL);
     777    err.put(&globExec, "sid", Number(sid));
    780778#if APPLE_CHANGES
    781779    unlockInterpreter();
     
    784782  }
    785783
    786   globExec->clearException();
     784  globExec.clearException();
    787785
    788786  recursion++;
     
    797795      thisObj = globalObject();
    798796    else {
    799       thisObj = thisV.toObject(globExec);
     797      thisObj = thisV.toObject(&globExec);
    800798    }
    801799  }
    802800
    803801  Completion res;
    804   if (globExec->hadException()) {
     802  if (globExec.hadException()) {
    805803    // the thisArg.toObject() conversion above might have thrown an exception - if so,
    806804    // propagate it back
    807     res = Completion(Throw,globExec->exception());
     805    res = Completion(Throw, globExec.exception());
    808806  }
    809807  else {
  • trunk/JavaScriptCore/kjs/internal.h

    r9929 r10076  
    2929#include "value.h"
    3030#include "object.h"
     31#include "protected_object.h"
    3132#include "types.h"
    3233#include "interpreter.h"
     
    288289    void mark();
    289290
    290     ExecState *globalExec() { return globExec; }
     291    ExecState *globalExec() { return &globExec; }
    291292    bool checkSyntax(const UString &code);
    292293    Completion evaluate(const UString &code, const Value &thisV, const UString &sourceURL, int startingLineNumber);
     
    388389    ProtectedObject b_uriErrorPrototype;
    389390
    390     ExecState *globExec;
     391    ExecState globExec;
    391392    Interpreter::CompatMode m_compatMode;
    392393
  • trunk/JavaScriptCore/kjs/interpreter.cpp

    r9929 r10076  
    2727#include "types.h"
    2828#include "interpreter.h"
     29#if APPLE_CHANGES
     30#include "runtime.h"
     31#endif
    2932
    3033#include <assert.h>
     
    6568// ------------------------------ Interpreter ----------------------------------
    6669
    67 Interpreter::Interpreter(const Object &global) : rep(0)
     70Interpreter::Interpreter(const Object &global)
     71  : rep(0)
     72  , m_argumentsPropertyName(&argumentsPropertyName)
     73  , m_specialPrototypePropertyName(&specialPrototypePropertyName)
    6874{
    6975  rep = new InterpreterImp(this,global);
     
    7177
    7278Interpreter::Interpreter()
     79  : rep(0)
     80  , m_argumentsPropertyName(&argumentsPropertyName)
     81  , m_specialPrototypePropertyName(&specialPrototypePropertyName)
    7382{
    7483  Object global(new ObjectImp());
     
    329338
    330339
    331 void *Interpreter::createLanguageInstanceForValue (ExecState *exec, Bindings::Instance::BindingLanguage language, const Object &value, const Bindings::RootObject *origin, const Bindings::RootObject *current)
    332 {
    333     return Bindings::Instance::createLanguageInstanceForValue (exec, language, value, origin, current);
     340void *Interpreter::createLanguageInstanceForValue (ExecState *exec, int language, const Object &value, const Bindings::RootObject *origin, const Bindings::RootObject *current)
     341{
     342    return Bindings::Instance::createLanguageInstanceForValue (exec, (Bindings::Instance::BindingLanguage)language, value, origin, current);
    334343}
    335344
  • trunk/JavaScriptCore/kjs/interpreter.h

    r9929 r10076  
    2626#define _KJS_INTERPRETER_H_
    2727
     28#include "object_wrapper.h"
    2829#include "value.h"
    29 #include "object.h"
    3030#include "types.h"
    31 #include "protect.h"
    32 
    33 #if APPLE_CHANGES
    34 
    35 #include "runtime.h"
    36 
    37 #endif
    3831
    3932namespace KJS {
     
    4134  class ContextImp;
    4235  class InterpreterImp;
     36  class RuntimeMethodImp;
     37
     38  namespace Bindings {
     39    class RootObject;
     40  }
    4341
    4442  /**
     
    402400    virtual bool isSafeScript (const Interpreter *target) { return true; }
    403401   
    404     virtual void *createLanguageInstanceForValue (ExecState *exec, Bindings::Instance::BindingLanguage language, const Object &value, const Bindings::RootObject *origin, const Bindings::RootObject *current);
     402    virtual void *createLanguageInstanceForValue (ExecState *exec, int language, const Object &value, const Bindings::RootObject *origin, const Bindings::RootObject *current);
    405403#endif
     404
     405    // This is a workaround to avoid accessing the global variables for these identifiers in
     406    // important property lookup functions, to avoid taking PIC branches in Mach-O binaries
     407    const Identifier& argumentsIdentifier() { return *m_argumentsPropertyName; }
     408    const Identifier& specialPrototypeIdentifier() { return *m_specialPrototypePropertyName; }
    406409   
    407410  private:
    408411    InterpreterImp *rep;
    409412
     413    const Identifier *m_argumentsPropertyName;
     414    const Identifier *m_specialPrototypePropertyName;
     415
    410416    /**
    411417     * This constructor is not implemented, in order to prevent
     
    421427     */
    422428    Interpreter operator=(const Interpreter&);
     429
    423430  protected:
    424431    virtual void virtual_hook( int id, void* data );
     
    474481    Interpreter *_interpreter;
    475482    ContextImp *_context;
    476     ProtectedValue _exception;
     483    Value _exception;
    477484  };
    478485
  • trunk/JavaScriptCore/kjs/lookup.h

    r9891 r10076  
    125125  /**
    126126   * @internal
    127    * Helper for lookupFunction and lookupValueOrFunction
     127   * Helper for getStaticFunctionSlot and getStaticPropertySlot
    128128   */
    129129  template <class FuncImp>
    130   inline Value lookupOrCreateFunction(ExecState *exec, const Identifier &propertyName,
    131                                       const ObjectImp *thisObj, int token, int params, int attr)
     130  inline Value staticFunctionGetter(ExecState *exec, const Identifier& propertyName, const PropertySlot& slot)
    132131  {
    133132      // Look for cached value in dynamic map of properties (in ObjectImp)
    134       ValueImp * cachedVal = thisObj->ObjectImp::getDirect(propertyName);
    135       /*if (cachedVal)
    136         fprintf(stderr, "lookupOrCreateFunction: Function -> looked up in ObjectImp, found type=%d\n", cachedVal->type());*/
     133      ObjectImp *thisObj = slot.slotBase();
     134      ValueImp *cachedVal = thisObj->getDirect(propertyName);
    137135      if (cachedVal)
    138         return Value(cachedVal);
    139 
    140       Value val = Value(new FuncImp(exec,token, params));
    141       ObjectImp *thatObj = const_cast<ObjectImp *>(thisObj);
    142       thatObj->ObjectImp::put(exec, propertyName, val, attr);
     136          return Value(cachedVal);
     137
     138      const HashEntry *entry = slot.staticEntry();
     139      Value val = Value(new FuncImp(exec, entry->value, entry->params));
     140      thisObj->putDirect(propertyName, val.imp(), entry->attr);
    143141      return val;
     142  }
     143
     144  /**
     145   * @internal
     146   * Helper for getStaticValueSlot and getStaticPropertySlot
     147   */
     148  template <class ThisImp>
     149  inline Value staticValueGetter(ExecState *exec, const Identifier&, const PropertySlot& slot)
     150  {
     151      ThisImp *thisObj = static_cast<ThisImp *>(slot.slotBase());
     152      const HashEntry *entry = slot.staticEntry();
     153      return thisObj->getValueProperty(exec, entry->value);
    144154  }
    145155
     
    165175   */
    166176  template <class FuncImp, class ThisImp, class ParentImp>
    167   inline bool lookupGetOwnProperty(ExecState *exec, const Identifier &propertyName,
    168                                    const HashTable* table, const ThisImp* thisObj, Value& result)
     177  inline bool getStaticPropertySlot(ExecState *exec, const HashTable* table,
     178                                    ThisImp* thisObj, const Identifier& propertyName, PropertySlot& slot)
    169179  {
    170180    const HashEntry* entry = Lookup::findEntry(table, propertyName);
    171181
    172182    if (!entry) // not found, forward to parent
    173       return thisObj->ParentImp::getOwnProperty(exec, propertyName, result);
     183      return thisObj->ParentImp::getOwnPropertySlot(exec, propertyName, slot);
    174184
    175185    if (entry->attr & Function)
    176       result = lookupOrCreateFunction<FuncImp>(exec, propertyName, thisObj, entry->value, entry->params, entry->attr);
     186      slot.setStaticEntry(thisObj, entry, staticFunctionGetter<FuncImp>);
    177187    else
    178       result = thisObj->getValueProperty(exec, entry->value);
     188      slot.setStaticEntry(thisObj, entry, staticValueGetter<ThisImp>);
    179189
    180190    return true;
     
    182192
    183193  /**
    184    * Simplified version of lookupGet in case there are only functions.
    185    * Using this instead of lookupGet prevents 'this' from implementing a dummy getValueProperty.
     194   * Simplified version of getStaticPropertySlot in case there are only functions.
     195   * Using this instead of getStaticPropertySlot allows 'this' to avoid implementing
     196   * a dummy getValueProperty.
    186197   */
    187198  template <class FuncImp, class ParentImp>
    188   inline bool lookupGetOwnFunction(ExecState *exec, const Identifier &propertyName,
    189                                    const HashTable* table, const ObjectImp* thisObj, Value& result)
     199  inline bool getStaticFunctionSlot(ExecState *exec, const HashTable *table,
     200                                    ObjectImp* thisObj, const Identifier& propertyName, PropertySlot& slot)
    190201  {
    191202    const HashEntry* entry = Lookup::findEntry(table, propertyName);
    192203
    193204    if (!entry) // not found, forward to parent
    194       return static_cast<const ParentImp *>(thisObj)->ParentImp::getOwnProperty(exec, propertyName, result);
     205      return static_cast<ParentImp *>(thisObj)->ParentImp::getOwnPropertySlot(exec, propertyName, slot);
    195206
    196207    assert(entry->attr & Function);
    197208
    198     result = lookupOrCreateFunction<FuncImp>(exec, propertyName, thisObj, entry->value, entry->params, entry->attr);
     209    slot.setStaticEntry(thisObj, entry, staticFunctionGetter<FuncImp>);
    199210    return true;
    200211  }
    201212
    202213  /**
    203    * Simplified version of lookupGet in case there are no functions, only "values".
    204    * Using this instead of lookupGet removes the need for a FuncImp class.
     214   * Simplified version of getStaticPropertySlot in case there are no functions, only "values".
     215   * Using this instead of getStaticPropertySlot removes the need for a FuncImp class.
    205216   */
    206217  template <class ThisImp, class ParentImp>
    207   inline bool lookupGetOwnValue(ExecState *exec, const Identifier &propertyName,
    208                                 const HashTable* table, const ThisImp* thisObj, Value& result)
     218  inline bool getStaticValueSlot(ExecState *exec, const HashTable* table,
     219                                 ThisImp* thisObj, const Identifier &propertyName, PropertySlot& slot)
    209220  {
    210221    const HashEntry* entry = Lookup::findEntry(table, propertyName);
    211222
    212223    if (!entry) // not found, forward to parent
    213       return thisObj->ParentImp::getOwnProperty(exec, propertyName, result);
     224      return thisObj->ParentImp::getOwnPropertySlot(exec, propertyName, slot);
    214225
    215226    assert(!(entry->attr & Function));
    216227
    217     result = thisObj->getValueProperty(exec, entry->value);
     228    slot.setStaticEntry(thisObj, entry, staticValueGetter<ThisImp>);
    218229    return true;
    219230  }
     
    296307    virtual const ClassInfo *classInfo() const { return &info; } \
    297308    static const ClassInfo info; \
    298     bool getOwnProperty(ExecState *exec, const Identifier &propertyName, Value& result) const; \
    299     bool hasOwnProperty(ExecState *exec, const Identifier &propertyName) const; \
     309    bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&); \
    300310  }; \
    301311  const ClassInfo ClassProto::info = { ClassName, 0, &ClassProto##Table, 0 };
    302312
    303313#define IMPLEMENT_PROTOTYPE(ClassProto,ClassFunc) \
    304     bool ClassProto::getOwnProperty(ExecState *exec, const Identifier &propertyName, Value& result) const \
     314    bool ClassProto::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot) \
    305315    { \
    306       return lookupGetOwnFunction<ClassFunc,ObjectImp>(exec, propertyName, &ClassProto##Table, this, result); \
    307     } \
    308     bool ClassProto::hasOwnProperty(ExecState *exec, const Identifier &propertyName) const \
    309     { /*stupid but we need this to have a common macro for the declaration*/ \
    310       return ObjectImp::hasOwnProperty(exec, propertyName); \
     316      return getStaticFunctionSlot<ClassFunc,ObjectImp>(exec, &ClassProto##Table, this, propertyName, slot); \
    311317    }
    312318
    313319#define IMPLEMENT_PROTOTYPE_WITH_PARENT(ClassProto,ClassFunc,ParentProto)  \
    314     bool ClassProto::getOwnProperty(ExecState *exec, const Identifier &propertyName, Value& result) const \
     320    bool ClassProto::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot) \
    315321    { \
    316       if (lookupGetOwnFunction<ClassFunc,ObjectImp>(exec, propertyName, &ClassProto##Table, this, result)) \
     322      if (getStaticFunctionSlot<ClassFunc,ObjectImp>(exec, &ClassProto##Table, this, propertyName, slot)) \
    317323          return true; \
    318       return ParentProto::self(exec)->getOwnProperty(exec, propertyName, result); \
    319     } \
    320     bool ClassProto::hasOwnProperty(ExecState *exec, const Identifier &propertyName) const \
    321     { \
    322       if (ObjectImp::hasOwnProperty(exec, propertyName)) \
    323         return true; \
    324       return ParentProto::self(exec)->hasOwnProperty(exec, propertyName); \
     324      return ParentProto::self(exec)->getOwnPropertySlot(exec, propertyName, slot); \
    325325    }
    326326
  • trunk/JavaScriptCore/kjs/math_object.cpp

    r9889 r10076  
    8282// ECMA 15.8
    8383
    84 bool MathObjectImp::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
    85 {
    86   return lookupGetOwnProperty<MathFuncImp, MathObjectImp, ObjectImp>(exec, propertyName, &mathTable, this, result);
     84bool MathObjectImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot &slot)
     85{
     86  return getStaticPropertySlot<MathFuncImp, MathObjectImp, ObjectImp>(exec, &mathTable, this, propertyName, slot);
    8787}
    8888
  • trunk/JavaScriptCore/kjs/math_object.h

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

    r9929 r10076  
    278278  ScopeChain chain = exec->context().imp()->scopeChain();
    279279
    280   Value result;
    281   while (!chain.isEmpty()) {
     280  assert(!chain.isEmpty());
     281
     282  PropertySlot slot;
     283  do {
    282284    ObjectImp *o = chain.top();
    283 
    284     if (o->getProperty(exec, ident, result))
    285       return result;
     285    if (o->getPropertySlot(exec, ident, slot))
     286      return slot.getValue(exec, ident);
    286287   
    287288    chain.pop();
    288   }
    289 
    290   UString m = I18N_NOOP("Can't find variable: ") + ident.ustring();
    291   Object err = Error::create(exec, ReferenceError, m.ascii());
    292   exec->setException(err);
    293   return err;
     289  } while (!chain.isEmpty());
     290
     291  return Reference(Null(), ident).getValue(exec);
    294292}
    295293
     
    298296  ScopeChain chain = exec->context().imp()->scopeChain();
    299297
    300   while (!chain.isEmpty()) {
     298  assert(!chain.isEmpty());
     299
     300  PropertySlot slot;
     301  do {
    301302    ObjectImp *o = chain.top();
    302 
    303     //cout << "Resolve: looking at '" << ident.ascii() << "'"
    304     //     << " in " << (void*)o << " " << o->classInfo()->className << endl;
    305     if (o->hasProperty(exec,ident)) {
    306       //cout << "Resolve: FOUND '" << ident.ascii() << "'"
    307       //     << " in " << (void*)o << " " << o->classInfo()->className << endl;
     303    if (o->getPropertySlot(exec, ident, slot))
    308304      return Reference(o, ident);
    309     }
    310305   
    311306    chain.pop();
    312   }
    313 
    314   // identifier not found
    315   //cout << "Resolve: didn't find '" << ident.ascii() << "'" << endl;
     307  } while (!chain.isEmpty());
     308
    316309  return Reference(Null(), ident);
    317310}
     
    530523Value AccessorNode1::evaluate(ExecState *exec)
    531524{
    532   return evaluateReference(exec).getValue(exec);
     525  Value v1 = expr1->evaluate(exec);
     526  KJS_CHECKEXCEPTIONVALUE
     527  Value v2 = expr2->evaluate(exec);
     528  KJS_CHECKEXCEPTIONVALUE
     529  Object o = v1.toObject(exec);
     530  unsigned i;
     531  if (v2.toUInt32(i))
     532    return o.get(exec, i);
     533
     534  String s = v2.toString(exec);
     535  return o.get(exec, Identifier(s.value()));
    533536}
    534537
     
    567570Value AccessorNode2::evaluate(ExecState *exec)
    568571{
    569   return evaluateReference(exec).getValue(exec);
     572  Value v = expr->evaluate(exec);
     573  KJS_CHECKEXCEPTIONVALUE
     574  Object o = v.toObject(exec);
     575  return o.get(exec, ident);
     576
    570577}
    571578
  • trunk/JavaScriptCore/kjs/number_object.cpp

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

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

    r10061 r10076  
    209209Value ObjectImp::get(ExecState *exec, const Identifier &propertyName) const
    210210{
    211   Value result;
    212 
    213   const ObjectImp *imp = this;
    214 
     211  PropertySlot slot;
     212
     213  if (const_cast<ObjectImp *>(this)->getPropertySlot(exec, propertyName, slot))
     214    return slot.getValue(exec, propertyName);
     215   
     216  return Undefined();
     217}
     218
     219Value ObjectImp::get(ExecState *exec, unsigned propertyName) const
     220{
     221  PropertySlot slot;
     222  if (const_cast<ObjectImp *>(this)->getPropertySlot(exec, propertyName, slot))
     223    return slot.getValue(exec, propertyName);
     224   
     225  return Undefined();
     226}
     227
     228bool ObjectImp::getProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
     229{
     230  PropertySlot slot;
     231  if (const_cast<ObjectImp *>(this)->getPropertySlot(exec, propertyName, slot)) {
     232    result = slot.getValue(exec, propertyName);
     233    return true;
     234  }
     235 
     236  return false;
     237}
     238
     239bool ObjectImp::getProperty(ExecState *exec, unsigned propertyName, Value& result) const
     240{
     241  PropertySlot slot;
     242  if (const_cast<ObjectImp *>(this)->getPropertySlot(exec, propertyName, slot)) {
     243    result = slot.getValue(exec, propertyName);
     244    return true;
     245  }
     246   
     247  return false;
     248}
     249
     250bool ObjectImp::getPropertySlot(ExecState *exec, unsigned propertyName, PropertySlot& slot)
     251{
     252  ObjectImp *imp = this;
     253 
    215254  while (true) {
    216     if (imp->getOwnProperty(exec, propertyName, result))
    217       return result;
    218 
    219     const ValueImp *proto = imp->_proto;
     255    if (imp->getOwnPropertySlot(exec, propertyName, slot))
     256      return true;
     257   
     258    ValueImp *proto = imp->_proto;
    220259    if (proto->dispatchType() != ObjectType)
    221260      break;
    222 
    223     imp = static_cast<const ObjectImp *>(proto);
    224   }
    225 
    226   return Undefined();
    227 }
    228 
    229 bool ObjectImp::getOwnProperty(ExecState *exec, unsigned propertyName, Value& result) const
    230 {
    231   return getOwnProperty(exec, Identifier::from(propertyName), result);
    232 }
    233 
    234 Value ObjectImp::get(ExecState *exec, unsigned propertyName) const
    235 {
    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 
    254 bool 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;
    261261   
    262     const ValueImp *proto = imp->_proto;
    263       if (proto->dispatchType() != ObjectType)
    264         break;
    265      
    266       imp = static_cast<const ObjectImp *>(proto);
     262    imp = static_cast<ObjectImp *>(proto);
    267263  }
    268264 
    269265  return false;
     266}
     267
     268bool ObjectImp::getOwnPropertySlot(ExecState *exec, unsigned propertyName, PropertySlot& slot)
     269{
     270  return getOwnPropertySlot(exec, Identifier::from(propertyName), slot);
    270271}
    271272
     
    277278
    278279  // non-standard netscape extension
    279   if (propertyName == specialPrototypePropertyName) {
     280  if (propertyName == exec->dynamicInterpreter()->specialPrototypeIdentifier()) {
    280281    setPrototype(value);
    281282    return;
     
    324325bool ObjectImp::hasProperty(ExecState *exec, const Identifier &propertyName) const
    325326{
    326   if (hasOwnProperty(exec, propertyName))
    327     return true;
    328 
    329   if (!_proto || _proto->dispatchType() != ObjectType) {
    330     return false;
    331   }
    332 
    333   // Look in the prototype
    334   return static_cast<ObjectImp *>(_proto)->hasProperty(exec, propertyName);
     327  PropertySlot slot;
     328  return const_cast<ObjectImp *>(this)->getPropertySlot(exec, propertyName, slot);
    335329}
    336330
    337331bool ObjectImp::hasProperty(ExecState *exec, unsigned propertyName) const
    338332{
    339     if (hasOwnProperty(exec, propertyName))
    340       return true;
    341 
    342     if (!_proto || _proto->dispatchType() != ObjectType) {
    343       return false;
    344     }
    345 
    346     // Look in the prototype
    347     return static_cast<ObjectImp *>(_proto)->hasProperty(exec, propertyName);
     333  PropertySlot slot;
     334  return const_cast<ObjectImp *>(this)->getPropertySlot(exec, propertyName, slot);
    348335}
    349336
    350337bool ObjectImp::hasOwnProperty(ExecState *exec, const Identifier &propertyName) const
    351338{
    352   if (_prop.get(propertyName))
    353     return true;
    354 
    355   // Look in the static hashtable of properties
    356   if (findPropertyHashEntry(propertyName))
    357     return true;
    358 
    359   // non-standard netscape extension
    360   if (propertyName == specialPrototypePropertyName)
    361     return true;
    362 
    363   return false;
    364 }
    365 
    366 bool ObjectImp::hasOwnProperty(ExecState *exec, unsigned propertyName) const
    367 {
    368   return hasOwnProperty(exec, Identifier::from(propertyName));
    369 }
    370 
     339  PropertySlot slot;
     340  return const_cast<ObjectImp *>(this)->getOwnPropertySlot(exec, propertyName, slot);
     341}
    371342
    372343// ECMA 8.6.2.5
  • trunk/JavaScriptCore/kjs/object.h

    r9889 r10076  
    3939#endif
    4040
    41 #include "value.h"
    4241#include "types.h"
     42#include "interpreter.h"
    4343#include "reference_list.h"
    4444#include "property_map.h"
     45#include "property_slot.h"
    4546#include "scope_chain.h"
    4647
     
    5051  class HashEntry;
    5152  class ListImp;
    52   class ReferenceList;
    53 
    54   // ECMA 262-3 8.6.1
    55   // Attributes (only applicable to the Object type)
    56   enum Attribute { None       = 0,
    57                    ReadOnly   = 1 << 1, // property can be only read, not written
    58                    DontEnum   = 1 << 2, // property doesn't appear in (for .. in ..)
    59                    DontDelete = 1 << 3, // property can't be deleted
    60                    Internal   = 1 << 4, // an internal property, set to by pass checks
    61                    Function   = 1 << 5 }; // property is a function - only used by static hashtables
    6253
    6354  /**
     
    8475  };
    8576 
    86   /**
    87    * Represents an Object. This is a wrapper for ObjectImp
    88    */
    89   class Object : public Value {
    90   public:
    91     Object() { }
    92     Object(ObjectImp *);
    93     operator ObjectImp *() const { return imp(); }
    94    
    95     ObjectImp *imp() const;
    96 
    97     const ClassInfo *classInfo() const;
    98     bool inherits(const ClassInfo *cinfo) const;
    99 
    100     /**
    101      * Converts a Value into an Object. If the value's type is not ObjectType,
    102      * a null object will be returned (i.e. one with it's internal pointer set
    103      * to 0). If you do not know for sure whether the value is of type
    104      * ObjectType, you should check the isValid() methods afterwards before
    105      * calling any methods on the Object.
    106      *
    107      * @return The value converted to an object
    108      */
    109     static Object dynamicCast(const Value &v);
    110 
    111     /**
    112      * Returns the prototype of this object. Note that this is not the same as
    113      * the "prototype" property.
    114      *
    115      * See ECMA 8.6.2
    116      *
    117      * @return The object's prototype
    118      */
    119     Value prototype() const;
    120 
    121     /**
    122      * Returns the class name of the object
    123      *
    124      * See ECMA 8.6.2
    125      *
    126      * @return The object's class name
    127      */
    128     UString className() const;
    129 
    130     /**
    131      * Retrieves the specified property from the object. If neither the object
    132      * or any other object in it's prototype chain have the property, this
    133      * function will return Undefined.
    134      *
    135      * See ECMA 8.6.2.1
    136      *
    137      * @param exec The current execution state
    138      * @param propertyName The name of the property to retrieve
    139      *
    140      * @return The specified property, or Undefined
    141      */
    142     Value get(ExecState *exec, const Identifier &propertyName) const;
    143     Value get(ExecState *exec, unsigned propertyName) const;
    144 
    145     /**
    146      * Sets the specified property.
    147      *
    148      * See ECMA 8.6.2.2
    149      *
    150      * @param exec The current execution state
    151      * @param propertyName The name of the property to set
    152      * @param propertyValue The value to set
    153      */
    154     void put(ExecState *exec, const Identifier &propertyName,
    155              const Value &value, int attr = None);
    156     void put(ExecState *exec, unsigned propertyName,
    157              const Value &value, int attr = None);
    158 
    159     /**
    160      * Used to check whether or not a particular property is allowed to be set
    161      * on an object
    162      *
    163      * See ECMA 8.6.2.3
    164      *
    165      * @param exec The current execution state
    166      * @param propertyName The name of the property
    167      * @return true if the property can be set, otherwise false
    168      */
    169     bool canPut(ExecState *exec, const Identifier &propertyName) const;
    170 
    171     /**
    172      * Checks to see whether the object (or any object in it's prototype chain)
    173      * has a property with the specified name.
    174      *
    175      * See ECMA 8.6.2.4
    176      *
    177      * @param exec The current execution state
    178      * @param propertyName The name of the property to check for
    179      * @return true if the object has the property, otherwise false
    180      */
    181     bool hasProperty(ExecState *exec, const Identifier &propertyName) const;
    182     bool hasProperty(ExecState *exec, unsigned propertyName) const;
    183 
    184     /**
    185      * Checks to see whether the object has a property with the specified name.
    186      *
    187      * See ECMA 15.2.4.5
    188      *
    189      * @param exec The current execution state
    190      * @param propertyName The name of the property to check for
    191      * @return true if the object has the property, otherwise false
    192      */
    193     bool hasOwnProperty(ExecState *exec, const Identifier &propertyName) const;
    194     bool hasOwnProperty(ExecState *exec, unsigned propertyName) const;
    195 
    196     /**
    197      * Removes the specified property from the object.
    198      *
    199      * See ECMA 8.6.2.5
    200      *
    201      * @param exec The current execution state
    202      * @param propertyName The name of the property to delete
    203      * @return true if the property was successfully deleted or did not
    204      * exist on the object. false if deleting the specified property is not
    205      * allowed.
    206      */
    207     bool deleteProperty(ExecState *exec, const Identifier &propertyName);
    208     bool deleteProperty(ExecState *exec, unsigned propertyName);
    209 
    210     /**
    211      * Converts the object into a primitive value. The value return may differ
    212      * depending on the supplied hint
    213      *
    214      * See ECMA 8.6.2.6
    215      *
    216      * @param exec The current execution state
    217      * @param hint The desired primitive type to convert to
    218      * @return A primitive value converted from the objetc. Note that the
    219      * type of primitive value returned may not be the same as the requested
    220      * hint.
    221      */
    222     Value defaultValue(ExecState *exec, Type hint) const;
    223 
    224     /**
    225      * Whether or not the object implements the construct() method. If this
    226      * returns false you should not call the construct() method on this
    227      * object (typically, an assertion will fail to indicate this).
    228      *
    229      * @return true if this object implements the construct() method, otherwise
    230      * false
    231      */
    232     bool implementsConstruct() const;
    233 
    234     /**
    235      * Creates a new object based on this object. Typically this means the
    236      * following:
    237      * 1. A new object is created
    238      * 2. The prototype of the new object is set to the value of this object's
    239      *    "prototype" property
    240      * 3. The call() method of this object is called, with the new object
    241      *    passed as the this value
    242      * 4. The new object is returned
    243      *
    244      * In some cases, Host objects may differ from these semantics, although
    245      * this is discouraged.
    246      *
    247      * If an error occurs during construction, the execution state's exception
    248      * will be set. This can be tested for with ExecState::hadException().
    249      * Under some circumstances, the exception object may also be returned.
    250      *
    251      * Note: This function should not be called if implementsConstruct() returns
    252      * false, in which case it will result in an assertion failure.
    253      *
    254      * @param exec The current execution state
    255      * @param args The arguments to be passed to call() once the new object has
    256      * been created
    257      * @return The newly created &amp; initialized object
    258      */
    259     Object construct(ExecState *exec, const List &args);
    260     Object construct(ExecState *exec, const List &args, const UString &sourceURL, int lineNumber);
    261 
    262     /**
    263      * Whether or not the object implements the call() method. If this returns
    264      * false you should not call the call() method on this object (typically,
    265      * an assertion will fail to indicate this).
    266      *
    267      * @return true if this object implements the call() method, otherwise
    268      * false
    269      */
    270     bool implementsCall() const;
    271 
    272 
    273     /**
    274      * Calls this object as if it is a function.
    275      *
    276      * Note: This function should not be called if implementsCall() returns
    277      * false, in which case it will result in an assertion failure.
    278      *
    279      * See ECMA 8.6.2.3
    280      *
    281      * @param exec The current execution state
    282      * @param thisObj The obj to be used as "this" within function execution.
    283      * Note that in most cases this will be different from the C++ "this"
    284      * object. For example, if the ECMAScript code "window.location.toString()"
    285      * is executed, call() will be invoked on the C++ object which implements
    286      * the toString method, with the thisObj being window.location
    287      * @param args List of arguments to be passed to the function
    288      * @return The return value from the function
    289      */
    290     Value call(ExecState *exec, Object &thisObj, const List &args);
    291 
    292     /**
    293      * Whether or not the object implements the hasInstance() method. If this
    294      * returns false you should not call the hasInstance() method on this
    295      * object (typically, an assertion will fail to indicate this).
    296      *
    297      * @return true if this object implements the hasInstance() method,
    298      * otherwise false
    299      */
    300     bool implementsHasInstance() const;
    301 
    302     /**
    303      * Checks whether value delegates behavior to this object. Used by the
    304      * instanceof operator.
    305      *
    306      * @param exec The current execution state
    307      * @param value The value to check
    308      * @return true if value delegates behavior to this object, otherwise
    309      * false
    310      */
    311     Boolean hasInstance(ExecState *exec, const Value &value);
    312 
    313     /**
    314      * Returns the scope of this object. This is used when execution declared
    315      * functions - the execution context for the function is initialized with
    316      * extra object in it's scope. An example of this is functions declared
    317      * inside other functions:
    318      *
    319      * \code
    320      * function f() {
    321      *
    322      *   function b() {
    323      *     return prototype;
    324      *   }
    325      *
    326      *   var x = 4;
    327      *   // do some stuff
    328      * }
    329      * f.prototype = new String();
    330      * \endcode
    331      *
    332      * When the function f.b is executed, its scope will include properties of
    333      * f. So in the example above the return value of f.b() would be the new
    334      * String object that was assigned to f.prototype.
    335      *
    336      * @param exec The current execution state
    337      * @return The function's scope
    338      */
    339     const ScopeChain &scope() const;
    340     void setScope(const ScopeChain &s);
    341 
    342     /**
    343      * Returns a List of References to all the properties of the object. Used
    344      * in "for x in y" statements. The list is created new, so it can be freely
    345      * modified without affecting the object's properties. It should be deleted
    346      * by the caller.
    347      *
    348      * Subclasses can override this method in ObjectImpl to provide the
    349      * appearance of
    350      * having extra properties other than those set specifically with put().
    351      *
    352      * @param exec The current execution state
    353      * @param recursive Whether or not properties in the object's prototype
    354      * chain should be
    355      * included in the list.
    356      * @return A List of References to properties of the object.
    357      **/
    358     ReferenceList propList(ExecState *exec, bool recursive = true);
    359 
    360     /**
    361      * Returns the internal value of the object. This is used for objects such
    362      * as String and Boolean which are wrappers for native types. The interal
    363      * value is the actual value represented by the wrapper objects.
    364      *
    365      * @see ECMA 8.6.2
    366      * @return The internal value of the object
    367      */
    368     Value internalValue() const;
    369 
    370     /**
    371      * Sets the internal value of the object
    372      *
    373      * @see internalValue()
    374      *
    375      * @param v The new internal value
    376      */
    377     void setInternalValue(const Value &v);
    378 
    379     void saveProperties(SavedProperties &p) const;
    380     void restoreProperties(const SavedProperties &p);
    381   };
    382 
    38377  inline Object Value::toObject(ExecState *exec) const { return rep->dispatchToObject(exec); }
    38478 
     
    510204    bool getProperty(ExecState *exec, unsigned propertyName, Value& result) const;
    511205
    512     virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
    513     virtual bool getOwnProperty(ExecState *exec, unsigned propertyName, Value& result) const;
     206    bool getPropertySlot(ExecState *, const Identifier&, PropertySlot&);
     207    bool getPropertySlot(ExecState *, unsigned, PropertySlot&);
     208    virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&);
     209    virtual bool getOwnPropertySlot(ExecState *, unsigned index, PropertySlot&);
    514210
    515211    /**
     
    538234     * @see Object::hasProperty()
    539235     */
    540     bool hasProperty(ExecState *exec,
    541                              const Identifier &propertyName) const;
     236    bool hasProperty(ExecState *exec, const Identifier &propertyName) const;
    542237    bool hasProperty(ExecState *exec, unsigned propertyName) const;
    543238
    544     virtual bool hasOwnProperty(ExecState *exec,
    545                      const Identifier &propertyName) const;
    546     virtual bool hasOwnProperty(ExecState *exec, unsigned propertyName) const;
     239    virtual bool hasOwnProperty(ExecState *exec, const Identifier &propertyName) const;
    547240
    548241    /**
     
    624317    ValueImp *getDirect(const Identifier& propertyName) const
    625318        { return _prop.get(propertyName); }
     319    ValueImp **getDirectLocation(const Identifier& propertyName)
     320        { return _prop.getLocation(propertyName); }
    626321    void putDirect(const Identifier &propertyName, ValueImp *value, int attr = 0);
    627322    void putDirect(const Identifier &propertyName, int value, int attr = 0);
     
    639334  };
    640335
    641 
    642336  // it may seem crazy to inline a function this large but it makes a big difference
    643337  // since this is function very hot in variable lookup
    644   inline bool ObjectImp::getProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
     338  inline bool ObjectImp::getPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
    645339  {
    646     const ObjectImp *imp = this;
     340    ObjectImp *imp = this;
    647341
    648342    while (true) {
    649       if (imp->getOwnProperty(exec, propertyName, result))
     343      if (imp->getOwnPropertySlot(exec, propertyName, slot))
    650344        return true;
    651345     
    652       const ValueImp *proto = imp->_proto;
     346      ValueImp *proto = imp->_proto;
    653347      if (proto->dispatchType() != ObjectType)
    654348        break;
    655349     
    656       imp = static_cast<const ObjectImp *>(proto);
     350      imp = static_cast<ObjectImp *>(proto);
    657351    }
    658352   
     
    663357  // but it makes a big difference to property lookup if subclasses can inline their
    664358  // superclass call to this
    665   inline bool ObjectImp::getOwnProperty(ExecState *exec, const Identifier &propertyName, Value &result) const
     359  inline bool ObjectImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
    666360  {
    667       ValueImp *imp = getDirect(propertyName);
    668       if (imp) {
    669         result = Value(imp);
     361      ValueImp **impLocation = getDirectLocation(propertyName);
     362      if (impLocation) {
     363        slot.setValueSlot(this, impLocation);
    670364        return true;
    671365      }
    672366
    673367      // non-standard netscape extension
    674       if (propertyName == specialPrototypePropertyName) {
    675         result = Value(_proto);
     368      if (propertyName == exec->dynamicInterpreter()->specialPrototypeIdentifier()) {
     369        slot.setValueSlot(this, &_proto);
    676370        return true;
    677371      }
     
    760454    { return imp()->hasProperty(exec, propertyName); }
    761455
    762   inline bool Object::hasProperty(ExecState *exec, unsigned propertyName) const
    763     { return imp()->hasProperty(exec, propertyName); }
    764 
    765456  inline bool Object::hasOwnProperty(ExecState *exec, const Identifier &propertyName) const
    766     { return imp()->hasOwnProperty(exec, propertyName); }
    767 
    768   inline bool Object::hasOwnProperty(ExecState *exec, unsigned propertyName) const
    769457    { return imp()->hasOwnProperty(exec, propertyName); }
    770458
  • trunk/JavaScriptCore/kjs/property_map.cpp

    r9992 r10076  
    233233}
    234234
     235ValueImp **PropertyMap::getLocation(const Identifier &name)
     236{
     237    assert(!name.isNull());
     238   
     239    UString::Rep *rep = name._ustring.rep;
     240
     241    if (!_table) {
     242#if USE_SINGLE_ENTRY
     243        UString::Rep *key = _singleEntry.key;
     244        if (rep == key)
     245            return &_singleEntry.value;
     246#endif
     247        return 0;
     248    }
     249   
     250    unsigned h = rep->hash();
     251    int sizeMask = _table->sizeMask;
     252    Entry *entries = _table->entries;
     253    int i = h & sizeMask;
     254    int k = 0;
     255#if DUMP_STATISTICS
     256    ++numProbes;
     257    numCollisions += entries[i].key && entries[i].key != rep;
     258#endif
     259    while (UString::Rep *key = entries[i].key) {
     260        if (rep == key)
     261            return &entries[i].value;
     262        if (k == 0)
     263            k = 1 | (h % sizeMask);
     264        i = (i + k) & sizeMask;
     265#if DUMP_STATISTICS
     266        ++numRehashes;
     267#endif
     268    }
     269    return 0;
     270}
     271
    235272#if DEBUG_PROPERTIES
    236273static void printAttributes(int attributes)
  • trunk/JavaScriptCore/kjs/property_map.h

    r9768 r10076  
    7979        ValueImp *get(const Identifier &name) const;
    8080        ValueImp *get(const Identifier &name, int &attributes) const;
     81        ValueImp **getLocation(const Identifier &name);
    8182
    8283        void mark() const;
  • trunk/JavaScriptCore/kjs/protect.h

    r9145 r10076  
    2525#define _KJS_PROTECT_H_
    2626
    27 #include "object.h"
    2827#include "reference.h"
    2928#include "value.h"
     
    7877    };
    7978
    80 
    81     class ProtectedObject : public Object {
    82     public:
    83       ProtectedObject() : Object() {}
    84       ProtectedObject(const Object &o)  : Object(o) { gcProtectNullTolerant(o.imp()); };
    85       ProtectedObject(const ProtectedObject &o)  : Object(o) { gcProtectNullTolerant(o.imp()); };
    86       ~ProtectedObject() { gcUnprotectNullTolerant(imp());}
    87       ProtectedObject& operator=(const Object &o)
    88         {
    89           ValueImp *old = imp();
    90           Object::operator=(o);
    91           gcProtectNullTolerant(o.imp());
    92           gcUnprotectNullTolerant(old);
    93           return *this;
    94         }
    95       ProtectedObject& operator=(const ProtectedObject &o)
    96         {
    97           ValueImp *old = imp();
    98           Object::operator=(o);
    99           gcProtectNullTolerant(o.imp());
    100           gcUnprotectNullTolerant(old);
    101           return *this;
    102         }
    103     private:
    104       explicit ProtectedObject(ObjectImp *o);
    105     };
    106 
    107 
    108     class ProtectedReference : public Reference {
    109     public:
    110       ProtectedReference(const Reference&r)  : Reference(r) { gcProtectNullTolerant(r.base.imp()); };
    111       ~ProtectedReference() { gcUnprotectNullTolerant(base.imp());}
    112       ProtectedReference& operator=(const Reference &r)
    113         {
    114           ValueImp *old = base.imp();
    115           Reference::operator=(r);
    116           gcProtectNullTolerant(r.base.imp());
    117           gcUnprotectNullTolerant(old);
    118           return *this;
    119         }
    120     private:
    121       ProtectedReference();
    122       ProtectedReference(const Object& b, const Identifier& p);
    123       ProtectedReference(const Object& b, unsigned p);
    124       ProtectedReference(ObjectImp *b, const Identifier& p);
    125       ProtectedReference(ObjectImp *b, unsigned p);
    126       ProtectedReference(const Null& b, const Identifier& p);
    127       ProtectedReference(const Null& b, unsigned p);
    128     };
    129 
    130 }
     79} // namespace
    13180
    13281#endif
  • trunk/JavaScriptCore/kjs/reference.h

    r9768 r10076  
    2828
    2929namespace KJS {
     30
     31  class Object;
     32  class ObjectImp;
    3033
    3134  class Reference {
  • trunk/JavaScriptCore/kjs/reference_list.cpp

    r9768 r10076  
    2323#include "reference_list.h"
    2424
    25 #include "protect.h"
     25#include "protected_object.h"
    2626
    2727namespace KJS {
  • trunk/JavaScriptCore/kjs/regexp_object.cpp

    r9889 r10076  
    217217}
    218218
    219 bool RegExpObjectImp::getOwnProperty(ExecState *exec, const Identifier& p, Value& result) const
    220 {
    221   UString s = p.ustring();
     219Value RegExpObjectImp::backrefGetter(ExecState *exec, const Identifier& propertyName, const PropertySlot& slot)
     220{
     221  RegExpObjectImp *thisObj = static_cast<RegExpObjectImp *>(slot.slotBase());
     222  unsigned long i = slot.index();
     223
     224  if (i < thisObj->lastNrSubPatterns + 1) {
     225    int *lastOvector = thisObj->lastOvector;
     226    UString substring = thisObj->lastString.substr(lastOvector[2*i], lastOvector[2*i+1] - lastOvector[2*i] );
     227    return String(substring);
     228  }
     229
     230  return String("");
     231}
     232
     233bool RegExpObjectImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
     234{
     235  UString s = propertyName.ustring();
    222236  if (s[0] == '$' && lastOvector)
    223237  {
     
    226240    if (ok)
    227241    {
    228       if (i < lastNrSubPatterns + 1)
    229       {
    230         UString substring = lastString.substr( lastOvector[2*i], lastOvector[2*i+1] - lastOvector[2*i] );
    231         result = String(substring);
    232       } else
    233         result = String("");
    234      
     242      slot.setCustomIndex(this, i, backrefGetter);
    235243      return true;
    236244    }
    237245  }
    238246
    239   return InternalFunctionImp::getOwnProperty(exec, p, result);
     247  return InternalFunctionImp::getOwnPropertySlot(exec, propertyName, slot);
    240248}
    241249
  • trunk/JavaScriptCore/kjs/regexp_object.h

    r9889 r10076  
    7575    virtual Value call(ExecState *exec, Object &thisObj, const List &args);
    7676
    77     virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     77    virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&);
    7878    int ** registerRegexp( const RegExp* re, const UString& s );
    7979    void setSubPatterns(int num) { lastNrSubPatterns = num; }
    8080    Object arrayOfMatches(ExecState *exec, const UString &result) const;
    8181  private:
     82    static Value backrefGetter(ExecState *exec, const Identifier&, const PropertySlot& slot);
     83 
    8284    UString lastString;
    8385    int *lastOvector;
  • trunk/JavaScriptCore/kjs/string_object.cpp

    r9889 r10076  
    5151}
    5252
    53 bool StringInstanceImp::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
     53Value StringInstanceImp::lengthGetter(ExecState *exec, const Identifier& propertyName, const PropertySlot &slot)
     54{
     55    return Value(static_cast<StringInstanceImp *>(slot.slotBase())->internalValue().toString(exec).size());
     56}
     57
     58Value StringInstanceImp::indexGetter(ExecState *exec, const Identifier& propertyName, const PropertySlot &slot)
     59{
     60    const UChar c = static_cast<StringInstanceImp *>(slot.slotBase())->internalValue().toString(exec)[slot.index()];
     61    return Value(UString(&c, 1));
     62}
     63
     64bool StringInstanceImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot &slot)
    5465{
    5566  if (propertyName == lengthPropertyName) {
    56     result = Value(internalValue().toString(exec).size());
     67    slot.setCustom(this, lengthGetter);
    5768    return true;
    5869  }
     
    6475    const unsigned length = s.size();
    6576    if (index >= length)
    66       return Undefined();
    67     const UChar c = s[index];
    68     result = Value(UString(&c, 1));
     77      return false;
     78    slot.setCustomIndex(this, index, indexGetter);
    6979    return true;
    7080  }
    7181
    72   return ObjectImp::getOwnProperty(exec, propertyName, result);
     82  return ObjectImp::getOwnPropertySlot(exec, propertyName, slot);
    7383}
    7484
     
    7888    return;
    7989  ObjectImp::put(exec, propertyName, value, attr);
    80 }
    81 
    82 bool StringInstanceImp::hasOwnProperty(ExecState *exec, const Identifier &propertyName) const
    83 {
    84   if (propertyName == lengthPropertyName)
    85     return true;
    86 
    87   bool ok;
    88   const unsigned index = propertyName.toArrayIndex(&ok);
    89   if (ok) {
    90     const unsigned length = internalValue().toString(exec).size();
    91     if (index < length)
    92       return true;
    93   }
    94 
    95   return ObjectImp::hasOwnProperty(exec, propertyName);
    9690}
    9791
     
    155149}
    156150
    157 bool StringPrototypeImp::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
    158 {
    159   return lookupGetOwnFunction<StringProtoFuncImp, StringInstanceImp>(exec, propertyName, &stringTable, this, result);
     151bool StringPrototypeImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot &slot)
     152{
     153  return getStaticFunctionSlot<StringProtoFuncImp, StringInstanceImp>(exec, &stringTable, this, propertyName, slot);
    160154}
    161155
  • trunk/JavaScriptCore/kjs/string_object.h

    r9889 r10076  
    3333    StringInstanceImp(ObjectImp *proto, const UString &string);
    3434
    35     virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     35    virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&);
    3636    virtual void put(ExecState *exec, const Identifier &propertyName, const Value &value, int attr = None);
    37     virtual bool hasOwnProperty(ExecState *exec, const Identifier &propertyName) const;
    3837    virtual bool deleteProperty(ExecState *exec, const Identifier &propertyName);
    3938
    4039    virtual const ClassInfo *classInfo() const { return &info; }
    4140    static const ClassInfo info;
     41  private:
     42    static Value lengthGetter(ExecState *exec, const Identifier&, const PropertySlot &slot);
     43    static Value indexGetter(ExecState *exec, const Identifier&, const PropertySlot &slot);
    4244  };
    4345
     
    5254    StringPrototypeImp(ExecState *exec,
    5355                       ObjectPrototypeImp *objProto);
    54     virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
     56    virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&);
    5557    virtual const ClassInfo *classInfo() const { return &info; }
    5658    static const ClassInfo info;
Note: See TracChangeset for help on using the changeset viewer.