Revision: 6446
Author: [email protected]
Date: Mon Jan 24 10:13:18 2011
Log: Strict mode octal literals.
http://code.google.com/p/v8/source/detail?r=6446
Modified:
/branches/bleeding_edge/src/messages.js
/branches/bleeding_edge/src/parser.cc
/branches/bleeding_edge/src/parser.h
/branches/bleeding_edge/src/scanner-base.cc
/branches/bleeding_edge/src/scanner-base.h
/branches/bleeding_edge/test/mjsunit/strict-mode.js
=======================================
--- /branches/bleeding_edge/src/messages.js Sun Jan 23 23:59:40 2011
+++ /branches/bleeding_edge/src/messages.js Mon Jan 24 10:13:18 2011
@@ -216,6 +216,7 @@
strict_param_dupe: "Strict mode function may not have
duplicate parameter names",
strict_var_name: "Variable name may not be eval or
arguments in strict mode",
strict_function_name: "Function name may not be eval or
arguments in strict mode",
+ strict_octal_literal: "Octal literals are not allowed in
strict mode.",
};
}
var format = kMessages[message.type];
=======================================
--- /branches/bleeding_edge/src/parser.cc Thu Jan 20 10:51:47 2011
+++ /branches/bleeding_edge/src/parser.cc Mon Jan 24 10:13:18 2011
@@ -664,7 +664,11 @@
TemporaryScope temp_scope(&this->temp_scope_);
ZoneList<Statement*>* body = new ZoneList<Statement*>(16);
bool ok = true;
+ int beg_loc = scanner().location().beg_pos;
ParseSourceElements(body, Token::EOS, &ok);
+ if (ok && temp_scope_->StrictMode()) {
+ CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok);
+ }
if (ok) {
result = new FunctionLiteral(
no_name,
@@ -3384,7 +3388,7 @@
*ok = false;
return NULL;
}
- // TODO(mmaly): Check for octal escape sequence here.
+ CheckOctalLiteral(start_pos, end_pos, CHECK_OK);
}
FunctionLiteral* function_literal =
@@ -3529,6 +3533,18 @@
}
return GetSymbol(ok);
}
+
+// Checks whether octal literal last seen is between beg_pos and end_pos.
+// If so, reports an error.
+void Parser::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) {
+ int octal = scanner().octal_position();
+ if (beg_pos <= octal && octal <= end_pos) {
+ ReportMessageAt(Scanner::Location(octal, octal +
1), "strict_octal_literal",
+ Vector<const char*>::empty());
+ scanner().clear_octal_position();
+ *ok = false;
+ }
+}
// This function reads an identifier and determines whether or not it
=======================================
--- /branches/bleeding_edge/src/parser.h Mon Jan 17 01:36:10 2011
+++ /branches/bleeding_edge/src/parser.h Mon Jan 24 10:13:18 2011
@@ -613,6 +613,9 @@
bool* is_set,
bool* ok);
+ // Strict mode octal literal validation.
+ void CheckOctalLiteral(int beg_pos, int end_pos, bool* ok);
+
// Parser support
VariableProxy* Declare(Handle<String> name, Variable::Mode mode,
FunctionLiteral* fun,
=======================================
--- /branches/bleeding_edge/src/scanner-base.cc Fri Jan 7 04:35:42 2011
+++ /branches/bleeding_edge/src/scanner-base.cc Mon Jan 24 10:13:18 2011
@@ -64,7 +64,8 @@
//
----------------------------------------------------------------------------
// Scanner
-Scanner::Scanner() { }
+Scanner::Scanner()
+ : octal_pos_(kNoOctalLocation) { }
uc32 Scanner::ScanHexEscape(uc32 c, int length) {
@@ -98,6 +99,7 @@
// Octal escapes of the forms '\0xx' and '\xxx' are not a part of
// ECMA-262. Other JS VMs support them.
uc32 Scanner::ScanOctalEscape(uc32 c, int length) {
+ octal_pos_ = source_pos() - 1; // Already advanced
uc32 x = c - '0';
for (int i = 0; i < length; i++) {
int d = c0_ - '0';
@@ -601,7 +603,11 @@
kind = DECIMAL;
break;
}
- if (c0_ < '0' || '7' < c0_) break;
+ if (c0_ < '0' || '7' < c0_) {
+ // Octal literal finished.
+ octal_pos_ = next_.location.beg_pos;
+ break;
+ }
AddLiteralCharAdvance();
}
}
=======================================
--- /branches/bleeding_edge/src/scanner-base.h Fri Jan 14 02:49:18 2011
+++ /branches/bleeding_edge/src/scanner-base.h Mon Jan 24 10:13:18 2011
@@ -247,6 +247,9 @@
// Generic functionality used by both JSON and JavaScript scanners.
class Scanner {
public:
+ // -1 is outside of the range of any real source code.
+ static const int kNoOctalLocation = -1;
+
typedef unibrow::Utf8InputBuffer<1024> Utf8Decoder;
class LiteralScope {
@@ -279,6 +282,10 @@
// (the token returned by Next()).
Location location() const { return current_.location; }
Location peek_location() const { return next_.location; }
+
+ // Returns the location of the last seen octal literal
+ int octal_position() const { return octal_pos_; }
+ void clear_octal_position() { octal_pos_ = -1; }
// Returns the literal string, if any, for the current token (the
// token returned by Next()). The string is 0-terminated and in
@@ -410,6 +417,8 @@
// Input stream. Must be initialized to an UC16CharacterStream.
UC16CharacterStream* source_;
+ // Start position of the octal literal last scanned.
+ int octal_pos_;
// One Unicode character look-ahead; c0_ < 0 at the end of the input.
uc32 c0_;
=======================================
--- /branches/bleeding_edge/test/mjsunit/strict-mode.js Thu Jan 20 10:51:47
2011
+++ /branches/bleeding_edge/test/mjsunit/strict-mode.js Mon Jan 24 10:13:18
2011
@@ -115,3 +115,17 @@
}
with ({}) {};
}
+
+// Octal literal
+CheckStrictMode("var x = 012");
+CheckStrictMode("012");
+CheckStrictMode("'Hello octal\\032'");
+CheckStrictMode("function octal() { return 012; }");
+CheckStrictMode("function octal() { return '\\032'; }");
+
+// Octal before "use strict"
+assertThrows('\
+ function strict() {\
+ "octal\\032directive";\
+ "use strict";\
+ }', SyntaxError);
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev