Commit 70d74214 authored by mjs's avatar mjs
Browse files

JavaScriptCore:

        Reviewed by Darin.

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

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

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

	* JavaScriptCore.xcodeproj/project.pbxproj:
        * bindings/objc/objc_runtime.h:
        * bindings/objc/objc_runtime.mm:
        (ObjcFallbackObjectImp::ObjcFallbackObjectImp):
        (ObjcFallbackObjectImp::getOwnPropertySlot):
        * bindings/runtime_array.cpp:
        (RuntimeArrayImp::lengthGetter):
        (RuntimeArrayImp::indexGetter):
        (RuntimeArrayImp::getOwnPropertySlot):
        * bindings/runtime_array.h:
        * bindings/runtime_method.cpp...
parent 0993ca34
2005-08-06 Maciej Stachowiak <mjs@apple.com>
Reviewed by Darin.
Change over to the new PropertySlot mechanism for property
lookup. This allows the elimination of hasOwnProperty
methods. Also did some of the performance tuning enabled by this
(but not yet all the possible improvements for function calls,
assignment, ++, and so forth). And also much code cleanup.
Net result is about a 2% speedup on the JS iBench.
Also redid Geoff's fix for the chrashing applet by avoiding a NULL
prototype in the bindings code and using the default of Null()
instead.
* JavaScriptCore.xcodeproj/project.pbxproj:
* bindings/objc/objc_runtime.h:
* bindings/objc/objc_runtime.mm:
(ObjcFallbackObjectImp::ObjcFallbackObjectImp):
(ObjcFallbackObjectImp::getOwnPropertySlot):
* bindings/runtime_array.cpp:
(RuntimeArrayImp::lengthGetter):
(RuntimeArrayImp::indexGetter):
(RuntimeArrayImp::getOwnPropertySlot):
* bindings/runtime_array.h:
* bindings/runtime_method.cpp:
(RuntimeMethodImp::lengthGetter):
(RuntimeMethodImp::getOwnPropertySlot):
* bindings/runtime_method.h:
* bindings/runtime_object.cpp:
(RuntimeObjectImp::RuntimeObjectImp):
(RuntimeObjectImp::fallbackObjectGetter):
(RuntimeObjectImp::fieldGetter):
(RuntimeObjectImp::methodGetter):
(RuntimeObjectImp::getOwnPropertySlot):
* bindings/runtime_object.h:
* bindings/runtime_root.h:
* kjs/array_instance.h:
* kjs/array_object.cpp:
(ArrayInstanceImp::lengthGetter):
(ArrayInstanceImp::getOwnPropertySlot):
(ArrayPrototypeImp::getOwnPropertySlot):
* kjs/array_object.h:
* kjs/date_object.cpp:
(DatePrototypeImp::getOwnPropertySlot):
* kjs/date_object.h:
* kjs/function.cpp:
(KJS::FunctionImp::argumentsGetter):
(KJS::FunctionImp::lengthGetter):
(KJS::FunctionImp::getOwnPropertySlot):
(KJS::FunctionImp::put):
(KJS::FunctionImp::deleteProperty):
(KJS::ArgumentsImp::mappedIndexGetter):
(KJS::ArgumentsImp::getOwnPropertySlot):
(KJS::ActivationImp::argumentsGetter):
(KJS::ActivationImp::getArgumentsGetter):
(KJS::ActivationImp::getOwnPropertySlot):
(KJS::ActivationImp::deleteProperty):
* kjs/function.h:
* kjs/internal.cpp:
(InterpreterImp::InterpreterImp):
(InterpreterImp::initGlobalObject):
(InterpreterImp::~InterpreterImp):
(InterpreterImp::evaluate):
* kjs/internal.h:
(KJS::InterpreterImp::globalExec):
* kjs/interpreter.cpp:
(Interpreter::Interpreter):
(Interpreter::createLanguageInstanceForValue):
* kjs/interpreter.h:
(KJS::Interpreter::argumentsIdentifier):
(KJS::Interpreter::specialPrototypeIdentifier):
* kjs/lookup.h:
(KJS::staticFunctionGetter):
(KJS::staticValueGetter):
(KJS::getStaticPropertySlot):
(KJS::getStaticFunctionSlot):
(KJS::getStaticValueSlot):
* kjs/math_object.cpp:
(MathObjectImp::getOwnPropertySlot):
* kjs/math_object.h:
* kjs/nodes.cpp:
(ResolveNode::evaluate):
(ResolveNode::evaluateReference):
(AccessorNode1::evaluate):
(AccessorNode2::evaluate):
* kjs/number_object.cpp:
(NumberObjectImp::getOwnPropertySlot):
* kjs/number_object.h:
* kjs/object.cpp:
(KJS::ObjectImp::get):
(KJS::ObjectImp::getProperty):
(KJS::ObjectImp::getPropertySlot):
(KJS::ObjectImp::getOwnPropertySlot):
(KJS::ObjectImp::put):
(KJS::ObjectImp::hasProperty):
(KJS::ObjectImp::hasOwnProperty):
* kjs/object.h:
(KJS::ObjectImp::getDirectLocation):
(KJS::ObjectImp::getPropertySlot):
(KJS::ObjectImp::getOwnPropertySlot):
* kjs/object_wrapper.h: Added.
(KJS::):
(KJS::Object::Object):
(KJS::Object::operator ObjectImp *):
* kjs/property_map.cpp:
(KJS::PropertyMap::getLocation):
* kjs/property_map.h:
* kjs/property_slot.cpp: Added.
(KJS::PropertySlot::undefinedGetter):
* kjs/property_slot.h: Added.
(KJS::PropertySlot::isSet):
(KJS::PropertySlot::getValue):
(KJS::PropertySlot::setValueSlot):
(KJS::PropertySlot::setStaticEntry):
(KJS::PropertySlot::setCustom):
(KJS::PropertySlot::setCustomIndex):
(KJS::PropertySlot::setUndefined):
(KJS::PropertySlot::slotBase):
(KJS::PropertySlot::staticEntry):
(KJS::PropertySlot::index):
(KJS::PropertySlot::):
* kjs/protect.h:
* kjs/protected_object.h: Added.
(KJS::ProtectedObject::ProtectedObject):
(KJS::ProtectedObject::~ProtectedObject):
(KJS::ProtectedObject::operator=):
(KJS::ProtectedReference::ProtectedReference):
(KJS::ProtectedReference::~ProtectedReference):
(KJS::ProtectedReference::operator=):
* kjs/reference.h:
* kjs/reference_list.cpp:
* kjs/regexp_object.cpp:
(RegExpObjectImp::backrefGetter):
(RegExpObjectImp::getOwnPropertySlot):
* kjs/regexp_object.h:
* kjs/string_object.cpp:
(StringInstanceImp::lengthGetter):
(StringInstanceImp::indexGetter):
(StringInstanceImp::getOwnPropertySlot):
(StringPrototypeImp::getOwnPropertySlot):
* kjs/string_object.h:
2005-08-05 Adele Peterson <adele@apple.com>
Reviewed by Darin.
......
......@@ -25,6 +25,14 @@
/* End PBXAggregateTarget section */
/* Begin PBXBuildFile section */
65305EAF08A58DDE00F31E73 /* protected_object.h in Headers */ = {isa = PBXBuildFile; fileRef = 65305EAE08A58DDE00F31E73 /* protected_object.h */; settings = {ATTRIBUTES = (Private, ); }; };
65305EB008A58E0900F31E73 /* protected_object.h in Headers */ = {isa = PBXBuildFile; fileRef = 65305EAE08A58DDE00F31E73 /* protected_object.h */; settings = {ATTRIBUTES = (Private, ); }; };
6539AACB08A3225A00223EE2 /* object_wrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 6539AACA08A3225A00223EE2 /* object_wrapper.h */; settings = {ATTRIBUTES = (Private, ); }; };
65621E6D089E859700760F35 /* property_slot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65621E6B089E859700760F35 /* property_slot.cpp */; };
65621E6E089E859700760F35 /* property_slot.h in Headers */ = {isa = PBXBuildFile; fileRef = 65621E6C089E859700760F35 /* property_slot.h */; settings = {ATTRIBUTES = (Private, ); }; };
65621E6F089E85D300760F35 /* property_slot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65621E6B089E859700760F35 /* property_slot.cpp */; };
65621E70089E85D300760F35 /* property_slot.h in Headers */ = {isa = PBXBuildFile; fileRef = 65621E6C089E859700760F35 /* property_slot.h */; settings = {ATTRIBUTES = (Private, ); }; };
65BBAEE008A329B300357728 /* object_wrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 6539AACA08A3225A00223EE2 /* object_wrapper.h */; settings = {ATTRIBUTES = (Private, ); }; };
932F5B400822A1C700736975 /* array_object.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A84E0255597D01FF60F7 /* array_object.h */; settings = {ATTRIBUTES = (Private, ); }; };
932F5B420822A1C700736975 /* collector.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A8530255597D01FF60F7 /* collector.h */; settings = {ATTRIBUTES = (Private, ); }; };
932F5B430822A1C700736975 /* date_object.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A8560255597D01FF60F7 /* date_object.h */; settings = {ATTRIBUTES = (Private, ); }; };
......@@ -449,6 +457,8 @@
651BDC78080F10CC00F10856 /* fast_malloc.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = fast_malloc.h; sourceTree = "<group>"; };
651F6412039D5B5F0078395C /* dtoa.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = dtoa.cpp; sourceTree = "<group>"; };
651F6413039D5B5F0078395C /* dtoa.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = dtoa.h; sourceTree = "<group>"; };
65305EAE08A58DDE00F31E73 /* protected_object.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = protected_object.h; sourceTree = "<group>"; };
6539AACA08A3225A00223EE2 /* object_wrapper.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = object_wrapper.h; sourceTree = "<group>"; };
65417205039E02E70058BFEB /* get.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = get.c; path = pcre/get.c; sourceTree = "<group>"; };
65417206039E02E70058BFEB /* maketables.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = maketables.c; path = pcre/maketables.c; sourceTree = "<group>"; };
65417207039E02E70058BFEB /* pcre.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pcre.c; path = pcre/pcre.c; sourceTree = "<group>"; };
......@@ -458,6 +468,8 @@
65417217039E0B280058BFEB /* pcre-config.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = "pcre-config.h"; path = "pcre/pcre-config.h"; sourceTree = "<group>"; };
6560A4CF04B3B3E7008AE952 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = "<absolute>"; };
6560A63D04B3B69F008AE952 /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = /System/Library/Frameworks/CoreServices.framework; sourceTree = "<absolute>"; };
65621E6B089E859700760F35 /* property_slot.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = property_slot.cpp; sourceTree = "<group>"; };
65621E6C089E859700760F35 /* property_slot.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = property_slot.h; sourceTree = "<group>"; };
65AB004806261CBA0076DE63 /* interpreter_map.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = interpreter_map.cpp; sourceTree = "<group>"; };
65AB004906261CBA0076DE63 /* interpreter_map.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = interpreter_map.h; sourceTree = "<group>"; };
65C02FBB0637462A003E7EE6 /* protect.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = protect.h; sourceTree = "<group>"; };
......@@ -632,6 +644,10 @@
08FB77AEFE84172EC02AAC07 /* Classes */ = {
isa = PBXGroup;
children = (
65305EAE08A58DDE00F31E73 /* protected_object.h */,
6539AACA08A3225A00223EE2 /* object_wrapper.h */,
65621E6B089E859700760F35 /* property_slot.cpp */,
65621E6C089E859700760F35 /* property_slot.h */,
938772E5038BFE19008635CE /* array_instance.h */,
650B68D80639033F009D42DE /* protected_values.cpp */,
650B68D90639033F009D42DE /* protected_values.h */,
......@@ -828,6 +844,7 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
65305EAF08A58DDE00F31E73 /* protected_object.h in Headers */,
932F5B400822A1C700736975 /* array_object.h in Headers */,
932F5B420822A1C700736975 /* collector.h in Headers */,
932F5B430822A1C700736975 /* date_object.h in Headers */,
......@@ -900,6 +917,8 @@
932F5B8E0822A1C700736975 /* npruntime_impl.h in Headers */,
932F5B8F0822A1C700736975 /* fast_malloc.h in Headers */,
932FC11D0824A6A3005B3C75 /* create_hash_table in Headers */,
65621E6E089E859700760F35 /* property_slot.h in Headers */,
6539AACB08A3225A00223EE2 /* object_wrapper.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......@@ -907,6 +926,7 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
65305EB008A58E0900F31E73 /* protected_object.h in Headers */,
A85D81F8087B2822006A9172 /* array_object.h in Headers */,
A85D81F9087B2822006A9172 /* collector.h in Headers */,
A85D81FA087B2822006A9172 /* date_object.h in Headers */,
......@@ -922,6 +942,7 @@
A85D8204087B2822006A9172 /* nodes.h in Headers */,
A85D8205087B2822006A9172 /* number_object.h in Headers */,
A85D8206087B2822006A9172 /* object_object.h in Headers */,
65BBAEE008A329B300357728 /* object_wrapper.h in Headers */,
A85D8207087B2822006A9172 /* object.h in Headers */,
A85D8208087B2822006A9172 /* operations.h in Headers */,
A85D8209087B2822006A9172 /* property_map.h in Headers */,
......@@ -978,6 +999,7 @@
A85D823C087B2822006A9172 /* npruntime_priv.h in Headers */,
A85D823D087B2822006A9172 /* npruntime_impl.h in Headers */,
A85D823E087B2822006A9172 /* fast_malloc.h in Headers */,
65621E70089E85D300760F35 /* property_slot.h in Headers */,
A85D823F087B2822006A9172 /* create_hash_table in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
......@@ -1529,6 +1551,7 @@
932F5BCF0822A1C700736975 /* jni_objc.mm in Sources */,
932F5BD00822A1C700736975 /* softlinking.c in Sources */,
932F5BD10822A1C700736975 /* fast_malloc.cpp in Sources */,
65621E6D089E859700760F35 /* property_slot.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......@@ -1616,6 +1639,7 @@
A85D827E087B2822006A9172 /* jni_objc.mm in Sources */,
A85D827F087B2822006A9172 /* softlinking.c in Sources */,
A85D8280087B2822006A9172 /* fast_malloc.cpp in Sources */,
65621E6F089E85D300760F35 /* property_slot.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......
......@@ -169,7 +169,7 @@ public:
const ClassInfo *classInfo() const { return &info; }
virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&);
virtual void put(ExecState *exec, const Identifier &propertyName,
const Value &value, int attr = None);
......@@ -179,12 +179,7 @@ public:
virtual bool implementsCall() const;
virtual Value call(ExecState *exec, Object &thisObj, const List &args);
virtual bool hasOwnProperty(ExecState *exec,
const Identifier &propertyName) const;
virtual bool deleteProperty(ExecState *exec,
const Identifier &propertyName);
virtual bool deleteProperty(ExecState *exec, const Identifier &propertyName);
virtual Value defaultValue(ExecState *exec, Type hint) const;
......
......@@ -262,16 +262,15 @@ ObjcFallbackObjectImp::ObjcFallbackObjectImp(ObjectImp *proto)
}
ObjcFallbackObjectImp::ObjcFallbackObjectImp(ObjcInstance *i, const KJS::Identifier propertyName)
: ObjectImp ((ObjectImp *)0)
{
_instance = i;
_item = propertyName;
}
bool ObjcFallbackObjectImp::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
bool ObjcFallbackObjectImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
{
// keep the prototype from getting called instead of just returning false
result = Undefined();
slot.setUndefined(this);
return true;
}
......@@ -335,12 +334,6 @@ Value ObjcFallbackObjectImp::call(ExecState *exec, Object &thisObj, const List &
return result;
}
bool ObjcFallbackObjectImp::hasOwnProperty(ExecState *exec,
const Identifier &propertyName) const
{
return false;
}
bool ObjcFallbackObjectImp::deleteProperty(ExecState *exec,
const Identifier &propertyName)
{
......
......@@ -43,34 +43,45 @@ RuntimeArrayImp::~RuntimeArrayImp()
delete _array;
}
bool RuntimeArrayImp::getOwnProperty(ExecState *exec, const Identifier &propertyName, Value& result) const
Value RuntimeArrayImp::lengthGetter(ExecState *exec, const Identifier& propertyName, const PropertySlot& slot)
{
RuntimeArrayImp *thisObj = static_cast<RuntimeArrayImp *>(slot.slotBase());
return Number(thisObj->getLength());
}
Value RuntimeArrayImp::indexGetter(ExecState *exec, const Identifier& propertyName, const PropertySlot& slot)
{
RuntimeArrayImp *thisObj = static_cast<RuntimeArrayImp *>(slot.slotBase());
return thisObj->getConcreteArray()->valueAt(exec, slot.index());
}
bool RuntimeArrayImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
{
if (propertyName == lengthPropertyName) {
result = Number(getLength());
slot.setCustom(this, lengthGetter);
return true;
}
bool ok;
unsigned index = propertyName.toArrayIndex(&ok);
if (ok) {
if (index >= getLength())
result = Undefined();
else
result = getConcreteArray()->valueAt(exec, index);
return true;
if (index < getLength()) {
slot.setCustomIndex(this, index, indexGetter);
return true;
}
}
return ArrayInstanceImp::getOwnProperty(exec, propertyName, result);
return ArrayInstanceImp::getOwnPropertySlot(exec, propertyName, slot);
}
bool RuntimeArrayImp::getOwnProperty(ExecState *exec, unsigned index, Value& result) const
bool RuntimeArrayImp::getOwnPropertySlot(ExecState *exec, unsigned index, PropertySlot& slot)
{
if (index >= getLength())
result = Undefined();
else
result = getConcreteArray()->valueAt(exec, index);
if (index < getLength()) {
slot.setCustomIndex(this, index, indexGetter);
return true;
}
return true;
return ArrayInstanceImp::getOwnPropertySlot(exec, index, slot);
}
void RuntimeArrayImp::put(ExecState *exec, const Identifier &propertyName, const Value &value, int attr)
......@@ -102,30 +113,6 @@ void RuntimeArrayImp::put(ExecState *exec, unsigned index, const Value &value, i
getConcreteArray()->setValueAt(exec, index, value);
}
bool RuntimeArrayImp::hasOwnProperty(ExecState *exec, const Identifier &propertyName) const
{
if (propertyName == lengthPropertyName)
return true;
bool ok;
unsigned index = propertyName.toArrayIndex(&ok);
if (ok) {
if (index >= getLength())
return false;
return true;
}
return ObjectImp::hasOwnProperty(exec, propertyName);
}
bool RuntimeArrayImp::hasOwnProperty(ExecState *exec, unsigned index) const
{
if (index >= getLength())
return false;
return true;
}
bool RuntimeArrayImp::deleteProperty(ExecState *exec, const Identifier &propertyName)
{
return false;
......
......@@ -37,13 +37,11 @@ public:
RuntimeArrayImp(ExecState *exec, Bindings::Array *i);
~RuntimeArrayImp();
virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
virtual bool getOwnProperty(ExecState *exec, unsigned index, Value& result) const ;
virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&);
virtual bool getOwnPropertySlot(ExecState *, unsigned, PropertySlot&);
virtual void put(ExecState *exec, const Identifier &propertyName, const Value &value, int attr = None);
virtual void put(ExecState *exec, unsigned propertyName, const Value &value, int attr = None);
virtual bool hasOwnProperty(ExecState *exec, const Identifier &propertyName) const;
virtual bool hasOwnProperty(ExecState *exec, unsigned propertyName) const;
virtual bool deleteProperty(ExecState *exec, const Identifier &propertyName);
virtual bool deleteProperty(ExecState *exec, unsigned propertyName);
......@@ -56,6 +54,9 @@ public:
static const ClassInfo info;
private:
static Value lengthGetter(ExecState *, const Identifier&, const PropertySlot&);
static Value indexGetter(ExecState *, const Identifier&, const PropertySlot&);
Bindings::Array *_array;
};
......
......@@ -40,19 +40,27 @@ RuntimeMethodImp::~RuntimeMethodImp()
{
}
bool RuntimeMethodImp::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
Value RuntimeMethodImp::lengthGetter(ExecState *exec, const Identifier& propertyName, const PropertySlot& slot)
{
RuntimeMethodImp *thisObj = static_cast<RuntimeMethodImp *>(slot.slotBase());
// Ick! There may be more than one method with this name. Arbitrarily
// just pick the first method. The fundamental problem here is that
// JavaScript doesn't have the notion of method overloading and
// Java does.
// FIXME: a better solution might be to give the maximum number of parameters
// of any method
return Number(thisObj->_methodList.methodAt(0)->numParameters());
}
bool RuntimeMethodImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot &slot)
{
// Compute length of parameters.
if (propertyName == lengthPropertyName) {
// Ick! There may be more than one method with this name. Arbitrarily
// just pick the first method. The fundamental problem here is that
// JavaScript doesn't have the notion of method overloading and
// Java does.
result = Number(_methodList.methodAt(0)->numParameters());
return result;
slot.setCustom(this, lengthGetter);
return true;
}
return FunctionImp::getOwnProperty(exec, propertyName, result);
return FunctionImp::getOwnPropertySlot(exec, propertyName, slot);
}
bool RuntimeMethodImp::implementsCall() const
......
......@@ -38,7 +38,7 @@ public:
virtual ~RuntimeMethodImp();
virtual bool getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const;
virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&);
virtual bool implementsCall() const;
virtual Value call(ExecState *exec, Object &thisObj, const List &args);
......@@ -48,6 +48,8 @@ public:
virtual Completion execute(ExecState *exec);
private:
static Value lengthGetter(ExecState *, const Identifier&, const PropertySlot&);
Bindings::MethodList _methodList;
};
......
......@@ -54,37 +54,87 @@ RuntimeObjectImp::~RuntimeObjectImp()
}
}
RuntimeObjectImp::RuntimeObjectImp(Bindings::Instance *i, bool oi) : ObjectImp ((ObjectImp *)0)
RuntimeObjectImp::RuntimeObjectImp(Bindings::Instance *i, bool oi)
{
ownsInstance = oi;
instance = i;
}
bool RuntimeObjectImp::getOwnProperty(ExecState *exec, const Identifier& propertyName, Value& result) const
Value RuntimeObjectImp::fallbackObjectGetter(ExecState *exec, const Identifier& propertyName, const PropertySlot& slot)
{
RuntimeObjectImp *thisObj = static_cast<RuntimeObjectImp *>(slot.slotBase());
Bindings::Instance *instance = thisObj->instance;
instance->begin();
Class *aClass = instance->getClass();
Value result = aClass->fallbackObject(exec, instance, propertyName);
instance->end();
return result;
}
Value RuntimeObjectImp::fieldGetter(ExecState *exec, const Identifier& propertyName, const PropertySlot& slot)
{
RuntimeObjectImp *thisObj = static_cast<RuntimeObjectImp *>(slot.slotBase());
Bindings::Instance *instance = thisObj->instance;
instance->begin();
Class *aClass = instance->getClass();
Field *aField = aClass->fieldNamed(propertyName.ascii(), instance);
Value result = instance->getValueOfField(exec, aField);
instance->end();
return result;
}
Value RuntimeObjectImp::methodGetter(ExecState *exec, const Identifier& propertyName, const PropertySlot& slot)
{
RuntimeObjectImp *thisObj = static_cast<RuntimeObjectImp *>(slot.slotBase());
Bindings::Instance *instance = thisObj->instance;
instance->begin();
Class *aClass = instance->getClass();
MethodList methodList = aClass->methodsNamed(propertyName.ascii(), instance);
Value result = Object(new RuntimeMethodImp(exec, propertyName, methodList));
instance->end();
return result;
}
bool RuntimeObjectImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
{
instance->begin();
Class *aClass = instance->getClass();
if (aClass) {
// See if the instance have a field with the specified name.
// See if the instance has a field with the specified name.
Field *aField = aClass->fieldNamed(propertyName.ascii(), instance);
if (aField) {
result = instance->getValueOfField(exec, aField);
slot.setCustom(this, fieldGetter);
instance->end();
return true;
} else {
// Now check if a method with specified name exists, if so return a function object for
// that method.
MethodList methodList = aClass->methodsNamed(propertyName.ascii(), instance);
if (methodList.length() > 0) {
result = Object(new RuntimeMethodImp(exec, propertyName, methodList));
slot.setCustom(this, methodGetter);
instance->end();
return true;
}
}
if (result.type() == UndefinedType) {
// Try a fallback object.
result = aClass->fallbackObject(exec, instance, propertyName);
// Try a fallback object.
if (!aClass->fallbackObject(exec, instance, propertyName).type() != UndefinedType) {
slot.setCustom(this, fallbackObjectGetter);
instance->end();
return true;
}
}
......@@ -130,29 +180,6 @@ bool RuntimeObjectImp::canPut(ExecState *exec, const Identifier &propertyName) c
return result;
}
bool RuntimeObjectImp::hasOwnProperty(ExecState *exec,
const Identifier &propertyName) const
{
bool result = false;
instance->begin();
Field *aField = instance->getClass()->fieldNamed(propertyName.ascii(), instance);
if (aField) {