Revision: 10759
Author:   [email protected]
Date:     Mon Feb 20 06:02:59 2012
Log:      Parsing of basic module declarations (no imports/exports yet).

Module definitions are not compiled or otherwise executed yet.
Toplevel module identifiers are bound but never initialized.

[email protected],[email protected]
BUG=
TEST=

Review URL: https://chromiumcodereview.appspot.com/9401008
http://code.google.com/p/v8/source/detail?r=10759

Added:
 /branches/bleeding_edge/test/mjsunit/harmony/module-parsing.js
Modified:
 /branches/bleeding_edge/src/ast.h
 /branches/bleeding_edge/src/contexts.h
 /branches/bleeding_edge/src/flag-definitions.h
 /branches/bleeding_edge/src/heap.cc
 /branches/bleeding_edge/src/heap.h
 /branches/bleeding_edge/src/parser.cc
 /branches/bleeding_edge/src/parser.h
 /branches/bleeding_edge/src/prettyprinter.cc
 /branches/bleeding_edge/src/runtime.cc
 /branches/bleeding_edge/src/scopes.cc
 /branches/bleeding_edge/src/scopes.h
 /branches/bleeding_edge/src/v8globals.h

=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/harmony/module-parsing.js Mon Feb 20 06:02:59 2012
@@ -0,0 +1,80 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --harmony-modules
+
+// Test basic module syntax, with and without ASI.
+
+module A {}
+
+module A1 = A
+module A2 = A;
+module A3 = A2
+
+module B {
+  var x
+  var x, y;
+  var x = 0, y
+  let x, y
+  let z = 1
+  const c = 9
+  function f() {}
+  module C {
+    let x
+    module D {}
+    let y
+  }
+  let zz = ""
+}
+
+module C1 = B.C;
+module D1 = B.C.D
+module D2 = C1.D
+module D3 = D2
+
+module E1 at "http://where";
+module E2 at "http://where";;
+module E3 = E1.F
+
+
+// Check that ASI does not interfere.
+
+module
+X
+{
+let x
+}
+
+module
+Y
+=
+X
+
+module
+Z
+at
+"file://local"
=======================================
--- /branches/bleeding_edge/src/ast.h   Tue Feb 14 06:14:51 2012
+++ /branches/bleeding_edge/src/ast.h   Mon Feb 20 06:02:59 2012
@@ -548,17 +548,17 @@
  public:
   DECLARE_NODE_TYPE(ModuleVariable)

-  Variable* var() const { return var_; }
+  VariableProxy* proxy() const { return proxy_; }

  protected:
   template<class> friend class AstNodeFactory;

-  explicit ModuleVariable(Variable* var)
-      : var_(var) {
+  explicit ModuleVariable(VariableProxy* proxy)
+      : proxy_(proxy) {
   }

  private:
-  Variable* var_;
+  VariableProxy* proxy_;
 };


@@ -2536,19 +2536,19 @@
     VISIT_AND_RETURN(ModuleLiteral, module)
   }

-  ModuleVariable* NewModuleVariable(Variable* var) {
-    ModuleVariable* module = new(zone_) ModuleVariable(var);
-    VISIT_AND_RETURN(ModuleLiteral, module)
+  ModuleVariable* NewModuleVariable(VariableProxy* proxy) {
+    ModuleVariable* module = new(zone_) ModuleVariable(proxy);
+    VISIT_AND_RETURN(ModuleVariable, module)
   }

   ModulePath* NewModulePath(Module* origin, Handle<String> name) {
     ModulePath* module = new(zone_) ModulePath(origin, name);
-    VISIT_AND_RETURN(ModuleLiteral, module)
+    VISIT_AND_RETURN(ModulePath, module)
   }

   ModuleUrl* NewModuleUrl(Handle<String> url) {
     ModuleUrl* module = new(zone_) ModuleUrl(url);
-    VISIT_AND_RETURN(ModuleLiteral, module)
+    VISIT_AND_RETURN(ModuleUrl, module)
   }

   Block* NewBlock(ZoneStringList* labels,
=======================================
--- /branches/bleeding_edge/src/contexts.h      Thu Feb  2 03:22:26 2012
+++ /branches/bleeding_edge/src/contexts.h      Mon Feb 20 06:02:59 2012
@@ -356,6 +356,10 @@
     Map* map = this->map();
     return map == map->GetHeap()->block_context_map();
   }
+  bool IsModuleContext() {
+    Map* map = this->map();
+    return map == map->GetHeap()->module_context_map();
+  }

   // Tells whether the global context is marked with out of memory.
   inline bool has_out_of_memory();
=======================================
--- /branches/bleeding_edge/src/flag-definitions.h      Mon Feb 20 05:48:24 2012
+++ /branches/bleeding_edge/src/flag-definitions.h      Mon Feb 20 06:02:59 2012
@@ -111,7 +111,8 @@

 DEFINE_bool(harmony_typeof, false, "enable harmony semantics for typeof")
 DEFINE_bool(harmony_scoping, false, "enable harmony block scoping")
-DEFINE_bool(harmony_modules, false, "enable harmony modules")
+DEFINE_bool(harmony_modules, false,
+            "enable harmony modules (implies block scoping)")
 DEFINE_bool(harmony_proxies, false, "enable harmony proxies")
 DEFINE_bool(harmony_collections, false,
             "enable harmony collections (sets, maps, and weak maps)")
@@ -120,6 +121,7 @@
 DEFINE_implication(harmony, harmony_modules)
 DEFINE_implication(harmony, harmony_proxies)
 DEFINE_implication(harmony, harmony_collections)
+DEFINE_implication(harmony_modules, harmony_scoping)

 // Flags for experimental implementation features.
 DEFINE_bool(smi_only_arrays, true, "tracks arrays with only smi values")
=======================================
--- /branches/bleeding_edge/src/heap.cc Mon Feb 20 04:57:23 2012
+++ /branches/bleeding_edge/src/heap.cc Mon Feb 20 06:02:59 2012
@@ -2230,6 +2230,12 @@
   }
   set_block_context_map(Map::cast(obj));

+  { MaybeObject* maybe_obj =
+        AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
+    if (!maybe_obj->ToObject(&obj)) return false;
+  }
+  set_module_context_map(Map::cast(obj));
+
   { MaybeObject* maybe_obj =
         AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
     if (!maybe_obj->ToObject(&obj)) return false;
=======================================
--- /branches/bleeding_edge/src/heap.h  Mon Feb 20 04:57:23 2012
+++ /branches/bleeding_edge/src/heap.h  Mon Feb 20 06:02:59 2012
@@ -130,6 +130,7 @@
V(Map, catch_context_map, CatchContextMap) \ V(Map, with_context_map, WithContextMap) \ V(Map, block_context_map, BlockContextMap) \ + V(Map, module_context_map, ModuleContextMap) \ V(Map, oddball_map, OddballMap) \ V(Map, message_object_map, JSMessageObjectMap) \ V(Map, foreign_map, ForeignMap) \
=======================================
--- /branches/bleeding_edge/src/parser.cc       Tue Feb 14 06:14:51 2012
+++ /branches/bleeding_edge/src/parser.cc       Mon Feb 20 06:02:59 2012
@@ -653,6 +653,7 @@
   if (result == NULL) zone_scope->DeleteOnExit();
   return result;
 }
+

 FunctionLiteral* Parser::ParseLazy(CompilationInfo* info) {
   ZoneScope zone_scope(isolate(), DONT_DELETE_ON_EXIT);
@@ -1085,34 +1086,13 @@
   ZoneList<int> assigned_arguments_;
   ZoneObjectList assigned_constants_;
 };
-
-
-Statement* Parser::ParseSourceElement(ZoneStringList* labels,
-                                      bool* ok) {
-  // (Ecma 262 5th Edition, clause 14):
-  // SourceElement:
-  //    Statement
-  //    FunctionDeclaration
-  //
-  // In harmony mode we allow additionally the following productions
-  // SourceElement:
-  //    LetDeclaration
-  //    ConstDeclaration
-
-  if (peek() == Token::FUNCTION) {
-    return ParseFunctionDeclaration(ok);
-  } else if (peek() == Token::LET || peek() == Token::CONST) {
-    return ParseVariableStatement(kSourceElement, ok);
-  }
-  return ParseStatement(labels, ok);
-}


 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
                                   int end_token,
                                   bool* ok) {
   // SourceElements ::
-  //   (SourceElement)* <end_token>
+  //   (ModuleElement)* <end_token>

   // Allocate a target stack to use for this set of source
   // elements. This way, all scripts and functions get their own
@@ -1131,7 +1111,7 @@
     }

     Scanner::Location token_loc = scanner().peek_location();
-    Statement* stat = ParseSourceElement(NULL, CHECK_OK);
+    Statement* stat = ParseModuleElement(NULL, CHECK_OK);
     if (stat == NULL || stat->IsEmpty()) {
       directive_prologue = false;   // End of directive prologue.
       continue;
@@ -1185,6 +1165,194 @@
   }
   return 0;
 }
+
+
+Statement* Parser::ParseModuleElement(ZoneStringList* labels,
+                                      bool* ok) {
+  // (Ecma 262 5th Edition, clause 14):
+  // SourceElement:
+  //    Statement
+  //    FunctionDeclaration
+  //
+  // In harmony mode we allow additionally the following productions
+  // ModuleElement:
+  //    LetDeclaration
+  //    ConstDeclaration
+  //    ModuleDeclaration
+  //    ImportDeclaration
+  //    ExportDeclaration
+
+  switch (peek()) {
+    case Token::FUNCTION:
+      return ParseFunctionDeclaration(ok);
+    case Token::LET:
+    case Token::CONST:
+      return ParseVariableStatement(kModuleElement, ok);
+    case Token::MODULE:
+      return ParseModuleDeclaration(ok);
+    case Token::IMPORT:
+      return ParseImportDeclaration(ok);
+    case Token::EXPORT:
+      return ParseExportDeclaration(ok);
+    default:
+      return ParseStatement(labels, ok);
+  }
+}
+
+
+Block* Parser::ParseModuleDeclaration(bool* ok) {
+  // ModuleDeclaration:
+  //    'module' Identifier Module
+
+  // Create new block with one expected declaration.
+  Block* block = factory()->NewBlock(NULL, 1, true);
+  Expect(Token::MODULE, CHECK_OK);
+  Handle<String> name = ParseIdentifier(CHECK_OK);
+  // top_scope_->AddDeclaration(
+  //     factory()->NewModuleDeclaration(proxy, module, top_scope_));
+  VariableProxy* proxy = Declare(name, LET, NULL, true, CHECK_OK);
+  Module* module = ParseModule(ok);
+  // TODO(rossberg): Add initialization statement to block.
+  USE(proxy);
+  USE(module);
+  return block;
+}
+
+
+Module* Parser::ParseModule(bool* ok) {
+  // Module:
+  //    '{' ModuleElement '}'
+  //    '=' ModulePath
+  //    'at' String
+
+  switch (peek()) {
+    case Token::LBRACE:
+      return ParseModuleLiteral(ok);
+
+    case Token::ASSIGN:
+      Expect(Token::ASSIGN, CHECK_OK);
+      return ParseModulePath(ok);
+
+    default:
+      return ParseModuleUrl(ok);
+  }
+}
+
+
+Module* Parser::ParseModuleLiteral(bool* ok) {
+  // Module:
+  //    '{' ModuleElement '}'
+
+  // Construct block expecting 16 statements.
+  Block* body = factory()->NewBlock(NULL, 16, false);
+  Scope* scope = NewScope(top_scope_, MODULE_SCOPE);
+
+  Expect(Token::LBRACE, CHECK_OK);
+  scope->set_start_position(scanner().location().beg_pos);
+  scope->SetLanguageMode(EXTENDED_MODE);
+
+  {
+    BlockState block_state(this, scope);
+    TargetCollector collector;
+    Target target(&this->target_stack_, &collector);
+    Target target_body(&this->target_stack_, body);
+    InitializationBlockFinder block_finder(top_scope_, target_stack_);
+
+    while (peek() != Token::RBRACE) {
+      Statement* stat = ParseModuleElement(NULL, CHECK_OK);
+      if (stat && !stat->IsEmpty()) {
+        body->AddStatement(stat);
+        block_finder.Update(stat);
+      }
+    }
+  }
+
+  Expect(Token::RBRACE, CHECK_OK);
+  scope->set_end_position(scanner().location().end_pos);
+  body->set_block_scope(scope);
+  return factory()->NewModuleLiteral(body);
+}
+
+
+Module* Parser::ParseModulePath(bool* ok) {
+  // ModulePath:
+  //    Identifier
+  //    ModulePath '.' Identifier
+
+  Module* result = ParseModuleVariable(CHECK_OK);
+
+  while (Check(Token::PERIOD)) {
+    Handle<String> name = ParseIdentifierName(CHECK_OK);
+    result = factory()->NewModulePath(result, name);
+  }
+
+  return result;
+}
+
+
+Module* Parser::ParseModuleVariable(bool* ok) {
+  // ModulePath:
+  //    Identifier
+
+  Handle<String> name = ParseIdentifier(CHECK_OK);
+  VariableProxy* proxy = top_scope_->NewUnresolved(
+      factory(), name, scanner().location().beg_pos);
+  return factory()->NewModuleVariable(proxy);
+}
+
+
+Module* Parser::ParseModuleUrl(bool* ok) {
+  // Module:
+  //    'at' String
+
+  Expect(Token::IDENTIFIER, CHECK_OK);
+  Handle<String> symbol = GetSymbol(CHECK_OK);
+  if (!symbol->IsEqualTo(CStrVector("at"))) {
+    *ok = false;
+    ReportUnexpectedToken(scanner().current_token());
+    return NULL;
+  }
+  Expect(Token::STRING, CHECK_OK);
+  symbol = GetSymbol(CHECK_OK);
+
+  return factory()->NewModuleUrl(symbol);
+}
+
+
+Block* Parser::ParseImportDeclaration(bool* ok) {
+  // TODO(rossberg)
+  return NULL;
+}
+
+
+Block* Parser::ParseExportDeclaration(bool* ok) {
+  // TODO(rossberg)
+  return NULL;
+}
+
+
+Statement* Parser::ParseBlockElement(ZoneStringList* labels,
+                                     bool* ok) {
+  // (Ecma 262 5th Edition, clause 14):
+  // SourceElement:
+  //    Statement
+  //    FunctionDeclaration
+  //
+  // In harmony mode we allow additionally the following productions
+  // BlockElement (aka SourceElement):
+  //    LetDeclaration
+  //    ConstDeclaration
+
+  switch (peek()) {
+    case Token::FUNCTION:
+      return ParseFunctionDeclaration(ok);
+    case Token::LET:
+    case Token::CONST:
+      return ParseVariableStatement(kModuleElement, ok);
+    default:
+      return ParseStatement(labels, ok);
+  }
+}


 Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) {
@@ -1344,7 +1512,8 @@
   // statically declared.
   if (declaration_scope->is_function_scope() ||
       declaration_scope->is_strict_or_extended_eval_scope() ||
-      declaration_scope->is_block_scope()) {
+      declaration_scope->is_block_scope() ||
+      declaration_scope->is_module_scope()) {
     // Declare the variable in the function scope.
     var = declaration_scope->LocalLookup(name);
     if (var == NULL) {
@@ -1574,10 +1743,10 @@


 Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) {
-  // The harmony mode uses source elements instead of statements.
+  // The harmony mode uses block elements instead of statements.
   //
   // Block ::
-  //   '{' SourceElement* '}'
+  //   '{' BlockElement* '}'

   // Construct block expecting 16 statements.
   Block* body = factory()->NewBlock(labels, 16, false);
@@ -1593,7 +1762,7 @@
     InitializationBlockFinder block_finder(top_scope_, target_stack_);

     while (peek() != Token::RBRACE) {
-      Statement* stat = ParseSourceElement(NULL, CHECK_OK);
+      Statement* stat = ParseBlockElement(NULL, CHECK_OK);
       if (stat && !stat->IsEmpty()) {
         body->AddStatement(stat);
         block_finder.Update(stat);
@@ -1614,10 +1783,8 @@
   //   VariableDeclarations ';'

   Handle<String> ignore;
-  Block* result = ParseVariableDeclarations(var_context,
-                                            NULL,
-                                            &ignore,
-                                            CHECK_OK);
+  Block* result =
+      ParseVariableDeclarations(var_context, NULL, &ignore, CHECK_OK);
   ExpectSemicolon(CHECK_OK);
   return result;
 }
@@ -1684,8 +1851,7 @@
         *ok = false;
         return NULL;
       case EXTENDED_MODE:
-        if (var_context != kSourceElement &&
-            var_context != kForStatement) {
+        if (var_context == kStatement) {
// In extended mode 'const' declarations are only allowed in source
           // element positions.
           ReportMessage("unprotected_const", Vector<const char*>::empty());
@@ -1710,10 +1876,8 @@
       return NULL;
     }
     Consume(Token::LET);
-    if (var_context != kSourceElement &&
-        var_context != kForStatement) {
+    if (var_context == kStatement) {
       // Let declarations are only allowed in source element positions.
-      ASSERT(var_context == kStatement);
       ReportMessage("unprotected_let", Vector<const char*>::empty());
       *ok = false;
       return NULL;
@@ -2453,10 +2617,7 @@
       Handle<String> name;
       VariableDeclarationProperties decl_props = kHasNoInitializers;
       Block* variable_statement =
-          ParseVariableDeclarations(kForStatement,
-                                    &decl_props,
-                                    &name,
-                                    CHECK_OK);
+ ParseVariableDeclarations(kForStatement, &decl_props, &name, CHECK_OK);
       bool accept_IN = !name.is_null() && decl_props != kHasInitializers;
       if (peek() == Token::IN && accept_IN) {
         // Rewrite a for-in statement of the form
=======================================
--- /branches/bleeding_edge/src/parser.h        Wed Feb  8 02:53:58 2012
+++ /branches/bleeding_edge/src/parser.h        Mon Feb 20 06:02:59 2012
@@ -464,7 +464,8 @@
   };

   enum VariableDeclarationContext {
-    kSourceElement,
+    kModuleElement,
+    kBlockElement,
     kStatement,
     kForStatement
   };
@@ -575,7 +576,16 @@
   // for failure at the call sites.
   void* ParseSourceElements(ZoneList<Statement*>* processor,
                             int end_token, bool* ok);
-  Statement* ParseSourceElement(ZoneStringList* labels, bool* ok);
+  Statement* ParseModuleElement(ZoneStringList* labels, bool* ok);
+  Block* ParseModuleDeclaration(bool* ok);
+  Module* ParseModule(bool* ok);
+  Module* ParseModuleLiteral(bool* ok);
+  Module* ParseModulePath(bool* ok);
+  Module* ParseModuleVariable(bool* ok);
+  Module* ParseModuleUrl(bool* ok);
+  Block* ParseImportDeclaration(bool* ok);
+  Block* ParseExportDeclaration(bool* ok);
+  Statement* ParseBlockElement(ZoneStringList* labels, bool* ok);
   Statement* ParseStatement(ZoneStringList* labels, bool* ok);
   Statement* ParseFunctionDeclaration(bool* ok);
   Statement* ParseNativeDeclaration(bool* ok);
=======================================
--- /branches/bleeding_edge/src/prettyprinter.cc        Thu Feb  9 05:40:41 2012
+++ /branches/bleeding_edge/src/prettyprinter.cc        Mon Feb 20 06:02:59 2012
@@ -84,7 +84,7 @@


 void PrettyPrinter::VisitModuleVariable(ModuleVariable* node) {
-  PrintLiteral(node->var()->name(), false);
+  Visit(node->proxy());
 }


@@ -773,7 +773,7 @@


 void AstPrinter::VisitModuleVariable(ModuleVariable* node) {
-  PrintLiteralIndented("VARIABLE", node->var()->name(), false);
+  Visit(node->proxy());
 }


=======================================
--- /branches/bleeding_edge/src/runtime.cc      Tue Feb 14 08:05:40 2012
+++ /branches/bleeding_edge/src/runtime.cc      Mon Feb 20 06:02:59 2012
@@ -11281,6 +11281,29 @@

   return block_scope;
 }
+
+
+// Create a plain JSObject which materializes the module scope for the specified
+// module context.
+static Handle<JSObject> MaterializeModuleScope(
+    Isolate* isolate,
+    Handle<Context> context) {
+  ASSERT(context->IsModuleContext());
+  Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension()));
+
+ // Allocate and initialize a JSObject with all the members of the debugged
+  // module.
+  Handle<JSObject> module_scope =
+      isolate->factory()->NewJSObject(isolate->object_function());
+
+  // Fill all context locals.
+  if (!CopyContextLocalsToScopeObject(
+          isolate, scope_info, context, module_scope)) {
+    return Handle<JSObject>();
+  }
+
+  return module_scope;
+}


 // Iterate over the actual scopes visible from a stack frame. The iteration
@@ -11295,7 +11318,8 @@
     ScopeTypeWith,
     ScopeTypeClosure,
     ScopeTypeCatch,
-    ScopeTypeBlock
+    ScopeTypeBlock,
+    ScopeTypeModule
   };

   ScopeIterator(Isolate* isolate,
@@ -11418,6 +11442,9 @@
           ASSERT(context_->IsFunctionContext() ||
                  !scope_info->HasContext());
           return ScopeTypeLocal;
+        case MODULE_SCOPE:
+          ASSERT(context_->IsModuleContext());
+          return ScopeTypeModule;
         case GLOBAL_SCOPE:
           ASSERT(context_->IsGlobalContext());
           return ScopeTypeGlobal;
@@ -11448,6 +11475,9 @@
     if (context_->IsBlockContext()) {
       return ScopeTypeBlock;
     }
+    if (context_->IsModuleContext()) {
+      return ScopeTypeModule;
+    }
     ASSERT(context_->IsWithContext());
     return ScopeTypeWith;
   }
@@ -11471,6 +11501,8 @@
         return MaterializeClosure(isolate_, CurrentContext());
       case ScopeIterator::ScopeTypeBlock:
         return MaterializeBlockScope(isolate_, CurrentContext());
+      case ScopeIterator::ScopeTypeModule:
+        return MaterializeModuleScope(isolate_, CurrentContext());
     }
     UNREACHABLE();
     return Handle<JSObject>();
=======================================
--- /branches/bleeding_edge/src/scopes.cc       Wed Feb  8 01:56:33 2012
+++ /branches/bleeding_edge/src/scopes.cc       Mon Feb 20 06:02:59 2012
@@ -704,6 +704,7 @@
   switch (type) {
     case EVAL_SCOPE: return "eval";
     case FUNCTION_SCOPE: return "function";
+    case MODULE_SCOPE: return "module";
     case GLOBAL_SCOPE: return "global";
     case CATCH_SCOPE: return "catch";
     case BLOCK_SCOPE: return "block";
=======================================
--- /branches/bleeding_edge/src/scopes.h        Wed Feb  8 01:56:33 2012
+++ /branches/bleeding_edge/src/scopes.h        Mon Feb 20 06:02:59 2012
@@ -263,6 +263,7 @@
   // Specific scope types.
   bool is_eval_scope() const { return type_ == EVAL_SCOPE; }
   bool is_function_scope() const { return type_ == FUNCTION_SCOPE; }
+  bool is_module_scope() const { return type_ == MODULE_SCOPE; }
   bool is_global_scope() const { return type_ == GLOBAL_SCOPE; }
   bool is_catch_scope() const { return type_ == CATCH_SCOPE; }
   bool is_block_scope() const { return type_ == BLOCK_SCOPE; }
=======================================
--- /branches/bleeding_edge/src/v8globals.h     Wed Jan 25 08:31:25 2012
+++ /branches/bleeding_edge/src/v8globals.h     Mon Feb 20 06:02:59 2012
@@ -461,6 +461,7 @@
 enum ScopeType {
   EVAL_SCOPE,      // The top-level scope for an eval source.
   FUNCTION_SCOPE,  // The top-level scope for a function.
+  MODULE_SCOPE,    // The scope introduced by a module literal
GLOBAL_SCOPE, // The top-level scope for a program or a top-level eval.
   CATCH_SCOPE,     // The scope introduced by catch.
   BLOCK_SCOPE,     // The scope introduced by a new block.

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to