Commit dd4a6e42 authored by barraclough@apple.com's avatar barraclough@apple.com
Browse files

Bug 51358 - Should check stack depth rather than using recursion limits in byte compilation

Reviewed by Olver Hunt.

The current implementation of recursion limit checking is not safe on smaller stacks.
Switch to using a common mechanism, shared with the parser, to check recursion limits.

Make bytecompiler use StackBounds. Empirical testing shows emitStrcat to have the largest
footprint on the stack, at just under 1k on x86-64.  Given this, the default recursion
check (requiring 4k of available space to recurse) seems reasonable.

* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::BytecodeGenerator):
* bytecompiler/BytecodeGenerator.h:
(JSC::BytecodeGenerator::emitNode):
(JSC::BytecodeGenerator::emitNodeInConditionContext):
* bytecompiler/NodesCodegen.cpp:
(JSC::BinaryOpNode::emitStrcat):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@74374 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 1ef080e2
2010-12-20 Gavin Barraclough <barraclough@apple.com>
Reviewed by Olver Hunt.
Bug 51358 - Should check stack depth rather than using recursion limits in byte compilation
The current implementation of recursion limit checking is not safe on smaller stacks.
Switch to using a common mechanism, shared with the parser, to check recursion limits.
Make bytecompiler use StackBounds. Empirical testing shows emitStrcat to have the largest
footprint on the stack, at just under 1k on x86-64. Given this, the default recursion
check (requiring 4k of available space to recurse) seems reasonable.
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::BytecodeGenerator):
* bytecompiler/BytecodeGenerator.h:
(JSC::BytecodeGenerator::emitNode):
(JSC::BytecodeGenerator::emitNodeInConditionContext):
* bytecompiler/NodesCodegen.cpp:
(JSC::BinaryOpNode::emitStrcat):
2010-12-20 Tony Gentilcore <tonyg@chromium.org>
 
Unreviewed build fix.
......
......@@ -218,7 +218,7 @@ BytecodeGenerator::BytecodeGenerator(ProgramNode* programNode, const ScopeChain&
#ifndef NDEBUG
, m_lastOpcodePosition(0)
#endif
, m_emitNodeDepth(0)
, m_stack(m_globalData->stack())
, m_usesExceptions(false)
, m_regeneratingForExceptionInfo(false)
, m_codeBlockBeingRegeneratedFrom(0)
......@@ -312,7 +312,7 @@ BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, const Scope
#ifndef NDEBUG
, m_lastOpcodePosition(0)
#endif
, m_emitNodeDepth(0)
, m_stack(m_globalData->stack())
, m_usesExceptions(false)
, m_regeneratingForExceptionInfo(false)
, m_codeBlockBeingRegeneratedFrom(0)
......@@ -477,7 +477,7 @@ BytecodeGenerator::BytecodeGenerator(EvalNode* evalNode, const ScopeChain& scope
#ifndef NDEBUG
, m_lastOpcodePosition(0)
#endif
, m_emitNodeDepth(0)
, m_stack(m_globalData->stack())
, m_usesExceptions(false)
, m_regeneratingForExceptionInfo(false)
, m_codeBlockBeingRegeneratedFrom(0)
......
......@@ -208,13 +208,9 @@ namespace JSC {
// Node::emitCode assumes that dst, if provided, is either a local or a referenced temporary.
ASSERT(!dst || dst == ignoredResult() || !dst->isTemporary() || dst->refCount());
addLineInfo(n->lineNo());
if (m_emitNodeDepth >= s_maxEmitNodeDepth)
return emitThrowExpressionTooDeepException();
++m_emitNodeDepth;
RegisterID* r = n->emitBytecode(*this, dst);
--m_emitNodeDepth;
return r;
return m_stack.recursionCheck()
? n->emitBytecode(*this, dst)
: emitThrowExpressionTooDeepException();
}
RegisterID* emitNode(Node* n)
......@@ -225,13 +221,10 @@ namespace JSC {
void emitNodeInConditionContext(ExpressionNode* n, Label* trueTarget, Label* falseTarget, bool fallThroughMeansTrue)
{
addLineInfo(n->lineNo());
if (m_emitNodeDepth >= s_maxEmitNodeDepth) {
if (m_stack.recursionCheck())
n->emitBytecodeInConditionContext(*this, trueTarget, falseTarget, fallThroughMeansTrue);
else
emitThrowExpressionTooDeepException();
return;
}
++m_emitNodeDepth;
n->emitBytecodeInConditionContext(*this, trueTarget, falseTarget, fallThroughMeansTrue);
--m_emitNodeDepth;
}
void emitExpressionInfo(unsigned divot, unsigned startOffset, unsigned endOffset)
......@@ -583,13 +576,11 @@ namespace JSC {
size_t m_lastOpcodePosition;
#endif
unsigned m_emitNodeDepth;
StackBounds m_stack;
bool m_usesExceptions;
bool m_regeneratingForExceptionInfo;
CodeBlock* m_codeBlockBeingRegeneratedFrom;
static const unsigned s_maxEmitNodeDepth = 5000;
};
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment