Changeset 47412 in webkit for trunk/JavaScriptCore/runtime


Ignore:
Timestamp:
Aug 17, 2009, 10:34:52 PM (16 years ago)
Author:
[email protected]
Message:

No, silly runtime, AST nodes are not for you.

Reviewed by Sam Weinig.

We still use AST nodes (ScopeNodes, particularly FunctionBodyNodes) within
the runtime, which means that these nodes must be persisted outside of the
arena, contain both parser & runtime data, etc. This is all a bit of a mess.

Move functionality into a new FunctionExecutable class.

(JSC::CodeBlock::CodeBlock):
(JSC::CodeBlock::markAggregate):
(JSC::CodeBlock::reparseForExceptionInfoIfNecessary):
(JSC::CodeBlock::lineNumberForBytecodeOffset):
(JSC::CodeBlock::shrinkToFit):

  • bytecode/CodeBlock.h:

(JSC::CodeBlock::getBytecodeIndex):
(JSC::CodeBlock::discardBytecode):
(JSC::CodeBlock::instructionCount):
(JSC::CodeBlock::getJITCode):
(JSC::CodeBlock::executablePool):
(JSC::CodeBlock::ownerExecutable):
(JSC::CodeBlock::extractExceptionInfo):
(JSC::CodeBlock::addFunctionDecl):
(JSC::CodeBlock::functionDecl):
(JSC::CodeBlock::numberOfFunctionDecls):
(JSC::CodeBlock::addFunctionExpr):
(JSC::CodeBlock::functionExpr):
(JSC::GlobalCodeBlock::GlobalCodeBlock):
(JSC::ProgramCodeBlock::ProgramCodeBlock):
(JSC::EvalCodeBlock::EvalCodeBlock):
(JSC::FunctionCodeBlock::FunctionCodeBlock):
(JSC::NativeCodeBlock::NativeCodeBlock):

  • bytecode/EvalCodeCache.h:
  • bytecode/SamplingTool.cpp:

(JSC::SamplingTool::doRun):

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::BytecodeGenerator):
(JSC::BytecodeGenerator::emitNewFunction):
(JSC::BytecodeGenerator::emitNewFunctionExpression):

  • bytecompiler/BytecodeGenerator.h:
  • debugger/Debugger.cpp:

(JSC::Debugger::recompileAllJSFunctions):

  • interpreter/CachedCall.h:

(JSC::CachedCall::CachedCall):

  • interpreter/CallFrameClosure.h:
  • interpreter/Interpreter.cpp:

(JSC::Interpreter::unwindCallFrame):
(JSC::Interpreter::throwException):
(JSC::Interpreter::execute):
(JSC::Interpreter::prepareForRepeatCall):
(JSC::Interpreter::debug):
(JSC::Interpreter::privateExecute):
(JSC::Interpreter::retrieveLastCaller):

  • interpreter/Interpreter.h:
  • jit/JIT.cpp:

(JSC::JIT::privateCompile):

  • jit/JIT.h:

(JSC::JIT::compile):

  • jit/JITOpcodes.cpp:

(JSC::JIT::privateCompileCTIMachineTrampolines):
(JSC::JIT::emit_op_new_func):
(JSC::JIT::emit_op_new_func_exp):

  • jit/JITStubs.cpp:

(JSC::DEFINE_STUB_FUNCTION):

  • jit/JITStubs.h:

(JSC::):

  • parser/Nodes.cpp:

(JSC::FunctionBodyNode::reparseDataIfNecessary):

  • parser/Nodes.h:

(JSC::EvalNode::partialDestroyData):

  • parser/Parser.h:
  • profiler/ProfileGenerator.cpp:
  • profiler/Profiler.cpp:

(JSC::Profiler::createCallIdentifier):
(JSC::createCallIdentifierFromFunctionImp):

  • runtime/Arguments.h:

(JSC::Arguments::getArgumentsData):
(JSC::Arguments::Arguments):
(JSC::JSActivation::copyRegisters):

  • runtime/ArrayPrototype.cpp:

(JSC::isNumericCompareFunction):

  • runtime/CallData.h:

(JSC::):

  • runtime/Collector.cpp:

(JSC::Heap::collect):

  • runtime/ConstructData.h:

(JSC::):

  • runtime/ExceptionHelpers.cpp:

(JSC::createUndefinedVariableError):
(JSC::createInvalidParamError):
(JSC::createNotAConstructorError):
(JSC::createNotAFunctionError):
(JSC::createNotAnObjectError):

  • runtime/Executable.cpp: Added.

