Revision: 19812
Author: [email protected]
Date: Tue Mar 11 16:30:47 2014 UTC
Log: Move ParseArguments to ParserBase and add tests.
Notes:
- PreParser didn't produce "too_many_arguments"; now it does.
- The argument count in the error message was wrong; fixed it.
BUG=v8:3126
LOG=N
[email protected]
Review URL: https://codereview.chromium.org/194503004
http://code.google.com/p/v8/source/detail?r=19812
Modified:
/branches/bleeding_edge/src/messages.js
/branches/bleeding_edge/src/parser.cc
/branches/bleeding_edge/src/parser.h
/branches/bleeding_edge/src/preparser.cc
/branches/bleeding_edge/src/preparser.h
/branches/bleeding_edge/test/cctest/test-parsing.cc
=======================================
--- /branches/bleeding_edge/src/messages.js Tue Mar 11 14:39:08 2014 UTC
+++ /branches/bleeding_edge/src/messages.js Tue Mar 11 16:30:47 2014 UTC
@@ -155,8 +155,8 @@
invalid_preparser_data: ["Invalid preparser data for
function ", "%0"],
strict_mode_with: ["Strict mode code may not include a with
statement"],
strict_eval_arguments: ["Unexpected eval or arguments in strict
mode"],
- too_many_arguments: ["Too many arguments in function call
(only 32766 allowed)"],
- too_many_parameters: ["Too many parameters in function
definition (only 32766 allowed)"],
+ too_many_arguments: ["Too many arguments in function call
(only 65535 allowed)"],
+ too_many_parameters: ["Too many parameters in function
definition (only 65535 allowed)"],
too_many_variables: ["Too many variables declared (only
131071 allowed)"],
strict_param_dupe: ["Strict mode function may not have
duplicate parameter names"],
strict_octal_literal: ["Octal literals are not allowed in
strict mode."],
=======================================
--- /branches/bleeding_edge/src/parser.cc Tue Mar 11 15:40:41 2014 UTC
+++ /branches/bleeding_edge/src/parser.cc Tue Mar 11 16:30:47 2014 UTC
@@ -3499,29 +3499,6 @@
Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value)
{
return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot)));
}
-
-
-ZoneList<Expression*>* Parser::ParseArguments(bool* ok) {
- // Arguments ::
- // '(' (AssignmentExpression)*[','] ')'
-
- ZoneList<Expression*>* result = new(zone()) ZoneList<Expression*>(4,
zone());
- Expect(Token::LPAREN, CHECK_OK);
- bool done = (peek() == Token::RPAREN);
- while (!done) {
- Expression* argument = ParseAssignmentExpression(true, CHECK_OK);
- result->Add(argument, zone());
- if (result->length() > Code::kMaxArguments) {
- ReportMessageAt(scanner()->location(), "too_many_arguments");
- *ok = false;
- return NULL;
- }
- done = (peek() == Token::RPAREN);
- if (!done) Expect(Token::COMMA, CHECK_OK);
- }
- Expect(Token::RPAREN, CHECK_OK);
- return result;
-}
class SingletonLogger : public ParserRecorder {
=======================================
--- /branches/bleeding_edge/src/parser.h Tue Mar 11 15:40:41 2014 UTC
+++ /branches/bleeding_edge/src/parser.h Tue Mar 11 16:30:47 2014 UTC
@@ -488,6 +488,9 @@
static Literal* EmptyLiteral() {
return NULL;
}
+ static ZoneList<Expression*>* NullExpressionList() {
+ return NULL;
+ }
// Odd-ball literal creators.
Literal* GetLiteralTheHole(int position,
@@ -687,7 +690,6 @@
Expression* subject,
Statement* body);
- ZoneList<Expression*>* ParseArguments(bool* ok);
FunctionLiteral* ParseFunctionLiteral(
Handle<String> name,
Scanner::Location function_name_location,
=======================================
--- /branches/bleeding_edge/src/preparser.cc Tue Mar 11 15:40:41 2014 UTC
+++ /branches/bleeding_edge/src/preparser.cc Tue Mar 11 16:30:47 2014 UTC
@@ -1135,28 +1135,6 @@
}
-PreParser::Arguments PreParser::ParseArguments(bool* ok) {
- // Arguments ::
- // '(' (AssignmentExpression)*[','] ')'
-
- Expect(Token::LPAREN, ok);
- if (!*ok) return -1;
- bool done = (peek() == Token::RPAREN);
- int argc = 0;
- while (!done) {
- ParseAssignmentExpression(true, ok);
- if (!*ok) return -1;
- argc++;
- done = (peek() == Token::RPAREN);
- if (!done) {
- Expect(Token::COMMA, ok);
- if (!*ok) return -1;
- }
- }
- Expect(Token::RPAREN, ok);
- return argc;
-}
-
PreParser::Expression PreParser::ParseFunctionLiteral(
Identifier function_name,
Scanner::Location function_name_location,
=======================================
--- /branches/bleeding_edge/src/preparser.h Tue Mar 11 15:40:41 2014 UTC
+++ /branches/bleeding_edge/src/preparser.h Tue Mar 11 16:30:47 2014 UTC
@@ -342,6 +342,7 @@
typename Traits::Type::Expression ParseExpression(bool accept_IN, bool*
ok);
typename Traits::Type::Expression ParseArrayLiteral(bool* ok);
typename Traits::Type::Expression ParseObjectLiteral(bool* ok);
+ typename Traits::Type::ExpressionList ParseArguments(bool* ok);
// Used to detect duplicates in object literals. Each of the values
// kGetterProperty, kSetterProperty and kValueProperty represents
@@ -556,8 +557,12 @@
class PreParserExpressionList {
public:
// These functions make list->Add(some_expression) work (and do nothing).
+ PreParserExpressionList() : length_(0) {}
PreParserExpressionList* operator->() { return this; }
- void Add(PreParserExpression, void*) { }
+ void Add(PreParserExpression, void*) { ++length_; }
+ int length() const { return length_; }
+ private:
+ int length_;
};
@@ -720,6 +725,9 @@
static PreParserExpression EmptyLiteral() {
return PreParserExpression::Default();
}
+ static PreParserExpressionList NullExpressionList() {
+ return PreParserExpressionList();
+ }
// Odd-ball literal creators.
static PreParserExpression GetLiteralTheHole(int position,
@@ -910,8 +918,6 @@
kUnknownSourceElements
};
- typedef int Arguments;
-
// All ParseXXX functions take as the last argument an *ok parameter
// which is set to false if parsing failed; it is unchanged otherwise.
// By making the 'exception handling' explicit, we are forced to check
@@ -955,7 +961,6 @@
Expression ParseObjectLiteral(bool* ok);
Expression ParseV8Intrinsic(bool* ok);
- Arguments ParseArguments(bool* ok);
Expression ParseFunctionLiteral(
Identifier name,
Scanner::Location function_name_location,
@@ -1153,6 +1158,13 @@
#define DUMMY ) // to make indentation work
#undef DUMMY
+// Used in functions where the return type is not Traits::Type::Expression.
+#define CHECK_OK_CUSTOM(x) ok); \
+ if (!*ok) return this->x(); \
+ ((void)0
+#define DUMMY ) // to make indentation work
+#undef DUMMY
+
template <class Traits>
typename Traits::Type::Expression
ParserBase<Traits>::ParsePrimaryExpression(
bool* ok) {
@@ -1370,7 +1382,10 @@
number_of_boilerplate_properties++;
}
properties->Add(property, zone());
- if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK);
+ if (peek() != Token::RBRACE) {
+ // Need {} because of the CHECK_OK macro.
+ Expect(Token::COMMA, CHECK_OK);
+ }
if (fni_ != NULL) {
fni_->Infer();
@@ -1437,7 +1452,10 @@
properties->Add(property, zone());
// TODO(1240767): Consider allowing trailing comma.
- if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK);
+ if (peek() != Token::RBRACE) {
+ // Need {} because of the CHECK_OK macro.
+ Expect(Token::COMMA, CHECK_OK);
+ }
if (fni_ != NULL) {
fni_->Infer();
@@ -1457,8 +1475,39 @@
}
+template <class Traits>
+typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments(
+ bool* ok) {
+ // Arguments ::
+ // '(' (AssignmentExpression)*[','] ')'
+
+ typename Traits::Type::ExpressionList result =
+ this->NewExpressionList(4, zone_);
+ Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList));
+ bool done = (peek() == Token::RPAREN);
+ while (!done) {
+ typename Traits::Type::Expression argument =
+ this->ParseAssignmentExpression(true,
+
CHECK_OK_CUSTOM(NullExpressionList));
+ result->Add(argument, zone_);
+ if (result->length() > Code::kMaxArguments) {
+ ReportMessageAt(scanner()->location(), "too_many_arguments");
+ *ok = false;
+ return this->NullExpressionList();
+ }
+ done = (peek() == Token::RPAREN);
+ if (!done) {
+ // Need {} because of the CHECK_OK_CUSTOM macro.
+ Expect(Token::COMMA, CHECK_OK_CUSTOM(NullExpressionList));
+ }
+ }
+ Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList));
+ return result;
+}
+
#undef CHECK_OK
+#undef CHECK_OK_CUSTOM
template <typename Traits>
=======================================
--- /branches/bleeding_edge/test/cctest/test-parsing.cc Tue Mar 11 14:41:22
2014 UTC
+++ /branches/bleeding_edge/test/cctest/test-parsing.cc Tue Mar 11 16:30:47
2014 UTC
@@ -35,6 +35,7 @@
#include "compiler.h"
#include "execution.h"
#include "isolate.h"
+#include "objects.h"
#include "parser.h"
#include "preparser.h"
#include "scanner-character-streams.h"
@@ -1463,7 +1464,9 @@
void RunParserSyncTest(const char* context_data[][2],
const char* statement_data[],
- ParserSyncTestResult result) {
+ ParserSyncTestResult result,
+ const ParserFlag* flags = NULL,
+ int flags_len = 0) {
v8::HandleScope handles(CcTest::isolate());
v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate());
v8::Context::Scope context_scope(context);
@@ -1472,10 +1475,14 @@
CcTest::i_isolate()->stack_guard()->SetStackLimit(
reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
- static const ParserFlag flags[] = {
+ static const ParserFlag default_flags[] = {
kAllowLazy, kAllowHarmonyScoping, kAllowModules, kAllowGenerators,
kAllowForOf, kAllowNativesSyntax
};
+ if (!flags) {
+ flags = default_flags;
+ flags_len = ARRAY_SIZE(default_flags);
+ }
for (int i = 0; context_data[i][0] != NULL; ++i) {
for (int j = 0; statement_data[j] != NULL; ++j) {
int kPrefixLen = i::StrLength(context_data[i][0]);
@@ -1493,7 +1500,7 @@
CHECK(length == kProgramSize);
TestParserSync(program.start(),
flags,
- ARRAY_SIZE(flags),
+ flags_len,
result);
}
}
@@ -2320,3 +2327,27 @@
RunParserSyncTest(context_data, statement_data, kSuccess);
}
+
+
+TEST(TooManyArguments) {
+ const char* context_data[][2] = {
+ {"foo(", "0)"},
+ { NULL, NULL }
+ };
+
+ using v8::internal::Code;
+ char statement[Code::kMaxArguments * 2];
+ for (int i = 0; i < Code::kMaxArguments; ++i) {
+ statement[2 * i] = '0';
+ statement[2 * i + 1] = ',';
+ }
+
+ const char* statement_data[] = {
+ statement,
+ NULL
+ };
+
+ // The test is quite slow, so run it with a reduced set of flags.
+ static const ParserFlag empty_flags[] = {kAllowLazy};
+ RunParserSyncTest(context_data, statement_data, kError, empty_flags, 1);
+}
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.