Commit ab7b6096 authored by barraclough@apple.com's avatar barraclough@apple.com

Some cleanup in JSValue::get

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

Reviewed by Geoff Garen.

Source/JavaScriptCore: 

JSValue::get is implemented to:
    1) Check if the value is a cell – if not, synthesize a prototype to search,
    2) call getOwnPropertySlot on the cell,
    3) if this returns false, cast to JSObject to get the prototype, and walk the prototype chain.
By all rights this should crash when passed a string and accessing a property that does not exist, because
the string is a cell, getOwnPropertySlot should return false, and the cast to JSObject should be unsafe.
To work around this, JSString::getOwnPropertySlot actually implements 'get' functionality - searching the
prototype chain, and faking out a return value of undefined if no property is found.

This is a huge hazard, since fixing JSString::getOwnPropertySlot or calling getOwnPropertySlot on cells
from elsewhere would introduce bugs. Fortunately it is only ever called in this one place.

The fix here is to move getOwnPropertySlot onto JSObjecte and end this madness - cells don't have property
slots anyway.

Interesting changes are in JSCJSValueInlines.h, JSString.cpp - the rest is pretty much all JSCell -> JSObject.

Source/WebCore: 

* WebCore.exp.in:
* bindings/js/JSDOMWindowCustom.cpp:
(WebCore::JSDOMWindow::getOwnPropertySlot):
(WebCore::JSDOMWindow::getOwnPropertySlotByIndex):
* bindings/scripts/CodeGeneratorJS.pm:
(GenerateHeader):
(GenerateImplementation):
(GenerateConstructorDeclaration):
(GenerateConstructorHelperMethods):
* bridge/objc/objc_runtime.h:
* bridge/objc/objc_runtime.mm:
(JSC::Bindings::ObjcFallbackObjectImp::getOwnPropertySlot):
* bridge/runtime_array.cpp:
(JSC::RuntimeArray::getOwnPropertySlot):
(JSC::RuntimeArray::getOwnPropertySlotByIndex):
* bridge/runtime_array.h:
* bridge/runtime_method.cpp:
(JSC::RuntimeMethod::getOwnPropertySlot):
* bridge/runtime_method.h:
* bridge/runtime_object.cpp:
(JSC::Bindings::RuntimeObject::getOwnPropertySlot):
* bridge/runtime_object.h:
    - getOwnPropertySlot, JSCell -> JSObject

Source/WebKit2: 

