Changeset 38247 in webkit for trunk/JavaScriptCore/bytecompiler


Ignore:
Timestamp:
Nov 9, 2008, 5:04:30 PM (17 years ago)
Author:
Darin Adler
Message:

JavaScriptCore:

2008-11-09 Darin Adler <Darin Adler>

Reviewed by Sam Weinig and Maciej Stachowiak.
Includes some work done by Chris Brichford.

Test: fast/js/large-expressions.html

1) Code generation is recursive, so takes stack proportional to the complexity

of the source code expression. Fixed by setting an arbitrary recursion limit
of 10,000 nodes.

2) Destruction of the syntax tree was recursive. Fixed by introducing a

non-recursive mechanism for destroying the tree.

  • bytecompiler/CodeGenerator.cpp: (JSC::CodeGenerator::CodeGenerator): Initialize depth to 0. (JSC::CodeGenerator::emitThrowExpressionTooDeepException): Added. Emits the code to throw a "too deep" exception.
  • bytecompiler/CodeGenerator.h: (JSC::CodeGenerator::emitNode): Check depth and emit an exception if we exceed the maximum depth.
  • parser/Nodes.cpp: (JSC::NodeReleaser::releaseAllNodes): Added. To be called inside node destructors to avoid recursive calls to destructors for nodes inside this one. (JSC::NodeReleaser::release): Added. To be called inside releaseNodes functions. Also added releaseNodes functions and calls to releaseAllNodes inside destructors for each class derived from Node that has RefPtr to other nodes. (JSC::NodeReleaser::adopt): Added. Used by the release function. (JSC::NodeReleaser::adoptFunctionBodyNode): Added.
  • parser/Nodes.h: Added declarations of releaseNodes and destructors in all classes that needed it. Eliminated use of ListRefPtr and releaseNext, which are the two parts of an older solution to the non-recursive destruction problem that works only for lists, whereas the new solution works for other graphs. Changed ReverseBinaryOpNode to use BinaryOpNode as a base class to avoid some duplicated code.

LayoutTests:

2008-11-09 Alexey Proskuryakov <[email protected]>

Reviewed by Darin Adler.

https://bugs.webkit.org/show_bug.cgi?id=22104
Javascript URL percent encoding/decoding broken by some characters

  • fast/loader/javascript-url-encoding-2-expected.txt:
  • fast/loader/javascript-url-encoding-2.html:
Location:
trunk/JavaScriptCore/bytecompiler
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/bytecompiler/CodeGenerator.cpp

    r38230 r38247  
    208208    , m_globalData(&scopeChain.globalObject()->globalExec()->globalData())
    209209    , m_lastOpcodeID(op_end)
     210    , m_emitNodeDepth(0)
    210211{
    211212    if (m_shouldEmitDebugHooks)
     
    284285    , m_globalData(&scopeChain.globalObject()->globalExec()->globalData())
    285286    , m_lastOpcodeID(op_end)
     287    , m_emitNodeDepth(0)
    286288{
    287289    if (m_shouldEmitDebugHooks)
     
    354356    , m_globalData(&scopeChain.globalObject()->globalExec()->globalData())
    355357    , m_lastOpcodeID(op_end)
     358    , m_emitNodeDepth(0)
    356359{
    357360    if (m_shouldEmitDebugHooks)
     
    16771680}
    16781681
     1682RegisterID* CodeGenerator::emitThrowExpressionTooDeepException()
     1683{
     1684    // It would be nice to do an even better job of identifying exactly where the expression is.
     1685    // And we could make the caller pass the node pointer in, if there was some way of getting
     1686    // that from an arbitrary node. However, calling emitExpressionInfo without any useful data
     1687    // is still good enough to get us an accurate line number.
     1688    emitExpressionInfo(0, 0, 0);
     1689    RegisterID* exception = emitNewError(newTemporary(), SyntaxError, jsString(globalData(), "Expression too deep"));
     1690    emitThrow(exception);
     1691    return exception;
     1692}
     1693
    16791694} // namespace JSC
  • trunk/JavaScriptCore/bytecompiler/CodeGenerator.h

    r38219 r38247  
    166166                m_codeBlock->lineInfo.append(info);
    167167            }
    168             return n->emitCode(*this, dst);
     168            if (m_emitNodeDepth >= s_maxEmitNodeDepth)
     169                return emitThrowExpressionTooDeepException();
     170            ++m_emitNodeDepth;
     171            RegisterID* r = n->emitCode(*this, dst);
     172            --m_emitNodeDepth;
     173            return r;
    169174        }
    170175
     
    400405        bool canOptimizeNonLocals() { return (m_codeType == FunctionCode) && !m_dynamicScopeDepth && !m_codeBlock->usesEval; }
    401406
     407        RegisterID* emitThrowExpressionTooDeepException();
     408
    402409        bool m_shouldEmitDebugHooks;
    403410        bool m_shouldEmitProfileHooks;
     
    445452        static bool s_dumpsGeneratedCode;
    446453#endif
     454
     455        unsigned m_emitNodeDepth;
     456
     457        static const unsigned s_maxEmitNodeDepth = 10000;
    447458    };
    448459
Note: See TracChangeset for help on using the changeset viewer.