| Index: src/parser.cc
 | 
| diff --git a/src/parser.cc b/src/parser.cc
 | 
| index 5ea1c5e083ac44a15ea4ac100f1f6848d9d4fffd..61f90377415f23e20e089f76e3f4373c29d95758 100644
 | 
| --- a/src/parser.cc
 | 
| +++ b/src/parser.cc
 | 
| @@ -283,6 +283,11 @@ class TemporaryScope BASE_EMBEDDED {
 | 
|    void AddLoop() { loop_count_++; }
 | 
|    bool ContainsLoops() const { return loop_count_ > 0; }
 | 
|  
 | 
| +  bool StrictMode() { return strict_mode_; }
 | 
| +  void EnableStrictMode() {
 | 
| +    strict_mode_ = FLAG_strict_mode;
 | 
| +  }
 | 
| +
 | 
|   private:
 | 
|    // Captures the number of literals that need materialization in the
 | 
|    // function.  Includes regexp literals, and boilerplate for object
 | 
| @@ -300,6 +305,9 @@ class TemporaryScope BASE_EMBEDDED {
 | 
|    // Captures the number of loops inside the scope.
 | 
|    int loop_count_;
 | 
|  
 | 
| +  // Parsing strict mode code.
 | 
| +  bool strict_mode_;
 | 
| +
 | 
|    // Bookkeeping
 | 
|    TemporaryScope** variable_;
 | 
|    TemporaryScope* parent_;
 | 
| @@ -314,6 +322,8 @@ TemporaryScope::TemporaryScope(TemporaryScope** variable)
 | 
|      loop_count_(0),
 | 
|      variable_(variable),
 | 
|      parent_(*variable) {
 | 
| +  // Inherit the strict mode from the parent scope.
 | 
| +  strict_mode_ = (parent_ != NULL) && parent_->strict_mode_;
 | 
|    *variable = this;
 | 
|  }
 | 
|  
 | 
| @@ -561,7 +571,6 @@ class LexicalScope BASE_EMBEDDED {
 | 
|    int prev_level_;
 | 
|  };
 | 
|  
 | 
| -
 | 
|  // ----------------------------------------------------------------------------
 | 
|  // The CHECK_OK macro is a convenient macro to enforce error
 | 
|  // handling for functions that may fail (by returning !*ok).
 | 
| @@ -668,7 +677,8 @@ FunctionLiteral* Parser::DoParseProgram(Handle<String> source,
 | 
|            0,
 | 
|            source->length(),
 | 
|            false,
 | 
| -          temp_scope.ContainsLoops());
 | 
| +          temp_scope.ContainsLoops(),
 | 
| +          temp_scope.StrictMode());
 | 
|      } else if (stack_overflow_) {
 | 
|        Top::StackOverflow();
 | 
|      }
 | 
| @@ -1058,9 +1068,46 @@ void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
 | 
|    ASSERT(processor != NULL);
 | 
|    InitializationBlockFinder block_finder;
 | 
|    ThisNamedPropertyAssigmentFinder this_property_assignment_finder;
 | 
| +  bool directive_prologue = true;     // Parsing directive prologue.
 | 
| +
 | 
