Ignore:
Timestamp:
Sep 6, 2012, 6:42:53 PM (13 years ago)
Author:
[email protected]
Message:

Source/JavaScriptCore: Rolled back in <http://trac.webkit.org/changeset/127698> with a fix for
fast/dom/HTMLScriptElement/script-reexecution-pretty-diff.html, which
is to make sure that function declarations don't put their names in scope.

Reviewed by Gavin Barraclough.

Named functions should not allocate scope objects for their names
https://bugs.webkit.org/show_bug.cgi?id=95659

Reviewed by Oliver Hunt.

LayoutTests: Rolled back in <http://trac.webkit.org/changeset/127698> with a fix for
fast/dom/HTMLScriptElement/script-reexecution-pretty-diff.html.

Added a more explicit test for the feature I broke in
fast/dom/HTMLScriptElement/script-reexecution-pretty-diff.html.

Reviewed by Gavin Barraclough.

Named functions should not allocate scope objects for their names
https://bugs.webkit.org/show_bug.cgi?id=95659

Reviewed by Oliver Hunt.

  • fast/dom/HTMLScriptElement/script-reexecution.html:
  • fast/js/function-name-is-in-scope-expected.txt: Added.
  • fast/js/function-name-is-in-scope.html: Added.
Location:
trunk/Source/JavaScriptCore/runtime
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/runtime/Executable.cpp

    r127774 r127810  
    134134const ClassInfo FunctionExecutable::s_info = { "FunctionExecutable", &ScriptExecutable::s_info, 0, 0, CREATE_METHOD_TABLE(FunctionExecutable) };
    135135
    136 FunctionExecutable::FunctionExecutable(JSGlobalData& globalData, const Identifier& name, const Identifier& inferredName, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool inStrictContext)
    137     : ScriptExecutable(globalData.functionExecutableStructure.get(), globalData, source, inStrictContext)
     136FunctionExecutable::FunctionExecutable(JSGlobalData& globalData, FunctionBodyNode* node)
     137    : ScriptExecutable(globalData.functionExecutableStructure.get(), globalData, node->source(), node->isStrictMode())
    138138    , m_numCapturedVariables(0)
    139     , m_forceUsesArguments(forceUsesArguments)
    140     , m_parameters(parameters)
    141     , m_name(name)
    142     , m_inferredName(inferredName.isNull() ? globalData.propertyNames->emptyIdentifier : inferredName)
    143 {
    144 }
    145 
    146 FunctionExecutable::FunctionExecutable(ExecState* exec, const Identifier& name, const Identifier& inferredName, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool inStrictContext)
    147     : ScriptExecutable(exec->globalData().functionExecutableStructure.get(), exec, source, inStrictContext)
    148     , m_numCapturedVariables(0)
    149     , m_forceUsesArguments(forceUsesArguments)
    150     , m_parameters(parameters)
    151     , m_name(name)
    152     , m_inferredName(inferredName.isNull() ? exec->globalData().propertyNames->emptyIdentifier : inferredName)
    153 {
     139    , m_forceUsesArguments(node->usesArguments())
     140    , m_parameters(node->parameters())
     141    , m_name(node->ident())
     142    , m_inferredName(node->inferredName().isNull() ? globalData.propertyNames->emptyIdentifier : node->inferredName())
     143    , m_functionNameIsInScopeToggle(node->functionNameIsInScopeToggle())
     144{
     145    m_firstLine = node->lineNo();
     146    m_lastLine = node->lastLine();
    154147}
    155148
     
    211204        if (!lexicalGlobalObject->evalEnabled())
    212205            return throwError(exec, createEvalError(exec, ASCIILiteral("Eval is disabled")));
    213         RefPtr<EvalNode> evalNode = parse<EvalNode>(globalData, lexicalGlobalObject, m_source, 0, isStrictMode() ? JSParseStrict : JSParseNormal, EvalNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject->debugger(), exec, &exception);
     206        RefPtr<EvalNode> evalNode = parse<EvalNode>(globalData, lexicalGlobalObject, m_source, 0, Identifier(), isStrictMode() ? JSParseStrict : JSParseNormal, EvalNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject->debugger(), exec, &exception);
    214207        if (!evalNode) {
    215208            ASSERT(exception);
     
    294287    JSGlobalData* globalData = &exec->globalData();
    295288    JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();
    296     RefPtr<ProgramNode> programNode = parse<ProgramNode>(globalData, lexicalGlobalObject, m_source, 0, JSParseNormal, ProgramNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject->debugger(), exec, &exception);
     289    RefPtr<ProgramNode> programNode = parse<ProgramNode>(globalData, lexicalGlobalObject, m_source, 0, Identifier(), JSParseNormal, ProgramNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject->debugger(), exec, &exception);
    297290    if (programNode)
    298291        return 0;
     
    336329        m_programCodeBlock = newCodeBlock.release();
    337330    } else {
    338         RefPtr<ProgramNode> programNode = parse<ProgramNode>(globalData, lexicalGlobalObject, m_source, 0, isStrictMode() ? JSParseStrict : JSParseNormal, ProgramNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject->debugger(), exec, &exception);
     331        RefPtr<ProgramNode> programNode = parse<ProgramNode>(globalData, lexicalGlobalObject, m_source, 0, Identifier(), isStrictMode() ? JSParseStrict : JSParseNormal, ProgramNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject->debugger(), exec, &exception);
    339332        if (!programNode) {
    340333            ASSERT(exception);
     
    479472    JSGlobalData* globalData = scope->globalData();
    480473    JSGlobalObject* globalObject = scope->globalObject();
    481     RefPtr<FunctionBodyNode> body = parse<FunctionBodyNode>(globalData, globalObject, m_source, m_parameters.get(), isStrictMode() ? JSParseStrict : JSParseNormal, FunctionBodyNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, 0, 0, &exception);
     474    RefPtr<FunctionBodyNode> body = parse<FunctionBodyNode>(
     475        globalData,
     476        globalObject,
     477        m_source,
     478        m_parameters.get(),
     479        name(),
     480        isStrictMode() ? JSParseStrict : JSParseNormal,
     481        FunctionBodyNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode,
     482        0,
     483        0,
     484        &exception
     485    );
    482486
    483487    if (!body) {
     
    487491    if (m_forceUsesArguments)
    488492        body->setUsesArguments();
    489     body->finishParsing(m_parameters, m_name);
     493    body->finishParsing(m_parameters, m_name, m_functionNameIsInScopeToggle);
    490494    recordParse(body->features(), body->hasCapturedVariables(), body->lineNo(), body->lastLine());
    491495
     
    648652}
    649653
    650 FunctionExecutable* FunctionExecutable::fromGlobalCode(const Identifier& functionName, ExecState* exec, Debugger* debugger, const SourceCode& source, JSObject** exception)
     654FunctionExecutable* FunctionExecutable::fromGlobalCode(const Identifier& name, ExecState* exec, Debugger* debugger, const SourceCode& source, JSObject** exception)
    651655{
    652656    JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();
    653     RefPtr<ProgramNode> program = parse<ProgramNode>(&exec->globalData(), lexicalGlobalObject, source, 0, JSParseNormal, ProgramNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, debugger, exec, exception);
     657    RefPtr<ProgramNode> program = parse<ProgramNode>(&exec->globalData(), lexicalGlobalObject, source, 0, Identifier(), JSParseNormal, ProgramNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, debugger, exec, exception);
    654658    if (!program) {
    655659        ASSERT(*exception);
     
    657661    }
    658662
    659     // Uses of this function that would not result in a single function expression are invalid.
     663    // This function assumes an input string that would result in a single anonymous function expression.
    660664    StatementNode* exprStatement = program->singleStatement();
    661665    ASSERT(exprStatement);
     
    666670    FunctionBodyNode* body = static_cast<FuncExprNode*>(funcExpr)->body();
    667671    ASSERT(body);
    668 
    669     return FunctionExecutable::create(exec->globalData(), functionName, functionName, body->source(), body->usesArguments(), body->parameters(), body->isStrictMode(), body->lineNo(), body->lastLine());
     672    ASSERT(body->ident().isNull());
     673
     674    FunctionExecutable* functionExecutable = FunctionExecutable::create(exec->globalData(), body);
     675    functionExecutable->m_nameValue.set(exec->globalData(), functionExecutable, jsString(&exec->globalData(), name.ustring()));
     676    return functionExecutable;
    670677}
    671678
  • trunk/Source/JavaScriptCore/runtime/Executable.h

    r127774 r127810  
    540540        typedef ScriptExecutable Base;
    541541
    542         static FunctionExecutable* create(ExecState* exec, const Identifier& name, const Identifier& inferredName, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool isInStrictContext, int firstLine, int lastLine)
    543         {
    544             FunctionExecutable* executable = new (NotNull, allocateCell<FunctionExecutable>(*exec->heap())) FunctionExecutable(exec, name, inferredName, source, forceUsesArguments, parameters, isInStrictContext);
    545             executable->finishCreation(exec->globalData(), name, firstLine, lastLine);
     542        static FunctionExecutable* create(JSGlobalData& globalData, FunctionBodyNode* node)
     543        {
     544            FunctionExecutable* executable = new (NotNull, allocateCell<FunctionExecutable>(globalData.heap)) FunctionExecutable(globalData, node);
     545            executable->finishCreation(globalData);
    546546            return executable;
    547547        }
    548 
    549         static FunctionExecutable* create(JSGlobalData& globalData, const Identifier& name, const Identifier& inferredName, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool isInStrictContext, int firstLine, int lastLine)
    550         {
    551             FunctionExecutable* executable = new (NotNull, allocateCell<FunctionExecutable>(globalData.heap)) FunctionExecutable(globalData, name, inferredName, source, forceUsesArguments, parameters, isInStrictContext);
    552             executable->finishCreation(globalData, name, firstLine, lastLine);
    553             return executable;
    554         }
     548        static FunctionExecutable* fromGlobalCode(const Identifier& name, ExecState*, Debugger*, const SourceCode&, JSObject** exception);
    555549
    556550        static void destroy(JSCell*);
    557551
    558         JSFunction* make(ExecState* exec, JSScope* scope)
    559         {
    560             return JSFunction::create(exec, this, scope);
    561         }
    562        
    563552        // Returns either call or construct bytecode. This can be appropriate
    564553        // for answering questions that that don't vary between call and construct --
     
    709698        void clearCodeIfNotCompiling();
    710699        static void visitChildren(JSCell*, SlotVisitor&);
    711         static FunctionExecutable* fromGlobalCode(const Identifier&, ExecState*, Debugger*, const SourceCode&, JSObject** exception);
    712700        static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)
    713701        {
     
    722710
    723711    protected:
    724         void finishCreation(JSGlobalData& globalData, const Identifier& name, int firstLine, int lastLine)
     712        void finishCreation(JSGlobalData& globalData)
    725713        {
    726714            Base::finishCreation(globalData);
    727             m_firstLine = firstLine;
    728             m_lastLine = lastLine;
    729             m_nameValue.set(globalData, this, jsString(&globalData, name.ustring()));
     715            m_nameValue.set(globalData, this, jsString(&globalData, name().ustring()));
    730716        }
    731717
    732718    private:
    733         FunctionExecutable(JSGlobalData&, const Identifier& name, const Identifier& inferredName, const SourceCode&, bool forceUsesArguments, FunctionParameters*, bool);
    734         FunctionExecutable(ExecState*, const Identifier& name, const Identifier& inferredName, const SourceCode&, bool forceUsesArguments, FunctionParameters*, bool);
     719        FunctionExecutable(JSGlobalData&, FunctionBodyNode*);
    735720
    736721        JSObject* compileForCallInternal(ExecState*, JSScope*, JITCode::JITType, unsigned bytecodeIndex = UINT_MAX);
     
    765750        Identifier m_name;
    766751        Identifier m_inferredName;
     752        FunctionNameIsInScopeToggle m_functionNameIsInScopeToggle;
    767753        WriteBarrier<JSString> m_nameValue;
    768754        WriteBarrier<SharedSymbolTable> m_symbolTable;
  • trunk/Source/JavaScriptCore/runtime/JSNameScope.h

    r127774 r127810  
    3939    static JSNameScope* create(ExecState* exec, const Identifier& identifier, JSValue value, unsigned attributes)
    4040    {
    41         JSNameScope* scopeObject = new (NotNull, allocateCell<JSNameScope>(*exec->heap())) JSNameScope(exec);
     41        JSNameScope* scopeObject = new (NotNull, allocateCell<JSNameScope>(*exec->heap())) JSNameScope(exec, exec->scope());
     42        scopeObject->finishCreation(exec, identifier, value, attributes);
     43        return scopeObject;
     44    }
     45
     46    static JSNameScope* create(ExecState* exec, const Identifier& identifier, JSValue value, unsigned attributes, JSScope* next)
     47    {
     48        JSNameScope* scopeObject = new (NotNull, allocateCell<JSNameScope>(*exec->heap())) JSNameScope(exec, next);
    4249        scopeObject->finishCreation(exec, identifier, value, attributes);
    4350        return scopeObject;
     
    6572
    6673private:
    67     JSNameScope(ExecState* exec)
     74    JSNameScope(ExecState* exec, JSScope* next)
    6875        : Base(
    6976            exec->globalData(),
    7077            exec->lexicalGlobalObject()->nameScopeStructure(),
    7178            reinterpret_cast<Register*>(&m_registerStore + 1),
    72             exec->scope()
     79            next
    7380        )
    7481    {
Note: See TracChangeset for help on using the changeset viewer.