| 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); | 
|  |