Changeset 47738 in webkit


Ignore:
Timestamp:
Aug 24, 2009 7:53:51 PM (15 years ago)
Author:
barraclough@apple.com
Message:

https://bugs.webkit.org/show_bug.cgi?id=28691
Do not retain ScopeNodes outside of parsing

Reviewed by Oliver Adler & Darin Hunt.

There is now no need for these to exist outside of parsing - their use in the runtime is replaced by Executable types.

  • bytecode/EvalCodeCache.h:

(JSC::EvalCodeCache::get):

  • bytecompiler/BytecodeGenerator.cpp:

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

  • bytecompiler/BytecodeGenerator.h:

(JSC::BytecodeGenerator::makeFunction):

  • debugger/Debugger.cpp:

(JSC::Debugger::recompileAllJSFunctions):
(JSC::evaluateInGlobalCallFrame):

  • debugger/DebuggerCallFrame.cpp:

(JSC::DebuggerCallFrame::evaluate):

  • interpreter/Interpreter.cpp:

(JSC::Interpreter::execute):
(JSC::Interpreter::prepareForRepeatCall):
(JSC::Interpreter::privateExecute):

  • jit/JITStubs.cpp:

(JSC::DEFINE_STUB_FUNCTION):

  • parser/Nodes.cpp:

(JSC::ScopeNodeData::ScopeNodeData):
(JSC::ProgramNode::create):
(JSC::EvalNode::create):
(JSC::FunctionBodyNode::create):

  • parser/Nodes.h:

(JSC::ScopeNode::adoptData):
(JSC::FunctionBodyNode::parameterCount):

  • parser/Parser.cpp:
  • parser/Parser.h:

(JSC::Parser::arena):
(JSC::Parser::Parser):
(JSC::Parser::parse):

  • runtime/ArrayPrototype.cpp:

(JSC::isNumericCompareFunction):
(JSC::arrayProtoFuncSort):

  • runtime/Completion.cpp:

(JSC::checkSyntax):
(JSC::evaluate):

  • runtime/Executable.cpp:

(JSC::FunctionExecutable::~FunctionExecutable):
(JSC::EvalExecutable::compile):
(JSC::ProgramExecutable::checkSyntax):
(JSC::ProgramExecutable::compile):
(JSC::FunctionExecutable::compile):
(JSC::EvalExecutable::generateJITCode):
(JSC::ProgramExecutable::generateJITCode):
(JSC::FunctionExecutable::generateJITCode):
(JSC::FunctionExecutable::reparseExceptionInfo):
(JSC::EvalExecutable::reparseExceptionInfo):
(JSC::FunctionExecutable::recompile):
(JSC::FunctionExecutable::fromGlobalCode):
(JSC::FunctionExecutable::copyParameters):
(JSC::FunctionExecutable::paramString):

  • runtime/Executable.h:

(JSC::ScriptExecutable::ScriptExecutable):
(JSC::ScriptExecutable::sourceID):
(JSC::ScriptExecutable::sourceURL):
(JSC::ScriptExecutable::lineNo):
(JSC::ScriptExecutable::lastLine):
(JSC::ScriptExecutable::usesEval):
(JSC::ScriptExecutable::usesArguments):
(JSC::ScriptExecutable::needsActivation):
(JSC::ScriptExecutable::recordParse):
(JSC::EvalExecutable::bytecode):
(JSC::EvalExecutable::jitCode):
(JSC::ProgramExecutable::bytecode):
(JSC::ProgramExecutable::reparseExceptionInfo):
(JSC::ProgramExecutable::jitCode):
(JSC::FunctionExecutable::FunctionExecutable):
(JSC::FunctionExecutable::make):
(JSC::FunctionExecutable::bytecode):
(JSC::FunctionExecutable::isGenerated):
(JSC::FunctionExecutable::name):
(JSC::FunctionExecutable::parameterCount):
(JSC::FunctionExecutable::jitCode):

  • runtime/FunctionConstructor.cpp:

(JSC::constructFunction):

  • runtime/JSGlobalData.cpp:

(JSC::JSGlobalData::numericCompareFunction):

  • runtime/JSGlobalObjectFunctions.cpp:

(JSC::globalFuncEval):

Location:
trunk/JavaScriptCore
Files:
19 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r47730 r47738  
     12009-08-24  Gavin Barraclough  <barraclough@apple.com>
     2
     3        Reviewed by Oliver Adler & Darin Hunt.
     4
     5        https://bugs.webkit.org/show_bug.cgi?id=28691
     6        Do not retain ScopeNodes outside of parsing
     7       
     8        There is now no need for these to exist outside of parsing - their use in the runtime is replaced by Executable types.
     9
     10        * bytecode/EvalCodeCache.h:
     11        (JSC::EvalCodeCache::get):
     12        * bytecompiler/BytecodeGenerator.cpp:
     13        (JSC::BytecodeGenerator::BytecodeGenerator):
     14        (JSC::BytecodeGenerator::emitNewFunction):
     15        (JSC::BytecodeGenerator::emitNewFunctionExpression):
     16        * bytecompiler/BytecodeGenerator.h:
     17        (JSC::BytecodeGenerator::makeFunction):
     18        * debugger/Debugger.cpp:
     19        (JSC::Debugger::recompileAllJSFunctions):
     20        (JSC::evaluateInGlobalCallFrame):
     21        * debugger/DebuggerCallFrame.cpp:
     22        (JSC::DebuggerCallFrame::evaluate):
     23        * interpreter/Interpreter.cpp:
     24        (JSC::Interpreter::execute):
     25        (JSC::Interpreter::prepareForRepeatCall):
     26        (JSC::Interpreter::privateExecute):
     27        * jit/JITStubs.cpp:
     28        (JSC::DEFINE_STUB_FUNCTION):
     29        * parser/Nodes.cpp:
     30        (JSC::ScopeNodeData::ScopeNodeData):
     31        (JSC::ProgramNode::create):
     32        (JSC::EvalNode::create):
     33        (JSC::FunctionBodyNode::create):
     34        * parser/Nodes.h:
     35        (JSC::ScopeNode::adoptData):
     36        (JSC::FunctionBodyNode::parameterCount):
     37        * parser/Parser.cpp:
     38        * parser/Parser.h:
     39        (JSC::Parser::arena):
     40        (JSC::Parser::Parser):
     41        (JSC::Parser::parse):
     42        * runtime/ArrayPrototype.cpp:
     43        (JSC::isNumericCompareFunction):
     44        (JSC::arrayProtoFuncSort):
     45        * runtime/Completion.cpp:
     46        (JSC::checkSyntax):
     47        (JSC::evaluate):
     48        * runtime/Executable.cpp:
     49        (JSC::FunctionExecutable::~FunctionExecutable):
     50        (JSC::EvalExecutable::compile):
     51        (JSC::ProgramExecutable::checkSyntax):
     52        (JSC::ProgramExecutable::compile):
     53        (JSC::FunctionExecutable::compile):
     54        (JSC::EvalExecutable::generateJITCode):
     55        (JSC::ProgramExecutable::generateJITCode):
     56        (JSC::FunctionExecutable::generateJITCode):
     57        (JSC::FunctionExecutable::reparseExceptionInfo):
     58        (JSC::EvalExecutable::reparseExceptionInfo):
     59        (JSC::FunctionExecutable::recompile):
     60        (JSC::FunctionExecutable::fromGlobalCode):
     61        (JSC::FunctionExecutable::copyParameters):
     62        (JSC::FunctionExecutable::paramString):
     63        * runtime/Executable.h:
     64        (JSC::ScriptExecutable::ScriptExecutable):
     65        (JSC::ScriptExecutable::sourceID):
     66        (JSC::ScriptExecutable::sourceURL):
     67        (JSC::ScriptExecutable::lineNo):
     68        (JSC::ScriptExecutable::lastLine):
     69        (JSC::ScriptExecutable::usesEval):
     70        (JSC::ScriptExecutable::usesArguments):
     71        (JSC::ScriptExecutable::needsActivation):
     72        (JSC::ScriptExecutable::recordParse):
     73        (JSC::EvalExecutable::bytecode):
     74        (JSC::EvalExecutable::jitCode):
     75        (JSC::ProgramExecutable::bytecode):
     76        (JSC::ProgramExecutable::reparseExceptionInfo):
     77        (JSC::ProgramExecutable::jitCode):
     78        (JSC::FunctionExecutable::FunctionExecutable):
     79        (JSC::FunctionExecutable::make):
     80        (JSC::FunctionExecutable::bytecode):
     81        (JSC::FunctionExecutable::isGenerated):
     82        (JSC::FunctionExecutable::name):
     83        (JSC::FunctionExecutable::parameterCount):
     84        (JSC::FunctionExecutable::jitCode):
     85        * runtime/FunctionConstructor.cpp:
     86        (JSC::constructFunction):
     87        * runtime/JSGlobalData.cpp:
     88        (JSC::JSGlobalData::numericCompareFunction):
     89        * runtime/JSGlobalObjectFunctions.cpp:
     90        (JSC::globalFuncEval):
     91
    1922009-08-24  Darin Adler  <darin@apple.com>
    293
  • trunk/JavaScriptCore/bytecode/EvalCodeCache.h

    r47641 r47738  
    5252            if (!evalExecutable) {
    5353                evalExecutable = EvalExecutable::create(makeSource(evalSource));
    54                 exceptionValue = evalExecutable->parse(exec);
     54                exceptionValue = evalExecutable->compile(exec, scopeChain);
    5555                if (exceptionValue)
    5656                    return 0;
  • trunk/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp

    r47664 r47738  
    274274        for (size_t i = 0; i < functionStack.size(); ++i) {
    275275            FunctionBodyNode* function = functionStack[i];
    276             globalObject->putWithAttributes(exec, function->ident(), new (exec) JSFunction(exec, adoptRef(new FunctionExecutable(function->ident(), function)), scopeChain.node()), DontDelete);
     276            globalObject->putWithAttributes(exec, function->ident(), new (exec) JSFunction(exec, makeFunction(function), scopeChain.node()), DontDelete);
    277277        }
    278278        for (size_t i = 0; i < varStack.size(); ++i) {
     
    399399
    400400    const DeclarationStacks::FunctionStack& functionStack = evalNode->functionStack();
    401     for (size_t i = 0; i < functionStack.size(); ++i) {
    402         FunctionBodyNode* function = functionStack[i];
    403         m_codeBlock->addFunctionDecl(adoptRef(new FunctionExecutable(function->ident(), function)));
    404     }
     401    for (size_t i = 0; i < functionStack.size(); ++i)
     402        m_codeBlock->addFunctionDecl(makeFunction(functionStack[i]));
    405403
    406404    const DeclarationStacks::VarStack& varStack = evalNode->varStack();
     
    13191317RegisterID* BytecodeGenerator::emitNewFunction(RegisterID* dst, FunctionBodyNode* function)
    13201318{
    1321     unsigned index = m_codeBlock->addFunctionDecl(adoptRef(new FunctionExecutable(function->ident(), function)));
     1319    unsigned index = m_codeBlock->addFunctionDecl(makeFunction(function));
    13221320
    13231321    emitOpcode(op_new_func);
     
    13391337{
    13401338    FunctionBodyNode* function = n->body();
    1341     unsigned index = m_codeBlock->addFunctionExpr(adoptRef(new FunctionExecutable(function->ident(), function)));
     1339    unsigned index = m_codeBlock->addFunctionExpr(makeFunction(function));
    13421340
    13431341    emitOpcode(op_new_func_exp);
  • trunk/JavaScriptCore/bytecompiler/BytecodeGenerator.h

    r47412 r47738  
    418418        unsigned addRegExp(RegExp*);
    419419
     420        PassRefPtr<FunctionExecutable> makeFunction(FunctionBodyNode* body)
     421        {
     422            return adoptRef(new FunctionExecutable(body->ident(), body->source(), body->usesArguments(), body->copyParameters(), body->parameterCount(), body->lineNo(), body->lastLine()));
     423        }
     424
    420425        Vector<Instruction>& instructions() { return m_codeBlock->instructions(); }
    421426        SymbolTable& symbolTable() { return *m_symbolTable; }
  • trunk/JavaScriptCore/debugger/Debugger.cpp

    r47641 r47738  
    9090    }
    9191
    92 
    9392    // Call sourceParsed() after reparsing all functions because it will execute
    9493    // JavaScript in the inspector.
     
    103102
    104103    EvalExecutable eval(makeSource(script));
    105     JSObject* error = eval.parse(globalCallFrame);
     104    JSObject* error = eval.compile(globalCallFrame, globalCallFrame->scopeChain());
    106105    if (error)
    107106        return error;
  • trunk/JavaScriptCore/debugger/DebuggerCallFrame.cpp

    r47304 r47738  
    8181
    8282    EvalExecutable eval(makeSource(script));
    83     JSObject* error = eval.parse(m_callFrame);
     83    JSObject* error = eval.compile(m_callFrame, m_callFrame->scopeChain());
    8484    if (error)
    8585        return error;
  • trunk/JavaScriptCore/interpreter/Interpreter.cpp

    r47641 r47738  
    621621    }
    622622
    623     CodeBlock* codeBlock = &program->bytecode(scopeChain);
     623    CodeBlock* codeBlock = &program->bytecode(callFrame, scopeChain);
    624624
    625625    Register* oldEnd = m_registerFile.end();
     
    653653        m_reentryDepth++;
    654654#if ENABLE(JIT)
    655         result = program->jitCode(scopeChain).execute(&m_registerFile, newCallFrame, scopeChain->globalData, exception);
     655        result = program->jitCode(newCallFrame, scopeChain).execute(&m_registerFile, newCallFrame, scopeChain->globalData, exception);
    656656#else
    657657        result = privateExecute(Normal, &m_registerFile, newCallFrame, exception);
     
    699699        newCallFrame->r(++dst) = *it;
    700700
    701     CodeBlock* codeBlock = &functionExecutable->bytecode(scopeChain);
     701    CodeBlock* codeBlock = &functionExecutable->bytecode(callFrame, scopeChain);
    702702    newCallFrame = slideRegisterWindowForCall(codeBlock, &m_registerFile, newCallFrame, argc + RegisterFile::CallFrameHeaderSize, argc);
    703703    if (UNLIKELY(!newCallFrame)) {
     
    719719        m_reentryDepth++;
    720720#if ENABLE(JIT)
    721         result = functionExecutable->jitCode(scopeChain).execute(&m_registerFile, newCallFrame, scopeChain->globalData, exception);
     721        result = functionExecutable->jitCode(newCallFrame, scopeChain).execute(&m_registerFile, newCallFrame, scopeChain->globalData, exception);
    722722#else
    723723        result = privateExecute(Normal, &m_registerFile, newCallFrame, exception);
     
    757757        newCallFrame->r(++dst) = jsUndefined();
    758758   
    759     CodeBlock* codeBlock = &FunctionExecutable->bytecode(scopeChain);
     759    CodeBlock* codeBlock = &FunctionExecutable->bytecode(callFrame, scopeChain);
    760760    newCallFrame = slideRegisterWindowForCall(codeBlock, &m_registerFile, newCallFrame, argc + RegisterFile::CallFrameHeaderSize, argc);
    761761    if (UNLIKELY(!newCallFrame)) {
     
    767767    newCallFrame->init(codeBlock, 0, scopeChain, callFrame->addHostCallFrameFlag(), 0, argc, function);
    768768#if ENABLE(JIT)
    769     FunctionExecutable->jitCode(scopeChain);
     769    FunctionExecutable->jitCode(newCallFrame, scopeChain);
    770770#endif
    771771
     
    806806JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSObject* thisObj, ScopeChainNode* scopeChain, JSValue* exception)
    807807{
    808     return execute(eval, callFrame, thisObj, m_registerFile.size() + eval->bytecode(scopeChain).m_numParameters + RegisterFile::CallFrameHeaderSize, scopeChain, exception);
     808    return execute(eval, callFrame, thisObj, m_registerFile.size() + eval->bytecode(callFrame, scopeChain).m_numParameters + RegisterFile::CallFrameHeaderSize, scopeChain, exception);
    809809}
    810810
     
    822822    DynamicGlobalObjectScope globalObjectScope(callFrame, callFrame->globalData().dynamicGlobalObject ? callFrame->globalData().dynamicGlobalObject : scopeChain->globalObject());
    823823
    824     EvalCodeBlock* codeBlock = &eval->bytecode(scopeChain);
     824    EvalCodeBlock* codeBlock = &eval->bytecode(callFrame, scopeChain);
    825825
    826826    JSVariableObject* variableObject;
     
    881881        m_reentryDepth++;
    882882#if ENABLE(JIT)
    883         result = eval->jitCode(scopeChain).execute(&m_registerFile, newCallFrame, scopeChain->globalData, exception);
     883        result = eval->jitCode(newCallFrame, scopeChain).execute(&m_registerFile, newCallFrame, scopeChain->globalData, exception);
    884884#else
    885885        result = privateExecute(Normal, &m_registerFile, newCallFrame, exception);
     
    30173017        if (callType == CallTypeJS) {
    30183018            ScopeChainNode* callDataScopeChain = callData.js.scopeChain;
    3019             CodeBlock* newCodeBlock = &callData.js.functionExecutable->bytecode(callDataScopeChain);
     3019            CodeBlock* newCodeBlock = &callData.js.functionExecutable->bytecode(callFrame, callDataScopeChain);
    30203020
    30213021            CallFrame* previousCallFrame = callFrame;
     
    31713171        if (callType == CallTypeJS) {
    31723172            ScopeChainNode* callDataScopeChain = callData.js.scopeChain;
    3173             CodeBlock* newCodeBlock = &callData.js.functionExecutable->bytecode(callDataScopeChain);
     3173            CodeBlock* newCodeBlock = &callData.js.functionExecutable->bytecode(callFrame, callDataScopeChain);
    31743174           
    31753175            CallFrame* previousCallFrame = callFrame;
     
    34193419        if (constructType == ConstructTypeJS) {
    34203420            ScopeChainNode* callDataScopeChain = constructData.js.scopeChain;
    3421             CodeBlock* newCodeBlock = &constructData.js.functionExecutable->bytecode(callDataScopeChain);
     3421            CodeBlock* newCodeBlock = &constructData.js.functionExecutable->bytecode(callFrame, callDataScopeChain);
    34223422
    34233423            Structure* structure;
  • trunk/JavaScriptCore/jit/JITStubs.cpp

    r47641 r47738  
    14841484    FunctionExecutable* executable = function->jsExecutable();
    14851485    ScopeChainNode* callDataScopeChain = function->scope().node();
    1486     executable->jitCode(callDataScopeChain);
     1486    executable->jitCode(stackFrame.callFrame, callDataScopeChain);
    14871487
    14881488    return function;
     
    15461546    CodeBlock* codeBlock = 0;
    15471547    if (!executable->isHostFunction())
    1548         codeBlock = &static_cast<FunctionExecutable*>(executable)->bytecode(callee->scope().node());
     1548        codeBlock = &static_cast<FunctionExecutable*>(executable)->bytecode(stackFrame.callFrame, callee->scope().node());
    15491549    CallLinkInfo* callLinkInfo = &stackFrame.callFrame->callerFrame()->codeBlock()->getCallLinkInfo(stackFrame.args[1].returnAddress());
    15501550
  • trunk/JavaScriptCore/parser/Nodes.cpp

    r47667 r47738  
    20372037}
    20382038
    2039 void FunctionBodyNode::reparseDataIfNecessary(ScopeChainNode* scopeChainNode)
    2040 {
    2041     // This branch is only necessary since you can still create a non-stub FunctionBodyNode by
    2042     // calling Parser::parse<FunctionBodyNode>().   
    2043     if (!data())
    2044         scopeChainNode->globalData->parser->reparseInPlace(scopeChainNode->globalData, this);
    2045     ASSERT(data());
    2046 }
    2047 
    20482039RegisterID* FunctionBodyNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
    20492040{
     
    20632054}
    20642055
    2065 UString FunctionBodyNode::paramString() const
    2066 {
    2067     UString s("");
    2068     for (size_t pos = 0; pos < m_parameterCount; ++pos) {
    2069         if (!s.isEmpty())
    2070             s += ", ";
    2071         s += parameters()[pos].ustring();
    2072     }
    2073 
    2074     return s;
    2075 }
    2076 
    20772056Identifier* FunctionBodyNode::copyParameters()
    20782057{
  • trunk/JavaScriptCore/parser/Nodes.h

    r47668 r47738  
    14261426        static PassRefPtr<ProgramNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants);
    14271427
     1428        static const bool scopeIsFunction = false;
     1429
    14281430    private:
    14291431        ProgramNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants);
     
    14351437    public:
    14361438        static PassRefPtr<EvalNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants);
     1439
     1440        static const bool scopeIsFunction = false;
    14371441
    14381442    private:
     
    14511455        const Identifier* parameters() const { return m_parameters; }
    14521456        size_t parameterCount() const { return m_parameterCount; }
    1453         UString paramString() const ;
    14541457        Identifier* copyParameters();
    14551458
     
    14611464        const Identifier& ident() { return m_ident; }
    14621465
    1463         void reparseDataIfNecessary(ScopeChainNode*);
     1466        static const bool scopeIsFunction = true;
    14641467
    14651468    private:
  • trunk/JavaScriptCore/parser/Parser.cpp

    r47664 r47738  
    6868}
    6969
    70 void Parser::reparseInPlace(JSGlobalData* globalData, FunctionBodyNode* functionBodyNode)
    71 {
    72     ASSERT(!functionBodyNode->data());
    73 
    74     m_source = &functionBodyNode->source();
    75     globalData->lexer->setIsReparsing();
    76     parse(globalData, 0, 0);
    77     ASSERT(m_sourceElements);
    78 
    79     functionBodyNode->adoptData(std::auto_ptr<ScopeNodeData>(new ScopeNodeData(globalData->parser->arena(),
    80         m_sourceElements,
    81         m_varDeclarations ? &m_varDeclarations->data : 0,
    82         m_funcDeclarations ? &m_funcDeclarations->data : 0,
    83         m_numConstants)));
    84     bool usesArguments = functionBodyNode->usesArguments();
    85     functionBodyNode->setFeatures(m_features);
    86     if (usesArguments && !functionBodyNode->usesArguments())
    87         functionBodyNode->setUsesArguments();
    88 
    89     ASSERT(globalData->parser->arena().isEmpty());
    90 
    91     m_source = 0;
    92     m_sourceElements = 0;
    93     m_varDeclarations = 0;
    94     m_funcDeclarations = 0;
    95 }
    96 
    9770void Parser::didFinishParsing(SourceElements* sourceElements, ParserArenaData<DeclarationStacks::VarStack>* varStack,
    9871                              ParserArenaData<DeclarationStacks::FunctionStack>* funcStack, CodeFeatures features, int lastLine, int numConstants)
  • trunk/JavaScriptCore/parser/Parser.h

    r47664 r47738  
    2727#include "Executable.h"
    2828#include "JSGlobalObject.h"
     29#include "Lexer.h"
    2930#include "Nodes.h"
    3031#include "ParserArena.h"
     
    4647    public:
    4748        template <class ParsedNode>
    48         PassRefPtr<ParsedNode> parse(ExecState*, Debugger*, const SourceCode&, int* errLine = 0, UString* errMsg = 0);
    49         template <class ParsedNode>
    50         PassRefPtr<ParsedNode> reparse(JSGlobalData*, ParsedNode*);
    51         void reparseInPlace(JSGlobalData*, FunctionBodyNode*);
    52         PassRefPtr<FunctionBodyNode> parseFunctionFromGlobalCode(ExecState*, Debugger*, const SourceCode&, int* errLine = 0, UString* errMsg = 0);
     49        PassRefPtr<ParsedNode> parse(JSGlobalData* globalData, Debugger*, ExecState*, const SourceCode& source, int* errLine = 0, UString* errMsg = 0);
    5350
    5451        void didFinishParsing(SourceElements*, ParserArenaData<DeclarationStacks::VarStack>*,
     
    7168
    7269    template <class ParsedNode>
    73     PassRefPtr<ParsedNode> Parser::parse(ExecState* exec, Debugger* debugger, const SourceCode& source, int* errLine, UString* errMsg)
     70    PassRefPtr<ParsedNode> Parser::parse(JSGlobalData* globalData, Debugger* debugger, ExecState* debuggerExecState, const SourceCode& source, int* errLine, UString* errMsg)
    7471    {
    7572        m_source = &source;
    76         parse(&exec->globalData(), errLine, errMsg);
     73        if (FunctionBodyNode::scopeIsFunction)
     74            globalData->lexer->setIsReparsing();
     75        parse(globalData, errLine, errMsg);
     76
    7777        RefPtr<ParsedNode> result;
    7878        if (m_sourceElements) {
    79             result = ParsedNode::create(&exec->globalData(),
    80                                          m_sourceElements,
    81                                          m_varDeclarations ? &m_varDeclarations->data : 0,
    82                                          m_funcDeclarations ? &m_funcDeclarations->data : 0,
    83                                          *m_source,
    84                                          m_features,
    85                                          m_numConstants);
     79            result = ParsedNode::create(globalData,
     80            m_sourceElements,
     81            m_varDeclarations ? &m_varDeclarations->data : 0,
     82            m_funcDeclarations ? &m_funcDeclarations->data : 0,
     83            source,
     84            m_features,
     85            m_numConstants);
    8686            result->setLoc(m_source->firstLine(), m_lastLine);
    8787        }
     
    9090
    9191        m_source = 0;
     92        m_sourceElements = 0;
    9293        m_varDeclarations = 0;
    9394        m_funcDeclarations = 0;
    9495
    95         if (debugger)
    96             debugger->sourceParsed(exec, source, *errLine, *errMsg);
     96        if (debugger && !FunctionBodyNode::scopeIsFunction)
     97            debugger->sourceParsed(debuggerExecState, source, *errLine, *errMsg);
    9798        return result.release();
    98     }
    99 
    100     template <class ParsedNode>
    101     PassRefPtr<ParsedNode> Parser::reparse(JSGlobalData* globalData, ParsedNode* oldParsedNode)
    102     {
    103         m_source = &oldParsedNode->source();
    104         parse(globalData, 0, 0);
    105         RefPtr<ParsedNode> result;
    106         if (m_sourceElements) {
    107             result = ParsedNode::create(globalData,
    108                                         m_sourceElements,
    109                                         m_varDeclarations ? &m_varDeclarations->data : 0,
    110                                         m_funcDeclarations ? &m_funcDeclarations->data : 0,
    111                                         *m_source,
    112                                         oldParsedNode->features(),
    113                                         m_numConstants);
    114             result->setLoc(m_source->firstLine(), m_lastLine);
    115         }
    116 
    117         m_arena.reset();
    118 
    119         m_source = 0;
    120         m_varDeclarations = 0;
    121         m_funcDeclarations = 0;
    122 
    123         return result.release();
    124     }
    125 
    126     inline PassRefPtr<FunctionBodyNode> Parser::parseFunctionFromGlobalCode(ExecState* exec, Debugger* debugger, const SourceCode& source, int* errLine, UString* errMsg)
    127     {
    128         RefPtr<ProgramNode> program = parse<ProgramNode>(exec, debugger, source, errLine, errMsg);
    129         if (!program)
    130             return 0;
    131 
    132         StatementNode* exprStatement = program->singleStatement();
    133         ASSERT(exprStatement);
    134         ASSERT(exprStatement->isExprStatement());
    135         if (!exprStatement || !exprStatement->isExprStatement())
    136             return 0;
    137 
    138         ExpressionNode* funcExpr = static_cast<ExprStatementNode*>(exprStatement)->expr();
    139         ASSERT(funcExpr);
    140         ASSERT(funcExpr->isFuncExprNode());
    141         if (!funcExpr || !funcExpr->isFuncExprNode())
    142             return 0;
    143 
    144         FunctionBodyNode* body = static_cast<FuncExprNode*>(funcExpr)->body();
    145         ASSERT(body);
    146         return body;
    147     }
    148 
    149     inline JSObject* EvalExecutable::parse(ExecState* exec, bool allowDebug)
    150     {
    151         int errLine;
    152         UString errMsg;
    153         m_node = exec->globalData().parser->parse<EvalNode>(exec, allowDebug ? exec->dynamicGlobalObject()->debugger() : 0, m_source, &errLine, &errMsg);
    154         if (!m_node)
    155             return Error::create(exec, SyntaxError, errMsg, errLine, m_source.provider()->asID(), m_source.provider()->url());
    156         return 0;
    157     }
    158 
    159     inline JSObject* ProgramExecutable::parse(ExecState* exec, bool allowDebug)
    160     {
    161         int errLine;
    162         UString errMsg;
    163         m_node = exec->globalData().parser->parse<ProgramNode>(exec, allowDebug ? exec->dynamicGlobalObject()->debugger() : 0, m_source, &errLine, &errMsg);
    164         if (!m_node)
    165             return Error::create(exec, SyntaxError, errMsg, errLine, m_source.provider()->asID(), m_source.provider()->url());
    166         return 0;
    16799    }
    168100
  • trunk/JavaScriptCore/runtime/ArrayPrototype.cpp

    r47412 r47738  
    6868namespace JSC {
    6969
    70 static inline bool isNumericCompareFunction(CallType callType, const CallData& callData)
     70static inline bool isNumericCompareFunction(ExecState* exec, CallType callType, const CallData& callData)
    7171{
    7272    if (callType != CallTypeJS)
     
    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.functionExecutable->jitCode(callData.js.scopeChain);
     78    callData.js.functionExecutable->jitCode(exec, callData.js.scopeChain);
    7979    CodeBlock& codeBlock = callData.js.functionExecutable->generatedBytecode();
    8080#else
    81     CodeBlock& codeBlock = callData.js.functionExecutable->bytecode(callData.js.scopeChain);
     81    CodeBlock& codeBlock = callData.js.functionExecutable->bytecode(exec, callData.js.scopeChain);
    8282#endif
    8383
     
    457457
    458458    if (thisObj->classInfo() == &JSArray::info) {
    459         if (isNumericCompareFunction(callType, callData))
     459        if (isNumericCompareFunction(exec, callType, callData))
    460460            asArray(thisObj)->sortNumeric(exec, function, callType, callData);
    461461        else if (callType != CallTypeNone)
  • trunk/JavaScriptCore/runtime/Completion.cpp

    r47304 r47738  
    4343
    4444    ProgramExecutable program(source);
    45     JSObject* error = program.parse(exec);
     45    JSObject* error = program.checkSyntax(exec);
    4646    if (error)
    4747        return Completion(Throw, error);
     
    5555
    5656    ProgramExecutable program(source);
    57     JSObject* error = program.parse(exec);
     57    JSObject* error = program.compile(exec, scopeChain.node());
    5858    if (error)
    5959        return Completion(Throw, error);
  • trunk/JavaScriptCore/runtime/Executable.cpp

    r47660 r47738  
    3131#include "JIT.h"
    3232#include "Parser.h"
     33#include "Vector.h"
    3334
    3435namespace JSC {
     
    5657FunctionExecutable::~FunctionExecutable()
    5758{
     59    for (int i = 0; i < m_parameterCount; ++i)
     60        m_parameters[i].~Identifier();
     61    fastFree(m_parameters);
    5862    delete m_codeBlock;
    5963}
    6064
    61 void EvalExecutable::generateBytecode(ScopeChainNode* scopeChainNode)
    62 {
     65JSObject* EvalExecutable::compile(ExecState* exec, ScopeChainNode* scopeChainNode)
     66{
     67    int errLine;
     68    UString errMsg;
     69    RefPtr<EvalNode> evalNode = exec->globalData().parser->parse<EvalNode>(&exec->globalData(), exec->lexicalGlobalObject()->debugger(), exec, m_source, &errLine, &errMsg);
     70    if (!evalNode)
     71        return Error::create(exec, SyntaxError, errMsg, errLine, m_source.provider()->asID(), m_source.provider()->url());
     72    recordParse(evalNode->features(), evalNode->lineNo(), evalNode->lastLine());
     73
    6374    ScopeChain scopeChain(scopeChainNode);
    6475    JSGlobalObject* globalObject = scopeChain.globalObject();
     
    6677    ASSERT(!m_evalCodeBlock);
    6778    m_evalCodeBlock = new EvalCodeBlock(this, globalObject, source().provider(), scopeChain.localDepth());
    68     OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(evalNode(), globalObject->debugger(), scopeChain, m_evalCodeBlock->symbolTable(), m_evalCodeBlock));
     79    OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(evalNode.get(), globalObject->debugger(), scopeChain, m_evalCodeBlock->symbolTable(), m_evalCodeBlock));
    6980    generator->generate();
    7081   
    71     evalNode()->destroyData();
    72 }
    73 
    74 void ProgramExecutable::generateBytecode(ScopeChainNode* scopeChainNode)
    75 {
     82    evalNode->destroyData();
     83    return 0;
     84}
     85
     86JSObject* ProgramExecutable::checkSyntax(ExecState* exec)
     87{
     88    int errLine;
     89    UString errMsg;
     90    RefPtr<ProgramNode> programNode = exec->globalData().parser->parse<ProgramNode>(&exec->globalData(), exec->lexicalGlobalObject()->debugger(), exec, m_source, &errLine, &errMsg);
     91    if (!programNode)
     92        return Error::create(exec, SyntaxError, errMsg, errLine, m_source.provider()->asID(), m_source.provider()->url());
     93    return 0;
     94}
     95
     96JSObject* ProgramExecutable::compile(ExecState* exec, ScopeChainNode* scopeChainNode)
     97{
     98    int errLine;
     99    UString errMsg;
     100    RefPtr<ProgramNode> programNode = exec->globalData().parser->parse<ProgramNode>(&exec->globalData(), exec->lexicalGlobalObject()->debugger(), exec, m_source, &errLine, &errMsg);
     101    if (!programNode)
     102        return Error::create(exec, SyntaxError, errMsg, errLine, m_source.provider()->asID(), m_source.provider()->url());
     103    recordParse(programNode->features(), programNode->lineNo(), programNode->lastLine());
     104
    76105    ScopeChain scopeChain(scopeChainNode);
    77106    JSGlobalObject* globalObject = scopeChain.globalObject();
     
    79108    ASSERT(!m_programCodeBlock);
    80109    m_programCodeBlock = new ProgramCodeBlock(this, GlobalCode, globalObject, source().provider());
    81     OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(programNode(), globalObject->debugger(), scopeChain, &globalObject->symbolTable(), m_programCodeBlock));
    82     generator->generate();
    83 
    84     programNode()->destroyData();
    85 }
    86 
    87 void FunctionExecutable::generateBytecode(ScopeChainNode* scopeChainNode)
    88 {
    89     body()->reparseDataIfNecessary(scopeChainNode);
     110    OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(programNode.get(), globalObject->debugger(), scopeChain, &globalObject->symbolTable(), m_programCodeBlock));
     111    generator->generate();
     112
     113    programNode->destroyData();
     114    return 0;
     115}
     116
     117void FunctionExecutable::compile(ExecState*, ScopeChainNode* scopeChainNode)
     118{
     119    JSGlobalData* globalData = scopeChainNode->globalData;
     120    RefPtr<FunctionBodyNode> body = globalData->parser->parse<FunctionBodyNode>(globalData, 0, 0, m_source);
     121    if (m_forceUsesArguments)
     122        body->setUsesArguments();
     123    body->finishParsing(copyParameters(), m_parameterCount, m_name);
     124    recordParse(body->features(), body->lineNo(), body->lastLine());
    90125
    91126    ScopeChain scopeChain(scopeChainNode);
     
    94129    ASSERT(!m_codeBlock);
    95130    m_codeBlock = new FunctionCodeBlock(this, FunctionCode, source().provider(), source().startOffset());
    96     OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(body(), globalObject->debugger(), scopeChain, m_codeBlock->symbolTable(), m_codeBlock));
     131    OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(body.get(), globalObject->debugger(), scopeChain, m_codeBlock->symbolTable(), m_codeBlock));
    97132    generator->generate();
    98133    m_numParameters = m_codeBlock->m_numParameters;
     
    100135    m_numVariables = m_codeBlock->m_numVars;
    101136
    102     body()->destroyData();
    103 }
    104 
    105 #if ENABLE(JIT)
    106 
    107 void EvalExecutable::generateJITCode(ScopeChainNode* scopeChainNode)
    108 {
    109     CodeBlock* codeBlock = &bytecode(scopeChainNode);
     137    body->destroyData();
     138}
     139
     140#if ENABLE(JIT)
     141
     142void EvalExecutable::generateJITCode(ExecState* exec, ScopeChainNode* scopeChainNode)
     143{
     144    CodeBlock* codeBlock = &bytecode(exec, scopeChainNode);
    110145    m_jitCode = JIT::compile(scopeChainNode->globalData, codeBlock);
    111146
     
    116151}
    117152
    118 void ProgramExecutable::generateJITCode(ScopeChainNode* scopeChainNode)
    119 {
    120     CodeBlock* codeBlock = &bytecode(scopeChainNode);
     153void ProgramExecutable::generateJITCode(ExecState* exec, ScopeChainNode* scopeChainNode)
     154{
     155    CodeBlock* codeBlock = &bytecode(exec, scopeChainNode);
    121156    m_jitCode = JIT::compile(scopeChainNode->globalData, codeBlock);
    122157
     
    127162}
    128163
    129 void FunctionExecutable::generateJITCode(ScopeChainNode* scopeChainNode)
    130 {
    131     CodeBlock* codeBlock = &bytecode(scopeChainNode);
     164void FunctionExecutable::generateJITCode(ExecState* exec, ScopeChainNode* scopeChainNode)
     165{
     166    CodeBlock* codeBlock = &bytecode(exec, scopeChainNode);
    132167    m_jitCode = JIT::compile(scopeChainNode->globalData, codeBlock);
    133168
     
    148183ExceptionInfo* FunctionExecutable::reparseExceptionInfo(JSGlobalData* globalData, ScopeChainNode* scopeChainNode, CodeBlock* codeBlock)
    149184{
    150     RefPtr<FunctionBodyNode> newFunctionBody = globalData->parser->reparse<FunctionBodyNode>(globalData, body());
    151     ASSERT(newFunctionBody);
    152     newFunctionBody->finishParsing(body()->copyParameters(), body()->parameterCount(), body()->ident());
     185    RefPtr<FunctionBodyNode> newFunctionBody = globalData->parser->parse<FunctionBodyNode>(globalData, 0, 0, m_source);
     186    if (m_forceUsesArguments)
     187        newFunctionBody->setUsesArguments();
     188    newFunctionBody->finishParsing(copyParameters(), m_parameterCount, m_name);
    153189
    154190    ScopeChain scopeChain(scopeChainNode);
     
    176212ExceptionInfo* EvalExecutable::reparseExceptionInfo(JSGlobalData* globalData, ScopeChainNode* scopeChainNode, CodeBlock* codeBlock)
    177213{
    178     RefPtr<EvalNode> newEvalBody = globalData->parser->reparse<EvalNode>(globalData, evalNode());
     214    RefPtr<EvalNode> newEvalBody = globalData->parser->parse<EvalNode>(globalData, 0, 0, m_source);
    179215
    180216    ScopeChain scopeChain(scopeChainNode);
     
    197233}
    198234
    199 void FunctionExecutable::recompile(ExecState* exec)
    200 {
    201     FunctionBodyNode* oldBody = body();
    202     RefPtr<FunctionBodyNode> newBody = exec->globalData().parser->parse<FunctionBodyNode>(exec, 0, m_source);
    203     ASSERT(newBody);
    204     newBody->finishParsing(oldBody->copyParameters(), oldBody->parameterCount(), oldBody->ident());
    205     m_node = newBody;
     235void FunctionExecutable::recompile(ExecState*)
     236{
    206237    delete m_codeBlock;
    207238    m_codeBlock = 0;
     
    212243}
    213244
     245PassRefPtr<FunctionExecutable> FunctionExecutable::fromGlobalCode(const Identifier& functionName, ExecState* exec, Debugger* debugger, const SourceCode& source, int* errLine, UString* errMsg)
     246{
     247    RefPtr<ProgramNode> program = exec->globalData().parser->parse<ProgramNode>(&exec->globalData(), debugger, exec, source, errLine, errMsg);
     248    if (!program)
     249        return 0;
     250
     251    StatementNode* exprStatement = program->singleStatement();
     252    ASSERT(exprStatement);
     253    ASSERT(exprStatement->isExprStatement());
     254    if (!exprStatement || !exprStatement->isExprStatement())
     255        return 0;
     256
     257    ExpressionNode* funcExpr = static_cast<ExprStatementNode*>(exprStatement)->expr();
     258    ASSERT(funcExpr);
     259    ASSERT(funcExpr->isFuncExprNode());
     260    if (!funcExpr || !funcExpr->isFuncExprNode())
     261        return 0;
     262
     263    FunctionBodyNode* body = static_cast<FuncExprNode*>(funcExpr)->body();
     264    ASSERT(body);
     265    return adoptRef(new FunctionExecutable(functionName, body->source(), body->usesArguments(), body->copyParameters(), body->parameterCount(), body->lineNo(), body->lastLine()));
     266}
     267
     268Identifier* FunctionExecutable::copyParameters()
     269{
     270    // This code uses the internal vector copier to make copy-constructed copies of the data in the array
     271    // (the array contains Identfiers which reference count Ustring::Reps, which must be ref'ed correctly).
     272    Identifier* parameters = static_cast<Identifier*>(fastMalloc(m_parameterCount * sizeof(Identifier)));
     273    WTF::VectorCopier<false, Identifier>::uninitializedCopy(m_parameters, m_parameters + m_parameterCount, parameters);
     274    return parameters;
     275}
     276
     277UString FunctionExecutable::paramString() const
     278{
     279    UString s("");
     280    for (int pos = 0; pos < m_parameterCount; ++pos) {
     281        if (!s.isEmpty())
     282            s += ", ";
     283        s += m_parameters[pos].ustring();
     284    }
     285
     286    return s;
     287}
     288
    214289};
    215290
  • trunk/JavaScriptCore/runtime/Executable.h

    r47665 r47738  
    3333
    3434    class CodeBlock;
     35    class Debugger;
    3536    class EvalCodeBlock;
    3637    class ProgramCodeBlock;
     
    105106            : ExecutableBase(NUM_PARAMETERS_NOT_COMPILED)
    106107            , m_source(source)
     108            , m_features(0)
    107109        {
    108110        }
    109111
    110112        const SourceCode& source() { return m_source; }
    111         intptr_t sourceID() const { return m_node->sourceID(); }
    112         const UString& sourceURL() const { return m_node->sourceURL(); }
    113         int lineNo() const { return m_node->lineNo(); }
    114         int lastLine() const { return m_node->lastLine(); }
    115 
    116         bool usesEval() const { return m_node->usesEval(); }
    117         bool usesArguments() const { return m_node->usesArguments(); }
    118         bool needsActivation() const { return m_node->needsActivation(); }
     113        intptr_t sourceID() const { return m_source.provider()->asID(); }
     114        const UString& sourceURL() const { return m_source.provider()->url(); }
     115        int lineNo() const { return m_firstLine; }
     116        int lastLine() const { return m_lastLine; }
     117
     118        bool usesEval() const { return m_features & EvalFeature; }
     119        bool usesArguments() const { return m_features & ArgumentsFeature; }
     120        bool needsActivation() const { return m_features & (EvalFeature | ClosureFeature | WithFeature | CatchFeature); }
    119121
    120122        virtual ExceptionInfo* reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*) = 0;
    121123
    122124    protected:
     125        void recordParse(CodeFeatures features, int firstLine, int lastLine)
     126        {
     127            m_features = features;
     128            m_firstLine = firstLine;
     129            m_lastLine = lastLine;
     130        }
     131
    123132        SourceCode m_source;
    124         RefPtr<ScopeNode> m_node;
     133        CodeFeatures m_features;
     134        int m_firstLine;
     135        int m_lastLine;
    125136    };
    126137
     
    135146        ~EvalExecutable();
    136147
    137         JSObject* parse(ExecState*, bool allowDebug = true);
    138 
    139         EvalCodeBlock& bytecode(ScopeChainNode* scopeChainNode)
    140         {
    141             if (!m_evalCodeBlock)
    142                 generateBytecode(scopeChainNode);
     148        EvalCodeBlock& bytecode(ExecState* exec, ScopeChainNode* scopeChainNode)
     149        {
     150            if (!m_evalCodeBlock) {
     151                JSObject* error = compile(exec, scopeChainNode);
     152                ASSERT_UNUSED(!error, error);
     153            }
    143154            return *m_evalCodeBlock;
    144155        }
    145156
     157        JSObject* compile(ExecState*, ScopeChainNode*);
     158
    146159        ExceptionInfo* reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*);
    147 
    148160        static PassRefPtr<EvalExecutable> create(const SourceCode& source) { return adoptRef(new EvalExecutable(source)); }
    149161
    150162    private:
    151         EvalNode* evalNode() { return static_cast<EvalNode*>(m_node.get()); }
    152 
    153         void generateBytecode(ScopeChainNode*);
    154 
    155163        EvalCodeBlock* m_evalCodeBlock;
    156164
    157165#if ENABLE(JIT)
    158166    public:
    159         JITCode& jitCode(ScopeChainNode* scopeChainNode)
     167        JITCode& jitCode(ExecState* exec, ScopeChainNode* scopeChainNode)
    160168        {
    161169            if (!m_jitCode)
    162                 generateJITCode(scopeChainNode);
     170                generateJITCode(exec, scopeChainNode);
    163171            return m_jitCode;
    164172        }
    165173
    166174    private:
    167         void generateJITCode(ScopeChainNode*);
     175        void generateJITCode(ExecState*, ScopeChainNode*);
    168176#endif
    169177    };
     
    179187        ~ProgramExecutable();
    180188
    181         JSObject* parse(ExecState*, bool allowDebug = true);
    182 
    183         // CodeBlocks for program code are transient and therefore to not gain from from throwing out there exception information.
     189        ProgramCodeBlock& bytecode(ExecState* exec, ScopeChainNode* scopeChainNode)
     190        {
     191            if (!m_programCodeBlock) {
     192                JSObject* error = compile(exec, scopeChainNode);
     193                ASSERT_UNUSED(!error, error);
     194            }
     195            return *m_programCodeBlock;
     196        }
     197
     198        JSObject* checkSyntax(ExecState*);
     199        JSObject* compile(ExecState*, ScopeChainNode*);
     200
     201        // CodeBlocks for program code are transient and therefore do not gain from from throwing out there exception information.
    184202        ExceptionInfo* reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*) { ASSERT_NOT_REACHED(); return 0; }
    185203
    186         ProgramCodeBlock& bytecode(ScopeChainNode* scopeChainNode)
    187         {
    188             if (!m_programCodeBlock)
    189                 generateBytecode(scopeChainNode);
    190             return *m_programCodeBlock;
    191         }
    192 
    193     private:
    194         ProgramNode* programNode() { return static_cast<ProgramNode*>(m_node.get()); }
    195 
    196         void generateBytecode(ScopeChainNode*);
    197 
     204    private:
    198205        ProgramCodeBlock* m_programCodeBlock;
    199206
    200207#if ENABLE(JIT)
    201208    public:
    202         JITCode& jitCode(ScopeChainNode* scopeChainNode)
     209        JITCode& jitCode(ExecState* exec, ScopeChainNode* scopeChainNode)
    203210        {
    204211            if (!m_jitCode)
    205                 generateJITCode(scopeChainNode);
     212                generateJITCode(exec, scopeChainNode);
    206213            return m_jitCode;
    207214        }
    208215
    209216    private:
    210         void generateJITCode(ScopeChainNode*);
     217        void generateJITCode(ExecState*, ScopeChainNode*);
    211218#endif
    212219    };
     
    215222        friend class JIT;
    216223    public:
    217         FunctionExecutable(const Identifier& name, FunctionBodyNode* body)
    218             : ScriptExecutable(body->source())
     224        FunctionExecutable(const Identifier& name, const SourceCode& source, bool forceUsesArguments, Identifier* parameters, int parameterCount, int firstLine, int lastLine)
     225            : ScriptExecutable(source)
     226            , m_forceUsesArguments(forceUsesArguments)
     227            , m_parameters(parameters)
     228            , m_parameterCount(parameterCount)
    219229            , m_codeBlock(0)
    220230            , m_name(name)
    221231            , m_numVariables(0)
    222232        {
    223             m_node = body;
     233            m_firstLine = firstLine;
     234            m_lastLine = lastLine;
    224235        }
    225236
    226237        ~FunctionExecutable();
    227238
    228         const Identifier& name() { return m_name; }
    229 
    230         JSFunction* make(ExecState*, ScopeChainNode* scopeChain);
    231 
    232         CodeBlock& bytecode(ScopeChainNode* scopeChainNode)
     239        JSFunction* make(ExecState* exec, ScopeChainNode* scopeChain)
     240        {
     241            return new (exec) JSFunction(exec, this, scopeChain);
     242        }
     243
     244        CodeBlock& bytecode(ExecState* exec, ScopeChainNode* scopeChainNode)
    233245        {
    234246            ASSERT(scopeChainNode);
    235247            if (!m_codeBlock)
    236                 generateBytecode(scopeChainNode);
     248                compile(exec, scopeChainNode);
    237249            return *m_codeBlock;
    238250        }
     251
     252        bool isGenerated() const
     253        {
     254            return m_codeBlock;
     255        }
     256
    239257        CodeBlock& generatedBytecode()
    240258        {
     
    243261        }
    244262
    245         bool usesEval() const { return body()->usesEval(); }
    246         bool usesArguments() const { return body()->usesArguments(); }
    247         size_t parameterCount() const { return body()->parameterCount(); }
     263        const Identifier& name() { return m_name; }
     264        size_t parameterCount() const { return m_parameterCount; }
    248265        size_t variableCount() const { return m_numVariables; }
    249         UString paramString() const { return body()->paramString(); }
    250 
    251         bool isGenerated() const
    252         {
    253             return m_codeBlock;
    254         }
     266        UString paramString() const;
    255267
    256268        void recompile(ExecState*);
    257 
    258269        ExceptionInfo* reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*);
    259 
    260270        void markAggregate(MarkStack& markStack);
    261 
    262     private:
    263         FunctionBodyNode* body() const { return static_cast<FunctionBodyNode*>(m_node.get()); }
    264 
    265         void generateBytecode(ScopeChainNode*);
    266 
     271        static PassRefPtr<FunctionExecutable> fromGlobalCode(const Identifier&, ExecState*, Debugger*, const SourceCode&, int* errLine = 0, UString* errMsg = 0);
     272
     273    private:
     274        void compile(ExecState*, ScopeChainNode*);
     275        Identifier* copyParameters();
     276
     277        bool m_forceUsesArguments;
     278        Identifier* m_parameters;
     279        int m_parameterCount;
    267280        CodeBlock* m_codeBlock;
    268         const Identifier& m_name;
     281        Identifier m_name;
    269282        size_t m_numVariables;
    270283
    271284#if ENABLE(JIT)
    272285    public:
    273         JITCode& jitCode(ScopeChainNode* scopeChainNode)
     286        JITCode& jitCode(ExecState* exec, ScopeChainNode* scopeChainNode)
    274287        {
    275288            if (!m_jitCode)
    276                 generateJITCode(scopeChainNode);
     289                generateJITCode(exec, scopeChainNode);
    277290            return m_jitCode;
    278291        }
    279292
    280293    private:
    281         void generateJITCode(ScopeChainNode*);
     294        void generateJITCode(ExecState*, ScopeChainNode*);
    282295#endif
    283296    };
     
    289302    }
    290303
    291     inline JSFunction* FunctionExecutable::make(ExecState* exec, ScopeChainNode* scopeChain)
    292     {
    293         return new (exec) JSFunction(exec, this, scopeChain);
    294     }
    295 
    296304    inline bool JSFunction::isHostFunction() const
    297305    {
  • trunk/JavaScriptCore/runtime/FunctionConstructor.cpp

    r47412 r47738  
    8888    UString errMsg;
    8989    SourceCode source = makeSource(program, sourceURL, lineNumber);
    90     RefPtr<FunctionBodyNode> body = exec->globalData().parser->parseFunctionFromGlobalCode(exec, exec->dynamicGlobalObject()->debugger(), source, &errLine, &errMsg);
    91     if (!body)
     90    RefPtr<FunctionExecutable> function = FunctionExecutable::fromGlobalCode(functionName, exec, exec->dynamicGlobalObject()->debugger(), source, &errLine, &errMsg);
     91    if (!function)
    9292        return throwError(exec, SyntaxError, errMsg, errLine, source.provider()->asID(), source.provider()->url());
    9393
    9494    JSGlobalObject* globalObject = exec->lexicalGlobalObject();
    9595    ScopeChain scopeChain(globalObject, globalObject->globalData(), exec->globalThisValue());
    96     return new (exec) JSFunction(exec, adoptRef(new FunctionExecutable(functionName, body.get())), scopeChain.node());
     96    return new (exec) JSFunction(exec, function, scopeChain.node());
    9797}
    9898
  • trunk/JavaScriptCore/runtime/JSGlobalData.cpp

    r47412 r47738  
    237237    if (!lazyNumericCompareFunction.size() && !initializingLazyNumericCompareFunction) {
    238238        initializingLazyNumericCompareFunction = true;
    239         RefPtr<FunctionBodyNode> functionBody = parser->parseFunctionFromGlobalCode(exec, 0, makeSource(UString("(function (v1, v2) { return v1 - v2; })")), 0, 0);
    240         FunctionExecutable function(functionBody->ident(), functionBody.get());
    241         lazyNumericCompareFunction = function.bytecode(exec->scopeChain()).instructions();
     239        RefPtr<FunctionExecutable> function = FunctionExecutable::fromGlobalCode(Identifier(exec, "numericCompare"), exec, 0, makeSource(UString("(function (v1, v2) { return v1 - v2; })")), 0, 0);
     240        lazyNumericCompareFunction = function->bytecode(exec, exec->scopeChain()).instructions();
    242241        initializingLazyNumericCompareFunction = false;
    243242    }
  • trunk/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp

    r47304 r47738  
    288288
    289289    EvalExecutable eval(makeSource(s));
    290     JSObject* error = eval.parse(exec);
     290    JSObject* error = eval.compile(exec, static_cast<JSGlobalObject*>(unwrappedObject)->globalScopeChain().node());
    291291    if (error)
    292292        return throwError(exec, error);
Note: See TracChangeset for help on using the changeset viewer.