Commit 68dbe316 authored by darin@apple.com's avatar darin@apple.com

2008-06-12 Darin Adler <darin@apple.com>

        Reviewed by Maciej.

        - https://bugs.webkit.org/show_bug.cgi?id=19434
          speed up SunSpider by avoiding some string boxing

        Speeds up SunSpider by 1.1%.

        Optimized code path for getting built-in properties from strings -- avoid
        boxing with a string object in that case. We can make further changes to avoid
        even more boxing, but this change alone is a win.

        * API/JSCallbackObjectFunctions.h:
        (KJS::JSCallbackObject::staticValueGetter): Use isObject instead of inherits
        in asssert, since the type of slotBase() is now JSValue, not JSObject.
        (KJS::JSCallbackObject::staticFunctionGetter): Ditto.
        (KJS::JSCallbackObject::callbackGetter): Ditto.

        * kjs/internal.cpp:
        (KJS::StringImp::getPrimitiveNumber): Updated for change of data member name.
        (KJS::StringImp::toBoolean): Ditto.
        (KJS::StringImp::toNumber): Ditto.
        (KJS::StringImp::toString): Ditto.
        (KJS::StringInstance::create): Added; avoids a bit of cut and paste code.
        (KJS::StringImp::toObject): Use StringInstance::create.
        (KJS::StringImp::toThisObject): Ditto.
        (KJS::StringImp::lengthGetter): Added. Replaces the getter that used to live in
        the StringInstance class.
        (KJS::StringImp::indexGetter): Ditto.
        (KJS::StringImp::indexNumericPropertyGetter): Ditto.
        (KJS::StringImp::getOwnPropertySlot): Added. Deals with built in properties of
        the string class without creating a StringInstance.

        * kjs/internal.h:
        (KJS::StringImp::getStringPropertySlot): Added. To be used by both the string
        and string object getOwnPropertySlot function.

        * kjs/lookup.h:
        (KJS::staticFunctionGetter): Updated since slotBase() is now a JSValue rather
        than a JSObject.

        * kjs/object.h: Removed PropertySlot::slotBase() function, which can now move
        back into property_slot.h where it belongs since it doesn't have to cast to
        JSObject*.

        * kjs/property_slot.cpp:
        (KJS::PropertySlot::functionGetter): Updated since slot.slotBase() is now a JSValue*
        instead of JSObject*. setGetterSlot still guarantees the base is a JSObject*.
        * kjs/property_slot.h:
        (KJS::PropertySlot::PropertySlot): Changed base to JSValue* intead of JSCell*.
        (KJS::PropertySlot::setStaticEntry): Ditto.
        (KJS::PropertySlot::setCustom): Ditto.
        (KJS::PropertySlot::setCustomIndex): Ditto.
        (KJS::PropertySlot::setCustomNumeric): Ditto.
        (KJS::PropertySlot::slotBase): Moved inline here since it no longer involves a
        downcast to JSObject*.
        (KJS::PropertySlot::setBase): Changed to JSValue*.

        * kjs/string_object.cpp:
        (KJS::StringInstance::getOwnPropertySlot): Changed to use getStringPropertySlot
        instead of coding the properties here. This allows sharing the code with StringImp.

        * kjs/string_object.h: Removed inlineGetOwnPropertySlot, lengthGetter, and indexGetter.
        Made one of the constructors protected.

        * kjs/value.h: Made getOwnPropertySlot private in the JSCell class -- this is better
        since it's not the real JSObject getOwnPropertySlot semantic and most callers shouldn't
        use it.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@34518 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 6276a603