* WebProcess/Plugins/Netscape/JSNPObject.cpp:
(WebKit::JSNPObject::getOwnPropertySlot):
* WebProcess/Plugins/Netscape/JSNPObject.h:
    - getOwnPropertySlot, JSCell -> JSObject



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153532 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 7a43ae44
......@@ -176,8 +176,8 @@ private:
static JSValue defaultValue(const JSObject*, ExecState*, PreferredPrimitiveType);
static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&);
static bool getOwnPropertySlotByIndex(JSCell*, ExecState*, unsigned propertyName, PropertySlot&);
static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
static bool getOwnPropertySlotByIndex(JSObject*, ExecState*, unsigned propertyName, PropertySlot&);
static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&);
static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
......
......@@ -122,9 +122,9 @@ String JSCallbackObject<Parent>::className(const JSObject* object)
}
template <class Parent>
bool JSCallbackObject<Parent>::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
bool JSCallbackObject<Parent>::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
{
JSCallbackObject* thisObject = jsCast<JSCallbackObject*>(cell);
JSCallbackObject* thisObject = jsCast<JSCallbackObject*>(object);
JSContextRef ctx = toRef(exec);
JSObjectRef thisRef = toRef(thisObject);
RefPtr<OpaqueJSString> propertyNameRef;
......@@ -183,9 +183,9 @@ bool JSCallbackObject<Parent>::getOwnPropertySlot(JSCell* cell, ExecState* exec,
}
template <class Parent>
bool JSCallbackObject<Parent>::getOwnPropertySlotByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, PropertySlot& slot)
bool JSCallbackObject<Parent>::getOwnPropertySlotByIndex(JSObject* object, ExecState* exec, unsigned propertyName, PropertySlot& slot)
{
return cell->methodTable()->getOwnPropertySlot(cell, exec, Identifier::from(exec, propertyName), slot);
return object->methodTable()->getOwnPropertySlot(object, exec, Identifier::from(exec, propertyName), slot);
}
template <class Parent>
......
2013-07-30 Gavin Barraclough <barraclough@apple.com>
Some cleanup in JSValue::get
https://bugs.webkit.org/show_bug.cgi?id=119343
Reviewed by Geoff Garen.
JSValue::get is implemented to:
1) Check if the value is a cell – if not, synthesize a prototype to search,
2) call getOwnPropertySlot on the cell,
3) if this returns false, cast to JSObject to get the prototype, and walk the prototype chain.
By all rights this should crash when passed a string and accessing a property that does not exist, because
the string is a cell, getOwnPropertySlot should return false, and the cast to JSObject should be unsafe.
To work around this, JSString::getOwnPropertySlot actually implements 'get' functionality - searching the
prototype chain, and faking out a return value of undefined if no property is found.
This is a huge hazard, since fixing JSString::getOwnPropertySlot or calling getOwnPropertySlot on cells
from elsewhere would introduce bugs. Fortunately it is only ever called in this one place.
The fix here is to move getOwnPropertySlot onto JSObjecte and end this madness - cells don't have property
slots anyway.
Interesting changes are in JSCJSValueInlines.h, JSString.cpp - the rest is pretty much all JSCell -> JSObject.
2013-07-31 Michael Saboff <msaboff@apple.com>
[Win] JavaScript crash.
......
......@@ -53,9 +53,9 @@ public: \
return ptr; \
}\
\
static bool getOwnPropertySlot(JSC::JSCell*, JSC::ExecState*, JSC::PropertyName propertyName, JSC::PropertySlot&);\
static bool getOwnPropertySlot(JSC::JSObject*, JSC::ExecState*, JSC::PropertyName propertyName, JSC::PropertySlot&);\
static bool getOwnPropertyDescriptor(JSC::JSObject*, JSC::ExecState*, JSC::PropertyName propertyName, JSC::PropertyDescriptor&);\
static bool getOwnPropertySlotByIndex(JSC::JSCell*, JSC::ExecState*, unsigned propertyName, JSC::PropertySlot&);\
static bool getOwnPropertySlotByIndex(JSC::JSObject*, JSC::ExecState*, unsigned propertyName, JSC::PropertySlot&);\
static void put(JSC::JSCell*, JSC::ExecState*, JSC::PropertyName propertyName, JSC::JSValue, JSC::PutPropertySlot&);\
static void putByIndex(JSC::JSCell*, JSC::ExecState*, unsigned propertyName, JSC::JSValue, bool);\
static const JSC::ClassInfo s_info;\
......@@ -99,9 +99,9 @@ void JS##name##Array::finishCreation(VM& vm)\
ASSERT(inherits(&s_info));\
}\
\
bool JS##name##Array::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot& slot)\
bool JS##name##Array::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)\
{\
JS##name##Array* thisObject = jsCast<JS##name##Array*>(cell);\
JS##name##Array* thisObject = jsCast<JS##name##Array*>(object);\
ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info);\
unsigned index = propertyName.asIndex();\
if (index < thisObject->m_storageLength) {\
......@@ -109,7 +109,7 @@ bool JS##name##Array::getOwnPropertySlot(JSCell* cell, ExecState* exec, Property
slot.setValue(thisObject->getByIndex(exec, index));\
return true;\
}\
return Base::getOwnPropertySlot(cell, exec, propertyName, slot);\
return Base::getOwnPropertySlot(object, exec, propertyName, slot);\
}\
\
bool JS##name##Array::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor)\
......@@ -125,9 +125,9 @@ bool JS##name##Array::getOwnPropertyDescriptor(JSObject* object, ExecState* exec
return Base::getOwnPropertyDescriptor(object, exec, propertyName, descriptor);\
}\
\
bool JS##name##Array::getOwnPropertySlotByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, PropertySlot& slot)\
bool JS##name##Array::getOwnPropertySlotByIndex(JSObject* object, ExecState* exec, unsigned propertyName, PropertySlot& slot)\
{\
JS##name##Array* thisObject = jsCast<JS##name##Array*>(cell);\
JS##name##Array* thisObject = jsCast<JS##name##Array*>(object);\
ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info);\
if (propertyName < thisObject->m_storageLength) {\
slot.setValue(thisObject->getByIndex(exec, propertyName));\
......
......@@ -65,9 +65,9 @@ String DebuggerActivation::className(const JSObject* object)
return thisObject->m_activation->methodTable()->className(thisObject->m_activation.get());
}
bool DebuggerActivation::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
bool DebuggerActivation::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
{
DebuggerActivation* thisObject = jsCast<DebuggerActivation*>(cell);
DebuggerActivation* thisObject = jsCast<DebuggerActivation*>(object);
return thisObject->m_activation->methodTable()->getOwnPropertySlot(thisObject->m_activation.get(), exec, propertyName, slot);
}
......
......@@ -43,7 +43,7 @@ namespace JSC {
static void visitChildren(JSCell*, SlotVisitor&);
static String className(const JSObject*);
static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&);
static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
static void putDirectVirtual(JSObject*, ExecState*, PropertyName, JSValue, unsigned attributes);
static bool deleteProperty(JSCell*, ExecState*, PropertyName);
......
......@@ -90,9 +90,9 @@ void Arguments::fillArgList(ExecState* exec, MarkedArgumentBuffer& args)
}
}
bool Arguments::getOwnPropertySlotByIndex(JSCell* cell, ExecState* exec, unsigned i, PropertySlot& slot)
bool Arguments::getOwnPropertySlotByIndex(JSObject* object, ExecState* exec, unsigned i, PropertySlot& slot)
{
Arguments* thisObject = jsCast<Arguments*>(cell);
Arguments* thisObject = jsCast<Arguments*>(object);
if (JSValue value = thisObject->tryGetArgument(i)) {
slot.setValue(value);
return true;
......@@ -123,9 +123,9 @@ void Arguments::createStrictModeCalleeIfNecessary(ExecState* exec)
methodTable()->defineOwnProperty(this, exec, exec->propertyNames().callee, descriptor, false);
}
bool Arguments::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
bool Arguments::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
{
Arguments* thisObject = jsCast<Arguments*>(cell);
Arguments* thisObject = jsCast<Arguments*>(object);
unsigned i = propertyName.asIndex();
if (JSValue value = thisObject->tryGetArgument(i)) {
RELEASE_ASSERT(i < PropertyName::NotAnIndex);
......
......@@ -97,8 +97,8 @@ protected:
private:
static void destroy(JSCell*);
static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&);
static bool getOwnPropertySlotByIndex(JSCell*, ExecState*, unsigned propertyName, PropertySlot&);
static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
static bool getOwnPropertySlotByIndex(JSObject*, ExecState*, unsigned propertyName, PropertySlot&);
static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&);
static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
......
......@@ -66,9 +66,9 @@ void ArrayConstructor::finishCreation(ExecState* exec, ArrayPrototype* arrayProt
putDirectWithoutTransition(exec->vm(), exec->propertyNames().length, jsNumber(1), ReadOnly | DontEnum | DontDelete);
}
bool ArrayConstructor::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot &slot)
bool ArrayConstructor::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot &slot)
{
return getStaticFunctionSlot<InternalFunction>(exec, ExecState::arrayConstructorTable(exec), jsCast<ArrayConstructor*>(cell), propertyName, slot);
return getStaticFunctionSlot<InternalFunction>(exec, ExecState::arrayConstructorTable(exec), jsCast<ArrayConstructor*>(object), propertyName, slot);
}
bool ArrayConstructor::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor)
......
......@@ -53,7 +53,7 @@ protected:
private:
ArrayConstructor(JSGlobalObject*, Structure*);
static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&);
static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&);
......
......@@ -136,9 +136,9 @@ void ArrayPrototype::finishCreation(JSGlobalObject* globalObject)
vm.prototypeMap.addPrototype(this);
}
bool ArrayPrototype::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
bool ArrayPrototype::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
{
return getStaticFunctionSlot<JSArray>(exec, ExecState::arrayPrototypeTable(exec), jsCast<ArrayPrototype*>(cell), propertyName, slot);
return getStaticFunctionSlot<JSArray>(exec, ExecState::arrayPrototypeTable(exec), jsCast<ArrayPrototype*>(object), propertyName, slot);
}
bool ArrayPrototype::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor)
......
......@@ -35,7 +35,7 @@ public:
static ArrayPrototype* create(ExecState*, JSGlobalObject*, Structure*);
static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&);
static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&);
static const ClassInfo s_info;
......
......@@ -63,9 +63,9 @@ void BooleanPrototype::finishCreation(ExecState* exec, JSGlobalObject*)
ASSERT(inherits(&s_info));
}
bool BooleanPrototype::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot &slot)
bool BooleanPrototype::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot &slot)
{
return getStaticFunctionSlot<BooleanObject>(exec, ExecState::booleanPrototypeTable(exec), jsCast<BooleanPrototype*>(cell), propertyName, slot);
return getStaticFunctionSlot<BooleanObject>(exec, ExecState::booleanPrototypeTable(exec), jsCast<BooleanPrototype*>(object), propertyName, slot);
}
bool BooleanPrototype::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor)
......
......@@ -49,7 +49,7 @@ protected:
private:
BooleanPrototype(ExecState*, Structure*);
static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&);
static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&);
};
......
......@@ -60,10 +60,10 @@ struct MethodTable {
typedef bool (*DeletePropertyByIndexFunctionPtr)(JSCell*, ExecState*, unsigned);
DeletePropertyByIndexFunctionPtr deletePropertyByIndex;
typedef bool (*GetOwnPropertySlotFunctionPtr)(JSCell*, ExecState*, PropertyName, PropertySlot&);
typedef bool (*GetOwnPropertySlotFunctionPtr)(JSObject*, ExecState*, PropertyName, PropertySlot&);
GetOwnPropertySlotFunctionPtr getOwnPropertySlot;
typedef bool (*GetOwnPropertySlotByIndexFunctionPtr)(JSCell*, ExecState*, unsigned, PropertySlot&);
typedef bool (*GetOwnPropertySlotByIndexFunctionPtr)(JSObject*, ExecState*, unsigned, PropertySlot&);
GetOwnPropertySlotByIndexFunctionPtr getOwnPropertySlotByIndex;
typedef JSValue (*ToThisFunctionPtr)(JSCell*, ExecState*, ECMAMode);
......
......@@ -86,9 +86,9 @@ void DateConstructor::finishCreation(ExecState* exec, DatePrototype* datePrototy
putDirectWithoutTransition(exec->vm(), exec->propertyNames().length, jsNumber(7), ReadOnly | DontEnum | DontDelete);
}
bool DateConstructor::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot &slot)
bool DateConstructor::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot &slot)
{
return getStaticFunctionSlot<InternalFunction>(exec, ExecState::dateConstructorTable(exec), jsCast<DateConstructor*>(cell), propertyName, slot);
return getStaticFunctionSlot<InternalFunction>(exec, ExecState::dateConstructorTable(exec), jsCast<DateConstructor*>(object), propertyName, slot);
}
bool DateConstructor::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor)
......
......@@ -54,7 +54,7 @@ namespace JSC {
static ConstructType getConstructData(JSCell*, ConstructData&);
static CallType getCallData(JSCell*, CallData&);
static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&);
static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&);
};
......
......@@ -514,9 +514,9 @@ void DatePrototype::finishCreation(ExecState* exec, JSGlobalObject*)
// The constructor will be added later, after DateConstructor has been built.
}
bool DatePrototype::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
bool DatePrototype::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
{
return getStaticFunctionSlot<JSObject>(exec, ExecState::dateTable(exec), jsCast<DatePrototype*>(cell), propertyName, slot);
return getStaticFunctionSlot<JSObject>(exec, ExecState::dateTable(exec), jsCast<DatePrototype*>(object), propertyName, slot);
}
bool DatePrototype::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor)
......
......@@ -40,7 +40,7 @@ namespace JSC {
prototype->finishCreation(exec, globalObject);
return prototype;
}
static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&);
static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&);
......
......@@ -61,9 +61,9 @@ void ErrorPrototype::finishCreation(ExecState* exec, JSGlobalObject*)
putDirect(exec->vm(), exec->propertyNames().name, jsNontrivialString(exec, String(ASCIILiteral("Error"))), DontEnum);
}
bool ErrorPrototype::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot &slot)
bool ErrorPrototype::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot &slot)
{
return getStaticFunctionSlot<ErrorInstance>(exec, ExecState::errorPrototypeTable(exec), jsCast<ErrorPrototype*>(cell), propertyName, slot);
return getStaticFunctionSlot<ErrorInstance>(exec, ExecState::errorPrototypeTable(exec), jsCast<ErrorPrototype*>(object), propertyName, slot);
}
bool ErrorPrototype::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor)
......
......@@ -52,7 +52,7 @@ namespace JSC {
static const unsigned StructureFlags = OverridesGetOwnPropertySlot | ErrorInstance::StructureFlags;
private:
static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&);
static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&);
};
......
......@@ -150,9 +150,9 @@ inline bool JSActivation::symbolTablePutWithAttributes(VM& vm, PropertyName prop
return true;
}
bool JSActivation::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
bool JSActivation::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
{
JSActivation* thisObject = jsCast<JSActivation*>(cell);
JSActivation* thisObject = jsCast<JSActivation*>(object);
if (propertyName == exec->propertyNames().arguments) {
// Defend against the inspector asking for the arguments object after it has been optimized out.
......
......@@ -62,7 +62,7 @@ namespace JSC {
static void visitChildren(JSCell*, SlotVisitor&);
static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&);
static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
JS_EXPORT_PRIVATE static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&);
......
......@@ -177,9 +177,9 @@ bool JSArray::defineOwnProperty(JSObject* object, ExecState* exec, PropertyName
return array->JSObject::defineOwnNonIndexProperty(exec, propertyName, descriptor, throwException);
}
bool JSArray::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
bool JSArray::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
{
JSArray* thisObject = jsCast<JSArray*>(cell);
JSArray* thisObject = jsCast<JSArray*>(object);
if (propertyName == exec->propertyNames().length) {
slot.setValue(jsNumber(thisObject->length()));
return true;
......
......@@ -55,7 +55,7 @@ public:
JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, PropertyDescriptor&, bool throwException);
static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&);
static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&);
static JS_EXPORTDATA const ClassInfo s_info;
......
......@@ -627,21 +627,19 @@ inline JSValue JSValue::get(ExecState* exec, PropertyName propertyName) const
inline JSValue JSValue::get(ExecState* exec, PropertyName propertyName, PropertySlot& slot) const
{
if (UNLIKELY(!isCell())) {
JSObject* prototype = synthesizePrototype(exec);
if (!prototype->getPropertySlot(exec, propertyName, slot))
return jsUndefined();
return slot.getValue(exec, propertyName);
}
JSCell* cell = asCell();
while (true) {
if (cell->fastGetOwnPropertySlot(exec, propertyName, slot))
// If this is a primitive, we'll need to synthesize the prototype -
// and if it's a string there are special properties to check first.
JSObject* object;
if (UNLIKELY(!isObject())) {
if (isCell() && asString(*this)->getStringPropertySlot(exec, propertyName, slot))
return slot.getValue(exec, propertyName);
JSValue prototype = asObject(cell)->prototype();
if (!prototype.isObject())
return jsUndefined();
cell = asObject(prototype);
}
object = synthesizePrototype(exec);
} else
object = asObject(asCell());
if (object->getPropertySlot(exec, propertyName, slot))
return slot.getValue(exec, propertyName);
return jsUndefined();
}
inline JSValue JSValue::get(ExecState* exec, unsigned propertyName) const
......@@ -652,21 +650,19 @@ inline JSValue JSValue::get(ExecState* exec, unsigned propertyName) const
inline JSValue JSValue::get(ExecState* exec, unsigned propertyName, PropertySlot& slot) const
{
if (UNLIKELY(!isCell())) {
JSObject* prototype = synthesizePrototype(exec);
if (!prototype->getPropertySlot(exec, propertyName, slot))
return jsUndefined();
return slot.getValue(exec, propertyName);
}
JSCell* cell = const_cast<JSCell*>(asCell());
while (true) {
if (cell->methodTable()->getOwnPropertySlotByIndex(cell, exec, propertyName, slot))
// If this is a primitive, we'll need to synthesize the prototype -
// and if it's a string there are special properties to check first.
JSObject* object;
if (UNLIKELY(!isObject())) {
if (isCell() && asString(*this)->getStringPropertySlot(exec, propertyName, slot))
return slot.getValue(exec, propertyName);
JSValue prototype = asObject(cell)->prototype();
if (!prototype.isObject())
return jsUndefined();
cell = prototype.asCell();
}
object = synthesizePrototype(exec);
} else
object = asObject(asCell());
if (object->getPropertySlot(exec, propertyName, slot))
return slot.getValue(exec, propertyName);
return jsUndefined();
}
inline void JSValue::put(ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
......
......@@ -82,30 +82,6 @@ ConstructType JSCell::getConstructData(JSCell*, ConstructData& constructData)
return ConstructTypeNone;
}
bool JSCell::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName identifier, PropertySlot& slot)
{
// This is not a general purpose implementation of getOwnPropertySlot.
// It should only be called by JSValue::get.
// It calls getPropertySlot, not getOwnPropertySlot.
JSObject* object = cell->toObject(exec, exec->lexicalGlobalObject());
slot.setBase(object);
if (!object->getPropertySlot(exec, identifier, slot))
slot.setUndefined();
return true;
}
bool JSCell::getOwnPropertySlotByIndex(JSCell* cell, ExecState* exec, unsigned identifier, PropertySlot& slot)
{
// This is not a general purpose implementation of getOwnPropertySlot.
// It should only be called by JSValue::get.
// It calls getPropertySlot, not getOwnPropertySlot.
JSObject* object = cell->toObject(exec, exec->lexicalGlobalObject());
slot.setBase(object);
if (!object->getPropertySlot(exec, identifier, slot))
slot.setUndefined();
return true;
}
void JSCell::put(JSCell* cell, ExecState* exec, PropertyName identifier, JSValue value, PutPropertySlot& slot)
{
if (cell->isString()) {
......@@ -186,6 +162,18 @@ JSValue JSCell::defaultValue(const JSObject*, ExecState*, PreferredPrimitiveType
return jsUndefined();
}
bool JSCell::getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&)
{
RELEASE_ASSERT_NOT_REACHED();
return false;
}
bool JSCell::getOwnPropertySlotByIndex(JSObject*, ExecState*, unsigned, PropertySlot&)
{
RELEASE_ASSERT_NOT_REACHED();
return false;
}
void JSCell::getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode)
{
RELEASE_ASSERT_NOT_REACHED();
......
......@@ -118,11 +118,6 @@ public:
void zap() { *reinterpret_cast<uintptr_t**>(this) = 0; }
bool isZapped() const { return !*reinterpret_cast<uintptr_t* const*>(this); }
// FIXME: Rename getOwnPropertySlot to virtualGetOwnPropertySlot, and
// fastGetOwnPropertySlot to getOwnPropertySlot. Callers should always
// call this function, not its slower virtual counterpart. (For integer
// property names, we want a similar interface with appropriate optimizations.)
bool fastGetOwnPropertySlot(ExecState*, PropertyName, PropertySlot&);
JSValue fastGetOwnProperty(ExecState*, const String&);
static ptrdiff_t structureOffset()
......@@ -145,10 +140,6 @@ protected:
void finishCreation(VM&);
void finishCreation(VM&, Structure*, CreatingEarlyCellTag);
// Base implementation; for non-object classes implements getPropertySlot.
static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&);
static bool getOwnPropertySlotByIndex(JSCell*, ExecState*, unsigned propertyName, PropertySlot&);
// Dummy implementations of override-able static functions for classes to put in their MethodTable
static JSValue defaultValue(const JSObject*, ExecState*, PreferredPrimitiveType);
static NO_RETURN_DUE_TO_CRASH void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
......@@ -159,6 +150,8 @@ protected:
static NO_RETURN_DUE_TO_CRASH void putDirectVirtual(JSObject*, ExecState*, PropertyName, JSValue, unsigned attributes);
static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, PropertyDescriptor&, bool shouldThrow);
static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&);
static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
static bool getOwnPropertySlotByIndex(JSObject*, ExecState*, unsigned propertyName, PropertySlot&);
private:
friend class LLIntOffsetsExtractor;
......
......@@ -165,13 +165,6 @@ inline bool JSCell::inherits(const ClassInfo* info) const
return classInfo()->isSubClassOf(info);
}
ALWAYS_INLINE bool JSCell::fastGetOwnPropertySlot(ExecState* exec, PropertyName propertyName, PropertySlot& slot)
{
if (!structure()->typeInfo().overridesGetOwnPropertySlot())
return asObject(this)->inlineGetOwnPropertySlot(exec, propertyName, slot);
return methodTable()->getOwnPropertySlot(this, exec, propertyName, slot);
}
// Fast call to get a property where we may not yet have converted the string to an
// identifier. The first time we perform a property access with a given string, try
// performing the property map lookup without forming an identifier. We detect this
......
......@@ -240,9 +240,9 @@ JSValue JSFunction::nameGetter(ExecState*, JSValue slotBase, PropertyName)
return thisObj->jsExecutable()->nameValue();
}
bool JSFunction::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
bool JSFunction::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
{
JSFunction* thisObject = jsCast<JSFunction*>(cell);
JSFunction* thisObject = jsCast<JSFunction*>(object);
if (thisObject->isHostFunction())
return Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
......
......@@ -170,7 +170,7 @@ namespace JSC {
ObjectAllocationProfile* createAllocationProfile(ExecState*, size_t inlineCapacity);
static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&);
static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&);
static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode = ExcludeDontEnumProperties);
static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, PropertyDescriptor&, bool shouldThrow);
......
......@@ -569,9 +569,9 @@ void JSGlobalObject::addStaticGlobals(GlobalPropertyInfo* globals, int count)
}
}
bool JSGlobalObject::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
bool JSGlobalObject::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
{
JSGlobalObject* thisObject = jsCast<JSGlobalObject*>(cell);
JSGlobalObject* thisObject = jsCast<JSGlobalObject*>(object);
if (getStaticFunctionSlot<Base>(exec, ExecState::globalObjectTable(exec), thisObject, propertyName, slot))
return true;
return symbolTableGet(thisObject, propertyName, slot);
......