Changeset 10076 in webkit for trunk/JavaScriptCore
- Timestamp:
- Aug 6, 2005, 11:17:49 PM (20 years ago)
- Location:
- trunk/JavaScriptCore
- Files:
-
- 4 added
- 39 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r10075 r10076 1 2005-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 1 145 2005-08-05 Adele Peterson <[email protected]> 2 146 -
trunk/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r10066 r10076 26 26 27 27 /* 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, ); }; }; 28 36 932F5B400822A1C700736975 /* array_object.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A84E0255597D01FF60F7 /* array_object.h */; settings = {ATTRIBUTES = (Private, ); }; }; 29 37 932F5B420822A1C700736975 /* collector.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A8530255597D01FF60F7 /* collector.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 450 458 651F6412039D5B5F0078395C /* dtoa.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = dtoa.cpp; sourceTree = "<group>"; }; 451 459 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>"; }; 452 462 65417205039E02E70058BFEB /* get.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = get.c; path = pcre/get.c; sourceTree = "<group>"; }; 453 463 65417206039E02E70058BFEB /* maketables.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = maketables.c; path = pcre/maketables.c; sourceTree = "<group>"; }; … … 459 469 6560A4CF04B3B3E7008AE952 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = "<absolute>"; }; 460 470 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>"; }; 461 473 65AB004806261CBA0076DE63 /* interpreter_map.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = interpreter_map.cpp; sourceTree = "<group>"; }; 462 474 65AB004906261CBA0076DE63 /* interpreter_map.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = interpreter_map.h; sourceTree = "<group>"; }; … … 633 645 isa = PBXGroup; 634 646 children = ( 647 65305EAE08A58DDE00F31E73 /* protected_object.h */, 648 6539AACA08A3225A00223EE2 /* object_wrapper.h */, 649 65621E6B089E859700760F35 /* property_slot.cpp */, 650 65621E6C089E859700760F35 /* property_slot.h */, 635 651 938772E5038BFE19008635CE /* array_instance.h */, 636 652 650B68D80639033F009D42DE /* protected_values.cpp */, … … 829 845 buildActionMask = 2147483647; 830 846 files = ( 847 65305EAF08A58DDE00F31E73 /* protected_object.h in Headers */, 831 848 932F5B400822A1C700736975 /* array_object.h in Headers */, 832 849 932F5B420822A1C700736975 /* collector.h in Headers */, … … 901 918 932F5B8F0822A1C700736975 /* fast_malloc.h in Headers */, 902 919 932FC11D0824A6A3005B3C75 /* create_hash_table in Headers */, 920 65621E6E089E859700760F35 /* property_slot.h in Headers */, 921 6539AACB08A3225A00223EE2 /* object_wrapper.h in Headers */, 903 922 ); 904 923 runOnlyForDeploymentPostprocessing = 0; … … 908 927 buildActionMask = 2147483647; 909 928 files = ( 929 65305EB008A58E0900F31E73 /* protected_object.h in Headers */, 910 930 A85D81F8087B2822006A9172 /* array_object.h in Headers */, 911 931 A85D81F9087B2822006A9172 /* collector.h in Headers */, … … 923 943 A85D8205087B2822006A9172 /* number_object.h in Headers */, 924 944 A85D8206087B2822006A9172 /* object_object.h in Headers */, 945 65BBAEE008A329B300357728 /* object_wrapper.h in Headers */, 925 946 A85D8207087B2822006A9172 /* object.h in Headers */, 926 947 A85D8208087B2822006A9172 /* operations.h in Headers */, … … 979 1000 A85D823D087B2822006A9172 /* npruntime_impl.h in Headers */, 980 1001 A85D823E087B2822006A9172 /* fast_malloc.h in Headers */, 1002 65621E70089E85D300760F35 /* property_slot.h in Headers */, 981 1003 A85D823F087B2822006A9172 /* create_hash_table in Headers */, 982 1004 ); … … 1530 1552 932F5BD00822A1C700736975 /* softlinking.c in Sources */, 1531 1553 932F5BD10822A1C700736975 /* fast_malloc.cpp in Sources */, 1554 65621E6D089E859700760F35 /* property_slot.cpp in Sources */, 1532 1555 ); 1533 1556 runOnlyForDeploymentPostprocessing = 0; … … 1617 1640 A85D827F087B2822006A9172 /* softlinking.c in Sources */, 1618 1641 A85D8280087B2822006A9172 /* fast_malloc.cpp in Sources */, 1642 65621E6F089E85D300760F35 /* property_slot.cpp in Sources */, 1619 1643 ); 1620 1644 runOnlyForDeploymentPostprocessing = 0; -
trunk/JavaScriptCore/bindings/objc/objc_runtime.h
r9889 r10076 170 170 const ClassInfo *classInfo() const { return &info; } 171 171 172 virtual bool getOwnProperty (ExecState *exec, const Identifier& propertyName, Value& result) const;172 virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&); 173 173 174 174 virtual void put(ExecState *exec, const Identifier &propertyName, … … 180 180 virtual Value call(ExecState *exec, Object &thisObj, const List &args); 181 181 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); 188 183 189 184 virtual Value defaultValue(ExecState *exec, Type hint) const; -
trunk/JavaScriptCore/bindings/objc/objc_runtime.mm
r9889 r10076 263 263 264 264 ObjcFallbackObjectImp::ObjcFallbackObjectImp(ObjcInstance *i, const KJS::Identifier propertyName) 265 : ObjectImp ((ObjectImp *)0)266 265 { 267 266 _instance = i; … … 269 268 } 270 269 271 bool ObjcFallbackObjectImp::getOwnProperty (ExecState *exec, const Identifier& propertyName, Value& result) const270 bool ObjcFallbackObjectImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot) 272 271 { 273 272 // keep the prototype from getting called instead of just returning false 274 result = Undefined();273 slot.setUndefined(this); 275 274 return true; 276 275 } … … 336 335 } 337 336 338 bool ObjcFallbackObjectImp::hasOwnProperty(ExecState *exec,339 const Identifier &propertyName) const340 {341 return false;342 }343 344 337 bool ObjcFallbackObjectImp::deleteProperty(ExecState *exec, 345 338 const Identifier &propertyName) -
trunk/JavaScriptCore/bindings/runtime_array.cpp
r9889 r10076 44 44 } 45 45 46 bool RuntimeArrayImp::getOwnProperty(ExecState *exec, const Identifier &propertyName, Value& result) const 46 Value 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 52 Value 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 58 bool RuntimeArrayImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot) 47 59 { 48 60 if (propertyName == lengthPropertyName) { 49 result = Number(getLength());61 slot.setCustom(this, lengthGetter); 50 62 return true; 51 63 } … … 54 66 unsigned index = propertyName.toArrayIndex(&ok); 55 67 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 77 bool RuntimeArrayImp::getOwnPropertySlot(ExecState *exec, unsigned index, PropertySlot& slot) 78 { 79 if (index < getLength()) { 80 slot.setCustomIndex(this, index, indexGetter); 60 81 return true; 61 82 } 62 83 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); 74 85 } 75 86 … … 103 114 } 104 115 105 106 bool RuntimeArrayImp::hasOwnProperty(ExecState *exec, const Identifier &propertyName) const107 {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) const123 {124 if (index >= getLength())125 return false;126 return true;127 }128 129 116 bool RuntimeArrayImp::deleteProperty(ExecState *exec, const Identifier &propertyName) 130 117 { -
trunk/JavaScriptCore/bindings/runtime_array.h
r9889 r10076 38 38 ~RuntimeArrayImp(); 39 39 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&); 42 42 virtual void put(ExecState *exec, const Identifier &propertyName, const Value &value, int attr = None); 43 43 virtual void put(ExecState *exec, unsigned propertyName, const Value &value, int attr = None); 44 44 45 virtual bool hasOwnProperty(ExecState *exec, const Identifier &propertyName) const;46 virtual bool hasOwnProperty(ExecState *exec, unsigned propertyName) const;47 45 virtual bool deleteProperty(ExecState *exec, const Identifier &propertyName); 48 46 virtual bool deleteProperty(ExecState *exec, unsigned propertyName); … … 57 55 58 56 private: 57 static Value lengthGetter(ExecState *, const Identifier&, const PropertySlot&); 58 static Value indexGetter(ExecState *, const Identifier&, const PropertySlot&); 59 59 60 Bindings::Array *_array; 60 61 }; -
trunk/JavaScriptCore/bindings/runtime_method.cpp
r9889 r10076 41 41 } 42 42 43 bool RuntimeMethodImp::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const 43 Value RuntimeMethodImp::lengthGetter(ExecState *exec, const Identifier& propertyName, const PropertySlot& slot) 44 44 { 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 56 bool RuntimeMethodImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot &slot) 57 { 46 58 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; 53 61 } 54 62 55 return FunctionImp::getOwnProperty (exec, propertyName, result);63 return FunctionImp::getOwnPropertySlot(exec, propertyName, slot); 56 64 } 57 65 -
trunk/JavaScriptCore/bindings/runtime_method.h
r9889 r10076 39 39 virtual ~RuntimeMethodImp(); 40 40 41 virtual bool getOwnProperty (ExecState *exec, const Identifier& propertyName, Value& result) const;41 virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&); 42 42 43 43 virtual bool implementsCall() const; … … 49 49 50 50 private: 51 static Value lengthGetter(ExecState *, const Identifier&, const PropertySlot&); 52 51 53 Bindings::MethodList _methodList; 52 54 }; -
trunk/JavaScriptCore/bindings/runtime_object.cpp
r9889 r10076 55 55 } 56 56 57 RuntimeObjectImp::RuntimeObjectImp(Bindings::Instance *i, bool oi) : ObjectImp ((ObjectImp *)0)57 RuntimeObjectImp::RuntimeObjectImp(Bindings::Instance *i, bool oi) 58 58 { 59 59 ownsInstance = oi; … … 61 61 } 62 62 63 bool RuntimeObjectImp::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const 63 Value 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 78 Value 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 94 Value 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 110 bool RuntimeObjectImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot) 64 111 { 65 112 instance->begin(); … … 68 115 69 116 if (aClass) { 70 // See if the instance ha vea field with the specified name.117 // See if the instance has a field with the specified name. 71 118 Field *aField = aClass->fieldNamed(propertyName.ascii(), instance); 72 119 if (aField) { 73 result = instance->getValueOfField(exec, aField); 120 slot.setCustom(this, fieldGetter); 121 instance->end(); 74 122 return true; 75 123 } else { … … 78 126 MethodList methodList = aClass->methodsNamed(propertyName.ascii(), instance); 79 127 if (methodList.length() > 0) { 80 result = Object(new RuntimeMethodImp(exec, propertyName, methodList)); 128 slot.setCustom(this, methodGetter); 129 instance->end(); 81 130 return true; 82 131 } 83 132 } 84 133 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(); 88 138 return true; 89 139 } … … 131 181 } 132 182 133 bool RuntimeObjectImp::hasOwnProperty(ExecState *exec,134 const Identifier &propertyName) const135 {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 156 183 bool RuntimeObjectImp::deleteProperty(ExecState *exec, 157 184 const Identifier &propertyName) -
trunk/JavaScriptCore/bindings/runtime_object.h
r9889 r10076 42 42 const ClassInfo *classInfo() const { return &info; } 43 43 44 virtual bool getOwnProperty (ExecState *exec, const Identifier& propertyName, Value& result) const;44 virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&); 45 45 46 46 virtual void put(ExecState *exec, const Identifier &propertyName, … … 48 48 49 49 virtual bool canPut(ExecState *exec, const Identifier &propertyName) const; 50 51 virtual bool hasOwnProperty(ExecState *exec,52 const Identifier &propertyName) const;53 54 50 55 51 virtual bool deleteProperty(ExecState *exec, … … 67 63 68 64 private: 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 69 69 Bindings::Instance *instance; 70 70 bool ownsInstance; -
trunk/JavaScriptCore/bindings/runtime_root.h
r9145 r10076 28 28 #include <JavaScriptCore/interpreter.h> 29 29 #include <JavaScriptCore/object.h> 30 #include <JavaScriptCore/protect.h> 30 31 #include <JavaScriptCore/jni_jsobject.h> 31 32 -
trunk/JavaScriptCore/kjs/array_instance.h
r9889 r10076 34 34 ~ArrayInstanceImp(); 35 35 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&); 38 38 virtual void put(ExecState *exec, const Identifier &propertyName, const Value &value, int attr = None); 39 39 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;42 40 virtual bool deleteProperty(ExecState *exec, const Identifier &propertyName); 43 41 virtual bool deleteProperty(ExecState *exec, unsigned propertyName); … … 55 53 56 54 private: 55 static Value lengthGetter(ExecState *, const Identifier&, const PropertySlot&); 56 57 57 void setLength(unsigned newLength, ExecState *exec); 58 58 -
trunk/JavaScriptCore/kjs/array_object.cpp
r9932 r10076 71 71 } 72 72 73 bool ArrayInstanceImp::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const 73 Value ArrayInstanceImp::lengthGetter(ExecState *exec, const Identifier& propertyName, const PropertySlot& slot) 74 { 75 return Number(static_cast<ArrayInstanceImp *>(slot.slotBase())->length); 76 } 77 78 bool ArrayInstanceImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot) 74 79 { 75 80 if (propertyName == lengthPropertyName) { 76 result = Number(length);81 slot.setCustom(this, lengthGetter); 77 82 return true; 78 83 } … … 87 92 if (!v || v == UndefinedImp::staticUndefined) 88 93 return false; 89 90 result = Value(v);94 95 slot.setValueSlot(this, &storage[index]); 91 96 return true; 92 97 } 93 98 } 94 99 95 return ObjectImp::getOwnProperty (exec, propertyName, result);96 } 97 98 bool ArrayInstanceImp::getOwnProperty (ExecState *exec, unsigned index, Value& result) const100 return ObjectImp::getOwnPropertySlot(exec, propertyName, slot); 101 } 102 103 bool ArrayInstanceImp::getOwnPropertySlot(ExecState *exec, unsigned index, PropertySlot& slot) 99 104 { 100 105 if (index >= length) … … 104 109 if (!v || v == UndefinedImp::staticUndefined) 105 110 return false; 106 107 result = Value(v);111 112 slot.setValueSlot(this, &storage[index]); 108 113 return true; 109 114 } 110 111 return ObjectImp::getOwnProperty (exec, Identifier::from(index), result);115 116 return ObjectImp::getOwnPropertySlot(exec, index, slot); 112 117 } 113 118 … … 147 152 assert(index >= sparseArrayCutoff); 148 153 ObjectImp::put(exec, Identifier::from(index), value, attr); 149 }150 151 bool ArrayInstanceImp::hasOwnProperty(ExecState *exec, const Identifier &propertyName) const152 {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) const171 {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));180 154 } 181 155 … … 429 403 } 430 404 431 bool ArrayPrototypeImp::getOwnProperty (ExecState *exec, const Identifier& propertyName, Value& result) const432 { 433 return lookupGetOwnFunction<ArrayProtoFuncImp, ArrayInstanceImp>(exec, propertyName, &arrayTable, this, result);405 bool ArrayPrototypeImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot) 406 { 407 return getStaticFunctionSlot<ArrayProtoFuncImp, ArrayInstanceImp>(exec, &arrayTable, this, propertyName, slot); 434 408 } 435 409 -
trunk/JavaScriptCore/kjs/array_object.h
r9889 r10076 32 32 ArrayPrototypeImp(ExecState *exec, 33 33 ObjectPrototypeImp *objProto); 34 bool getOwnProperty (ExecState *exec, const Identifier& propertyName, Value& result) const;34 bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&); 35 35 virtual const ClassInfo *classInfo() const { return &info; } 36 36 static const ClassInfo info; -
trunk/JavaScriptCore/kjs/date_object.cpp
r9924 r10076 491 491 } 492 492 493 bool DatePrototypeImp::getOwnProperty (ExecState *exec, const Identifier& propertyName, Value& result) const494 { 495 return lookupGetOwnFunction<DateProtoFuncImp, ObjectImp>(exec, propertyName, &dateTable, this, result);493 bool DatePrototypeImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot) 494 { 495 return getStaticFunctionSlot<DateProtoFuncImp, ObjectImp>(exec, &dateTable, this, propertyName, slot); 496 496 } 497 497 -
trunk/JavaScriptCore/kjs/date_object.h
r9922 r10076 47 47 public: 48 48 DatePrototypeImp(ExecState *exec, ObjectPrototypeImp *objectProto); 49 bool getOwnProperty (ExecState *exec, const Identifier& p, Value& result) const;49 bool getOwnPropertySlot(ExecState *, const Identifier &, PropertySlot&); 50 50 virtual const ClassInfo *classInfo() const { return &info; } 51 51 static const ClassInfo info; -
trunk/JavaScriptCore/kjs/function.cpp
r9929 r10076 209 209 } 210 210 211 bool FunctionImp::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const 211 Value 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 224 Value 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 236 bool FunctionImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot) 212 237 { 213 238 // 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); 224 241 return true; 225 242 } … … 227 244 // Compute length of parameters. 228 245 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); 236 247 return true; 237 248 } 238 249 239 return InternalFunctionImp::getOwnProperty (exec, propertyName, result);250 return InternalFunctionImp::getOwnPropertySlot(exec, propertyName, slot); 240 251 } 241 252 242 253 void FunctionImp::put(ExecState *exec, const Identifier &propertyName, const Value &value, int attr) 243 254 { 244 if (propertyName == argumentsPropertyName|| propertyName == lengthPropertyName)255 if (propertyName == exec->dynamicInterpreter()->argumentsIdentifier() || propertyName == lengthPropertyName) 245 256 return; 246 257 InternalFunctionImp::put(exec, propertyName, value, attr); 247 258 } 248 259 249 bool FunctionImp::hasOwnProperty(ExecState *exec, const Identifier &propertyName) const250 {251 if (propertyName == argumentsPropertyName || propertyName == lengthPropertyName)252 return true;253 return InternalFunctionImp::hasOwnProperty(exec, propertyName);254 }255 256 260 bool FunctionImp::deleteProperty(ExecState *exec, const Identifier &propertyName) 257 261 { 258 if (propertyName == argumentsPropertyName|| propertyName == lengthPropertyName)262 if (propertyName == exec->dynamicInterpreter()->argumentsIdentifier() || propertyName == lengthPropertyName) 259 263 return false; 260 264 return InternalFunctionImp::deleteProperty(exec, propertyName); … … 450 454 } 451 455 452 bool ArgumentsImp::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const 456 Value 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 462 bool ArgumentsImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot) 453 463 { 454 464 if (indexToNameMap.isMapped(propertyName)) { 455 result = _activationObject->get(exec, indexToNameMap[propertyName]);465 slot.setCustom(this, mappedIndexGetter); 456 466 return true; 457 467 } 458 468 459 return ObjectImp::getOwnProperty (exec, propertyName, result);469 return ObjectImp::getOwnPropertySlot(exec, propertyName, slot); 460 470 } 461 471 … … 479 489 } 480 490 481 bool ArgumentsImp::hasOwnProperty(ExecState *exec, const Identifier &propertyName) const482 {483 if (indexToNameMap.isMapped(propertyName))484 return true;485 486 return ObjectImp::hasOwnProperty(exec, propertyName);487 }488 489 491 // ------------------------------ ActivationImp -------------------------------- 490 492 … … 499 501 } 500 502 501 bool ActivationImp::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const 503 Value 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 514 PropertySlot::GetValueFunc ActivationImp::getArgumentsGetter() 515 { 516 return ActivationImp::argumentsGetter; 517 } 518 519 bool ActivationImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot) 502 520 { 503 521 // 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)) 505 523 return true; 506 524 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()); 513 527 return true; 514 528 } … … 517 531 } 518 532 519 bool ActivationImp::hasOwnProperty(ExecState *exec, const Identifier &propertyName) const520 {521 if (propertyName == argumentsPropertyName)522 return true;523 return ObjectImp::hasOwnProperty(exec, propertyName);524 }525 526 533 bool ActivationImp::deleteProperty(ExecState *exec, const Identifier &propertyName) 527 534 { 528 if (propertyName == argumentsPropertyName)535 if (propertyName == exec->dynamicInterpreter()->argumentsIdentifier()) 529 536 return false; 530 537 return ObjectImp::deleteProperty(exec, propertyName); -
trunk/JavaScriptCore/kjs/function.h
r9917 r10076 43 43 virtual ~FunctionImp(); 44 44 45 virtual bool getOwnProperty (ExecState *exec, const Identifier& propertyName, Value& result) const;45 virtual bool getOwnPropertySlot(ExecState *, const Identifier &, PropertySlot&); 46 46 virtual void put(ExecState *exec, const Identifier &propertyName, const Value &value, int attr = None); 47 virtual bool hasOwnProperty(ExecState *exec, const Identifier &propertyName) const;48 47 virtual bool deleteProperty(ExecState *exec, const Identifier &propertyName); 49 48 … … 67 66 68 67 private: 68 static Value argumentsGetter(ExecState *, const Identifier &, const PropertySlot&); 69 static Value lengthGetter(ExecState *, const Identifier &, const PropertySlot&); 70 69 71 void processParameters(ExecState *exec, const List &); 70 72 virtual void processVarDecls(ExecState *exec); … … 110 112 ArgumentsImp(ExecState *exec, FunctionImp *func, const List &args, ActivationImp *act); 111 113 virtual void mark(); 112 virtual bool getOwnProperty (ExecState *exec, const Identifier& propertyName, Value& result) const;114 virtual bool getOwnPropertySlot(ExecState *, const Identifier &, PropertySlot&); 113 115 virtual void put(ExecState *exec, const Identifier &propertyName, 114 116 const Value &value, int attr = None); 115 virtual bool hasOwnProperty(ExecState *exec, const Identifier &propertyName) const;116 117 virtual bool deleteProperty(ExecState *exec, const Identifier &propertyName); 117 118 virtual const ClassInfo *classInfo() const { return &info; } 118 119 static const ClassInfo info; 119 120 private: 121 static Value mappedIndexGetter(ExecState *exec, const Identifier &, const PropertySlot& slot); 122 120 123 ActivationImp *_activationObject; 121 124 mutable IndexToNameMap indexToNameMap; … … 126 129 ActivationImp(FunctionImp *function, const List &arguments); 127 130 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&); 130 132 virtual bool deleteProperty(ExecState *exec, const Identifier &propertyName); 131 133 … … 136 138 137 139 private: 140 static PropertySlot::GetValueFunc getArgumentsGetter(); 141 static Value argumentsGetter(ExecState *exec, const Identifier &, const PropertySlot& slot); 138 142 void createArgumentsObject(ExecState *exec) const; 139 143 -
trunk/JavaScriptCore/kjs/internal.cpp
r9929 r10076 498 498 499 499 InterpreterImp::InterpreterImp(Interpreter *interp, const Object &glob) 500 : _context(0) 500 : globExec(interp, 0) 501 , _context(0) 501 502 { 502 503 // add this interpreter to the global chain … … 518 519 519 520 global = glob; 520 globExec = new ExecState(m_interpreter,0);521 521 dbg = 0; 522 522 m_compatMode = Interpreter::NativeMode; … … 550 550 // Contructor prototype objects (Object.prototype, Array.prototype etc) 551 551 552 FunctionPrototypeImp *funcProto = new FunctionPrototypeImp( globExec);552 FunctionPrototypeImp *funcProto = new FunctionPrototypeImp(&globExec); 553 553 b_FunctionPrototype = Object(funcProto); 554 ObjectPrototypeImp *objProto = new ObjectPrototypeImp( globExec,funcProto);554 ObjectPrototypeImp *objProto = new ObjectPrototypeImp(&globExec, funcProto); 555 555 b_ObjectPrototype = Object(objProto); 556 556 funcProto->setPrototype(b_ObjectPrototype); 557 557 558 ArrayPrototypeImp *arrayProto = new ArrayPrototypeImp( globExec,objProto);558 ArrayPrototypeImp *arrayProto = new ArrayPrototypeImp(&globExec, objProto); 559 559 b_ArrayPrototype = Object(arrayProto); 560 StringPrototypeImp *stringProto = new StringPrototypeImp( globExec,objProto);560 StringPrototypeImp *stringProto = new StringPrototypeImp(&globExec, objProto); 561 561 b_StringPrototype = Object(stringProto); 562 BooleanPrototypeImp *booleanProto = new BooleanPrototypeImp( globExec,objProto,funcProto);562 BooleanPrototypeImp *booleanProto = new BooleanPrototypeImp(&globExec, objProto, funcProto); 563 563 b_BooleanPrototype = Object(booleanProto); 564 NumberPrototypeImp *numberProto = new NumberPrototypeImp( globExec,objProto,funcProto);564 NumberPrototypeImp *numberProto = new NumberPrototypeImp(&globExec, objProto, funcProto); 565 565 b_NumberPrototype = Object(numberProto); 566 DatePrototypeImp *dateProto = new DatePrototypeImp( globExec,objProto);566 DatePrototypeImp *dateProto = new DatePrototypeImp(&globExec, objProto); 567 567 b_DatePrototype = Object(dateProto); 568 RegExpPrototypeImp *regexpProto = new RegExpPrototypeImp( globExec,objProto,funcProto);568 RegExpPrototypeImp *regexpProto = new RegExpPrototypeImp(&globExec, objProto, funcProto); 569 569 b_RegExpPrototype = Object(regexpProto); 570 ErrorPrototypeImp *errorProto = new ErrorPrototypeImp( globExec,objProto,funcProto);570 ErrorPrototypeImp *errorProto = new ErrorPrototypeImp(&globExec, objProto, funcProto); 571 571 b_ErrorPrototype = Object(errorProto); 572 572 … … 574 574 575 575 // 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)); 585 585 586 586 // 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")); 599 599 600 600 // 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)); 607 607 608 608 // 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); 620 620 // Using Internal for those to have something != 0 621 621 // (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); 628 628 629 629 // 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); 645 645 646 646 // 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); 650 650 651 651 // 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); 663 663 #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); 665 665 #endif 666 666 667 667 // 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); 669 669 } 670 670 … … 673 673 if (dbg) 674 674 dbg->detach(m_interpreter); 675 delete globExec;676 globExec = 0L;677 675 clear(); 678 676 } … … 746 744 if (recursion >= 20) { 747 745 #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")); 749 747 unlockInterpreter(); 750 748 return result; 751 749 #else 752 return Completion(Throw,Error::create( globExec,GeneralError,"Recursion too deep"));750 return Completion(Throw,Error::create(&globExec, GeneralError, "Recursion too deep")); 753 751 #endif 754 752 } … … 762 760 // notify debugger that source has been parsed 763 761 if (dbg) { 764 bool cont = dbg->sourceParsed( globExec,sid,sourceURL,code,errLine);762 bool cont = dbg->sourceParsed(&globExec, sid, sourceURL, code, errLine); 765 763 if (!cont) 766 764 #if APPLE_CHANGES … … 776 774 // no program node means a syntax error occurred 777 775 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)); 780 778 #if APPLE_CHANGES 781 779 unlockInterpreter(); … … 784 782 } 785 783 786 globExec ->clearException();784 globExec.clearException(); 787 785 788 786 recursion++; … … 797 795 thisObj = globalObject(); 798 796 else { 799 thisObj = thisV.toObject( globExec);797 thisObj = thisV.toObject(&globExec); 800 798 } 801 799 } 802 800 803 801 Completion res; 804 if (globExec ->hadException()) {802 if (globExec.hadException()) { 805 803 // the thisArg.toObject() conversion above might have thrown an exception - if so, 806 804 // propagate it back 807 res = Completion(Throw, globExec->exception());805 res = Completion(Throw, globExec.exception()); 808 806 } 809 807 else { -
trunk/JavaScriptCore/kjs/internal.h
r9929 r10076 29 29 #include "value.h" 30 30 #include "object.h" 31 #include "protected_object.h" 31 32 #include "types.h" 32 33 #include "interpreter.h" … … 288 289 void mark(); 289 290 290 ExecState *globalExec() { return globExec; }291 ExecState *globalExec() { return &globExec; } 291 292 bool checkSyntax(const UString &code); 292 293 Completion evaluate(const UString &code, const Value &thisV, const UString &sourceURL, int startingLineNumber); … … 388 389 ProtectedObject b_uriErrorPrototype; 389 390 390 ExecState *globExec;391 ExecState globExec; 391 392 Interpreter::CompatMode m_compatMode; 392 393 -
trunk/JavaScriptCore/kjs/interpreter.cpp
r9929 r10076 27 27 #include "types.h" 28 28 #include "interpreter.h" 29 #if APPLE_CHANGES 30 #include "runtime.h" 31 #endif 29 32 30 33 #include <assert.h> … … 65 68 // ------------------------------ Interpreter ---------------------------------- 66 69 67 Interpreter::Interpreter(const Object &global) : rep(0) 70 Interpreter::Interpreter(const Object &global) 71 : rep(0) 72 , m_argumentsPropertyName(&argumentsPropertyName) 73 , m_specialPrototypePropertyName(&specialPrototypePropertyName) 68 74 { 69 75 rep = new InterpreterImp(this,global); … … 71 77 72 78 Interpreter::Interpreter() 79 : rep(0) 80 , m_argumentsPropertyName(&argumentsPropertyName) 81 , m_specialPrototypePropertyName(&specialPrototypePropertyName) 73 82 { 74 83 Object global(new ObjectImp()); … … 329 338 330 339 331 void *Interpreter::createLanguageInstanceForValue (ExecState *exec, Bindings::Instance::BindingLanguagelanguage, const Object &value, const Bindings::RootObject *origin, const Bindings::RootObject *current)332 { 333 return Bindings::Instance::createLanguageInstanceForValue (exec, language, value, origin, current);340 void *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); 334 343 } 335 344 -
trunk/JavaScriptCore/kjs/interpreter.h
r9929 r10076 26 26 #define _KJS_INTERPRETER_H_ 27 27 28 #include "object_wrapper.h" 28 29 #include "value.h" 29 #include "object.h"30 30 #include "types.h" 31 #include "protect.h"32 33 #if APPLE_CHANGES34 35 #include "runtime.h"36 37 #endif38 31 39 32 namespace KJS { … … 41 34 class ContextImp; 42 35 class InterpreterImp; 36 class RuntimeMethodImp; 37 38 namespace Bindings { 39 class RootObject; 40 } 43 41 44 42 /** … … 402 400 virtual bool isSafeScript (const Interpreter *target) { return true; } 403 401 404 virtual void *createLanguageInstanceForValue (ExecState *exec, Bindings::Instance::BindingLanguagelanguage, 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); 405 403 #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; } 406 409 407 410 private: 408 411 InterpreterImp *rep; 409 412 413 const Identifier *m_argumentsPropertyName; 414 const Identifier *m_specialPrototypePropertyName; 415 410 416 /** 411 417 * This constructor is not implemented, in order to prevent … … 421 427 */ 422 428 Interpreter operator=(const Interpreter&); 429 423 430 protected: 424 431 virtual void virtual_hook( int id, void* data ); … … 474 481 Interpreter *_interpreter; 475 482 ContextImp *_context; 476 ProtectedValue _exception;483 Value _exception; 477 484 }; 478 485 -
trunk/JavaScriptCore/kjs/lookup.h
r9891 r10076 125 125 /** 126 126 * @internal 127 * Helper for lookupFunction and lookupValueOrFunction127 * Helper for getStaticFunctionSlot and getStaticPropertySlot 128 128 */ 129 129 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) 132 131 { 133 132 // 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); 137 135 if (cachedVal) 138 return Value(cachedVal);139 140 Value val = Value(new FuncImp(exec,token, params));141 ObjectImp *thatObj = const_cast<ObjectImp *>(thisObj);142 th atObj->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); 143 141 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); 144 154 } 145 155 … … 165 175 */ 166 176 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) 169 179 { 170 180 const HashEntry* entry = Lookup::findEntry(table, propertyName); 171 181 172 182 if (!entry) // not found, forward to parent 173 return thisObj->ParentImp::getOwnProperty (exec, propertyName, result);183 return thisObj->ParentImp::getOwnPropertySlot(exec, propertyName, slot); 174 184 175 185 if (entry->attr & Function) 176 result = lookupOrCreateFunction<FuncImp>(exec, propertyName, thisObj, entry->value, entry->params, entry->attr);186 slot.setStaticEntry(thisObj, entry, staticFunctionGetter<FuncImp>); 177 187 else 178 result = thisObj->getValueProperty(exec, entry->value);188 slot.setStaticEntry(thisObj, entry, staticValueGetter<ThisImp>); 179 189 180 190 return true; … … 182 192 183 193 /** 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. 186 197 */ 187 198 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) 190 201 { 191 202 const HashEntry* entry = Lookup::findEntry(table, propertyName); 192 203 193 204 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); 195 206 196 207 assert(entry->attr & Function); 197 208 198 result = lookupOrCreateFunction<FuncImp>(exec, propertyName, thisObj, entry->value, entry->params, entry->attr);209 slot.setStaticEntry(thisObj, entry, staticFunctionGetter<FuncImp>); 199 210 return true; 200 211 } 201 212 202 213 /** 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. 205 216 */ 206 217 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) 209 220 { 210 221 const HashEntry* entry = Lookup::findEntry(table, propertyName); 211 222 212 223 if (!entry) // not found, forward to parent 213 return thisObj->ParentImp::getOwnProperty (exec, propertyName, result);224 return thisObj->ParentImp::getOwnPropertySlot(exec, propertyName, slot); 214 225 215 226 assert(!(entry->attr & Function)); 216 227 217 result = thisObj->getValueProperty(exec, entry->value);228 slot.setStaticEntry(thisObj, entry, staticValueGetter<ThisImp>); 218 229 return true; 219 230 } … … 296 307 virtual const ClassInfo *classInfo() const { return &info; } \ 297 308 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&); \ 300 310 }; \ 301 311 const ClassInfo ClassProto::info = { ClassName, 0, &ClassProto##Table, 0 }; 302 312 303 313 #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) \ 305 315 { \ 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); \ 311 317 } 312 318 313 319 #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) \ 315 321 { \ 316 if ( lookupGetOwnFunction<ClassFunc,ObjectImp>(exec, propertyName, &ClassProto##Table, this, result)) \322 if (getStaticFunctionSlot<ClassFunc,ObjectImp>(exec, &ClassProto##Table, this, propertyName, slot)) \ 317 323 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); \ 325 325 } 326 326 -
trunk/JavaScriptCore/kjs/math_object.cpp
r9889 r10076 82 82 // ECMA 15.8 83 83 84 bool MathObjectImp::getOwnProperty (ExecState *exec, const Identifier& propertyName, Value& result) const85 { 86 return lookupGetOwnProperty<MathFuncImp, MathObjectImp, ObjectImp>(exec, propertyName, &mathTable, this, result);84 bool MathObjectImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot &slot) 85 { 86 return getStaticPropertySlot<MathFuncImp, MathObjectImp, ObjectImp>(exec, &mathTable, this, propertyName, slot); 87 87 } 88 88 -
trunk/JavaScriptCore/kjs/math_object.h
r9889 r10076 32 32 MathObjectImp(ExecState *exec, 33 33 ObjectPrototypeImp *objProto); 34 bool getOwnProperty (ExecState *exec, const Identifier& propertyName, Value& result) const;34 bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&); 35 35 Value getValueProperty(ExecState *exec, int token) const; 36 36 virtual const ClassInfo *classInfo() const { return &info; } -
trunk/JavaScriptCore/kjs/nodes.cpp
r9929 r10076 278 278 ScopeChain chain = exec->context().imp()->scopeChain(); 279 279 280 Value result; 281 while (!chain.isEmpty()) { 280 assert(!chain.isEmpty()); 281 282 PropertySlot slot; 283 do { 282 284 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); 286 287 287 288 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); 294 292 } 295 293 … … 298 296 ScopeChain chain = exec->context().imp()->scopeChain(); 299 297 300 while (!chain.isEmpty()) { 298 assert(!chain.isEmpty()); 299 300 PropertySlot slot; 301 do { 301 302 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)) 308 304 return Reference(o, ident); 309 }310 305 311 306 chain.pop(); 312 } 313 314 // identifier not found 315 //cout << "Resolve: didn't find '" << ident.ascii() << "'" << endl; 307 } while (!chain.isEmpty()); 308 316 309 return Reference(Null(), ident); 317 310 } … … 530 523 Value AccessorNode1::evaluate(ExecState *exec) 531 524 { 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())); 533 536 } 534 537 … … 567 570 Value AccessorNode2::evaluate(ExecState *exec) 568 571 { 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 570 577 } 571 578 -
trunk/JavaScriptCore/kjs/number_object.cpp
r9889 r10076 403 403 } 404 404 405 bool NumberObjectImp::getOwnProperty (ExecState *exec, const Identifier& propertyName, Value& result) const406 { 407 return lookupGetOwnValue<NumberObjectImp, InternalFunctionImp>(exec, propertyName, &numberTable, this, result);405 bool NumberObjectImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot) 406 { 407 return getStaticValueSlot<NumberObjectImp, InternalFunctionImp>(exec, &numberTable, this, propertyName, slot); 408 408 } 409 409 -
trunk/JavaScriptCore/kjs/number_object.h
r9889 r10076 85 85 virtual Value call(ExecState *exec, Object &thisObj, const List &args); 86 86 87 bool getOwnProperty (ExecState *exec, const Identifier& propertyName, Value& result) const;87 bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&); 88 88 Value getValueProperty(ExecState *exec, int token) const; 89 89 virtual const ClassInfo *classInfo() const { return &info; } -
trunk/JavaScriptCore/kjs/object.cpp
r10061 r10076 209 209 Value ObjectImp::get(ExecState *exec, const Identifier &propertyName) const 210 210 { 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 219 Value 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 228 bool 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 239 bool 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 250 bool ObjectImp::getPropertySlot(ExecState *exec, unsigned propertyName, PropertySlot& slot) 251 { 252 ObjectImp *imp = this; 253 215 254 while (true) { 216 if (imp->getOwnProperty (exec, propertyName, result))217 return result;218 219 constValueImp *proto = imp->_proto;255 if (imp->getOwnPropertySlot(exec, propertyName, slot)) 256 return true; 257 258 ValueImp *proto = imp->_proto; 220 259 if (proto->dispatchType() != ObjectType) 221 260 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) const230 {231 return getOwnProperty(exec, Identifier::from(propertyName), result);232 }233 234 Value ObjectImp::get(ExecState *exec, unsigned propertyName) const235 {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) const255 {256 const ObjectImp *imp = this;257 258 while (true) {259 if (imp->getOwnProperty(exec, propertyName, result))260 return true;261 261 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); 267 263 } 268 264 269 265 return false; 266 } 267 268 bool ObjectImp::getOwnPropertySlot(ExecState *exec, unsigned propertyName, PropertySlot& slot) 269 { 270 return getOwnPropertySlot(exec, Identifier::from(propertyName), slot); 270 271 } 271 272 … … 277 278 278 279 // non-standard netscape extension 279 if (propertyName == specialPrototypePropertyName) {280 if (propertyName == exec->dynamicInterpreter()->specialPrototypeIdentifier()) { 280 281 setPrototype(value); 281 282 return; … … 324 325 bool ObjectImp::hasProperty(ExecState *exec, const Identifier &propertyName) const 325 326 { 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); 335 329 } 336 330 337 331 bool ObjectImp::hasProperty(ExecState *exec, unsigned propertyName) const 338 332 { 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); 348 335 } 349 336 350 337 bool ObjectImp::hasOwnProperty(ExecState *exec, const Identifier &propertyName) const 351 338 { 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 } 371 342 372 343 // ECMA 8.6.2.5 -
trunk/JavaScriptCore/kjs/object.h
r9889 r10076 39 39 #endif 40 40 41 #include "value.h"42 41 #include "types.h" 42 #include "interpreter.h" 43 43 #include "reference_list.h" 44 44 #include "property_map.h" 45 #include "property_slot.h" 45 46 #include "scope_chain.h" 46 47 … … 50 51 class HashEntry; 51 52 class ListImp; 52 class ReferenceList;53 54 // ECMA 262-3 8.6.155 // Attributes (only applicable to the Object type)56 enum Attribute { None = 0,57 ReadOnly = 1 << 1, // property can be only read, not written58 DontEnum = 1 << 2, // property doesn't appear in (for .. in ..)59 DontDelete = 1 << 3, // property can't be deleted60 Internal = 1 << 4, // an internal property, set to by pass checks61 Function = 1 << 5 }; // property is a function - only used by static hashtables62 53 63 54 /** … … 84 75 }; 85 76 86 /**87 * Represents an Object. This is a wrapper for ObjectImp88 */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 set103 * to 0). If you do not know for sure whether the value is of type104 * ObjectType, you should check the isValid() methods afterwards before105 * calling any methods on the Object.106 *107 * @return The value converted to an object108 */109 static Object dynamicCast(const Value &v);110 111 /**112 * Returns the prototype of this object. Note that this is not the same as113 * the "prototype" property.114 *115 * See ECMA 8.6.2116 *117 * @return The object's prototype118 */119 Value prototype() const;120 121 /**122 * Returns the class name of the object123 *124 * See ECMA 8.6.2125 *126 * @return The object's class name127 */128 UString className() const;129 130 /**131 * Retrieves the specified property from the object. If neither the object132 * or any other object in it's prototype chain have the property, this133 * function will return Undefined.134 *135 * See ECMA 8.6.2.1136 *137 * @param exec The current execution state138 * @param propertyName The name of the property to retrieve139 *140 * @return The specified property, or Undefined141 */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.2149 *150 * @param exec The current execution state151 * @param propertyName The name of the property to set152 * @param propertyValue The value to set153 */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 set161 * on an object162 *163 * See ECMA 8.6.2.3164 *165 * @param exec The current execution state166 * @param propertyName The name of the property167 * @return true if the property can be set, otherwise false168 */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.4176 *177 * @param exec The current execution state178 * @param propertyName The name of the property to check for179 * @return true if the object has the property, otherwise false180 */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.5188 *189 * @param exec The current execution state190 * @param propertyName The name of the property to check for191 * @return true if the object has the property, otherwise false192 */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.5200 *201 * @param exec The current execution state202 * @param propertyName The name of the property to delete203 * @return true if the property was successfully deleted or did not204 * exist on the object. false if deleting the specified property is not205 * 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 differ212 * depending on the supplied hint213 *214 * See ECMA 8.6.2.6215 *216 * @param exec The current execution state217 * @param hint The desired primitive type to convert to218 * @return A primitive value converted from the objetc. Note that the219 * type of primitive value returned may not be the same as the requested220 * hint.221 */222 Value defaultValue(ExecState *exec, Type hint) const;223 224 /**225 * Whether or not the object implements the construct() method. If this226 * returns false you should not call the construct() method on this227 * object (typically, an assertion will fail to indicate this).228 *229 * @return true if this object implements the construct() method, otherwise230 * false231 */232 bool implementsConstruct() const;233 234 /**235 * Creates a new object based on this object. Typically this means the236 * following:237 * 1. A new object is created238 * 2. The prototype of the new object is set to the value of this object's239 * "prototype" property240 * 3. The call() method of this object is called, with the new object241 * passed as the this value242 * 4. The new object is returned243 *244 * In some cases, Host objects may differ from these semantics, although245 * this is discouraged.246 *247 * If an error occurs during construction, the execution state's exception248 * 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() returns252 * false, in which case it will result in an assertion failure.253 *254 * @param exec The current execution state255 * @param args The arguments to be passed to call() once the new object has256 * been created257 * @return The newly created & initialized object258 */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 returns264 * 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, otherwise268 * false269 */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() returns277 * false, in which case it will result in an assertion failure.278 *279 * See ECMA 8.6.2.3280 *281 * @param exec The current execution state282 * @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 implements286 * the toString method, with the thisObj being window.location287 * @param args List of arguments to be passed to the function288 * @return The return value from the function289 */290 Value call(ExecState *exec, Object &thisObj, const List &args);291 292 /**293 * Whether or not the object implements the hasInstance() method. If this294 * returns false you should not call the hasInstance() method on this295 * object (typically, an assertion will fail to indicate this).296 *297 * @return true if this object implements the hasInstance() method,298 * otherwise false299 */300 bool implementsHasInstance() const;301 302 /**303 * Checks whether value delegates behavior to this object. Used by the304 * instanceof operator.305 *306 * @param exec The current execution state307 * @param value The value to check308 * @return true if value delegates behavior to this object, otherwise309 * false310 */311 Boolean hasInstance(ExecState *exec, const Value &value);312 313 /**314 * Returns the scope of this object. This is used when execution declared315 * functions - the execution context for the function is initialized with316 * extra object in it's scope. An example of this is functions declared317 * inside other functions:318 *319 * \code320 * function f() {321 *322 * function b() {323 * return prototype;324 * }325 *326 * var x = 4;327 * // do some stuff328 * }329 * f.prototype = new String();330 * \endcode331 *332 * When the function f.b is executed, its scope will include properties of333 * f. So in the example above the return value of f.b() would be the new334 * String object that was assigned to f.prototype.335 *336 * @param exec The current execution state337 * @return The function's scope338 */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. Used344 * in "for x in y" statements. The list is created new, so it can be freely345 * modified without affecting the object's properties. It should be deleted346 * by the caller.347 *348 * Subclasses can override this method in ObjectImpl to provide the349 * appearance of350 * having extra properties other than those set specifically with put().351 *352 * @param exec The current execution state353 * @param recursive Whether or not properties in the object's prototype354 * chain should be355 * 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 such362 * as String and Boolean which are wrappers for native types. The interal363 * value is the actual value represented by the wrapper objects.364 *365 * @see ECMA 8.6.2366 * @return The internal value of the object367 */368 Value internalValue() const;369 370 /**371 * Sets the internal value of the object372 *373 * @see internalValue()374 *375 * @param v The new internal value376 */377 void setInternalValue(const Value &v);378 379 void saveProperties(SavedProperties &p) const;380 void restoreProperties(const SavedProperties &p);381 };382 383 77 inline Object Value::toObject(ExecState *exec) const { return rep->dispatchToObject(exec); } 384 78 … … 510 204 bool getProperty(ExecState *exec, unsigned propertyName, Value& result) const; 511 205 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&); 514 210 515 211 /** … … 538 234 * @see Object::hasProperty() 539 235 */ 540 bool hasProperty(ExecState *exec, 541 const Identifier &propertyName) const; 236 bool hasProperty(ExecState *exec, const Identifier &propertyName) const; 542 237 bool hasProperty(ExecState *exec, unsigned propertyName) const; 543 238 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; 547 240 548 241 /** … … 624 317 ValueImp *getDirect(const Identifier& propertyName) const 625 318 { return _prop.get(propertyName); } 319 ValueImp **getDirectLocation(const Identifier& propertyName) 320 { return _prop.getLocation(propertyName); } 626 321 void putDirect(const Identifier &propertyName, ValueImp *value, int attr = 0); 627 322 void putDirect(const Identifier &propertyName, int value, int attr = 0); … … 639 334 }; 640 335 641 642 336 // it may seem crazy to inline a function this large but it makes a big difference 643 337 // since this is function very hot in variable lookup 644 inline bool ObjectImp::getProperty (ExecState *exec, const Identifier& propertyName, Value& result) const338 inline bool ObjectImp::getPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot) 645 339 { 646 constObjectImp *imp = this;340 ObjectImp *imp = this; 647 341 648 342 while (true) { 649 if (imp->getOwnProperty (exec, propertyName, result))343 if (imp->getOwnPropertySlot(exec, propertyName, slot)) 650 344 return true; 651 345 652 constValueImp *proto = imp->_proto;346 ValueImp *proto = imp->_proto; 653 347 if (proto->dispatchType() != ObjectType) 654 348 break; 655 349 656 imp = static_cast< constObjectImp *>(proto);350 imp = static_cast<ObjectImp *>(proto); 657 351 } 658 352 … … 663 357 // but it makes a big difference to property lookup if subclasses can inline their 664 358 // superclass call to this 665 inline bool ObjectImp::getOwnProperty (ExecState *exec, const Identifier &propertyName, Value &result) const359 inline bool ObjectImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot) 666 360 { 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); 670 364 return true; 671 365 } 672 366 673 367 // non-standard netscape extension 674 if (propertyName == specialPrototypePropertyName) {675 result = Value(_proto);368 if (propertyName == exec->dynamicInterpreter()->specialPrototypeIdentifier()) { 369 slot.setValueSlot(this, &_proto); 676 370 return true; 677 371 } … … 760 454 { return imp()->hasProperty(exec, propertyName); } 761 455 762 inline bool Object::hasProperty(ExecState *exec, unsigned propertyName) const763 { return imp()->hasProperty(exec, propertyName); }764 765 456 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) const769 457 { return imp()->hasOwnProperty(exec, propertyName); } 770 458 -
trunk/JavaScriptCore/kjs/property_map.cpp
r9992 r10076 233 233 } 234 234 235 ValueImp **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 235 272 #if DEBUG_PROPERTIES 236 273 static void printAttributes(int attributes) -
trunk/JavaScriptCore/kjs/property_map.h
r9768 r10076 79 79 ValueImp *get(const Identifier &name) const; 80 80 ValueImp *get(const Identifier &name, int &attributes) const; 81 ValueImp **getLocation(const Identifier &name); 81 82 82 83 void mark() const; -
trunk/JavaScriptCore/kjs/protect.h
r9145 r10076 25 25 #define _KJS_PROTECT_H_ 26 26 27 #include "object.h"28 27 #include "reference.h" 29 28 #include "value.h" … … 78 77 }; 79 78 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 131 80 132 81 #endif -
trunk/JavaScriptCore/kjs/reference.h
r9768 r10076 28 28 29 29 namespace KJS { 30 31 class Object; 32 class ObjectImp; 30 33 31 34 class Reference { -
trunk/JavaScriptCore/kjs/reference_list.cpp
r9768 r10076 23 23 #include "reference_list.h" 24 24 25 #include "protect .h"25 #include "protected_object.h" 26 26 27 27 namespace KJS { -
trunk/JavaScriptCore/kjs/regexp_object.cpp
r9889 r10076 217 217 } 218 218 219 bool RegExpObjectImp::getOwnProperty(ExecState *exec, const Identifier& p, Value& result) const 220 { 221 UString s = p.ustring(); 219 Value 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 233 bool RegExpObjectImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot) 234 { 235 UString s = propertyName.ustring(); 222 236 if (s[0] == '$' && lastOvector) 223 237 { … … 226 240 if (ok) 227 241 { 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); 235 243 return true; 236 244 } 237 245 } 238 246 239 return InternalFunctionImp::getOwnProperty (exec, p, result);247 return InternalFunctionImp::getOwnPropertySlot(exec, propertyName, slot); 240 248 } 241 249 -
trunk/JavaScriptCore/kjs/regexp_object.h
r9889 r10076 75 75 virtual Value call(ExecState *exec, Object &thisObj, const List &args); 76 76 77 virtual bool getOwnProperty (ExecState *exec, const Identifier& propertyName, Value& result) const;77 virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&); 78 78 int ** registerRegexp( const RegExp* re, const UString& s ); 79 79 void setSubPatterns(int num) { lastNrSubPatterns = num; } 80 80 Object arrayOfMatches(ExecState *exec, const UString &result) const; 81 81 private: 82 static Value backrefGetter(ExecState *exec, const Identifier&, const PropertySlot& slot); 83 82 84 UString lastString; 83 85 int *lastOvector; -
trunk/JavaScriptCore/kjs/string_object.cpp
r9889 r10076 51 51 } 52 52 53 bool StringInstanceImp::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const 53 Value 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 58 Value 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 64 bool StringInstanceImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot &slot) 54 65 { 55 66 if (propertyName == lengthPropertyName) { 56 result = Value(internalValue().toString(exec).size());67 slot.setCustom(this, lengthGetter); 57 68 return true; 58 69 } … … 64 75 const unsigned length = s.size(); 65 76 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); 69 79 return true; 70 80 } 71 81 72 return ObjectImp::getOwnProperty (exec, propertyName, result);82 return ObjectImp::getOwnPropertySlot(exec, propertyName, slot); 73 83 } 74 84 … … 78 88 return; 79 89 ObjectImp::put(exec, propertyName, value, attr); 80 }81 82 bool StringInstanceImp::hasOwnProperty(ExecState *exec, const Identifier &propertyName) const83 {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);96 90 } 97 91 … … 155 149 } 156 150 157 bool StringPrototypeImp::getOwnProperty (ExecState *exec, const Identifier& propertyName, Value& result) const158 { 159 return lookupGetOwnFunction<StringProtoFuncImp, StringInstanceImp>(exec, propertyName, &stringTable, this, result);151 bool StringPrototypeImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot &slot) 152 { 153 return getStaticFunctionSlot<StringProtoFuncImp, StringInstanceImp>(exec, &stringTable, this, propertyName, slot); 160 154 } 161 155 -
trunk/JavaScriptCore/kjs/string_object.h
r9889 r10076 33 33 StringInstanceImp(ObjectImp *proto, const UString &string); 34 34 35 virtual bool getOwnProperty (ExecState *exec, const Identifier& propertyName, Value& result) const;35 virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&); 36 36 virtual void put(ExecState *exec, const Identifier &propertyName, const Value &value, int attr = None); 37 virtual bool hasOwnProperty(ExecState *exec, const Identifier &propertyName) const;38 37 virtual bool deleteProperty(ExecState *exec, const Identifier &propertyName); 39 38 40 39 virtual const ClassInfo *classInfo() const { return &info; } 41 40 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); 42 44 }; 43 45 … … 52 54 StringPrototypeImp(ExecState *exec, 53 55 ObjectPrototypeImp *objProto); 54 virtual bool getOwnProperty (ExecState *exec, const Identifier& propertyName, Value& result) const;56 virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&); 55 57 virtual const ClassInfo *classInfo() const { return &info; } 56 58 static const ClassInfo info;
Note:
See TracChangeset
for help on using the changeset viewer.