......@@ -437,7 +437,7 @@ JSValue* JSCallbackObject<Base>::cachedValueGetter(ExecState*, const Identifier&
template <class Base>
JSValue* JSCallbackObject<Base>::staticValueGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
{
ASSERT(slot.slotBase()->inherits(&JSCallbackObject::info));
ASSERT(slot.slotBase()->isObject(&JSCallbackObject::info));
JSCallbackObject* thisObj = static_cast<JSCallbackObject*>(slot.slotBase());
JSObjectRef thisRef = toRef(thisObj);
......@@ -458,7 +458,7 @@ JSValue* JSCallbackObject<Base>::staticValueGetter(ExecState* exec, const Identi
template <class Base>
JSValue* JSCallbackObject<Base>::staticFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
{
ASSERT(slot.slotBase()->inherits(&JSCallbackObject::info));
ASSERT(slot.slotBase()->isObject(&JSCallbackObject::info));
JSCallbackObject* thisObj = static_cast<JSCallbackObject*>(slot.slotBase());
// Check for cached or override property.
......@@ -484,7 +484,7 @@ JSValue* JSCallbackObject<Base>::staticFunctionGetter(ExecState* exec, const Ide
template <class Base>
JSValue* JSCallbackObject<Base>::callbackGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
{
ASSERT(slot.slotBase()->inherits(&JSCallbackObject::info));
ASSERT(slot.slotBase()->isObject(&JSCallbackObject::info));
JSCallbackObject* thisObj = static_cast<JSCallbackObject*>(slot.slotBase());
JSObjectRef thisRef = toRef(thisObj);
......
2008-06-12 Darin Adler <darin@apple.com>
Reviewed by Maciej.
- https://bugs.webkit.org/show_bug.cgi?id=19434
speed up SunSpider by avoiding some string boxing
Speeds up SunSpider by 1.1%.
Optimized code path for getting built-in properties from strings -- avoid
boxing with a string object in that case. We can make further changes to avoid
even more boxing, but this change alone is a win.
* API/JSCallbackObjectFunctions.h:
(KJS::JSCallbackObject::staticValueGetter): Use isObject instead of inherits
in asssert, since the type of slotBase() is now JSValue, not JSObject.
(KJS::JSCallbackObject::staticFunctionGetter): Ditto.
(KJS::JSCallbackObject::callbackGetter): Ditto.
* kjs/internal.cpp:
(KJS::StringImp::getPrimitiveNumber): Updated for change of data member name.
(KJS::StringImp::toBoolean): Ditto.
(KJS::StringImp::toNumber): Ditto.
(KJS::StringImp::toString): Ditto.
(KJS::StringInstance::create): Added; avoids a bit of cut and paste code.
(KJS::StringImp::toObject): Use StringInstance::create.
(KJS::StringImp::toThisObject): Ditto.
(KJS::StringImp::lengthGetter): Added. Replaces the getter that used to live in
the StringInstance class.
(KJS::StringImp::indexGetter): Ditto.
(KJS::StringImp::indexNumericPropertyGetter): Ditto.
(KJS::StringImp::getOwnPropertySlot): Added. Deals with built in properties of
the string class without creating a StringInstance.
* kjs/internal.h:
(KJS::StringImp::getStringPropertySlot): Added. To be used by both the string
and string object getOwnPropertySlot function.
* kjs/lookup.h:
(KJS::staticFunctionGetter): Updated since slotBase() is now a JSValue rather
than a JSObject.
* kjs/object.h: Removed PropertySlot::slotBase() function, which can now move
back into property_slot.h where it belongs since it doesn't have to cast to
JSObject*.
* kjs/property_slot.cpp:
(KJS::PropertySlot::functionGetter): Updated since slot.slotBase() is now a JSValue*
instead of JSObject*. setGetterSlot still guarantees the base is a JSObject*.
* kjs/property_slot.h:
(KJS::PropertySlot::PropertySlot): Changed base to JSValue* intead of JSCell*.
(KJS::PropertySlot::setStaticEntry): Ditto.
(KJS::PropertySlot::setCustom): Ditto.
(KJS::PropertySlot::setCustomIndex): Ditto.
(KJS::PropertySlot::setCustomNumeric): Ditto.
(KJS::PropertySlot::slotBase): Moved inline here since it no longer involves a
downcast to JSObject*.
(KJS::PropertySlot::setBase): Changed to JSValue*.
* kjs/string_object.cpp:
(KJS::StringInstance::getOwnPropertySlot): Changed to use getStringPropertySlot
instead of coding the properties here. This allows sharing the code with StringImp.
* kjs/string_object.h: Removed inlineGetOwnPropertySlot, lengthGetter, and indexGetter.
Made one of the constructors protected.
* kjs/value.h: Made getOwnPropertySlot private in the JSCell class -- this is better
since it's not the real JSObject getOwnPropertySlot semantic and most callers shouldn't
use it.
2008-06-12 Alexey Proskuryakov <ap@webkit.org>
Reviewed by Maciej.
......
......@@ -59,33 +59,84 @@ JSValue* StringImp::toPrimitive(ExecState*, JSType) const
bool StringImp::getPrimitiveNumber(ExecState*, double& number, JSValue*& value)
{
value = this;
number = val.toDouble();
number = m_value.toDouble();
return false;
}
bool StringImp::toBoolean(ExecState *) const
bool StringImp::toBoolean(ExecState*) const
{
return (val.size() > 0);
return !m_value.isEmpty();
}
double StringImp::toNumber(ExecState *) const
double StringImp::toNumber(ExecState*) const
{
return val.toDouble();
return m_value.toDouble();
}
UString StringImp::toString(ExecState *) const
UString StringImp::toString(ExecState*) const
{
return val;
return m_value;
}
JSObject* StringImp::toObject(ExecState *exec) const
inline StringInstance* StringInstance::create(ExecState* exec, StringImp* string)
{
return new StringInstance(exec->lexicalGlobalObject()->stringPrototype(), const_cast<StringImp*>(this));
return new StringInstance(exec->lexicalGlobalObject()->stringPrototype(), string);
}
JSObject* StringImp::toObject(ExecState* exec) const
{
return StringInstance::create(exec, const_cast<StringImp*>(this));
}
JSObject* StringImp::toThisObject(ExecState* exec) const
{
return new StringInstance(exec->lexicalGlobalObject()->stringPrototype(), const_cast<StringImp*>(this));
return StringInstance::create(exec, const_cast<StringImp*>(this));
}
JSValue* StringImp::lengthGetter(ExecState*, const Identifier&, const PropertySlot& slot)
{
return jsNumber(static_cast<StringImp*>(slot.slotBase())->value().size());
}
JSValue* StringImp::indexGetter(ExecState*, const Identifier&, const PropertySlot& slot)
{
return jsString(static_cast<StringImp*>(slot.slotBase())->value().substr(slot.index(), 1));
}
JSValue* StringImp::indexNumericPropertyGetter(ExecState*, unsigned index, const PropertySlot& slot)
{
return jsString(static_cast<StringImp*>(slot.slotBase())->value().substr(index, 1));
}
bool StringImp::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
// The semantics here are really getPropertySlot, not getOwnPropertySlot.
// This function should only be called by JSValue::get.
if (getStringPropertySlot(exec, propertyName, slot))
return true;
JSObject* object = StringInstance::create(exec, this);
slot.setBase(object);
if (object->JSObject::getOwnPropertySlot(exec, propertyName, slot))
return true;
while (true) {
JSValue* proto = object->prototype();
if (!proto->isObject()) {
slot.setUndefined();
return true;
}
object = static_cast<JSObject*>(proto);
if (object->getOwnPropertySlot(exec, propertyName, slot))
return true;
}
}
bool StringImp::getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
{
// The semantics here are really getPropertySlot, not getOwnPropertySlot.
// This function should only be called by JSValue::get.
if (getStringPropertySlot(propertyName, slot))
return true;
return StringImp::getOwnPropertySlot(exec, Identifier::from(propertyName), slot);
}
// ------------------------------ NumberImp ------------------------------------
......
......@@ -2,7 +2,7 @@
/*
* Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
* Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
......@@ -24,49 +24,70 @@
#ifndef INTERNAL_H
#define INTERNAL_H
#include "JSType.h"
#include "object.h"
#include "protect.h"
#include "scope_chain.h"
#include "types.h"
#include "ustring.h"
#include <wtf/Noncopyable.h>
#define I18N_NOOP(s) s
namespace KJS {
class FunctionPrototype;
// ---------------------------------------------------------------------------
// Primitive impls
// ---------------------------------------------------------------------------
class StringImp : public JSCell {
public:
StringImp(const UString& v) : val(v) { Collector::reportExtraMemoryCost(v.cost()); }
StringImp(const UString& value) : m_value(value) { Collector::reportExtraMemoryCost(value.cost()); }
enum HasOtherOwnerType { HasOtherOwner };
StringImp(const UString& value, HasOtherOwnerType) : val(value) { }
const UString& value() const { return val; }
StringImp(const UString& value, HasOtherOwnerType) : m_value(value) { }
const UString& value() const { return m_value; }
bool getStringPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
bool getStringPropertySlot(unsigned propertyName, PropertySlot&);
private:
virtual JSType type() const { return StringType; }
virtual JSValue* toPrimitive(ExecState*, JSType preferred = UnspecifiedType) const;
virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*& value);
virtual bool toBoolean(ExecState *exec) const;
virtual double toNumber(ExecState *exec) const;
virtual JSObject *toObject(ExecState *exec) const;
virtual bool toBoolean(ExecState*) const;
virtual double toNumber(ExecState*) const;
virtual JSObject* toObject(ExecState*) const;
virtual UString toString(ExecState*) const;
virtual JSObject* toThisObject(ExecState*) const;
UString val;
// Actually getPropertySlot, not getOwnPropertySlot (see JSCell).
virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
static JSValue* lengthGetter(ExecState*, const Identifier&, const PropertySlot&);
static JSValue* indexGetter(ExecState*, const Identifier&, const PropertySlot&);
static JSValue* indexNumericPropertyGetter(ExecState*, unsigned, const PropertySlot&);
UString m_value;
};
// ---------------------------------------------------------------------------
// Evaluation
// ---------------------------------------------------------------------------
ALWAYS_INLINE bool StringImp::getStringPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
if (propertyName == exec->propertyNames().length) {
slot.setCustom(this, lengthGetter);
return true;
}
bool isStrictUInt32;
unsigned i = propertyName.toStrictUInt32(&isStrictUInt32);
if (isStrictUInt32 && i < static_cast<unsigned>(m_value.size())) {
slot.setCustomIndex(this, i, indexGetter);
return true;
}
return false;
}
ALWAYS_INLINE bool StringImp::getStringPropertySlot(unsigned propertyName, PropertySlot& slot)
{
if (propertyName < static_cast<unsigned>(m_value.size())) {
slot.setCustomNumeric(this, indexNumericPropertyGetter);
return true;
}
return false;
}
} // namespace
......
......@@ -86,7 +86,8 @@ namespace KJS {
inline JSValue* staticFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
{
// Look for cached value in dynamic map of properties (in JSObject)
JSObject* thisObj = slot.slotBase();
ASSERT(slot.slotBase()->isObject());
JSObject* thisObj = static_cast<JSObject*>(slot.slotBase());
JSValue* cachedVal = thisObj->getDirect(propertyName);
if (cachedVal)
return cachedVal;
......
......@@ -701,14 +701,6 @@ inline void JSValue::put(ExecState* exec, unsigned propertyName, JSValue* value)
asCell()->put(exec, propertyName, value);
}
inline JSObject* PropertySlot::slotBase() const
{
ASSERT(m_slotBase);
// It's be nice to assert that m_slotBase is an object here, but that's a bit
// too slow, even for debug builds.
return static_cast<JSObject*>(m_slotBase);
}
} // namespace
#endif // KJS_OBJECT_H
......@@ -39,11 +39,11 @@ JSValue* PropertySlot::functionGetter(ExecState* exec, const Identifier&, const
CallData data;
CallType callType = slot.m_data.getterFunc->getCallData(data);
if (callType == CallTypeNative)
return slot.m_data.getterFunc->callAsFunction(exec, slot.slotBase(), exec->emptyList());
return slot.m_data.getterFunc->callAsFunction(exec, static_cast<JSObject*>(slot.slotBase()), exec->emptyList());
ASSERT(callType == CallTypeJS);
RegisterFileStack* stack = &exec->dynamicGlobalObject()->registerFileStack();
stack->pushFunctionRegisterFile();
JSValue* result = slot.m_data.getterFunc->callAsFunction(exec, slot.slotBase(), exec->emptyList());
JSValue* result = slot.m_data.getterFunc->callAsFunction(exec, static_cast<JSObject*>(slot.slotBase()), exec->emptyList());
stack->popFunctionRegisterFile();
return result;
}
......
......@@ -43,7 +43,7 @@ public:
clearBase();
}
explicit PropertySlot(JSCell* base)
explicit PropertySlot(JSValue* base)
: m_slotBase(base)
{
}
......@@ -82,7 +82,7 @@ public:
m_data.valueSlot = valueSlot;
}
void setStaticEntry(JSCell* slotBase, const HashEntry* staticEntry, GetValueFunc getValue)
void setStaticEntry(JSValue* slotBase, const HashEntry* staticEntry, GetValueFunc getValue)
{
ASSERT(slotBase);
ASSERT(staticEntry);
......@@ -92,7 +92,7 @@ public:
m_data.staticEntry = staticEntry;
}
void setCustom(JSCell* slotBase, GetValueFunc getValue)
void setCustom(JSValue* slotBase, GetValueFunc getValue)
{
ASSERT(slotBase);
ASSERT(getValue);
......@@ -100,7 +100,7 @@ public:
m_slotBase = slotBase;
}
void setCustomIndex(JSCell* slotBase, unsigned index, GetValueFunc getValue)
void setCustomIndex(JSValue* slotBase, unsigned index, GetValueFunc getValue)
{
ASSERT(slotBase);
ASSERT(getValue);
......@@ -109,7 +109,7 @@ public:
m_data.index = index;
}
void setCustomNumeric(JSCell* slotBase, GetValueNumericFunc getValue)
void setCustomNumeric(JSValue* slotBase, GetValueNumericFunc getValue)
{
ASSERT(slotBase);
ASSERT(getValue);
......@@ -131,9 +131,9 @@ public:
m_getValue = undefinedGetter;
}
JSObject* slotBase() const;
JSValue* slotBase() const { ASSERT(m_slotBase); return m_slotBase; }
void setBase(JSCell* base)
void setBase(JSValue* base)
{
ASSERT(m_slotBase);
ASSERT(base);
......@@ -156,7 +156,7 @@ private:
GetValueFunc m_getValue;
JSCell* m_slotBase;
JSValue* m_slotBase;
union {
JSObject* getterFunc;
JSValue** valueSlot;
......
......@@ -58,47 +58,17 @@ StringInstance::StringInstance(JSObject *proto, const UString &string)
setInternalValue(jsString(string));
}
JSValue *StringInstance::lengthGetter(ExecState*, const Identifier&, const PropertySlot &slot)
{
return jsNumber(static_cast<StringInstance*>(slot.slotBase())->internalValue()->value().size());
}
JSValue* StringInstance::indexGetter(ExecState*, const Identifier&, const PropertySlot& slot)
{
return jsString(static_cast<StringInstance*>(slot.slotBase())->internalValue()->value().substr(slot.index(), 1));
}
static JSValue* stringInstanceNumericPropertyGetter(ExecState*, unsigned index, const PropertySlot& slot)
{
return jsString(static_cast<StringInstance*>(slot.slotBase())->internalValue()->value().substr(index, 1));
}
bool StringInstance::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
if (propertyName == exec->propertyNames().length) {
slot.setCustom(this, lengthGetter);
if (internalValue()->getStringPropertySlot(exec, propertyName, slot))
return true;
}
bool isStrictUInt32;
unsigned i = propertyName.toStrictUInt32(&isStrictUInt32);
unsigned length = internalValue()->value().size();
if (isStrictUInt32 && i < length) {
slot.setCustomIndex(this, i, indexGetter);
return true;
}
return JSObject::getOwnPropertySlot(exec, propertyName, slot);
}
bool StringInstance::getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
{
unsigned length = internalValue()->value().size();
if (propertyName < length) {
slot.setCustomNumeric(this, stringInstanceNumericPropertyGetter);
return true;
}
if (internalValue()->getStringPropertySlot(propertyName, slot))
return true;
return JSObject::getOwnPropertySlot(exec, Identifier::from(propertyName), slot);
}
......
// -*- c-basic-offset: 2 -*-
/*
* This file is part of the KDE libraries
* Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
* Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
......@@ -31,27 +31,25 @@ namespace KJS {
class StringInstance : public JSWrapperObject {
public:
StringInstance(JSObject *proto);
StringInstance(JSObject *proto, StringImp*);
StringInstance(JSObject *proto, const UString&);
StringInstance(JSObject* prototype);
StringInstance(JSObject* prototype, const UString&);
static StringInstance* create(ExecState*, StringImp*);
virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
virtual void put(ExecState* exec, const Identifier& propertyName, JSValue*);
virtual bool deleteProperty(ExecState* exec, const Identifier& propertyName);
virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
virtual void getPropertyNames(ExecState*, PropertyNameArray&);
virtual const ClassInfo *classInfo() const { return &info; }
virtual const ClassInfo* classInfo() const { return &info; }
static const ClassInfo info;
StringImp* internalValue() const { return static_cast<StringImp*>(JSWrapperObject::internalValue());}
private:
bool inlineGetOwnPropertySlot(ExecState*, unsigned, PropertySlot&);
static JSValue* lengthGetter(ExecState*, const Identifier&, const PropertySlot&);
static JSValue* indexGetter(ExecState*, const Identifier&, const PropertySlot&);
protected:
StringInstance(JSObject* prototype, StringImp*);
};
// WebCore uses this to make style.filter undetectable
......@@ -143,10 +141,9 @@ namespace KJS {
class StringObjectFuncImp : public InternalFunctionImp {
public:
StringObjectFuncImp(ExecState*, FunctionPrototype*, const Identifier&);
virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args);
virtual JSValue* callAsFunction(ExecState*, JSObject* thisObj, const List& args);
};
} // namespace
#endif
......@@ -358,7 +358,7 @@ static void runInteractive(GlobalObject* globalObject)
Completion completion = Interpreter::evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), interpreterName, 1, line);
free(line);
#else
printf(interactivePrompt);
puts(interactivePrompt);
Vector<char, 256> line;
int c;
while ((c = getchar()) != EOF) {
......
/*
* Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
* Copyright (C) 2003, 2004, 2005, 2007 Apple Inc. All rights reserved.
* Copyright (C) 2003, 2004, 2005, 2007, 2008 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
......@@ -142,11 +142,12 @@ private:
class JSCell : public JSValue {
friend class Collector;
friend class NumberImp;
friend class StringImp;
friend class JSObject;
friend class GetterSetterImp;
friend class JSObject;
friend class JSPropertyNameIterator;
friend class JSValue;
friend class NumberImp;
friend class StringImp;
private:
JSCell();
virtual ~JSCell();
......@@ -193,6 +194,7 @@ public:
virtual void put(ExecState*, unsigned propertyName, JSValue*);
virtual JSObject* toThisObject(ExecState*) const;
private:
// Base implementation, but for non-object classes implements getPropertySlot.
virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
......
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