Commit fea4353b authored by ggaren@apple.com's avatar ggaren@apple.com

JavaScriptCore:

2008-08-17  Geoffrey Garen  <ggaren@apple.com>

        Reviewed by Cameron Zwarich.

        Made room for a free word in JSCell.
        
        SunSpider says no change.
        
        I changed JSCallbackObjectData, Arguments, JSArray, and RegExpObject to
        store auxiliary data in a secondary structure.

        I changed InternalFunction to store the function's name in the property
        map.
        
        I changed JSGlobalObjectData to use a virtual destructor, so WebCore's
        JSDOMWindowBaseData could inherit from it safely. (It's a strange design
        for JSDOMWindowBase to allocate an object that JSGlobalObject deletes,
        but that's really our only option, given the size constraint.)
        
        I also added a bunch of compile-time ASSERTs, and removed lots of comments
        in JSObject.h because they were often out of date, and they got in the
        way of reading what was actually going on.
        
        Also renamed JSArray::getLength to JSArray::length, to match our style
        guidelines.

WebCore:

2008-08-17  Geoffrey Garen  <ggaren@apple.com>

        Reviewed by Cameron Zwarich.

        Made room for a free word in JSCell.
        
        Changed JSDOMWindowBase to store its auxiliary data in a subclass of
        JSGlobalData, so the two could share a pointer.
        
        Added a bunch of ASSERTs, to help catch over-sized objects.

WebKit/mac:

2008-08-17  Geoffrey Garen  <ggaren@apple.com>

        Reviewed by Cameron Zwarich.

        Made room for a free word in JSCell.
        
        (Updated for JavaScriptCore changes.)



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@35807 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 64fa293b
......@@ -36,10 +36,12 @@
namespace KJS {
ASSERT_CLASS_FITS_IN_CELL(JSCallbackFunction);
const ClassInfo JSCallbackFunction::info = { "CallbackFunction", &InternalFunction::info, 0, 0 };
JSCallbackFunction::JSCallbackFunction(ExecState* exec, JSObjectCallAsFunctionCallback callback, const Identifier& name)
: InternalFunction(exec->lexicalGlobalObject()->functionPrototype(), name)
: InternalFunction(exec, exec->lexicalGlobalObject()->functionPrototype(), name)
, m_callback(callback)
{
}
......
......@@ -32,10 +32,11 @@
namespace KJS {
ASSERT_CLASS_FITS_IN_CELL(JSCallbackObject<JSObject>);
ASSERT_CLASS_FITS_IN_CELL(JSCallbackObject<JSGlobalObject>);
// Define the two types of JSCallbackObjects we support.
template <> const ClassInfo JSCallbackObject<JSObject>::info = { "CallbackObject", 0, 0, 0 };
template <> const ClassInfo JSCallbackObject<JSGlobalObject>::info = { "CallbackGlobalObject", 0, 0, 0 };
COMPILE_ASSERT(sizeof(JSCallbackObject<JSGlobalObject>) <= CELL_SIZE, global_callback_object_fits_in_cell);
} // namespace KJS
......@@ -46,7 +46,7 @@ public:
static const ClassInfo info;
JSClassRef classRef() const { return m_class; }
JSClassRef classRef() const { return m_callbackObjectData->jsClass; }
bool inherits(JSClassRef) const;
private:
......@@ -82,9 +82,25 @@ private:
static JSValue* staticValueGetter(ExecState*, const Identifier&, const PropertySlot&);
static JSValue* staticFunctionGetter(ExecState*, const Identifier&, const PropertySlot&);
static JSValue* callbackGetter(ExecState*, const Identifier&, const PropertySlot&);
struct JSCallbackObjectData {
JSCallbackObjectData(void* privateData_, JSClassRef jsClass_)
: privateData(privateData_)
, jsClass(jsClass_)
{
JSClassRetain(jsClass);
}
~JSCallbackObjectData()
{
JSClassRelease(jsClass);
}
void* privateData;
JSClassRef jsClass;
};
void* m_privateData;
JSClassRef m_class;
OwnPtr<JSCallbackObjectData> m_callbackObjectData;
};
} // namespace KJS
......
2008-08-17 Geoffrey Garen <ggaren@apple.com>
Reviewed by Cameron Zwarich.
Made room for a free word in JSCell.
SunSpider says no change.
I changed JSCallbackObjectData, Arguments, JSArray, and RegExpObject to
store auxiliary data in a secondary structure.
I changed InternalFunction to store the function's name in the property
map.
I changed JSGlobalObjectData to use a virtual destructor, so WebCore's
JSDOMWindowBaseData could inherit from it safely. (It's a strange design
for JSDOMWindowBase to allocate an object that JSGlobalObject deletes,
but that's really our only option, given the size constraint.)
I also added a bunch of compile-time ASSERTs, and removed lots of comments
in JSObject.h because they were often out of date, and they got in the
way of reading what was actually going on.
Also renamed JSArray::getLength to JSArray::length, to match our style
guidelines.
2008-08-16 Geoffrey Garen <ggaren@apple.com>
Reviewed by Oliver Hunt.
......
......@@ -131,11 +131,8 @@ __ZN3KJS14JSGlobalObjectD2Ev
__ZN3KJS14JSGlobalObjectnwEmPNS_12JSGlobalDataE
__ZN3KJS14constructArrayEPNS_9ExecStateERKNS_7ArgListE
__ZN3KJS15JSWrapperObject4markEv
__ZN3KJS16InternalFunction14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
__ZN3KJS16InternalFunction18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
__ZN3KJS16InternalFunction3putEPNS_9ExecStateERKNS_10IdentifierEPNS_7JSValueE
__ZN3KJS16InternalFunction4infoE
__ZN3KJS16InternalFunctionC2EPNS_17FunctionPrototypeERKNS_10IdentifierE
__ZN3KJS16InternalFunctionC2EPNS_9ExecStateEPNS_17FunctionPrototypeERKNS_10IdentifierE
__ZN3KJS16JSVariableObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
__ZN3KJS16JSVariableObject16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
__ZN3KJS16JSVariableObject16setRegisterArrayEPNS_8RegisterEm
......@@ -208,7 +205,7 @@ __ZN3KJS8JSObject12lookupSetterEPNS_9ExecStateERKNS_10IdentifierE
__ZN3KJS8JSObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
__ZN3KJS8JSObject14deletePropertyEPNS_9ExecStateEj
__ZN3KJS8JSObject16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
__ZN3KJS8JSObject17putDirectFunctionEPNS_16InternalFunctionEj
__ZN3KJS8JSObject17putDirectFunctionEPNS_9ExecStateEPNS_16InternalFunctionEj
__ZN3KJS8JSObject17putWithAttributesEPNS_9ExecStateERKNS_10IdentifierEPNS_7JSValueEj
__ZN3KJS8JSObject17putWithAttributesEPNS_9ExecStateEjPNS_7JSValueEj
__ZN3KJS8JSObject18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
......
......@@ -36,7 +36,7 @@
namespace KJS {
COMPILE_ASSERT(sizeof(JSPropertyNameIterator) <= CellSize<sizeof(void*)>::m_value, JSPropertyNameIteratorSizeASSERT);
ASSERT_CLASS_FITS_IN_CELL(JSPropertyNameIterator);
JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, JSValue* v)
{
......
......@@ -645,7 +645,7 @@ NEVER_INLINE bool Machine::unwindCallFrame(ExecState* exec, JSValue* exceptionVa
Register* callFrame = r - oldCodeBlock->numLocals - RegisterFile::CallFrameHeaderSize;
if (Debugger* debugger = exec->dynamicGlobalObject()->debugger()) {
DebuggerCallFrame debuggerCallFrame(exec->dynamicGlobalObject(), codeBlock, scopeChain, r, exceptionValue);
DebuggerCallFrame debuggerCallFrame(exec, exec->dynamicGlobalObject(), codeBlock, scopeChain, r, exceptionValue);
if (callFrame[RegisterFile::Callee].jsValue(exec))
debugger->returnEvent(debuggerCallFrame, codeBlock->ownerNode->sourceId(), codeBlock->ownerNode->lastLine());
else
......@@ -723,7 +723,7 @@ NEVER_INLINE Instruction* Machine::throwException(ExecState* exec, JSValue*& exc
}
if (Debugger* debugger = exec->dynamicGlobalObject()->debugger()) {
DebuggerCallFrame debuggerCallFrame(exec->dynamicGlobalObject(), codeBlock, scopeChain, r, exceptionValue);
DebuggerCallFrame debuggerCallFrame(exec, exec->dynamicGlobalObject(), codeBlock, scopeChain, r, exceptionValue);
debugger->exception(debuggerCallFrame, codeBlock->ownerNode->sourceId(), codeBlock->lineNumberForVPC(vPC));
}
......@@ -955,7 +955,7 @@ NEVER_INLINE void Machine::debug(ExecState* exec, const Instruction* vPC, const
if (!debugger)
return;
DebuggerCallFrame debuggerCallFrame(exec->dynamicGlobalObject(), codeBlock, scopeChain, r, 0);
DebuggerCallFrame debuggerCallFrame(exec, exec->dynamicGlobalObject(), codeBlock, scopeChain, r, 0);
switch((DebugHookID)debugHookID) {
case DidEnterCallFrame: {
......
......@@ -32,14 +32,17 @@
namespace KJS {
ASSERT_CLASS_FITS_IN_CELL(Arguments);
const ClassInfo Arguments::info = { "Arguments", 0, 0, 0 };
// ECMA 10.1.8
Arguments::Arguments(ExecState* exec, JSFunction* function, const ArgList& args, JSActivation* activation)
: JSObject(exec->lexicalGlobalObject()->objectPrototype())
, m_activationObject(activation)
, m_indexToNameMap(function, args)
, d(new ArgumentsData(activation, function, args))
{
ASSERT(activation);
putDirect(exec->propertyNames().callee, function, DontEnum);
putDirect(exec, exec->propertyNames().length, args.size(), DontEnum);
......@@ -47,7 +50,7 @@ Arguments::Arguments(ExecState* exec, JSFunction* function, const ArgList& args,
ArgList::const_iterator end = args.end();
for (ArgList::const_iterator it = args.begin(); it != end; ++it, ++i) {
Identifier name = Identifier::from(exec, i);
if (!m_indexToNameMap.isMapped(name))
if (!d->indexToNameMap.isMapped(name))
putDirect(name, (*it).jsValue(exec), DontEnum);
}
}
......@@ -55,19 +58,19 @@ Arguments::Arguments(ExecState* exec, JSFunction* function, const ArgList& args,
void Arguments::mark()
{
JSObject::mark();
if (m_activationObject && !m_activationObject->marked())
m_activationObject->mark();
if (!d->activation->marked())
d->activation->mark();
}
JSValue* Arguments::mappedIndexGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
{
Arguments* thisObj = static_cast<Arguments*>(slot.slotBase());
return thisObj->m_activationObject->get(exec, thisObj->m_indexToNameMap[propertyName]);
return thisObj->d->activation->get(exec, thisObj->d->indexToNameMap[propertyName]);
}
bool Arguments::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
if (m_indexToNameMap.isMapped(propertyName)) {
if (d->indexToNameMap.isMapped(propertyName)) {
slot.setCustom(this, mappedIndexGetter);
return true;
}
......@@ -77,16 +80,16 @@ bool Arguments::getOwnPropertySlot(ExecState* exec, const Identifier& propertyNa
void Arguments::put(ExecState* exec, const Identifier& propertyName, JSValue* value)
{
if (m_indexToNameMap.isMapped(propertyName))
m_activationObject->put(exec, m_indexToNameMap[propertyName], value);
if (d->indexToNameMap.isMapped(propertyName))
d->activation->put(exec, d->indexToNameMap[propertyName], value);
else
JSObject::put(exec, propertyName, value);
}
bool Arguments::deleteProperty(ExecState* exec, const Identifier& propertyName)
{
if (m_indexToNameMap.isMapped(propertyName)) {
m_indexToNameMap.unMap(exec, propertyName);
if (d->indexToNameMap.isMapped(propertyName)) {
d->indexToNameMap.unMap(exec, propertyName);
return true;
}
......
......@@ -47,8 +47,18 @@ namespace KJS {
private:
static JSValue* mappedIndexGetter(ExecState*, const Identifier&, const PropertySlot& slot);
JSActivation* m_activationObject;
mutable IndexToNameMap m_indexToNameMap;
struct ArgumentsData {
ArgumentsData(JSActivation* activation_, JSFunction* function_, const ArgList& args_)
: activation(activation_)
, indexToNameMap(function_, args_)
{
}
JSActivation* activation;
mutable IndexToNameMap indexToNameMap;
};
OwnPtr<ArgumentsData> d;
};
} // namespace KJS
......
......@@ -31,8 +31,10 @@
namespace KJS {
ASSERT_CLASS_FITS_IN_CELL(ArrayConstructor);
ArrayConstructor::ArrayConstructor(ExecState* exec, FunctionPrototype* functionPrototype, ArrayPrototype* arrayPrototype)
: InternalFunction(functionPrototype, Identifier(exec, arrayPrototype->classInfo()->className))
: InternalFunction(exec, functionPrototype, Identifier(exec, arrayPrototype->classInfo()->className))
{
// ECMA 15.4.3.1 Array.prototype
putDirect(exec->propertyNames().prototype, arrayPrototype, DontEnum | DontDelete | ReadOnly);
......
......@@ -34,6 +34,8 @@
namespace KJS {
ASSERT_CLASS_FITS_IN_CELL(ArrayPrototype);
static JSValue* arrayProtoFuncToString(ExecState*, JSObject*, JSValue*, const ArgList&);
static JSValue* arrayProtoFuncToLocaleString(ExecState*, JSObject*, JSValue*, const ArgList&);
static JSValue* arrayProtoFuncConcat(ExecState*, JSObject*, JSValue*, const ArgList&);
......@@ -262,7 +264,7 @@ JSValue* arrayProtoFuncConcat(ExecState* exec, JSObject*, JSValue* thisValue, co
while (1) {
if (curArg->isObject(&JSArray::info)) {
JSArray* curArray = static_cast<JSArray*>(curArg);
unsigned length = curArray->getLength();
unsigned length = curArray->length();
for (unsigned k = 0; k < length; ++k) {
if (JSValue* v = getProperty(exec, curArray, k))
arr->put(exec, n, v);
......
......@@ -26,8 +26,10 @@
namespace KJS {
ASSERT_CLASS_FITS_IN_CELL(BooleanConstructor);
BooleanConstructor::BooleanConstructor(ExecState* exec, FunctionPrototype* functionPrototype, BooleanPrototype* booleanPrototype)
: InternalFunction(functionPrototype, Identifier(exec, booleanPrototype->classInfo()->className))
: InternalFunction(exec, functionPrototype, Identifier(exec, booleanPrototype->classInfo()->className))
{
putDirect(exec->propertyNames().prototype, booleanPrototype, DontEnum | DontDelete | ReadOnly);
......
......@@ -23,6 +23,8 @@
namespace KJS {
ASSERT_CLASS_FITS_IN_CELL(BooleanObject);
const ClassInfo BooleanObject::info = { "Boolean", 0, 0, 0 };
BooleanObject::BooleanObject(JSObject* prototype)
......
......@@ -29,6 +29,8 @@
namespace KJS {
ASSERT_CLASS_FITS_IN_CELL(BooleanPrototype);
// Functions
static JSValue* booleanProtoFuncToString(ExecState*, JSObject*, JSValue*, const ArgList&);
static JSValue* booleanProtoFuncValueOf(ExecState*, JSObject*, JSValue*, const ArgList&);
......@@ -40,8 +42,8 @@ BooleanPrototype::BooleanPrototype(ExecState* exec, ObjectPrototype* objectProto
{
setInternalValue(jsBoolean(false));
putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toString, booleanProtoFuncToString), DontEnum);
putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().valueOf, booleanProtoFuncValueOf), DontEnum);
putDirectFunction(exec, new (exec) PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toString, booleanProtoFuncToString), DontEnum);
putDirectFunction(exec, new (exec) PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().valueOf, booleanProtoFuncValueOf), DontEnum);
}
......
......@@ -45,18 +45,20 @@ namespace KJS {
// TODO: MakeTime (15.9.11.1) etc. ?
ASSERT_CLASS_FITS_IN_CELL(DateConstructor);
static JSValue* dateParse(ExecState*, JSObject*, JSValue*, const ArgList&);
static JSValue* dateNow(ExecState*, JSObject*, JSValue*, const ArgList&);
static JSValue* dateUTC(ExecState*, JSObject*, JSValue*, const ArgList&);
DateConstructor::DateConstructor(ExecState* exec, FunctionPrototype* functionPrototype, DatePrototype* datePrototype)
: InternalFunction(functionPrototype, Identifier(exec, datePrototype->classInfo()->className))
: InternalFunction(exec, functionPrototype, Identifier(exec, datePrototype->classInfo()->className))
{
putDirect(exec->propertyNames().prototype, datePrototype, DontEnum|DontDelete|ReadOnly);
putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().parse, dateParse), DontEnum);
putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 7, exec->propertyNames().UTC, dateUTC), DontEnum);
putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().now, dateNow), DontEnum);
putDirectFunction(exec, new (exec) PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().parse, dateParse), DontEnum);
putDirectFunction(exec, new (exec) PrototypeFunction(exec, functionPrototype, 7, exec->propertyNames().UTC, dateUTC), DontEnum);
putDirectFunction(exec, new (exec) PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().now, dateNow), DontEnum);
putDirect(exec, exec->propertyNames().length, 7, ReadOnly | DontEnum | DontDelete);
}
......
......@@ -56,6 +56,8 @@ using namespace WTF;
namespace KJS {
ASSERT_CLASS_FITS_IN_CELL(DatePrototype);
static JSValue* dateProtoFuncGetDate(ExecState*, JSObject*, JSValue*, const ArgList&);
static JSValue* dateProtoFuncGetDay(ExecState*, JSObject*, JSValue*, const ArgList&);
static JSValue* dateProtoFuncGetFullYear(ExecState*, JSObject*, JSValue*, const ArgList&);
......
......@@ -49,7 +49,7 @@ const UString* DebuggerCallFrame::functionName() const
JSFunction* function = static_cast<JSFunction*>(callFrame()[RegisterFile::Callee].getJSValue());
if (!function)
return 0;
return &function->functionName().ustring();
return &function->name(m_exec);
}
DebuggerCallFrame::Type DebuggerCallFrame::type() const
......
......@@ -32,6 +32,7 @@
namespace KJS {
class CodeBlock;
class ExecState;
class JSGlobalObject;
class JSObject;
class JSValue;
......@@ -47,8 +48,9 @@ namespace KJS {
FunctionType
};
DebuggerCallFrame(JSGlobalObject* dynamicGlobalObject, const CodeBlock* codeBlock, ScopeChainNode* scopeChain, Register* r, JSValue* exception)
: m_dynamicGlobalObject(dynamicGlobalObject)
DebuggerCallFrame(ExecState* exec, JSGlobalObject* dynamicGlobalObject, const CodeBlock* codeBlock, ScopeChainNode* scopeChain, Register* r, JSValue* exception)
: m_exec(exec)
, m_dynamicGlobalObject(dynamicGlobalObject)
, m_codeBlock(codeBlock)
, m_scopeChain(scopeChain)
, m_registers(r)
......@@ -67,6 +69,7 @@ namespace KJS {
private:
Register* callFrame() const;
ExecState* m_exec;
JSGlobalObject* m_dynamicGlobalObject;
const CodeBlock* m_codeBlock;
ScopeChainNode* m_scopeChain;
......
......@@ -29,8 +29,10 @@
namespace KJS {
ASSERT_CLASS_FITS_IN_CELL(ErrorConstructor);
ErrorConstructor::ErrorConstructor(ExecState* exec, FunctionPrototype* functionPrototype, ErrorPrototype* errorPrototype)
: InternalFunction(functionPrototype, Identifier(exec, errorPrototype->classInfo()->className))
: InternalFunction(exec, functionPrototype, Identifier(exec, errorPrototype->classInfo()->className))
{
// ECMA 15.11.3.1 Error.prototype
putDirect(exec->propertyNames().prototype, errorPrototype, DontEnum | DontDelete | ReadOnly);
......
......@@ -29,6 +29,8 @@
namespace KJS {
ASSERT_CLASS_FITS_IN_CELL(ErrorPrototype);
static JSValue* errorProtoFuncToString(ExecState*, JSObject*, JSValue*, const ArgList&);
// ECMA 15.9.4
......@@ -40,7 +42,7 @@ ErrorPrototype::ErrorPrototype(ExecState* exec, ObjectPrototype* objectPrototype
putDirect(exec->propertyNames().name, jsString(exec, "Error"), DontEnum);
putDirect(exec->propertyNames().message, jsString(exec, "Unknown error"), DontEnum);
putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toString, errorProtoFuncToString), DontEnum);
putDirectFunction(exec, new (exec) PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toString, errorProtoFuncToString), DontEnum);
}
JSValue* errorProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
......
......@@ -32,8 +32,10 @@
namespace KJS {
ASSERT_CLASS_FITS_IN_CELL(FunctionConstructor);
FunctionConstructor::FunctionConstructor(ExecState* exec, FunctionPrototype* functionPrototype)
: InternalFunction(functionPrototype, Identifier(exec, functionPrototype->classInfo()->className))
: InternalFunction(exec, functionPrototype, Identifier(exec, functionPrototype->classInfo()->className))
{
putDirect(exec->propertyNames().prototype, functionPrototype, DontEnum | DontDelete | ReadOnly);
......
......@@ -29,17 +29,20 @@
namespace KJS {
ASSERT_CLASS_FITS_IN_CELL(FunctionPrototype);
static JSValue* functionProtoFuncToString(ExecState*, JSObject*, JSValue*, const ArgList&);
static JSValue* functionProtoFuncApply(ExecState*, JSObject*, JSValue*, const ArgList&);
static JSValue* functionProtoFuncCall(ExecState*, JSObject*, JSValue*, const ArgList&);
FunctionPrototype::FunctionPrototype(ExecState* exec)
: InternalFunction(exec)
{
putDirect(exec->propertyNames().length, jsNumber(exec, 0), DontDelete | ReadOnly | DontEnum);
putDirectFunction(new (exec) PrototypeFunction(exec, this, 0, exec->propertyNames().toString, functionProtoFuncToString), DontEnum);
putDirectFunction(new (exec) PrototypeFunction(exec, this, 2, exec->propertyNames().apply, functionProtoFuncApply), DontEnum);
putDirectFunction(new (exec) PrototypeFunction(exec, this, 1, exec->propertyNames().call, functionProtoFuncCall), DontEnum);
putDirectFunction(exec, new (exec) PrototypeFunction(exec, this, 0, exec->propertyNames().toString, functionProtoFuncToString), DontEnum);
putDirectFunction(exec, new (exec) PrototypeFunction(exec, this, 2, exec->propertyNames().apply, functionProtoFuncApply), DontEnum);
putDirectFunction(exec, new (exec) PrototypeFunction(exec, this, 1, exec->propertyNames().call, functionProtoFuncCall), DontEnum);
}
static JSValue* callFunctionPrototype(ExecState*, JSObject*, JSValue*, const ArgList&)
......@@ -58,17 +61,17 @@ CallType FunctionPrototype::getCallData(CallData& callData)
JSValue* functionProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
{
if (!thisValue->isObject(&InternalFunction::info))
return throwError(exec, TypeError);
InternalFunction* function = static_cast<InternalFunction*>(thisValue);
if (thisValue->isObject(&JSFunction::info)) {
JSFunction* function = static_cast<JSFunction*>(thisValue);
return jsString(exec, "function " + function->name(exec) + "(" + function->m_body->paramString() + ") " + function->m_body->toSourceString());
}
if (function->inherits(&JSFunction::info)) {
JSFunction* fi = static_cast<JSFunction*>(thisValue);
return jsString(exec, "function " + fi->functionName().ustring() + "(" + fi->m_body->paramString() + ") " + fi->m_body->toSourceString());
if (thisValue->isObject(&InternalFunction::info)) {
InternalFunction* function = static_cast<InternalFunction*>(thisValue);
return jsString(exec, "function " + function->name(exec) + "() {\n [native code]\n}");
}
return jsString(exec, "function " + function->functionName().ustring() + "() {\n [native code]\n}");
return throwError(exec, TypeError);
}
JSValue* functionProtoFuncApply(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
......
......@@ -31,6 +31,8 @@
namespace KJS {
ASSERT_CLASS_FITS_IN_CELL(GlobalEvalFunction);
GlobalEvalFunction::GlobalEvalFunction(ExecState* exec, FunctionPrototype* functionPrototype, int len, const Identifier& name, NativeFunction function, JSGlobalObject* cachedGlobalObject)
: PrototypeFunction(exec, functionPrototype, len, name, function)
, m_cachedGlobalObject(cachedGlobalObject)
......
......@@ -28,51 +28,31 @@
namespace KJS {
ASSERT_CLASS_FITS_IN_CELL(InternalFunction);
const ClassInfo InternalFunction::info = { "Function", 0, 0, 0 };
InternalFunction::InternalFunction()
InternalFunction::InternalFunction(ExecState* exec)
{
putDirect(exec->propertyNames().name, jsString(exec, exec->propertyNames().nullIdentifier.ustring()), DontDelete | ReadOnly | DontEnum);
}
InternalFunction::InternalFunction(FunctionPrototype* prototype, const Identifier& name)
InternalFunction::InternalFunction(ExecState* exec, FunctionPrototype* prototype, const Identifier& name)
: JSObject(prototype)
, m_name(name)
{
}
bool InternalFunction::implementsHasInstance() const
{
return true;
putDirect(exec->propertyNames().name, jsString(exec, name.ustring()), DontDelete | ReadOnly | DontEnum);
}
bool InternalFunction::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
const UString& InternalFunction::name(ExecState* exec)
{
if (propertyName == exec->propertyNames().name) {
slot.setCustom(this, nameGetter);
return true;
}
return JSObject::getOwnPropertySlot(exec, propertyName, slot);
JSValue* v = getDirect(exec->propertyNames().name);
ASSERT(v->isString());
return static_cast<JSString*>(v)->value();
}
void InternalFunction::put(ExecState* exec, const Identifier& propertyName, JSValue* value)
{
if (propertyName == exec->propertyNames().name)
return;
JSObject::put(exec, propertyName, value);
}
bool InternalFunction::deleteProperty(ExecState* exec, const Identifier& propertyName)
{
if (propertyName == exec->propertyNames().name)
return false;
return JSObject::deleteProperty(exec, propertyName);
}
JSValue* InternalFunction::nameGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
bool InternalFunction::implementsHasInstance() const
{
InternalFunction* thisObj = static_cast<InternalFunction*>(slot.slotBase());
return jsString(exec, thisObj->functionName().ustring());
return true;
}
} // namespace KJS
......@@ -35,23 +35,16 @@ namespace KJS {
public:
virtual const ClassInfo* classInfo() const { return &info; }
static const ClassInfo info;
virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
virtual void put(ExecState*, const Identifier& propertyName, JSValue*);
virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
const Identifier& functionName() const { return m_name; }
const UString& name(ExecState*);
protected:
InternalFunction();
InternalFunction(FunctionPrototype*, const Identifier&);
InternalFunction(ExecState*);
InternalFunction(ExecState*, FunctionPrototype*, const Identifier&);
private:
static JSValue* nameGetter(ExecState*, const Identifier&, const PropertySlot&);
virtual CallType getCallData(CallData&) = 0;
virtual bool implementsHasInstance() const;
Identifier m_name;
};
} // namespace KJS
......
......@@ -37,6 +37,8 @@
namespace KJS {
ASSERT_CLASS_FITS_IN_CELL(JSActivation);
const ClassInfo JSActivation::info = { "JSActivation", 0, 0, 0 };
JSActivation::JSActivation(PassRefPtr<FunctionBodyNode> functionBody, Register* registers)
......
......@@ -35,6 +35,8 @@ using namespace std;
namespace KJS {
ASSERT_CLASS_FITS_IN_CELL(JSArray);
// Overview of JSArray
//
// Properties of JSArray objects may be stored in one of three locations:
......@@ -128,10 +130,10 @@ JSArray::JSArray(JSValue* prototype, unsigned initialLength)
{
unsigned initialCapacity = min(initialLength, MIN_SPARSE_ARRAY_INDEX);