Commit 069ad172 authored by mhahnenberg@apple.com's avatar mhahnenberg@apple.com

De-virtualize JSObject::hasInstance

https://bugs.webkit.org/show_bug.cgi?id=71430

Reviewed by Darin Adler.

Added hasInstance to the MethodTable, changed all the virtual
implementations of hasInstance to static ones, and replaced
all call sites with corresponding lookups in the MethodTable.

* API/JSCallbackObject.h:
* API/JSCallbackObjectFunctions.h:
(JSC::::hasInstance):
* API/JSValueRef.cpp:
(JSValueIsInstanceOfConstructor):
* JavaScriptCore.exp:
* JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
* interpreter/Interpreter.cpp:
(JSC::Interpreter::privateExecute):
* jit/JITStubs.cpp:
(JSC::DEFINE_STUB_FUNCTION):
* runtime/ClassInfo.h:
* runtime/JSBoundFunction.cpp:
(JSC::JSBoundFunction::hasInstance):
* runtime/JSBoundFunction.h:
* runtime/JSCell.cpp:
(JSC::JSCell::hasInstance):
* runtime/JSCell.h:
* runtime/JSObject.cpp:
(JSC::JSObject::hasInstance):
* runtime/JSObject.h:


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@99312 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent b01b5c62
......@@ -185,7 +185,7 @@ private:
static bool deleteProperty(JSCell*, ExecState*, const Identifier&);
static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned);
virtual bool hasInstance(ExecState* exec, JSValue value, JSValue proto);
static bool hasInstance(JSObject*, ExecState*, JSValue, JSValue proto);
static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
......
......@@ -355,12 +355,13 @@ EncodedJSValue JSCallbackObject<Parent>::construct(ExecState* exec)
}
template <class Parent>
bool JSCallbackObject<Parent>::hasInstance(ExecState* exec, JSValue value, JSValue)
bool JSCallbackObject<Parent>::hasInstance(JSObject* object, ExecState* exec, JSValue value, JSValue)
{
JSCallbackObject* thisObject = static_cast<JSCallbackObject*>(object);
JSContextRef execRef = toRef(exec);
JSObjectRef thisRef = toRef(this);
JSObjectRef thisRef = toRef(thisObject);
for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass) {
for (JSClassRef jsClass = thisObject->classRef(); jsClass; jsClass = jsClass->parentClass) {
if (JSObjectHasInstanceCallback hasInstance = jsClass->hasInstance) {
JSValueRef valueRef = toRef(exec, value);
JSValueRef exception = 0;
......
......@@ -175,7 +175,7 @@ bool JSValueIsInstanceOfConstructor(JSContextRef ctx, JSValueRef value, JSObject
JSObject* jsConstructor = toJS(constructor);
if (!jsConstructor->structure()->typeInfo().implementsHasInstance())
return false;
bool result = jsConstructor->hasInstance(exec, jsValue, jsConstructor->get(exec, exec->propertyNames().prototype)); // false if an exception is thrown
bool result = jsConstructor->methodTable()->hasInstance(jsConstructor, exec, jsValue, jsConstructor->get(exec, exec->propertyNames().prototype)); // false if an exception is thrown
if (exec->hadException()) {
if (exception)
*exception = toRef(exec, exec->exception());
......
2011-11-04 Mark Hahnenberg <mhahnenberg@apple.com>
De-virtualize JSObject::hasInstance
https://bugs.webkit.org/show_bug.cgi?id=71430
Reviewed by Darin Adler.
Added hasInstance to the MethodTable, changed all the virtual
implementations of hasInstance to static ones, and replaced
all call sites with corresponding lookups in the MethodTable.
* API/JSCallbackObject.h:
* API/JSCallbackObjectFunctions.h:
(JSC::::hasInstance):
* API/JSValueRef.cpp:
(JSValueIsInstanceOfConstructor):
* JavaScriptCore.exp:
* JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
* interpreter/Interpreter.cpp:
(JSC::Interpreter::privateExecute):
* jit/JITStubs.cpp:
(JSC::DEFINE_STUB_FUNCTION):
* runtime/ClassInfo.h:
* runtime/JSBoundFunction.cpp:
(JSC::JSBoundFunction::hasInstance):
* runtime/JSBoundFunction.h:
* runtime/JSCell.cpp:
(JSC::JSCell::hasInstance):
* runtime/JSCell.h:
* runtime/JSObject.cpp:
(JSC::JSObject::hasInstance):
* runtime/JSObject.h:
2011-11-04 Tor Arne Vestbø <tor.arne.vestbo@nokia.com>
[Qt] Refactor and clean up the qmake build system
......@@ -303,7 +303,7 @@ __ZN3JSC8Debugger6attachEPNS_14JSGlobalObjectE
__ZN3JSC8Debugger6detachEPNS_14JSGlobalObjectE
__ZN3JSC8DebuggerD2Ev
__ZN3JSC8JSObject10putByIndexEPNS_6JSCellEPNS_9ExecStateEjNS_7JSValueE
__ZN3JSC8JSObject11hasInstanceEPNS_9ExecStateENS_7JSValueES3_
__ZN3JSC8JSObject11hasInstanceEPS0_PNS_9ExecStateENS_7JSValueES4_
__ZN3JSC8JSObject12defineGetterEPS0_PNS_9ExecStateERKNS_10IdentifierES1_j
__ZN3JSC8JSObject12defaultValueEPKS0_PNS_9ExecStateENS_22PreferredPrimitiveTypeE
__ZN3JSC8JSObject12defineSetterEPS0_PNS_9ExecStateERKNS_10IdentifierES1_j
......
......@@ -211,7 +211,7 @@ EXPORTS
?globalExec@JSGlobalObject@JSC@@QAEPAVExecState@2@XZ
?globalObjectCount@Heap@JSC@@QAEIXZ
?grow@HandleHeap@JSC@@AAEXXZ
?hasInstance@JSObject@JSC@@UAE_NPAVExecState@2@VJSValue@2@1@Z
?hasInstance@JSObject@JSC@@SA_NPAV12@PAVExecState@2@VJSValue@2@2@Z
?hasProperty@JSObject@JSC@@QBE_NPAVExecState@2@ABVIdentifier@2@@Z
?hasProperty@JSObject@JSC@@QBE_NPAVExecState@2@I@Z
?heap@Heap@JSC@@SAPAV12@VJSValue@2@@Z
......
......@@ -2354,7 +2354,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
ASSERT(!isInvalidParamForInstanceOf(callFrame, baseVal, exceptionValue));
bool result = asObject(baseVal)->hasInstance(callFrame, callFrame->r(value).jsValue(), callFrame->r(baseProto).jsValue());
bool result = asObject(baseVal)->methodTable()->hasInstance(asObject(baseVal), callFrame, callFrame->r(value).jsValue(), callFrame->r(baseProto).jsValue());
CHECK_FOR_EXCEPTION();
callFrame->uncheckedR(dst) = jsBoolean(result);
......
......@@ -2092,7 +2092,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_instanceof)
if (!typeInfo.overridesHasInstance() && !value.isObject())
return JSValue::encode(jsBoolean(false));
JSValue result = jsBoolean(asObject(baseVal)->hasInstance(callFrame, value, proto));
JSValue result = jsBoolean(asObject(baseVal)->methodTable()->hasInstance(asObject(baseVal), callFrame, value, proto));
CHECK_FOR_EXCEPTION_AT_END();
return JSValue::encode(result);
......
......@@ -80,6 +80,9 @@ namespace JSC {
typedef UString (*ClassNameFunctionPtr)(const JSObject*);
ClassNameFunctionPtr className;
typedef bool (*HasInstanceFunctionPtr)(JSObject*, ExecState*, JSValue, JSValue);
HasInstanceFunctionPtr hasInstance;
};
#define CREATE_MEMBER_CHECKER(member) \
......@@ -118,6 +121,7 @@ struct MemberCheck##member { \
&ClassName::getOwnPropertyNames, \
&ClassName::getPropertyNames, \
&ClassName::className, \
&ClassName::hasInstance, \
}, \
sizeof(ClassName)
......
......@@ -87,13 +87,14 @@ JSBoundFunction* JSBoundFunction::create(ExecState* exec, JSGlobalObject* global
return function;
}
bool JSBoundFunction::hasInstance(ExecState* exec, JSValue value, JSValue)
bool JSBoundFunction::hasInstance(JSObject* object, ExecState* exec, JSValue value, JSValue)
{
JSBoundFunction* thisObject = static_cast<JSBoundFunction*>(object);
// FIXME: our instanceof implementation will have already (incorrectly) performed
// a [[Get]] of .prototype from the bound function object, which is incorrect!
// https://bugs.webkit.org/show_bug.cgi?id=68656
JSValue proto = m_targetFunction->get(exec, exec->propertyNames().prototype);
return m_targetFunction->hasInstance(exec, value, proto);
JSValue proto = thisObject->m_targetFunction->get(exec, exec->propertyNames().prototype);
return thisObject->m_targetFunction->methodTable()->hasInstance(thisObject->m_targetFunction.get(), exec, value, proto);
}
JSBoundFunction::JSBoundFunction(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, JSObject* targetFunction, JSValue boundThis, JSValue boundArgs)
......
......@@ -39,7 +39,7 @@ public:
static JSBoundFunction* create(ExecState*, JSGlobalObject*, JSObject* targetFunction, JSValue boundThis, JSValue boundArgs, int, const Identifier&);
virtual bool hasInstance(ExecState*, JSValue value, JSValue proto);
static bool hasInstance(JSObject*, ExecState*, JSValue, JSValue proto);
JSObject* targetFunction() { return m_targetFunction.get(); }
JSValue boundThis() { return m_boundThis.get(); }
......
......@@ -190,4 +190,10 @@ void JSCell::getPropertyNames(JSObject*, ExecState*, PropertyNameArray&, Enumera
ASSERT_NOT_REACHED();
}
bool JSCell::hasInstance(JSObject*, ExecState*, JSValue, JSValue)
{
ASSERT_NOT_REACHED();
return false;
}
} // namespace JSC
......@@ -146,6 +146,7 @@ namespace JSC {
static NO_RETURN_DUE_TO_ASSERT void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
static NO_RETURN_DUE_TO_ASSERT void getPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
static UString className(const JSObject*);
static bool hasInstance(JSObject*, ExecState*, JSValue, JSValue prototypeProperty);
private:
WriteBarrier<Structure> m_structure;
......
......@@ -456,7 +456,7 @@ JSValue JSObject::lookupSetter(ExecState* exec, const Identifier& propertyName)
return descriptor.setter();
}
bool JSObject::hasInstance(ExecState* exec, JSValue value, JSValue proto)
bool JSObject::hasInstance(JSObject*, ExecState* exec, JSValue value, JSValue proto)
{
if (!value.isObject())
return false;
......
......@@ -124,7 +124,7 @@ namespace JSC {
static JSValue defaultValue(const JSObject*, ExecState*, PreferredPrimitiveType);
virtual bool hasInstance(ExecState*, JSValue, JSValue prototypeProperty);
static bool hasInstance(JSObject*, ExecState*, JSValue, JSValue prototypeProperty);
static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
static void getPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment