diff options
author | Erik Verbruggen <erik.verbruggen@theqtcompany.com> | 2015-06-09 12:23:43 +0200 |
---|---|---|
committer | Erik Verbruggen <erik.verbruggen@theqtcompany.com> | 2015-06-10 12:47:18 +0000 |
commit | 25ad8b7a1f05f0dee8010f56f42242aa62b6f375 (patch) | |
tree | 09c67645b5f5fedecfc494b511fd0ed2d4d89550 /src/xmlpatterns/parser/qparsercontext.cpp | |
parent | ec9ab0ba6d0e28fc63f9ff28135ec9911ffa882b (diff) | |
download | qtxmlpatterns-25ad8b7a1f05f0dee8010f56f42242aa62b6f375.tar.gz |
Implement bison parser stack re(al)location.
The elements on the parser stack are of a complex type, which bison
generated parsers don't know how to reallocate when they need to grow
the stack. This patch implements yyoverflow, which is called whenever
the parser runs out of stack space.
The size of the elements is quite large (152 bytes on x86_64), so the
initial stack (which is allocated on the C stack) is set to 1 element.
Any subsequent reallocations are done by using QVector for reallocation,
copying the elements, and handling the deallocation. Because of the size
of the elements, the stack (vectors) are grown linearly.
The upper limit of the stack size if left at 10000 elements, which
should really be enough for an lalr(1) grammar.
Task-number: QTBUG-4470
Change-Id: Ic1ef08655b388c38ef452d03a425cbd31b91825b
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
Diffstat (limited to 'src/xmlpatterns/parser/qparsercontext.cpp')
-rw-r--r-- | src/xmlpatterns/parser/qparsercontext.cpp | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/src/xmlpatterns/parser/qparsercontext.cpp b/src/xmlpatterns/parser/qparsercontext.cpp index beb1b0b..a30f07d 100644 --- a/src/xmlpatterns/parser/qparsercontext.cpp +++ b/src/xmlpatterns/parser/qparsercontext.cpp @@ -88,5 +88,29 @@ void ParserContext::finalizePushedVariable(const int amount, } } +void ParserContext::handleStackOverflow(const char *, short **yyss, size_t, + TokenValue **yyvs, size_t, + YYLTYPE **yyls, size_t, + size_t *yystacksize) +{ + bool isFirstTime = parserStack_yyvs.isEmpty(); + Q_ASSERT(*yystacksize < INT_MAX - 50); + int new_yystacksize = static_cast<int>(*yystacksize) + 50; + parserStack_yyss.resize(new_yystacksize); + parserStack_yyvs.resize(new_yystacksize); + parserStack_yyls.resize(new_yystacksize); + if (isFirstTime) { + for (int i = 0, ei = static_cast<int>(*yystacksize); i != ei; ++i) { + parserStack_yyss[i] = (*yyss)[i]; + parserStack_yyvs[i] = (*yyvs)[i]; + parserStack_yyls[i] = (*yyls)[i]; + } + } + *yyss = parserStack_yyss.data(); + *yyvs = parserStack_yyvs.data(); + *yyls = parserStack_yyls.data(); + *yystacksize = new_yystacksize; +} + QT_END_NAMESPACE |