|    while (peek() != end_token) {
 | 
| +    if (directive_prologue && peek() != Token::STRING) {
 | 
| +      directive_prologue = false;
 | 
| +    }
 | 
| +
 | 
| +    Scanner::Location token_loc = scanner().peek_location();
 | 
|      Statement* stat = ParseStatement(NULL, CHECK_OK);
 | 
| -    if (stat == NULL || stat->IsEmpty()) continue;
 | 
| +
 | 
| +    if (stat == NULL || stat->IsEmpty()) {
 | 
| +      directive_prologue = false;   // End of directive prologue.
 | 
| +      continue;
 | 
| +    }
 | 
| +
 | 
| +    if (directive_prologue) {
 | 
| +      // A shot at a directive.
 | 
| +      ExpressionStatement *e_stat;
 | 
| +      Literal *literal;
 | 
| +      // Still processing directive prologue?
 | 
| +      if ((e_stat = stat->AsExpressionStatement()) != NULL &&
 | 
| +          (literal = e_stat->expression()->AsLiteral()) != NULL &&
 | 
| +          literal->handle()->IsString()) {
 | 
| +        Handle<String> directive = Handle<String>::cast(literal->handle());
 | 
| +
 | 
| +        // Check "use strict" directive (ES5 14.1).
 | 
| +        if (!temp_scope_->StrictMode() &&
 | 
| +            directive->Equals(Heap::use_strict()) &&
 | 
| +            token_loc.end_pos - token_loc.beg_pos ==
 | 
| +              Heap::use_strict()->length() + 2) {
 | 
| +          temp_scope_->EnableStrictMode();
 | 
| +          // "use strict" is the only directive for now.
 | 
| +          directive_prologue = false;
 | 
| +        }
 | 
| +      } else {
 | 
| +        // End of the directive prologue.
 | 
| +        directive_prologue = false;
 | 
| +      }
 | 
| +    }
 | 
| +
 | 
|      // We find and mark the initialization blocks on top level code only.
 | 
|      // This is because the optimization prevents reuse of the map transitions,
 | 
|      // so it should be used only for code that will only be run once.
 | 
| @@ -1414,6 +1461,10 @@ Block* Parser::ParseVariableStatement(bool* ok) {
 | 
|    return result;
 | 
|  }
 | 
|  
 | 
| +static bool IsEvalOrArguments(Handle<String> string) {
 | 
| +  return string.is_identical_to(Factory::eval_symbol()) ||
 | 
| +         string.is_identical_to(Factory::arguments_symbol());
 | 
| +}
 | 
|  
 | 
|  // If the variable declaration declares exactly one non-const
 | 
|  // variable, then *var is set to that variable. In all other cases,
 | 
| @@ -1462,6 +1513,13 @@ Block* Parser::ParseVariableDeclarations(bool accept_IN,
 | 
|      Handle<String> name = ParseIdentifier(CHECK_OK);
 | 
|      if (fni_ != NULL) fni_->PushVariableName(name);
 | 
|  
 | 
| +    // Strict mode variables may not be named eval or arguments
 | 
| +    if (temp_scope_->StrictMode() && IsEvalOrArguments(name)) {
 | 
| +      ReportMessage("strict_var_name", Vector<const char*>::empty());
 | 
| +      *ok = false;
 | 
| +      return NULL;
 | 
| +    }
 | 
| +
 | 
|      // Declare variable.
 | 
|      // Note that we *always* must treat the initial value via a separate init
 | 
|      // assignment for variables and constants because the value must be assigned
 | 
| @@ -1814,6 +1872,13 @@ Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) {
 | 
|    //   'with' '(' Expression ')' Statement
 | 
|  
 | 
|    Expect(Token::WITH, CHECK_OK);
 | 
| +
 | 
| +  if (temp_scope_->StrictMode()) {
 | 
| +    ReportMessage("strict_mode_with", Vector<const char*>::empty());
 | 
| +    *ok = false;
 | 
| +    return NULL;
 | 
| +  }
 | 
| +
 | 
|    Expect(Token::LPAREN, CHECK_OK);
 | 
|    Expression* expr = ParseExpression(true, CHECK_OK);
 | 
|    Expect(Token::RPAREN, CHECK_OK);
 | 
| @@ -1946,6 +2011,13 @@ TryStatement* Parser::ParseTryStatement(bool* ok) {
 | 
|  
 | 
|      Expect(Token::LPAREN, CHECK_OK);
 | 
|      Handle<String> name = ParseIdentifier(CHECK_OK);
 | 
| +
 | 
| +    if (temp_scope_->StrictMode() && IsEvalOrArguments(name)) {
 | 
| +      ReportMessage("strict_catch_variable", Vector<const char*>::empty());
 | 
| +      *ok = false;
 | 
| +      return NULL;
 | 
| +    }
 | 
| +
 | 
|      Expect(Token::RPAREN, CHECK_OK);
 | 
|  
 | 
|      if (peek() == Token::LBRACE) {
 | 
| @@ -3192,11 +3264,12 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
 | 
|      //    '(' (Identifier)*[','] ')'
 | 
|      Expect(Token::LPAREN, CHECK_OK);
 | 
|      int start_pos = scanner().location().beg_pos;
 | 
| +
 | 
|      bool done = (peek() == Token::RPAREN);
 | 
|      while (!done) {
 | 
|        Handle<String> param_name = ParseIdentifier(CHECK_OK);
 | 
| -      top_scope_->AddParameter(top_scope_->DeclareLocal(param_name,
 | 
| -                                                        Variable::VAR));
 | 
| +      Variable* parameter = top_scope_->DeclareLocal(param_name, Variable::VAR);
 | 
| +      top_scope_->AddParameter(parameter);
 | 
|        num_parameters++;
 | 
|        done = (peek() == Token::RPAREN);
 | 
|        if (!done) Expect(Token::COMMA, CHECK_OK);
 | 
| @@ -3265,6 +3338,20 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
 | 
|        end_pos = scanner().location().end_pos;
 | 
|      }
 | 
|  
 | 
| +    // Validate strict mode.
 | 
| +    if (temp_scope_->StrictMode()) {
 | 
| +      if (IsEvalOrArguments(name)) {
 | 
| +        int position = function_token_position != RelocInfo::kNoPosition
 | 
| +                         ? function_token_position
 | 
| +                         : (start_pos > 0 ? start_pos - 1 : start_pos);
 | 
| +        ReportMessageAt(Scanner::Location(position, start_pos),
 | 
| +                        "strict_function_name", Vector<const char*>::empty());
 | 
| +        *ok = false;
 | 
| +        return NULL;
 | 
| +      }
 | 
| +      // TODO(mmaly): Check for octal escape sequence here.
 | 
| +    }
 | 
| +
 | 
|      FunctionLiteral* function_literal =
 | 
|          new FunctionLiteral(name,
 | 
|                              top_scope_,
 | 
| @@ -3277,7 +3364,8 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
 | 
|                              start_pos,
 | 
|                              end_pos,
 | 
|                              function_name->length() > 0,
 | 
| -                            temp_scope.ContainsLoops());
 | 
| +                            temp_scope.ContainsLoops(),
 | 
| +                            temp_scope.StrictMode());
 | 
|      function_literal->set_function_token_position(function_token_position);
 | 
|  
 | 
|      if (fni_ != NULL && !is_named) fni_->AddFunction(function_literal);
 | 
| 
 |