Commit fe12c1f5 authored by barraclough@apple.com's avatar barraclough@apple.com
Browse files

Bug 39393 - JSFunction need not be a subclass of InternalFunction.

Reviewed by Oliver Hunt.

This may prevent us from introducing a more useful parent class to
JSFunction, e.g. a JSObject that holds an executable, which could
also reference an eval or program executable.

* JavaScriptCore.exp:
* interpreter/Interpreter.cpp:
(JSC::Interpreter::retrieveCaller):
(JSC::Interpreter::findFunctionCallFrame):
* interpreter/Interpreter.h:
* profiler/Profiler.cpp:
(JSC::Profiler::createCallIdentifier):
* runtime/FunctionPrototype.cpp:
(JSC::functionProtoFuncToString):
* runtime/JSFunction.cpp:
(JSC::):
(JSC::JSFunction::JSFunction):
(JSC::JSFunction::name):
(JSC::JSFunction::displayName):
(JSC::JSFunction::calculatedDisplayName):
* runtime/JSFunction.h:
* runtime/JSObject.cpp:
(JSC::JSObject::putDirectFunction):
(JSC::JSObject::putDirectFunctionWithoutTransition):
* runtime/JSObject.h:
* runtime/Lookup.cpp:
(JSC::setUpStaticFunctionSlot):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@59800 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 6aa66153
2010-05-19 Gavin Barraclough <barraclough@apple.com>
Reviewed by Oliver Hunt.
Bug 39393 - JSFunction need not be a subclass of InternalFunction.
This may prevent us from introducing a more useful parent class to
JSFunction, e.g. a JSObject that holds an executable, which could
also reference an eval or program executable.
* JavaScriptCore.exp:
* interpreter/Interpreter.cpp:
(JSC::Interpreter::retrieveCaller):
(JSC::Interpreter::findFunctionCallFrame):
* interpreter/Interpreter.h:
* profiler/Profiler.cpp:
(JSC::Profiler::createCallIdentifier):
* runtime/FunctionPrototype.cpp:
(JSC::functionProtoFuncToString):
* runtime/JSFunction.cpp:
(JSC::):
(JSC::JSFunction::JSFunction):
(JSC::JSFunction::name):
(JSC::JSFunction::displayName):
(JSC::JSFunction::calculatedDisplayName):
* runtime/JSFunction.h:
* runtime/JSObject.cpp:
(JSC::JSObject::putDirectFunction):
(JSC::JSObject::putDirectFunctionWithoutTransition):
* runtime/JSObject.h:
* runtime/Lookup.cpp:
(JSC::setUpStaticFunctionSlot):
2010-05-19 Oliver Hunt <oliver@apple.com>
 
Reviewed by Geoffrey Garen.
......
......@@ -264,6 +264,7 @@ __ZN3JSC8JSObject15unwrappedObjectEv
__ZN3JSC8JSObject16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE
__ZN3JSC8JSObject17createInheritorIDEv
__ZN3JSC8JSObject17defineOwnPropertyEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorEb
__ZN3JSC8JSObject17putDirectFunctionEPNS_9ExecStateEPNS_10JSFunctionEj
__ZN3JSC8JSObject17putDirectFunctionEPNS_9ExecStateEPNS_16InternalFunctionEj
__ZN3JSC8JSObject17putWithAttributesEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueEj
__ZN3JSC8JSObject17putWithAttributesEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueEjbRNS_15PutPropertySlotE
......@@ -452,7 +453,6 @@ __ZN7WebCoreplEPKcRKNS_6StringE
__ZN7WebCoreplERKNS_6StringEPKc
__ZN7WebCoreplERKNS_6StringES2_
__ZNK3JSC10JSFunction23isHostFunctionNonInlineEv
__ZNK3JSC11Interpreter14retrieveCallerEPNS_9ExecStateEPNS_16InternalFunctionE
__ZNK3JSC11Interpreter18retrieveLastCallerEPNS_9ExecStateERiRlRNS_7UStringERNS_7JSValueE
__ZNK3JSC12PropertySlot14functionGetterEPNS_9ExecStateE
__ZNK3JSC14JSGlobalObject14isDynamicScopeERb
......
......@@ -4424,7 +4424,7 @@ JSValue Interpreter::retrieveArguments(CallFrame* callFrame, JSFunction* functio
return arguments;
}
JSValue Interpreter::retrieveCaller(CallFrame* callFrame, InternalFunction* function) const
JSValue Interpreter::retrieveCaller(CallFrame* callFrame, JSFunction* function) const
{
CallFrame* functionCallFrame = findFunctionCallFrame(callFrame, function);
if (!functionCallFrame)
......@@ -4462,7 +4462,7 @@ void Interpreter::retrieveLastCaller(CallFrame* callFrame, int& lineNumber, intp
function = callerFrame->callee();
}
CallFrame* Interpreter::findFunctionCallFrame(CallFrame* callFrame, InternalFunction* function)
CallFrame* Interpreter::findFunctionCallFrame(CallFrame* callFrame, JSFunction* function)
{
for (CallFrame* candidate = callFrame; candidate; candidate = candidate->callerFrame()->removeHostCallFrameFlag()) {
if (candidate->callee() == function)
......
......@@ -44,7 +44,6 @@ namespace JSC {
class CodeBlock;
class EvalExecutable;
class FunctionExecutable;
class InternalFunction;
class JSFunction;
class JSGlobalObject;
class ProgramExecutable;
......@@ -101,7 +100,7 @@ namespace JSC {
JSValue execute(EvalExecutable* evalNode, CallFrame* exec, JSObject* thisObj, ScopeChainNode* scopeChain, JSValue* exception);
JSValue retrieveArguments(CallFrame*, JSFunction*) const;
JSValue retrieveCaller(CallFrame*, InternalFunction*) const;
JSValue retrieveCaller(CallFrame*, JSFunction*) const;
void retrieveLastCaller(CallFrame*, int& lineNumber, intptr_t& sourceID, UString& sourceURL, JSValue& function) const;
void getArgumentsData(CallFrame*, JSFunction*&, ptrdiff_t& firstParameterIndex, Register*& argv, int& argc);
......@@ -143,7 +142,7 @@ namespace JSC {
static ALWAYS_INLINE CallFrame* slideRegisterWindowForCall(CodeBlock*, RegisterFile*, CallFrame*, size_t registerOffset, int argc);
static CallFrame* findFunctionCallFrame(CallFrame*, InternalFunction*);
static CallFrame* findFunctionCallFrame(CallFrame*, JSFunction*);
JSValue privateExecute(ExecutionFlag, RegisterFile*, CallFrame*, JSValue* exception);
......
......@@ -32,6 +32,7 @@
#include "CommonIdentifiers.h"
#include "CallFrame.h"
#include "CodeBlock.h"
#include "InternalFunction.h"
#include "JSFunction.h"
#include "JSGlobalObject.h"
#include "Nodes.h"
......@@ -146,6 +147,8 @@ CallIdentifier Profiler::createCallIdentifier(ExecState* exec, JSValue functionV
if (!function->executable()->isHostFunction())
return createCallIdentifierFromFunctionImp(exec, function);
}
if (asObject(functionValue)->inherits(&JSFunction::info))
return CallIdentifier(static_cast<JSFunction*>(asObject(functionValue))->name(exec), defaultSourceURL, defaultLineNumber);
if (asObject(functionValue)->inherits(&InternalFunction::info))
return CallIdentifier(static_cast<InternalFunction*>(asObject(functionValue))->name(exec), defaultSourceURL, defaultLineNumber);
return CallIdentifier(makeString("(", asObject(functionValue)->className(), " object)"), defaultSourceURL, defaultLineNumber);
......
......@@ -87,12 +87,12 @@ JSValue JSC_HOST_CALL functionProtoFuncToString(ExecState* exec, JSObject*, JSVa
{
if (thisValue.inherits(&JSFunction::info)) {
JSFunction* function = asFunction(thisValue);
if (!function->isHostFunction()) {
FunctionExecutable* executable = function->jsExecutable();
UString sourceString = executable->source().toString();
insertSemicolonIfNeeded(sourceString);
return jsMakeNontrivialString(exec, "function ", function->name(exec), "(", executable->paramString(), ") ", sourceString);
}
if (function->isHostFunction())
return jsMakeNontrivialString(exec, "function ", function->name(exec), "() {\n [native code]\n}");
FunctionExecutable* executable = function->jsExecutable();
UString sourceString = executable->source().toString();
insertSemicolonIfNeeded(sourceString);
return jsMakeNontrivialString(exec, "function ", function->name(exec), "(", executable->paramString(), ") ", sourceString);
}
if (thisValue.inherits(&InternalFunction::info)) {
......
......@@ -43,7 +43,7 @@ namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(JSFunction);
const ClassInfo JSFunction::info = { "Function", &InternalFunction::info, 0, 0 };
const ClassInfo JSFunction::info = { "Function", 0, 0, 0 };
bool JSFunction::isHostFunctionNonInline() const
{
......@@ -58,12 +58,13 @@ JSFunction::JSFunction(NonNullPassRefPtr<Structure> structure)
}
JSFunction::JSFunction(ExecState* exec, NonNullPassRefPtr<Structure> structure, int length, const Identifier& name, PassRefPtr<NativeExecutable> thunk)
: Base(&exec->globalData(), structure, name)
: Base(structure)
#if ENABLE(JIT)
, m_executable(thunk)
#endif
, m_scopeChain(NoScopeChain())
{
putDirect(exec->globalData().propertyNames->name, jsString(exec, name.isNull() ? "" : name.ustring()), DontDelete | ReadOnly | DontEnum);
#if ENABLE(JIT)
putDirect(exec->propertyNames().length, jsNumber(exec, length), DontDelete | ReadOnly | DontEnum);
#else
......@@ -74,12 +75,13 @@ JSFunction::JSFunction(ExecState* exec, NonNullPassRefPtr<Structure> structure,
}
JSFunction::JSFunction(ExecState* exec, NonNullPassRefPtr<Structure> structure, int length, const Identifier& name, NativeFunction func)
: Base(&exec->globalData(), structure, name)
: Base(structure)
#if ENABLE(JIT)
, m_executable(exec->globalData().getHostFunction(func))
#endif
, m_scopeChain(NoScopeChain())
{
putDirect(exec->globalData().propertyNames->name, jsString(exec, name.isNull() ? "" : name.ustring()), DontDelete | ReadOnly | DontEnum);
#if ENABLE(JIT)
putDirect(exec->propertyNames().length, jsNumber(exec, length), DontDelete | ReadOnly | DontEnum);
#else
......@@ -90,10 +92,12 @@ JSFunction::JSFunction(ExecState* exec, NonNullPassRefPtr<Structure> structure,
}
JSFunction::JSFunction(ExecState* exec, NonNullPassRefPtr<FunctionExecutable> executable, ScopeChainNode* scopeChainNode)
: Base(&exec->globalData(), exec->lexicalGlobalObject()->functionStructure(), executable->name())
: Base(exec->lexicalGlobalObject()->functionStructure())
, m_executable(executable)
, m_scopeChain(scopeChainNode)
{
const Identifier& name = static_cast<FunctionExecutable*>(m_executable.get())->name();
putDirect(exec->globalData().propertyNames->name, jsString(exec, name.isNull() ? "" : name.ustring()), DontDelete | ReadOnly | DontEnum);
}
JSFunction::~JSFunction()
......@@ -114,6 +118,31 @@ JSFunction::~JSFunction()
}
}
const UString& JSFunction::name(ExecState* exec)
{
return asString(getDirect(exec->globalData().propertyNames->name))->value(exec);
}
const UString JSFunction::displayName(ExecState* exec)
{
JSValue displayName = getDirect(exec->globalData().propertyNames->displayName);
if (displayName && isJSString(&exec->globalData(), displayName))
return asString(displayName)->value(exec);
return UString::null();
}
const UString JSFunction::calculatedDisplayName(ExecState* exec)
{
const UString explicitName = displayName(exec);
if (!explicitName.isEmpty())
return explicitName;
return name(exec);
}
void JSFunction::markChildren(MarkStack& markStack)
{
Base::markChildren(markStack);
......
......@@ -24,7 +24,7 @@
#ifndef JSFunction_h
#define JSFunction_h
#include "InternalFunction.h"
#include "JSObject.h"
namespace JSC {
......@@ -35,11 +35,11 @@ namespace JSC {
class JSGlobalObject;
class NativeExecutable;
class JSFunction : public InternalFunction {
class JSFunction : public JSObject {
friend class JIT;
friend class JSGlobalData;
typedef InternalFunction Base;
typedef JSObject Base;
public:
JSFunction(ExecState*, NonNullPassRefPtr<Structure>, int length, const Identifier&, NativeFunction);
......@@ -50,6 +50,10 @@ namespace JSC {
JSObject* construct(ExecState*, const ArgList&);
JSValue call(ExecState*, JSValue thisValue, const ArgList&);
const UString& name(ExecState*);
const UString displayName(ExecState*);
const UString calculatedDisplayName(ExecState*);
ScopeChain& scope()
{
ASSERT(!isHostFunctionNonInline());
......@@ -80,7 +84,7 @@ namespace JSC {
virtual CallType getCallData(CallData&);
protected:
const static unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | OverridesMarkChildren | OverridesGetPropertyNames | InternalFunction::StructureFlags;
const static unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | OverridesMarkChildren | OverridesGetPropertyNames | JSObject::StructureFlags;
private:
JSFunction(NonNullPassRefPtr<Structure>);
......
......@@ -27,6 +27,7 @@
#include "DatePrototype.h"
#include "ErrorConstructor.h"
#include "GetterSetter.h"
#include "JSFunction.h"
#include "JSGlobalObject.h"
#include "NativeErrorConstructor.h"
#include "ObjectPrototype.h"
......@@ -509,11 +510,21 @@ void JSObject::putDirectFunction(ExecState* exec, InternalFunction* function, un
putDirectFunction(Identifier(exec, function->name(exec)), function, attr);
}
void JSObject::putDirectFunction(ExecState* exec, JSFunction* function, unsigned attr)
{
putDirectFunction(Identifier(exec, function->name(exec)), function, attr);
}
void JSObject::putDirectFunctionWithoutTransition(ExecState* exec, InternalFunction* function, unsigned attr)
{
putDirectFunctionWithoutTransition(Identifier(exec, function->name(exec)), function, attr);
}
void JSObject::putDirectFunctionWithoutTransition(ExecState* exec, JSFunction* function, unsigned attr)
{
putDirectFunctionWithoutTransition(Identifier(exec, function->name(exec)), function, attr);
}
NEVER_INLINE void JSObject::fillGetterPropertySlot(PropertySlot& slot, JSValue* location)
{
if (JSObject* getterFunction = asGetterSetter(*location)->getter()) {
......
......@@ -176,10 +176,12 @@ namespace JSC {
void putDirectFunction(const Identifier& propertyName, JSCell* value, unsigned attr = 0);
void putDirectFunction(const Identifier& propertyName, JSCell* value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot);
void putDirectFunction(ExecState* exec, InternalFunction* function, unsigned attr = 0);
void putDirectFunction(ExecState* exec, JSFunction* function, unsigned attr = 0);
void putDirectWithoutTransition(const Identifier& propertyName, JSValue value, unsigned attr = 0);
void putDirectFunctionWithoutTransition(const Identifier& propertyName, JSCell* value, unsigned attr = 0);
void putDirectFunctionWithoutTransition(ExecState* exec, InternalFunction* function, unsigned attr = 0);
void putDirectFunctionWithoutTransition(ExecState* exec, JSFunction* function, unsigned attr = 0);
// Fast access to known property offsets.
JSValue getDirectOffset(size_t offset) const { return JSValue::decode(propertyStorage()[offset]); }
......
......@@ -75,7 +75,7 @@ void setUpStaticFunctionSlot(ExecState* exec, const HashEntry* entry, JSObject*
JSValue* location = thisObj->getDirectLocation(propertyName);
if (!location) {
InternalFunction* function;
NativeFunctionWrapper* function;
#if ENABLE(JIT)
if (entry->generator())
function = new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), entry->functionLength(), propertyName, exec->globalData().getHostFunction(entry->function(), entry->generator()));
......
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