(JSC::EvalExecutable::generateBytecode):
(JSC::ProgramExecutable::generateBytecode):
(JSC::FunctionExecutable::generateBytecode):
(JSC::EvalExecutable::generateJITCode):
(JSC::ProgramExecutable::generateJITCode):
(JSC::FunctionExecutable::generateJITCode):
(JSC::FunctionExecutable::isHostFunction):
(JSC::FunctionExecutable::markAggregate):
(JSC::FunctionExecutable::reparseExceptionInfo):
(JSC::EvalExecutable::reparseExceptionInfo):
(JSC::FunctionExecutable::recompile):
(JSC::FunctionExecutable::FunctionExecutable):

  • runtime/Executable.h:

(JSC::ExecutableBase::~ExecutableBase):
(JSC::ExecutableBase::ExecutableBase):
(JSC::ExecutableBase::source):
(JSC::ExecutableBase::sourceID):
(JSC::ExecutableBase::lastLine):
(JSC::ExecutableBase::usesEval):
(JSC::ExecutableBase::usesArguments):
(JSC::ExecutableBase::needsActivation):
(JSC::ExecutableBase::astNode):
(JSC::ExecutableBase::generatedJITCode):
(JSC::ExecutableBase::getExecutablePool):
(JSC::EvalExecutable::EvalExecutable):
(JSC::EvalExecutable::bytecode):
(JSC::EvalExecutable::varStack):
(JSC::EvalExecutable::evalNode):
(JSC::EvalExecutable::jitCode):
(JSC::ProgramExecutable::ProgramExecutable):
(JSC::ProgramExecutable::reparseExceptionInfo):
(JSC::ProgramExecutable::bytecode):
(JSC::ProgramExecutable::programNode):
(JSC::ProgramExecutable::jitCode):
(JSC::FunctionExecutable::FunctionExecutable):
(JSC::FunctionExecutable::name):
(JSC::FunctionExecutable::bytecode):
(JSC::FunctionExecutable::generatedBytecode):
(JSC::FunctionExecutable::usesEval):
(JSC::FunctionExecutable::usesArguments):
(JSC::FunctionExecutable::parameterCount):
(JSC::FunctionExecutable::paramString):
(JSC::FunctionExecutable::isGenerated):
(JSC::FunctionExecutable::body):
(JSC::FunctionExecutable::jitCode):
(JSC::FunctionExecutable::createNativeThunk):

  • runtime/FunctionConstructor.cpp:

(JSC::constructFunction):

  • runtime/FunctionPrototype.cpp:

(JSC::functionProtoFuncToString):

  • runtime/JSActivation.cpp:

(JSC::JSActivation::JSActivation):
(JSC::JSActivation::markChildren):
(JSC::JSActivation::isDynamicScope):
(JSC::JSActivation::argumentsGetter):

  • runtime/JSActivation.h:

(JSC::JSActivation::JSActivationData::JSActivationData):

  • runtime/JSFunction.cpp:

(JSC::JSFunction::isHostFunction):
(JSC::JSFunction::JSFunction):
(JSC::JSFunction::~JSFunction):
(JSC::JSFunction::markChildren):
(JSC::JSFunction::getCallData):
(JSC::JSFunction::call):
(JSC::JSFunction::lengthGetter):
(JSC::JSFunction::getConstructData):
(JSC::JSFunction::construct):

  • runtime/JSFunction.h:

(JSC::JSFunction::executable):
(JSC::FunctionExecutable::make):

  • runtime/JSGlobalData.cpp:

(JSC::JSGlobalData::JSGlobalData):
(JSC::JSGlobalData::numericCompareFunction):

  • runtime/JSGlobalData.h:
Location:
trunk/JavaScriptCore/runtime
Files:
1 added
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/runtime/Arguments.h

    r47404 r47412  
    117117        function = callFrame->callee();
    118118   
    119         CodeBlock* codeBlock = &function->body()->generatedBytecode();
     119        CodeBlock* codeBlock = &function->executable()->generatedBytecode();
    120120        int numParameters = codeBlock->m_numParameters;
    121121        argc = callFrame->argumentCount();
     
    140140        getArgumentsData(callFrame, callee, firstParameterIndex, argv, numArguments);
    141141
    142         d->numParameters = callee->body()->parameterCount();
     142        d->numParameters = callee->executable()->parameterCount();
    143143        d->firstParameterIndex = firstParameterIndex;
    144144        d->numArguments = numArguments;
     
    171171        , d(new ArgumentsData)
    172172    {
    173         ASSERT(!callFrame->callee()->body()->parameterCount());
     173        ASSERT(!callFrame->callee()->executable()->parameterCount());
    174174
    175175        unsigned numArguments = callFrame->argumentCount() - 1;
     
    217217        ASSERT(!d()->registerArray);
    218218
    219         size_t numParametersMinusThis = d()->functionBody->generatedBytecode().m_numParameters - 1;
    220         size_t numVars = d()->functionBody->generatedBytecode().m_numVars;
     219        size_t numParametersMinusThis = d()->functionExecutable->generatedBytecode().m_numParameters - 1;
     220        size_t numVars = d()->functionExecutable->generatedBytecode().m_numVars;
    221221        size_t numLocals = numVars + numParametersMinusThis;
    222222
  • trunk/JavaScriptCore/runtime/ArrayPrototype.cpp

    r47288 r47412  
    7676    // If the JIT is enabled then we need to preserve the invariant that every
    7777    // function with a CodeBlock also has JIT code.
    78     callData.js.functionBody->jitCode(callData.js.scopeChain);
    79     CodeBlock& codeBlock = callData.js.functionBody->generatedBytecode();
     78    callData.js.functionExecutable->jitCode(callData.js.scopeChain);
     79    CodeBlock& codeBlock = callData.js.functionExecutable->generatedBytecode();
    8080#else
    81     CodeBlock& codeBlock = callData.js.functionBody->bytecode(callData.js.scopeChain);
     81    CodeBlock& codeBlock = callData.js.functionExecutable->bytecode(callData.js.scopeChain);
    8282#endif
    8383
  • trunk/JavaScriptCore/runtime/CallData.h

    r43372 r47412  
    3636    class ArgList;
    3737    class ExecState;
    38     class FunctionBodyNode;
     38    class FunctionExecutable;
    3939    class JSObject;
    4040    class JSValue;
     
    5454        } native;
    5555        struct {
    56             FunctionBodyNode* functionBody;
     56            FunctionExecutable* functionExecutable;
    5757            ScopeChainNode* scopeChain;
    5858        } js;
  • trunk/JavaScriptCore/runtime/Collector.cpp

    r47284 r47412  
    11391139    m_globalData->interpreter->registerFile().markCallFrames(markStack, this);
    11401140    m_globalData->smallStrings.mark();
    1141     if (m_globalData->scopeNodeBeingReparsed)
    1142         m_globalData->scopeNodeBeingReparsed->markAggregate(markStack);
     1141    if (m_globalData->functionCodeBlockBeingReparsed)
     1142        m_globalData->functionCodeBlockBeingReparsed->markAggregate(markStack);
    11431143    if (m_globalData->firstStringifierToMark)
    11441144        JSONObject::markStringifiers(markStack, m_globalData->firstStringifierToMark);
  • trunk/JavaScriptCore/runtime/ConstructData.h

    r43122 r47412  
    3434    class ArgList;
    3535    class ExecState;
    36     class FunctionBodyNode;
     36    class FunctionExecutable;
    3737    class JSObject;
    3838    class JSValue;
     
    5252        } native;
    5353        struct {
    54             FunctionBodyNode* functionBody;
     54            FunctionExecutable* functionExecutable;
    5555            ScopeChainNode* scopeChain;
    5656        } js;
  • trunk/JavaScriptCore/runtime/ExceptionHelpers.cpp

    r43122 r47412  
    7575    UString message = "Can't find variable: ";
    7676    message.append(ident.ustring());
    77     JSObject* exception = Error::create(exec, ReferenceError, message, line, codeBlock->ownerNode()->sourceID(), codeBlock->ownerNode()->sourceURL());
     77    JSObject* exception = Error::create(exec, ReferenceError, message, line, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->sourceURL());
    7878    exception->putWithAttributes(exec, Identifier(exec, expressionBeginOffsetPropertyName), jsNumber(exec, divotPoint - startOffset), ReadOnly | DontDelete);
    7979    exception->putWithAttributes(exec, Identifier(exec, expressionCaretOffsetPropertyName), jsNumber(exec, divotPoint), ReadOnly | DontDelete);
     
    137137    int line = codeBlock->expressionRangeForBytecodeOffset(exec, bytecodeOffset, divotPoint, startOffset, endOffset);
    138138    UString errorMessage = createErrorMessage(exec, codeBlock, line, divotPoint, divotPoint + endOffset, value, message);
    139     JSObject* exception = Error::create(exec, TypeError, errorMessage, line, codeBlock->ownerNode()->sourceID(), codeBlock->ownerNode()->sourceURL());
     139    JSObject* exception = Error::create(exec, TypeError, errorMessage, line, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->sourceURL());
    140140    exception->putWithAttributes(exec, Identifier(exec, expressionBeginOffsetPropertyName), jsNumber(exec, divotPoint - startOffset), ReadOnly | DontDelete);
    141141    exception->putWithAttributes(exec, Identifier(exec, expressionCaretOffsetPropertyName), jsNumber(exec, divotPoint), ReadOnly | DontDelete);
     
    158158   
    159159    UString errorMessage = createErrorMessage(exec, codeBlock, line, startPoint, divotPoint, value, "not a constructor");
    160     JSObject* exception = Error::create(exec, TypeError, errorMessage, line, codeBlock->ownerNode()->sourceID(), codeBlock->ownerNode()->sourceURL());
     160    JSObject* exception = Error::create(exec, TypeError, errorMessage, line, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->sourceURL());
    161161    exception->putWithAttributes(exec, Identifier(exec, expressionBeginOffsetPropertyName), jsNumber(exec, divotPoint - startOffset), ReadOnly | DontDelete);
    162162    exception->putWithAttributes(exec, Identifier(exec, expressionCaretOffsetPropertyName), jsNumber(exec, divotPoint), ReadOnly | DontDelete);
     
    172172    int line = codeBlock->expressionRangeForBytecodeOffset(exec, bytecodeOffset, divotPoint, startOffset, endOffset);
    173173    UString errorMessage = createErrorMessage(exec, codeBlock, line, divotPoint - startOffset, divotPoint, value, "not a function");
    174     JSObject* exception = Error::create(exec, TypeError, errorMessage, line, codeBlock->ownerNode()->sourceID(), codeBlock->ownerNode()->sourceURL());   
     174    JSObject* exception = Error::create(exec, TypeError, errorMessage, line, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->sourceURL());   
    175175    exception->putWithAttributes(exec, Identifier(exec, expressionBeginOffsetPropertyName), jsNumber(exec, divotPoint - startOffset), ReadOnly | DontDelete);
    176176    exception->putWithAttributes(exec, Identifier(exec, expressionCaretOffsetPropertyName), jsNumber(exec, divotPoint), ReadOnly | DontDelete);
     
    202202    int line = codeBlock->expressionRangeForBytecodeOffset(exec, bytecodeOffset, divotPoint, startOffset, endOffset);
    203203    UString errorMessage = createErrorMessage(exec, codeBlock, line, divotPoint - startOffset, divotPoint, error->isNull() ? jsNull() : jsUndefined(), "not an object");
    204     JSObject* exception = Error::create(exec, TypeError, errorMessage, line, codeBlock->ownerNode()->sourceID(), codeBlock->ownerNode()->sourceURL());
     204    JSObject* exception = Error::create(exec, TypeError, errorMessage, line, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->sourceURL());
    205205    exception->putWithAttributes(exec, Identifier(exec, expressionBeginOffsetPropertyName), jsNumber(exec, divotPoint - startOffset), ReadOnly | DontDelete);
    206206    exception->putWithAttributes(exec, Identifier(exec, expressionCaretOffsetPropertyName), jsNumber(exec, divotPoint), ReadOnly | DontDelete);
  • trunk/JavaScriptCore/runtime/Executable.h

    r47405 r47412  
    3131namespace JSC {
    3232
    33     template<class ASTNodeType, class CodeBlockType>
    34     class TemplateExecutable {
    35     public:
    36         TemplateExecutable(const SourceCode& source)
     33    class CodeBlock;
     34    class EvalCodeBlock;
     35    class ProgramCodeBlock;
     36    class ScopeChainNode;
     37
     38    struct ExceptionInfo;
     39
     40    class ExecutableBase {
     41        friend class JIT;
     42    public:
     43        virtual ~ExecutableBase() {}
     44
     45        ExecutableBase(const SourceCode& source)
    3746            : m_source(source)
    3847        {
    3948        }
    4049
    41         void markAggregate(MarkStack& markStack)
    42         {
    43             m_node->markAggregate(markStack);
    44         }
    45 
     50        const SourceCode& source() { return m_source; }
     51        intptr_t sourceID() const { return m_node->sourceID(); }
    4652        const UString& sourceURL() const { return m_node->sourceURL(); }
    4753        int lineNo() const { return m_node->lineNo(); }
    48         CodeBlockType& bytecode(ScopeChainNode* scopeChainNode) { return m_node->bytecode(scopeChainNode); }
    49 
    50 #if ENABLE(JIT)
    51         JITCode& jitCode(ScopeChainNode* scopeChainNode) { return m_node->jitCode(scopeChainNode); }
    52 #endif
     54        int lastLine() const { return m_node->lastLine(); }
     55
     56        bool usesEval() const { return m_node->usesEval(); }
     57        bool usesArguments() const { return m_node->usesArguments(); }
     58        bool needsActivation() const { return m_node->needsActivation(); }
     59
     60        virtual ExceptionInfo* reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*) = 0;
     61
     62        ScopeNode* astNode() { return m_node.get(); }
    5363
    5464    protected:
    55         RefPtr<ASTNodeType> m_node;
     65        RefPtr<ScopeNode> m_node;
    5666        SourceCode m_source;
    57     };
    58 
    59     class EvalExecutable : public TemplateExecutable<EvalNode, EvalCodeBlock> {
     67
     68    private:
     69        // For use making native thunk.
     70        friend class FunctionExecutable;
     71        ExecutableBase()
     72        {
     73        }
     74
     75#if ENABLE(JIT)
     76    public:
     77        JITCode& generatedJITCode()
     78        {
     79            ASSERT(m_jitCode);
     80            return m_jitCode;
     81        }
     82
     83        ExecutablePool* getExecutablePool()
     84        {
     85            return m_jitCode.getExecutablePool();
     86        }
     87
     88    protected:
     89        JITCode m_jitCode;
     90#endif
     91    };
     92
     93    class EvalExecutable : public ExecutableBase {
    6094    public:
    6195        EvalExecutable(const SourceCode& source)
    62             : TemplateExecutable<EvalNode, EvalCodeBlock>(source)
    63         {
    64         }
     96            : ExecutableBase(source)
     97            , m_evalCodeBlock(0)
     98        {
     99        }
     100
     101        ~EvalExecutable();
    65102
    66103        JSObject* parse(ExecState* exec, bool allowDebug = true);
     104
     105        EvalCodeBlock& bytecode(ScopeChainNode* scopeChainNode)
     106        {
     107            if (!m_evalCodeBlock)
     108                generateBytecode(scopeChainNode);
     109            return *m_evalCodeBlock;
     110        }
     111
     112        DeclarationStacks::VarStack& varStack() { return m_node->varStack(); }
     113
     114        ExceptionInfo* reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*);
     115
     116    private:
     117        EvalNode* evalNode() { return static_cast<EvalNode*>(m_node.get()); }
     118
     119        void generateBytecode(ScopeChainNode*);
     120
     121        EvalCodeBlock* m_evalCodeBlock;
     122
     123#if ENABLE(JIT)
     124    public:
     125        JITCode& jitCode(ScopeChainNode* scopeChainNode)
     126        {
     127            if (!m_jitCode)
     128                generateJITCode(scopeChainNode);
     129            return m_jitCode;
     130        }
     131
     132    private:
     133        void generateJITCode(ScopeChainNode*);
     134#endif
    67135    };
    68136
     
    78146    };
    79147
    80     class ProgramExecutable : public TemplateExecutable<ProgramNode, ProgramCodeBlock> {
     148    class ProgramExecutable : public ExecutableBase {
    81149    public:
    82150        ProgramExecutable(const SourceCode& source)
    83             : TemplateExecutable<ProgramNode, ProgramCodeBlock>(source)
    84         {
    85         }
     151            : ExecutableBase(source)
     152            , m_programCodeBlock(0)
     153        {
     154        }
     155       
     156        ~ProgramExecutable();
    86157
    87158        JSObject* parse(ExecState* exec, bool allowDebug = true);
     159
     160        // CodeBlocks for program code are transient and therefore to not gain from from throwing out there exception information.
     161        ExceptionInfo* reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*) { ASSERT_NOT_REACHED(); return 0; }
     162
     163        ProgramCodeBlock& bytecode(ScopeChainNode* scopeChainNode)
     164        {
     165            if (!m_programCodeBlock)
     166                generateBytecode(scopeChainNode);
     167            return *m_programCodeBlock;
     168        }
     169
     170    private:
     171        ProgramNode* programNode() { return static_cast<ProgramNode*>(m_node.get()); }
     172
     173        void generateBytecode(ScopeChainNode*);
     174
     175        ProgramCodeBlock* m_programCodeBlock;
     176
     177#if ENABLE(JIT)
     178    public:
     179        JITCode& jitCode(ScopeChainNode* scopeChainNode)
     180        {
     181            if (!m_jitCode)
     182                generateJITCode(scopeChainNode);
     183            return m_jitCode;
     184        }
     185
     186    private:
     187        void generateJITCode(ScopeChainNode*);
     188#endif
     189    };
     190
     191    class FunctionExecutable : public ExecutableBase, public RefCounted<FunctionExecutable> {
     192        friend class JIT;
     193    public:
     194        FunctionExecutable(const Identifier& name, FunctionBodyNode* body)
     195            : ExecutableBase(body->source())
     196            , m_codeBlock(0)
     197            , m_name(name)
     198        {
     199            m_node = body;
     200        }
     201
     202        ~FunctionExecutable();
     203
     204        const Identifier& name() { return m_name; }
     205
     206        JSFunction* make(ExecState* exec, ScopeChainNode* scopeChain);
     207
     208        CodeBlock& bytecode(ScopeChainNode* scopeChainNode)
     209        {
     210            ASSERT(scopeChainNode);
     211            if (!m_codeBlock)
     212                generateBytecode(scopeChainNode);
     213            return *m_codeBlock;
     214        }
     215        CodeBlock& generatedBytecode()
     216        {
     217            ASSERT(m_codeBlock);
     218            return *m_codeBlock;
     219        }
     220
     221        bool usesEval() const { return body()->usesEval(); }
     222        bool usesArguments() const { return body()->usesArguments(); }
     223        size_t parameterCount() const { return body()->parameterCount(); }
     224        UString paramString() const { return body()->paramString(); }
     225
     226        bool isHostFunction() const;
     227        bool isGenerated() const
     228        {
     229            return m_codeBlock;
     230        }
     231
     232        void recompile(ExecState* exec);
     233
     234        ExceptionInfo* reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*);
     235
     236        void markAggregate(MarkStack& markStack);
     237
     238    private:
     239        FunctionBodyNode* body() const { return static_cast<FunctionBodyNode*>(m_node.get()); }
     240
     241        void generateBytecode(ScopeChainNode*);
     242
     243        CodeBlock* m_codeBlock;
     244        const Identifier& m_name;
     245
     246#if ENABLE(JIT)
     247    public:
     248        JITCode& jitCode(ScopeChainNode* scopeChainNode)
     249        {
     250            if (!m_jitCode)
     251                generateJITCode(scopeChainNode);
     252            return m_jitCode;
     253        }
     254
     255        static PassRefPtr<FunctionExecutable> createNativeThunk(ExecState* exec)
     256        {
     257            return adoptRef(new FunctionExecutable(exec));
     258        }
     259
     260    private:
     261        FunctionExecutable(ExecState* exec);
     262        void generateJITCode(ScopeChainNode*);
     263#endif
    88264    };
    89265
  • trunk/JavaScriptCore/runtime/FunctionConstructor.cpp

    r47304 r47412  
    9494    JSGlobalObject* globalObject = exec->lexicalGlobalObject();
    9595    ScopeChain scopeChain(globalObject, globalObject->globalData(), exec->globalThisValue());
    96     return new (exec) JSFunction(exec, functionName, body.get(), scopeChain.node());
     96    return new (exec) JSFunction(exec, adoptRef(new FunctionExecutable(functionName, body.get())), scopeChain.node());
    9797}
    9898
  • trunk/JavaScriptCore/runtime/FunctionPrototype.cpp

    r47288 r47412  
    8787    if (thisValue.inherits(&JSFunction::info)) {
    8888        JSFunction* function = asFunction(thisValue);
    89         FunctionBodyNode* body = function->body();
    90         if (!body->isHostFunction()) {
    91             UString bodySourceString = body->toSourceString();
    92             insertSemicolonIfNeeded(bodySourceString);
    93             return jsString(exec, "function " + function->name(&exec->globalData()) + "(" + body->paramString() + ") " + bodySourceString);
     89        FunctionExecutable* executable = function->executable();
     90        if (!executable->isHostFunction()) {
     91            UString sourceString = executable->source().toString();
     92            insertSemicolonIfNeeded(sourceString);
     93            return jsString(exec, "function " + function->name(&exec->globalData()) + "(" + executable->paramString() + ") " + sourceString);
    9494        }
    9595    }
  • trunk/JavaScriptCore/runtime/JSActivation.cpp

    r47288 r47412  
    4040const ClassInfo JSActivation::info = { "JSActivation", 0, 0, 0 };
    4141
    42 JSActivation::JSActivation(CallFrame* callFrame, PassRefPtr<FunctionBodyNode> functionBody)
    43     : Base(callFrame->globalData().activationStructure, new JSActivationData(functionBody, callFrame->registers()))
     42JSActivation::JSActivation(CallFrame* callFrame, PassRefPtr<FunctionExecutable> functionExecutable)
     43    : Base(callFrame->globalData().activationStructure, new JSActivationData(functionExecutable, callFrame->registers()))
    4444{
    4545}
     
    5858        return;
    5959
    60     size_t numParametersMinusThis = d()->functionBody->generatedBytecode().m_numParameters - 1;
     60    size_t numParametersMinusThis = d()->functionExecutable->generatedBytecode().m_numParameters - 1;
    6161
    6262    size_t count = numParametersMinusThis;
    6363    markStack.appendValues(registerArray, count);
    6464
    65     size_t numVars = d()->functionBody->generatedBytecode().m_numVars;
     65    size_t numVars = d()->functionExecutable->generatedBytecode().m_numVars;
    6666
    6767    // Skip the call frame, which sits between the parameters and vars.
     
    137137bool JSActivation::isDynamicScope() const
    138138{
    139     return d()->functionBody->usesEval();
     139    return d()->functionExecutable->usesEval();
    140140}
    141141
     
    144144    JSActivation* activation = asActivation(slot.slotBase());
    145145
    146     if (activation->d()->functionBody->usesArguments()) {
     146    if (activation->d()->functionExecutable->usesArguments()) {
    147147        PropertySlot slot;
    148148        activation->symbolTableGet(exec->propertyNames().arguments, slot);
  • trunk/JavaScriptCore/runtime/JSActivation.h

    r47022 r47412  
    4444        typedef JSVariableObject Base;
    4545    public:
    46         JSActivation(CallFrame*, PassRefPtr<FunctionBodyNode>);
     46        JSActivation(CallFrame*, PassRefPtr<FunctionExecutable>);
    4747        virtual ~JSActivation();
    4848
     
    7171    private:
    7272        struct JSActivationData : public JSVariableObjectData {
    73             JSActivationData(PassRefPtr<FunctionBodyNode> functionBody, Register* registers)
    74                 : JSVariableObjectData(&functionBody->generatedBytecode().symbolTable(), registers)
    75                 , functionBody(functionBody)
     73            JSActivationData(PassRefPtr<FunctionExecutable> functionExecutable, Register* registers)
     74                : JSVariableObjectData(&functionExecutable->generatedBytecode().symbolTable(), registers)
     75                , functionExecutable(functionExecutable)
    7676            {
    7777            }
    7878
    79             RefPtr<FunctionBodyNode> functionBody;
     79            RefPtr<FunctionExecutable> functionExecutable;
    8080        };
    8181       
  • trunk/JavaScriptCore/runtime/JSFunction.cpp

    r47236 r47412  
    4848inline bool JSFunction::isHostFunction() const
    4949{
    50     return m_body && m_body->isHostFunction();
     50    return m_executable && m_executable->isHostFunction();
    5151}
    5252
     
    6565    : Base(&exec->globalData(), structure, name)
    6666#if ENABLE(JIT)
    67     , m_body(FunctionBodyNode::createNativeThunk(&exec->globalData()))
     67    , m_executable(FunctionExecutable::createNativeThunk(exec))
    6868#endif
    6969{
     
    7878}
    7979
    80 JSFunction::JSFunction(ExecState* exec, const Identifier& name, PassRefPtr<FunctionBodyNode> body, ScopeChainNode* scopeChainNode)
    81     : Base(&exec->globalData(), exec->lexicalGlobalObject()->functionStructure(), name)
    82     , m_body(body)
     80JSFunction::JSFunction(ExecState* exec, PassRefPtr<FunctionExecutable> executable, ScopeChainNode* scopeChainNode)
     81    : Base(&exec->globalData(), exec->lexicalGlobalObject()->functionStructure(), executable->name())
     82    , m_executable(executable)
    8383{
    8484    setScopeChain(scopeChainNode);
     
    9191    // this memory is freed and may be reused (potentially for another, different JSFunction).
    9292#if ENABLE(JIT_OPTIMIZE_CALL)
    93     if (m_body && m_body->isGenerated())
    94         m_body->generatedBytecode().unlinkCallers();
     93    if (m_executable && m_executable->isGenerated())
     94        m_executable->generatedBytecode().unlinkCallers();
    9595#endif
    9696    if (!isHostFunction())
     
    101101{
    102102    Base::markChildren(markStack);
    103     m_body->markAggregate(markStack);
     103    m_executable->markAggregate(markStack);
    104104    if (!isHostFunction())
    105105        scopeChain().markAggregate(markStack);
     
    112112        return CallTypeHost;
    113113    }
    114     callData.js.functionBody = m_body.get();
     114    callData.js.functionExecutable = m_executable.get();
    115115    callData.js.scopeChain = scopeChain().node();
    116116    return CallTypeJS;
     
    120120{
    121121    ASSERT(!isHostFunction());
    122     return exec->interpreter()->execute(m_body.get(), exec, this, thisValue.toThisObject(exec), args, scopeChain().node(), exec->exceptionSlot());
     122    return exec->interpreter()->execute(m_executable.get(), exec, this, thisValue.toThisObject(exec), args, scopeChain().node(), exec->exceptionSlot());
    123123}
    124124
     
    141141    JSFunction* thisObj = asFunction(slot.slotBase());
    142142    ASSERT(!thisObj->isHostFunction());
    143     return jsNumber(exec, thisObj->m_body->parameterCount());
     143    return jsNumber(exec, thisObj->m_executable->parameterCount());
    144144}
    145145
     
    205205    if (isHostFunction())
    206206        return ConstructTypeNone;
    207     constructData.js.functionBody = m_body.get();
     207    constructData.js.functionExecutable = m_executable.get();
    208208    constructData.js.scopeChain = scopeChain().node();
    209209    return ConstructTypeJS;
     
    221221    JSObject* thisObj = new (exec) JSObject(structure);
    222222
    223     JSValue result = exec->interpreter()->execute(m_body.get(), exec, this, thisObj, args, scopeChain().node(), exec->exceptionSlot());
     223    JSValue result = exec->interpreter()->execute(m_executable.get(), exec, this, thisObj, args, scopeChain().node(), exec->exceptionSlot());
    224224    if (exec->hadException() || !result.isObject())
    225225        return thisObj;
     
    227227}
    228228
    229 void JSFunction::setBody(PassRefPtr<FunctionBodyNode> body)
    230 {
    231     m_body = body;
    232 }
    233 
    234229} // namespace JSC
  • trunk/JavaScriptCore/runtime/JSFunction.h

    r47236 r47412  
    2525#define JSFunction_h
    2626
     27#include "Executable.h"
    2728#include "InternalFunction.h"
    2829
    2930namespace JSC {
    3031
    31     class FunctionBodyNode;
    3232    class FunctionPrototype;
    3333    class JSActivation;
     
    4242    public:
    4343        JSFunction(ExecState*, PassRefPtr<Structure>, int length, const Identifier&, NativeFunction);
    44         JSFunction(ExecState*, const Identifier&, PassRefPtr<FunctionBodyNode>, ScopeChainNode*);
     44        JSFunction(ExecState*, PassRefPtr<FunctionExecutable>, ScopeChainNode*);
    4545        virtual ~JSFunction();
    4646
     
    5151        ScopeChain& scope() { return scopeChain(); }
    5252
    53         void setBody(PassRefPtr<FunctionBodyNode>);
    54         FunctionBodyNode* body() const { return m_body.get(); }
     53        FunctionExecutable* executable() const { return m_executable.get(); }
    5554
    5655        static JS_EXPORTDATA const ClassInfo info;
     
    8786        static JSValue lengthGetter(ExecState*, const Identifier&, const PropertySlot&);
    8887
    89         RefPtr<FunctionBodyNode> m_body;
     88        RefPtr<FunctionExecutable> m_executable;
    9089        ScopeChain& scopeChain()
    9190        {
     
    123122    }
    124123
     124    inline JSFunction* FunctionExecutable::make(ExecState* exec, ScopeChainNode* scopeChain)
     125    {
     126        return new (exec) JSFunction(exec, this, scopeChain);
     127    }
     128
    125129} // namespace JSC
    126130
  • trunk/JavaScriptCore/runtime/JSGlobalData.cpp

    r47304 r47412  
    145145    , head(0)
    146146    , dynamicGlobalObject(0)
    147     , scopeNodeBeingReparsed(0)
     147    , functionCodeBlockBeingReparsed(0)
    148148    , firstStringifierToMark(0)
    149149    , markStack(vptrSet.jsArrayVPtr)
     
    238238        initializingLazyNumericCompareFunction = true;
    239239        RefPtr<FunctionBodyNode> functionBody = parser->parseFunctionFromGlobalCode(exec, 0, makeSource(UString("(function (v1, v2) { return v1 - v2; })")), 0, 0);
    240         lazyNumericCompareFunction = functionBody->bytecode(exec->scopeChain()).instructions();
     240        FunctionExecutable function(functionBody->ident(), functionBody.get());
     241        lazyNumericCompareFunction = function.bytecode(exec->scopeChain()).instructions();
    241242        initializingLazyNumericCompareFunction = false;
    242243    }
  • trunk/JavaScriptCore/runtime/JSGlobalData.h

    r47022 r47412  
    4646namespace JSC {
    4747
     48    class CodeBlock;
    4849    class CommonIdentifiers;
    49     class FunctionBodyNode;
    5050    class IdentifierTable;
    5151    class Interpreter;
     
    5454    class Lexer;
    5555    class Parser;
    56     class ScopeNode;
    5756    class Stringifier;
    5857    class Structure;
     
    146145        HashSet<JSObject*> arrayVisitedElements;
    147146
    148         ScopeNode* scopeNodeBeingReparsed;
     147        CodeBlock* functionCodeBlockBeingReparsed;
    149148        Stringifier* firstStringifierToMark;
    150149
Note: See TracChangeset for help on using the changeset viewer.