Changeset 32533 in webkit


Ignore:
Timestamp:
Apr 24, 2008, 10:00:43 PM (17 years ago)
Author:
oliver@apple.com
Message:

Bug 18628: SQUIRRELFISH: need to support recursion limit
<https://bugs.webkit.org/show_bug.cgi?id=18628>

Reviewed by Maciej

Partial fix -- this gets us some of the required bounds checking, but not
complete coverage. But it does manage to do them without regressing :D

Location:
branches/squirrelfish/JavaScriptCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • branches/squirrelfish/JavaScriptCore/ChangeLog

    r32522 r32533  
     12008-04-24  Oliver Hunt  <oliver@apple.com>
     2
     3        Reviewed by Maciej.
     4
     5        Bug 18628: SQUIRRELFISH: need to support recursion limit
     6        <https://bugs.webkit.org/show_bug.cgi?id=18628>
     7
     8        Partial fix -- this gets us some of the required bounds checking, but not
     9        complete coverage.  But it does manage to do them without regressing :D
     10
     11        * VM/ExceptionHelpers.cpp:
     12        (KJS::createError):
     13        (KJS::createStackOverflowError):
     14        * VM/ExceptionHelpers.h:
     15        * VM/Machine.cpp:
     16        (KJS::slideRegisterWindowForCall):
     17        (KJS::Machine::execute):
     18        (KJS::Machine::privateExecute):
     19        * VM/RegisterFile.cpp:
     20        * VM/RegisterFile.h:
     21        (KJS::RegisterFile::):
     22        (KJS::RegisterFile::RegisterFile):
     23        (KJS::RegisterFile::grow):
     24
    1252008-04-24  Geoffrey Garen  <ggaren@apple.com>
    226
  • branches/squirrelfish/JavaScriptCore/VM/ExceptionHelpers.cpp

    r32377 r32533  
    4545    string = newString;
    4646}
     47   
     48JSValue* createError(ExecState* exec, ErrorType e, const char* msg)
     49{
     50    return Error::create(exec, e, msg, -1, -1, 0); // lineNo(), currentSourceId(exec), currentSourceURL(exec)
     51}
    4752
    4853JSValue* createError(ExecState* exec, ErrorType e, const char* msg, const Identifier& label)
     
    6267        substitute(message, "<<no string for expression>>");
    6368    return Error::create(exec, e, message, -1, -1, 0); //, lineNo(), currentSourceId(exec), currentSourceURL(exec));
     69}
     70
     71JSValue* createStackOverflowError(ExecState* exec)
     72{
     73    return createError(exec, RangeError, "Stack overflow");
    6474}
    6575
  • branches/squirrelfish/JavaScriptCore/VM/ExceptionHelpers.h

    r32377 r32533  
    3434namespace KJS {
    3535    class Node;
     36    JSValue* createStackOverflowError(ExecState*);
    3637    JSValue* createUndefinedVariableError(ExecState*, const Identifier&);
    3738    JSValue* createNotAnObjectError(ExecState*, JSValue*, Node*);
  • branches/squirrelfish/JavaScriptCore/VM/Machine.cpp

    r32493 r32533  
    378378}
    379379
    380 ALWAYS_INLINE Register* slideRegisterWindowForCall(CodeBlock* newCodeBlock, RegisterFile* registerFile, Register** registerBase, int registerOffset, int argv, int argc)
    381 {
    382     Register* r;
     380ALWAYS_INLINE Register* slideRegisterWindowForCall(ExecState* exec, CodeBlock* newCodeBlock, RegisterFile* registerFile, Register** registerBase, int registerOffset, int argv, int argc, JSValue*& exceptionValue)
     381{
     382    Register* r = 0;
     383    int oldOffset = registerOffset;
    383384    registerOffset += argv + argc + newCodeBlock->numVars;
    384385
    385386    if (argc == newCodeBlock->numParameters) { // correct number of arguments
    386387        size_t size = registerOffset + newCodeBlock->numTemporaries;
    387         registerFile->grow(size);
     388        if (!registerFile->grow(size)) {
     389            exceptionValue = createStackOverflowError(exec);
     390            return *registerBase + oldOffset;
     391        }
    388392        r = (*registerBase) + registerOffset;
    389393    } else if (argc < newCodeBlock->numParameters) { // too few arguments -- fill in the blanks
    390394        int omittedArgCount = newCodeBlock->numParameters - argc;
    391395        size_t size = registerOffset + omittedArgCount + newCodeBlock->numTemporaries;
    392         registerFile->grow(size);
     396        if (!registerFile->grow(size)) {
     397            exceptionValue = createStackOverflowError(exec);
     398            return *registerBase + oldOffset;
     399        }
    393400        r = (*registerBase) + omittedArgCount + registerOffset;
    394401       
     
    398405    } else { // too many arguments -- copy return info and expected arguments, leaving the extra arguments behind
    399406        size_t size = registerOffset + Machine::CallFrameHeaderSize + newCodeBlock->numParameters + newCodeBlock->numTemporaries;
    400         registerFile->grow(size);
     407        if (!registerFile->grow(size)) {
     408            exceptionValue = createStackOverflowError(exec);
     409            return *registerBase + oldOffset;
     410        }
    401411        r = (*registerBase) + Machine::CallFrameHeaderSize + newCodeBlock->numParameters + registerOffset;
    402412       
     
    562572    size_t oldSize = registerFile->size();
    563573    registerFile->grow(oldSize + CallFrameHeaderSize + argc);
    564    
    565574    Register** registerBase = registerFile->basePointer();
    566575    int registerOffset = oldSize;
     
    580589
    581590    CodeBlock* newCodeBlock = &functionBodyNode->code(scopeChain);
    582     Register* r = slideRegisterWindowForCall(newCodeBlock, registerFile, registerBase, registerOffset, argv, argc);
     591    Register* r = slideRegisterWindowForCall(exec, newCodeBlock, registerFile, registerBase, registerOffset, argv, argc, *exception);
     592   
    583593    callFrame = (*registerBase) + callFrameOffset; // registerBase may have moved, recompute callFrame
    584594    scopeChain = scopeChainForCall(newCodeBlock, scopeChain, functionBodyNode, callFrame, registerBase, r);           
     
    587597    registerFile->shrink(oldSize);
    588598    return result;
     599   
    589600}
    590601
     
    613624    size_t oldSize = registerFile->size();
    614625    size_t newSize = registerOffset + codeBlock->numVars + codeBlock->numTemporaries + CallFrameHeaderSize;
    615     registerFile->grow(newSize);
     626    if (!registerFile->grow(newSize)) {
     627        *exception = createStackOverflowError(exec);
     628        return 0;
     629    }
    616630    Register* r = (*registerFile->basePointer()) + registerOffset + codeBlock->numVars + CallFrameHeaderSize;
    617631   
     
    13251339            FunctionBodyNode* functionBodyNode = callData.js.functionBody;
    13261340
    1327             codeBlock = &functionBodyNode->code(callDataScopeChain);
    1328             r = slideRegisterWindowForCall(codeBlock, registerFile, registerBase, registerOffset, argv, argc);
     1341            CodeBlock* newCodeBlock = &functionBodyNode->code(callDataScopeChain);
     1342            r = slideRegisterWindowForCall(exec, newCodeBlock, registerFile, registerBase, registerOffset, argv, argc, exceptionValue);
     1343            if (UNLIKELY(exceptionValue != 0))
     1344                goto vm_throw;
     1345
     1346            codeBlock = newCodeBlock;
    13291347            callFrame = (*registerBase) + callFrameOffset; // registerBase may have moved, recompute callFrame
    13301348            scopeChain = scopeChainForCall(codeBlock, callDataScopeChain, functionBodyNode, callFrame, registerBase, r);           
     
    14271445            FunctionBodyNode* functionBodyNode = constructData.js.functionBody;
    14281446
    1429             codeBlock = &functionBodyNode->code(callDataScopeChain);
    1430             r = slideRegisterWindowForCall(codeBlock, registerFile, registerBase, registerOffset, argv, argc);
     1447            CodeBlock* newCodeBlock = &functionBodyNode->code(callDataScopeChain);
     1448            r = slideRegisterWindowForCall(exec, newCodeBlock, registerFile, registerBase, registerOffset, argv, argc, exceptionValue);
     1449            if (exceptionValue)
     1450                goto vm_throw;
     1451
     1452            codeBlock = newCodeBlock;
    14311453            callFrame = (*registerBase) + callFrameOffset; // registerBase may have moved, recompute callFrame
    14321454            scopeChain = scopeChainForCall(codeBlock, callDataScopeChain, functionBodyNode, callFrame, registerBase, r);           
  • branches/squirrelfish/JavaScriptCore/VM/RegisterFile.cpp

    r32169 r32533  
    3939size_t RegisterFile::newBuffer(size_t size, size_t capacity, size_t minCapacity, size_t offset)
    4040{
    41     capacity = (max(minCapacity, max<size_t>(16, capacity + capacity / 4 + 1)));
     41    capacity = (max(minCapacity, min(m_maxSize, max<size_t>(16, capacity + capacity / 4 + 1))));
    4242    Register* newBuffer = static_cast<Register*>(fastCalloc(capacity, sizeof(Register))); // zero-filled memory
    4343
  • branches/squirrelfish/JavaScriptCore/VM/RegisterFile.h

    r32164 r32533  
    8787    class RegisterFile : Noncopyable {
    8888    public:
    89         RegisterFile(RegisterFileStack* stack)
     89        enum { DefaultRegisterFileSize = 8 * 1024 * 1024 };
     90        RegisterFile(RegisterFileStack* stack, size_t maxSize = DefaultRegisterFileSize)
    9091            : m_size(0)
    9192            , m_capacity(0)
     93            , m_maxSize(maxSize)
    9294            , m_base(0)
    9395            , m_buffer(0)
     
    110112        }
    111113
    112         void grow(size_t size)
     114        bool grow(size_t size)
    113115        {
    114116            if (size > m_size) {
    115                 if (size > m_capacity)
     117                if (size > m_capacity) {
     118                    if (size > DefaultRegisterFileSize)
     119                        return false;
    116120                    growBuffer(size);
     121                }
    117122                m_size = size;
    118123            }
     124            return true;
    119125        }
    120126
     
    148154        size_t m_size;
    149155        size_t m_capacity;
     156        size_t m_maxSize;
    150157        Register* m_base;
    151158        Register* m_buffer;
Note: See TracChangeset for help on using the changeset viewer.