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

Reply via email to