Strip Interface class of most of its logic, make it all about Module exports
authoradamk <adamk@chromium.org>
Tue, 17 Feb 2015 20:51:24 +0000 (12:51 -0800)
committerCommit bot <commit-bot@chromium.org>
Tue, 17 Feb 2015 20:51:35 +0000 (20:51 +0000)
This gets Variable and VariableProxy out of the business of worrying about
Interfaces.

At the same time, get rid of the notion of "module variables". In ES6, variables
that refer to modules will be simply be CONST bindings to module namespace
objects.

The only change in logic here is one more early error:
duplicate export names are now rejected.

BUG=v8:1569
LOG=n

Review URL: https://codereview.chromium.org/918373002

Cr-Commit-Position: refs/heads/master@{#26708}

33 files changed:
src/arm/full-codegen-arm.cc
src/arm64/full-codegen-arm64.cc
src/ast-numbering.cc
src/ast.cc
src/ast.h
src/compiler/ast-graph-builder.cc
src/compiler/ast-loop-assignment-analyzer.cc
src/contexts.cc
src/full-codegen.cc
src/globals.h
src/hydrogen.cc
src/ia32/full-codegen-ia32.cc
src/interface.cc
src/interface.h
src/messages.js
src/mips/full-codegen-mips.cc
src/mips64/full-codegen-mips64.cc
src/parser.cc
src/parser.h
src/ppc/full-codegen-ppc.cc
src/prettyprinter.cc
src/rewriter.cc
src/runtime/runtime-scopes.cc
src/scopeinfo.cc
src/scopeinfo.h
src/scopes.cc
src/scopes.h
src/typing.cc
src/variables.cc
src/variables.h
src/x64/full-codegen-x64.cc
src/x87/full-codegen-x87.cc
test/cctest/test-parsing.cc

index 30e0682039b22cd04737ce8029734179d610d942..885f3ba2759493b761341418ca03e3b12a5f3023 100644 (file)
@@ -957,15 +957,16 @@ void FullCodeGenerator::VisitFunctionDeclaration(
 
 void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) {
   Variable* variable = declaration->proxy()->var();
+  Interface* interface = declaration->module()->interface();
   DCHECK(variable->location() == Variable::CONTEXT);
-  DCHECK(variable->interface()->IsFrozen());
+  DCHECK(interface->IsFrozen());
 
   Comment cmnt(masm_, "[ ModuleDeclaration");
   EmitDebugCheckDeclarationContext(variable);
 
   // Load instance object.
   __ LoadContext(r1, scope_->ContextChainLength(scope_->ScriptScope()));
-  __ ldr(r1, ContextOperand(r1, variable->interface()->Index()));
+  __ ldr(r1, ContextOperand(r1, interface->Index()));
   __ ldr(r1, ContextOperand(r1, Context::EXTENSION_INDEX));
 
   // Assign it.
index 7342038af014df3c36ba379ec9ee3d83edc5fef3..e3386a651d5a5bdab14f0135725b14397a4f24a4 100644 (file)
@@ -954,15 +954,16 @@ void FullCodeGenerator::VisitFunctionDeclaration(
 
 void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) {
   Variable* variable = declaration->proxy()->var();
+  Interface* interface = declaration->module()->interface();
   DCHECK(variable->location() == Variable::CONTEXT);
-  DCHECK(variable->interface()->IsFrozen());
+  DCHECK(interface->IsFrozen());
 
   Comment cmnt(masm_, "[ ModuleDeclaration");
   EmitDebugCheckDeclarationContext(variable);
 
   // Load instance object.
   __ LoadContext(x1, scope_->ContextChainLength(scope_->ScriptScope()));
-  __ Ldr(x1, ContextMemOperand(x1, variable->interface()->Index()));
+  __ Ldr(x1, ContextMemOperand(x1, interface->Index()));
   __ Ldr(x1, ContextMemOperand(x1, Context::EXTENSION_INDEX));
 
   // Assign it.
index a2bc65827d9ded4afdc131c0467d2dab6d0006f4..ea25ad8bbca4722f0deeb89be9f40a1d77004757 100644 (file)
@@ -190,13 +190,6 @@ void AstNumberingVisitor::VisitImportDeclaration(ImportDeclaration* node) {
 }
 
 
-void AstNumberingVisitor::VisitModuleVariable(ModuleVariable* node) {
-  IncrementNodeCount();
-  DisableOptimization(kModuleVariable);
-  Visit(node->proxy());
-}
-
-
 void AstNumberingVisitor::VisitModulePath(ModulePath* node) {
   IncrementNodeCount();
   DisableOptimization(kModulePath);
index 02c264fa29507ac16a2352372a195e9e701c8cc6..ac81e751afb31f1ea89e8e47ac1cd68c6b198e2b 100644 (file)
@@ -65,24 +65,21 @@ VariableProxy::VariableProxy(Zone* zone, Variable* var, int position)
                  IsAssignedField::encode(false) |
                  IsResolvedField::encode(false)),
       variable_feedback_slot_(FeedbackVectorICSlot::Invalid()),
-      raw_name_(var->raw_name()),
-      interface_(var->interface()) {
+      raw_name_(var->raw_name()) {
   BindTo(var);
 }
 
 
 VariableProxy::VariableProxy(Zone* zone, const AstRawString* name, bool is_this,
-                             Interface* interface, int position)
+                             int position)
     : Expression(zone, position),
       bit_field_(IsThisField::encode(is_this) | IsAssignedField::encode(false) |
                  IsResolvedField::encode(false)),
       variable_feedback_slot_(FeedbackVectorICSlot::Invalid()),
-      raw_name_(name),
-      interface_(interface) {}
+      raw_name_(name) {}
 
 
 void VariableProxy::BindTo(Variable* var) {
-  DCHECK(!FLAG_harmony_modules || interface_->IsUnified(var->interface()));
   DCHECK((is_this() && var->is_this()) || raw_name() == var->raw_name());
   set_var(var);
   set_is_resolved();
index 68cbb38e8b6902b9ed908c812113a4d6d0019205..2f2de55e67647bd976858e81200b3f715998cae6 100644 (file)
--- a/src/ast.h
+++ b/src/ast.h
@@ -48,7 +48,6 @@ namespace internal {
 
 #define MODULE_NODE_LIST(V)                     \
   V(ModuleLiteral)                              \
-  V(ModuleVariable)                             \
   V(ModulePath)                                 \
   V(ModuleUrl)
 
@@ -598,14 +597,9 @@ class ModuleDeclaration FINAL : public Declaration {
   }
 
  protected:
-  ModuleDeclaration(Zone* zone,
-                    VariableProxy* proxy,
-                    Module* module,
-                    Scope* scope,
-                    int pos)
-      : Declaration(zone, proxy, MODULE, scope, pos),
-        module_(module) {
-  }
+  ModuleDeclaration(Zone* zone, VariableProxy* proxy, Module* module,
+                    Scope* scope, int pos)
+      : Declaration(zone, proxy, CONST, scope, pos), module_(module) {}
 
  private:
   Module* module_;
@@ -658,7 +652,7 @@ class Module : public AstNode {
  protected:
   Module(Zone* zone, int pos)
       : AstNode(pos),
-        interface_(Interface::NewModule(zone)),
+        interface_(Interface::New(zone)),
         body_(NULL) {}
   Module(Zone* zone, Interface* interface, int pos, Block* body = NULL)
       : AstNode(pos),
@@ -681,20 +675,6 @@ class ModuleLiteral FINAL : public Module {
 };
 
 
-class ModuleVariable FINAL : public Module {
- public:
-  DECLARE_NODE_TYPE(ModuleVariable)
-
-  VariableProxy* proxy() const { return proxy_; }
-
- protected:
-  inline ModuleVariable(Zone* zone, VariableProxy* proxy, int pos);
-
- private:
-  VariableProxy* proxy_;
-};
-
-
 class ModulePath FINAL : public Module {
  public:
   DECLARE_NODE_TYPE(ModulePath)
@@ -732,18 +712,13 @@ class ModuleStatement FINAL : public Statement {
  public:
   DECLARE_NODE_TYPE(ModuleStatement)
 
-  VariableProxy* proxy() const { return proxy_; }
   Block* body() const { return body_; }
 
  protected:
-  ModuleStatement(Zone* zone, VariableProxy* proxy, Block* body, int pos)
-      : Statement(zone, pos),
-        proxy_(proxy),
-        body_(body) {
-  }
+  ModuleStatement(Zone* zone, Block* body, int pos)
+      : Statement(zone, pos), body_(body) {}
 
  private:
-  VariableProxy* proxy_;
   Block* body_;
 };
 
@@ -1661,9 +1636,7 @@ class VariableProxy FINAL : public Expression {
     bit_field_ = IsResolvedField::update(bit_field_, true);
   }
 
-  Interface* interface() const { return interface_; }
-
-  // Bind this proxy to the variable var. Interfaces must match.
+  // Bind this proxy to the variable var.
   void BindTo(Variable* var);
 
   bool UsesVariableFeedbackSlot() const {
@@ -1688,7 +1661,7 @@ class VariableProxy FINAL : public Expression {
   VariableProxy(Zone* zone, Variable* var, int position);
 
   VariableProxy(Zone* zone, const AstRawString* name, bool is_this,
-                Interface* interface, int position);
+                int position);
 
   class IsThisField : public BitField8<bool, 0, 1> {};
   class IsAssignedField : public BitField8<bool, 1, 1> {};
@@ -1702,7 +1675,6 @@ class VariableProxy FINAL : public Expression {
     const AstRawString* raw_name_;  // if !is_resolved_
     Variable* var_;                 // if is_resolved_
   };
-  Interface* interface_;
 };
 
 
@@ -3099,15 +3071,6 @@ class RegExpEmpty FINAL : public RegExpTree {
 };
 
 
-// ----------------------------------------------------------------------------
-// Out-of-line inline constructors (to side-step cyclic dependencies).
-
-inline ModuleVariable::ModuleVariable(Zone* zone, VariableProxy* proxy, int pos)
-    : Module(zone, proxy->interface(), pos),
-      proxy_(proxy) {
-}
-
-
 // ----------------------------------------------------------------------------
 // Basic visitor
 // - leaf node visitors are abstract.
@@ -3213,10 +3176,6 @@ class AstNodeFactory FINAL BASE_EMBEDDED {
     return new (zone_) ModuleLiteral(zone_, body, interface, pos);
   }
 
-  ModuleVariable* NewModuleVariable(VariableProxy* proxy, int pos) {
-    return new (zone_) ModuleVariable(zone_, proxy, pos);
-  }
-
   ModulePath* NewModulePath(Module* origin, const AstRawString* name, int pos) {
     return new (zone_) ModulePath(zone_, origin, name, pos);
   }
@@ -3258,9 +3217,8 @@ class AstNodeFactory FINAL BASE_EMBEDDED {
     return NULL;
   }
 
-  ModuleStatement* NewModuleStatement(
-      VariableProxy* proxy, Block* body, int pos) {
-    return new (zone_) ModuleStatement(zone_, proxy, body, pos);
+  ModuleStatement* NewModuleStatement(Block* body, int pos) {
+    return new (zone_) ModuleStatement(zone_, body, pos);
   }
 
   ExpressionStatement* NewExpressionStatement(Expression* expression, int pos) {
@@ -3405,9 +3363,8 @@ class AstNodeFactory FINAL BASE_EMBEDDED {
 
   VariableProxy* NewVariableProxy(const AstRawString* name,
                                   bool is_this,
-                                  Interface* interface = Interface::NewValue(),
                                   int position = RelocInfo::kNoPosition) {
-    return new (zone_) VariableProxy(zone_, name, is_this, interface, position);
+    return new (zone_) VariableProxy(zone_, name, is_this, position);
   }
 
   Property* NewProperty(Expression* obj, Expression* key, int pos) {
index 89c8339c2a12b1ee3e48538ca7202018c26ee5ff..c33cc60ce573afa4b9270c3f83a8588e3f085421 100644 (file)
@@ -876,11 +876,6 @@ void AstGraphBuilder::VisitExportDeclaration(ExportDeclaration* decl) {
 void AstGraphBuilder::VisitModuleLiteral(ModuleLiteral* modl) { UNREACHABLE(); }
 
 
-void AstGraphBuilder::VisitModuleVariable(ModuleVariable* modl) {
-  UNREACHABLE();
-}
-
-
 void AstGraphBuilder::VisitModulePath(ModulePath* modl) { UNREACHABLE(); }
 
 
index e6764d0eb02f42feda6ed2caff172b46424f830e..c81d5483bf7893d328cf907dd048e45b64a94bf1 100644 (file)
@@ -57,7 +57,6 @@ void ALAA::VisitFunctionDeclaration(FunctionDeclaration* leaf) {}
 void ALAA::VisitModuleDeclaration(ModuleDeclaration* leaf) {}
 void ALAA::VisitImportDeclaration(ImportDeclaration* leaf) {}
 void ALAA::VisitExportDeclaration(ExportDeclaration* leaf) {}
-void ALAA::VisitModuleVariable(ModuleVariable* leaf) {}
 void ALAA::VisitModulePath(ModulePath* leaf) {}
 void ALAA::VisitModuleUrl(ModuleUrl* leaf) {}
 void ALAA::VisitEmptyStatement(EmptyStatement* leaf) {}
@@ -205,9 +204,8 @@ void ALAA::VisitCaseClause(CaseClause* cc) {
 // -- Interesting nodes-------------------------------------------------------
 // ---------------------------------------------------------------------------
 void ALAA::VisitModuleStatement(ModuleStatement* stmt) {
-  Visit(stmt->body());
   // TODO(turbofan): can a module appear in a loop?
-  AnalyzeAssignment(stmt->proxy()->var());
+  Visit(stmt->body());
 }
 
 
index 57490a118f5d9663ab55d6bb95a0ed4890ff3688..6537e2c3e260d5f8b1da53e04b0153e9c724d73e 100644 (file)
@@ -173,10 +173,6 @@ static void GetAttributesAndBindingFlags(VariableMode mode,
                            ? IMMUTABLE_CHECK_INITIALIZED_HARMONY
                            : IMMUTABLE_IS_INITIALIZED_HARMONY;
       break;
-    case MODULE:
-      *attributes = READ_ONLY;
-      *binding_flags = IMMUTABLE_IS_INITIALIZED_HARMONY;
-      break;
     case DYNAMIC:
     case DYNAMIC_GLOBAL:
     case DYNAMIC_LOCAL:
index 349626b0e08181dcf90781cbc91c51464a384f94..8cc7f8205941b16a4294d704f4e1f1d62a06a79e 100644 (file)
@@ -60,10 +60,6 @@ void BreakableStatementChecker::VisitModuleLiteral(ModuleLiteral* module) {
 }
 
 
-void BreakableStatementChecker::VisitModuleVariable(ModuleVariable* module) {
-}
-
-
 void BreakableStatementChecker::VisitModulePath(ModulePath* module) {
 }
 
@@ -615,7 +611,7 @@ void FullCodeGenerator::AllocateModules(ZoneList<Declaration*>* declarations) {
         Comment cmnt(masm_, "[ Link nested modules");
         Scope* scope = module->body()->scope();
         Interface* interface = scope->interface();
-        DCHECK(interface->IsModule() && interface->IsFrozen());
+        DCHECK(interface->IsFrozen());
 
         interface->Allocate(scope->module_var()->index());
 
@@ -789,12 +785,6 @@ void FullCodeGenerator::VisitModuleLiteral(ModuleLiteral* module) {
 }
 
 
-void FullCodeGenerator::VisitModuleVariable(ModuleVariable* module) {
-  // Nothing to do.
-  // The instance object is resolved statically through the module's interface.
-}
-
-
 void FullCodeGenerator::VisitModulePath(ModulePath* module) {
   // Nothing to do.
   // The instance object is resolved statically through the module's interface.
@@ -806,7 +796,7 @@ void FullCodeGenerator::VisitModuleUrl(ModuleUrl* module) {
   Scope* scope = module->body()->scope();
   Interface* interface = scope_->interface();
 
-  DCHECK(interface->IsModule() && interface->IsFrozen());
+  DCHECK(interface->IsFrozen());
   DCHECK(!modules_.is_null());
   DCHECK(module_index_ < modules_->length());
   interface->Allocate(scope->module_var()->index());
@@ -1103,7 +1093,9 @@ void FullCodeGenerator::VisitBlock(Block* stmt) {
 void FullCodeGenerator::VisitModuleStatement(ModuleStatement* stmt) {
   Comment cmnt(masm_, "[ Module context");
 
-  __ Push(Smi::FromInt(stmt->proxy()->interface()->Index()));
+  DCHECK(stmt->body()->scope()->is_module_scope());
+
+  __ Push(Smi::FromInt(stmt->body()->scope()->interface()->Index()));
   __ Push(Smi::FromInt(0));
   __ CallRuntime(Runtime::kPushModuleContext, 2);
   StoreToFrameField(
index a3ae4abd00bbc1f33dde5aaa8d2efb38aa6dc2e4..38d5ab27261186ae2f87bc41fd925317fe116bdb 100644 (file)
@@ -712,12 +712,10 @@ enum VariableMode {
 
   CONST_LEGACY,    // declared via legacy 'const' declarations
 
-  LET,             // declared via 'let' declarations (first lexical)
+  LET,             // declared via 'let' declarations
 
   CONST,           // declared via 'const' declarations
 
-  MODULE,          // declared via 'module' declaration (last lexical)
-
   // Variables introduced by the compiler:
   INTERNAL,        // like VAR, but not user-visible (may or may not
                    // be in a context)
@@ -745,17 +743,17 @@ inline bool IsDynamicVariableMode(VariableMode mode) {
 
 
 inline bool IsDeclaredVariableMode(VariableMode mode) {
-  return mode >= VAR && mode <= MODULE;
+  return mode >= VAR && mode <= CONST;
 }
 
 
 inline bool IsLexicalVariableMode(VariableMode mode) {
-  return mode >= LET && mode <= MODULE;
+  return mode == LET || mode == CONST;
 }
 
 
 inline bool IsImmutableVariableMode(VariableMode mode) {
-  return (mode >= CONST && mode <= MODULE) || mode == CONST_LEGACY;
+  return mode == CONST || mode == CONST_LEGACY;
 }
 
 
index 84d0c7c11033b9216338c26b84d7e20637bd049a..daaa1ff0131eaf70dff24239cf25a41b17dd0bc7 100644 (file)
@@ -11485,11 +11485,6 @@ void HOptimizedGraphBuilder::VisitModuleLiteral(ModuleLiteral* module) {
 }
 
 
-void HOptimizedGraphBuilder::VisitModuleVariable(ModuleVariable* module) {
-  UNREACHABLE();
-}
-
-
 void HOptimizedGraphBuilder::VisitModulePath(ModulePath* module) {
   UNREACHABLE();
 }
index 4425045bd2ca1eab7b0b1c98339b63ffd9369211..e70ac4c378a431e3db6e3ba8859118c32fde1d2c 100644 (file)
@@ -893,15 +893,16 @@ void FullCodeGenerator::VisitFunctionDeclaration(
 
 void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) {
   Variable* variable = declaration->proxy()->var();
+  Interface* interface = declaration->module()->interface();
   DCHECK(variable->location() == Variable::CONTEXT);
-  DCHECK(variable->interface()->IsFrozen());
+  DCHECK(interface->IsFrozen());
 
   Comment cmnt(masm_, "[ ModuleDeclaration");
   EmitDebugCheckDeclarationContext(variable);
 
   // Load instance object.
   __ LoadContext(eax, scope_->ContextChainLength(scope_->ScriptScope()));
-  __ mov(eax, ContextOperand(eax, variable->interface()->Index()));
+  __ mov(eax, ContextOperand(eax, interface->Index()));
   __ mov(eax, ContextOperand(eax, Context::EXTENSION_INDEX));
 
   // Assign it.
index a45804cf5275eb3674695bd42c73d2c44a20ef7e..4e391ac92bb2d43dd1ab54f505a083521e17d642 100644 (file)
@@ -6,61 +6,11 @@
 
 #include "src/interface.h"
 
-#include "src/base/lazy-instance.h"
+#include "src/ast-value-factory.h"
 
 namespace v8 {
 namespace internal {
 
-// ---------------------------------------------------------------------------
-// Initialization.
-
-struct Interface::Cache {
-  template<int flags>
-  struct Create {
-    static void Construct(Interface* ptr) { ::new (ptr) Interface(flags); }
-  };
-  typedef Create<VALUE + FROZEN> ValueCreate;
-  typedef Create<VALUE + CONST + FROZEN> ConstCreate;
-
-  static base::LazyInstance<Interface, ValueCreate>::type value_interface;
-  static base::LazyInstance<Interface, ConstCreate>::type const_interface;
-};
-
-
-base::LazyInstance<Interface, Interface::Cache::ValueCreate>::type
-    Interface::Cache::value_interface = LAZY_INSTANCE_INITIALIZER;
-
-base::LazyInstance<Interface, Interface::Cache::ConstCreate>::type
-    Interface::Cache::const_interface = LAZY_INSTANCE_INITIALIZER;
-
-
-Interface* Interface::NewValue() {
-  return Cache::value_interface.Pointer();  // Cached.
-}
-
-
-Interface* Interface::NewConst() {
-  return Cache::const_interface.Pointer();  // Cached.
-}
-
-
-// ---------------------------------------------------------------------------
-// Lookup.
-
-Interface* Interface::Lookup(Handle<String> name, Zone* zone) {
-  DCHECK(IsModule());
-  ZoneHashMap* map = Chase()->exports_;
-  if (map == nullptr) return nullptr;
-  ZoneAllocationPolicy allocator(zone);
-  ZoneHashMap::Entry* p =
-      map->Lookup(name.location(), name->Hash(), false, allocator);
-  if (p == nullptr) return nullptr;
-  DCHECK(*static_cast<String**>(p->key) == *name);
-  DCHECK(p->value != nullptr);
-  return static_cast<Interface*>(p->value);
-}
-
-
 // ---------------------------------------------------------------------------
 // Addition.
 
@@ -79,24 +29,20 @@ int Nesting::current_ = 0;
 #endif
 
 
-void Interface::DoAdd(const void* name, uint32_t hash, Interface* interface,
-                      Zone* zone, bool* ok) {
-  MakeModule(ok);
-  if (!*ok) return;
+void Interface::Add(const AstRawString* name, Zone* zone, bool* ok) {
+  void* key = const_cast<AstRawString*>(name);
 
 #ifdef DEBUG
   if (FLAG_print_interface_details) {
     PrintF("%*s# Adding...\n", Nesting::current(), "");
     PrintF("%*sthis = ", Nesting::current(), "");
     this->Print(Nesting::current());
-    const AstRawString* raw = static_cast<const AstRawString*>(name);
-    PrintF("%*s%.*s : ", Nesting::current(), "",
-           raw->length(), raw->raw_data());
-    interface->Print(Nesting::current());
+    PrintF("%*s%.*s : ", Nesting::current(), "", name->length(),
+           name->raw_data());
   }
 #endif
 
-  ZoneHashMap** map = &Chase()->exports_;
+  ZoneHashMap** map = &exports_;
   ZoneAllocationPolicy allocator(zone);
 
   if (*map == nullptr) {
@@ -106,118 +52,23 @@ void Interface::DoAdd(const void* name, uint32_t hash, Interface* interface,
   }
 
   ZoneHashMap::Entry* p =
-      (*map)->Lookup(const_cast<void*>(name), hash, !IsFrozen(), allocator);
-  if (p == nullptr) {
-    // This didn't have name but was frozen already, that's an error.
+      (*map)->Lookup(key, name->hash(), !IsFrozen(), allocator);
+  if (p == nullptr || p->value != nullptr) {
     *ok = false;
-  } else if (p->value == nullptr) {
-    p->value = interface;
-  } else {
-#ifdef DEBUG
-    Nesting nested;
-#endif
-    static_cast<Interface*>(p->value)->Unify(interface, zone, ok);
-  }
-
-#ifdef DEBUG
-  if (FLAG_print_interface_details) {
-    PrintF("%*sthis' = ", Nesting::current(), "");
-    this->Print(Nesting::current());
-    PrintF("%*s# Added.\n", Nesting::current(), "");
-  }
-#endif
-}
-
-
-// ---------------------------------------------------------------------------
-// Unification.
-
-void Interface::Unify(Interface* that, Zone* zone, bool* ok) {
-  if (this->forward_) return this->Chase()->Unify(that, zone, ok);
-  if (that->forward_) return this->Unify(that->Chase(), zone, ok);
-  DCHECK(this->forward_ == nullptr);
-  DCHECK(that->forward_ == nullptr);
-
-  *ok = true;
-  if (this == that) return;
-  if (this->IsValue()) {
-    that->MakeValue(ok);
-    if (*ok && this->IsConst()) that->MakeConst(ok);
-    return;
-  }
-  if (that->IsValue()) {
-    this->MakeValue(ok);
-    if (*ok && that->IsConst()) this->MakeConst(ok);
-    return;
   }
 
-#ifdef DEBUG
-  if (FLAG_print_interface_details) {
-    PrintF("%*s# Unifying...\n", Nesting::current(), "");
-    PrintF("%*sthis = ", Nesting::current(), "");
-    this->Print(Nesting::current());
-    PrintF("%*sthat = ", Nesting::current(), "");
-    that->Print(Nesting::current());
-  }
-#endif
-
-  // Merge the smaller interface into the larger, for performance.
-  if (this->exports_ != nullptr && (that->exports_ == nullptr ||
-      this->exports_->occupancy() >= that->exports_->occupancy())) {
-    this->DoUnify(that, ok, zone);
-  } else {
-    that->DoUnify(this, ok, zone);
-  }
+  p->value = key;
 
 #ifdef DEBUG
   if (FLAG_print_interface_details) {
     PrintF("%*sthis' = ", Nesting::current(), "");
     this->Print(Nesting::current());
-    PrintF("%*sthat' = ", Nesting::current(), "");
-    that->Print(Nesting::current());
-    PrintF("%*s# Unified.\n", Nesting::current(), "");
+    PrintF("%*s# Added.\n", Nesting::current(), "");
   }
 #endif
 }
 
 
-void Interface::DoUnify(Interface* that, bool* ok, Zone* zone) {
-  DCHECK(this->forward_ == nullptr);
-  DCHECK(that->forward_ == nullptr);
-  DCHECK(!this->IsValue());
-  DCHECK(!that->IsValue());
-  DCHECK(this->index_ == -1);
-  DCHECK(that->index_ == -1);
-  DCHECK(*ok);
-
-#ifdef DEBUG
-    Nesting nested;
-#endif
-
-  // Try to merge all members from that into this.
-  ZoneHashMap* map = that->exports_;
-  if (map != nullptr) {
-    for (ZoneHashMap::Entry* p = map->Start(); p != nullptr; p = map->Next(p)) {
-      this->DoAdd(p->key, p->hash, static_cast<Interface*>(p->value), zone, ok);
-      if (!*ok) return;
-    }
-  }
-
-  // If the new interface is larger than that's, then there were members in
-  // 'this' which 'that' didn't have. If 'that' was frozen that is an error.
-  int this_size = this->exports_ == nullptr ? 0 : this->exports_->occupancy();
-  int that_size = map == nullptr ? 0 : map->occupancy();
-  if (that->IsFrozen() && this_size > that_size) {
-    *ok = false;
-    return;
-  }
-
-  // Merge interfaces.
-  this->flags_ |= that->flags_;
-  that->forward_ = this;
-}
-
-
 // ---------------------------------------------------------------------------
 // Printing.
 
@@ -226,39 +77,23 @@ void Interface::Print(int n) {
   int n0 = n > 0 ? n : 0;
 
   if (FLAG_print_interface_details) {
-    PrintF("%p", static_cast<void*>(this));
-    for (Interface* link = this->forward_; link != nullptr;
-        link = link->forward_) {
-      PrintF("->%p", static_cast<void*>(link));
-    }
-    PrintF(" ");
+    PrintF("%p ", static_cast<void*>(this));
   }
 
-  if (IsUnknown()) {
-    PrintF("unknown\n");
-  } else if (IsConst()) {
-    PrintF("const\n");
-  } else if (IsValue()) {
-    PrintF("value\n");
-  } else if (IsModule()) {
-    PrintF("module %d %s{", Index(), IsFrozen() ? "" : "(unresolved) ");
-    ZoneHashMap* map = Chase()->exports_;
-    if (map == nullptr || map->occupancy() == 0) {
-      PrintF("}\n");
-    } else if (n < 0 || n0 >= 2 * FLAG_print_interface_depth) {
-      // Avoid infinite recursion on cyclic types.
-      PrintF("...}\n");
-    } else {
-      PrintF("\n");
-      for (ZoneHashMap::Entry* p = map->Start();
-           p != nullptr; p = map->Next(p)) {
-        String* name = *static_cast<String**>(p->key);
-        Interface* interface = static_cast<Interface*>(p->value);
-        PrintF("%*s%s : ", n0 + 2, "", name->ToAsciiArray());
-        interface->Print(n0 + 2);
-      }
-      PrintF("%*s}\n", n0, "");
+  PrintF("module %d %s{", Index(), IsFrozen() ? "" : "(unresolved) ");
+  ZoneHashMap* map = exports_;
+  if (map == nullptr || map->occupancy() == 0) {
+    PrintF("}\n");
+  } else if (n < 0 || n0 >= 2 * FLAG_print_interface_depth) {
+    // Avoid infinite recursion on cyclic types.
+    PrintF("...}\n");
+  } else {
+    PrintF("\n");
+    for (ZoneHashMap::Entry* p = map->Start(); p != nullptr; p = map->Next(p)) {
+      String* name = *static_cast<String**>(p->key);
+      PrintF("%*s%s : ", n0 + 2, "", name->ToAsciiArray());
     }
+    PrintF("%*s}\n", n0, "");
   }
 }
 #endif
index 3336021d8284206204f902a33b8abdf9f1d6c066..9c6e2c34d1e06947185d79397f8d40ea7d129f3a 100644 (file)
 #ifndef V8_INTERFACE_H_
 #define V8_INTERFACE_H_
 
-#include "src/ast-value-factory.h"
+#include "src/zone.h"
 
 namespace v8 {
 namespace internal {
 
 
-// This class implements the following abstract grammar of interfaces
-// (i.e. module types):
-//   interface ::= UNDETERMINED | VALUE | CONST | MODULE(exports)
-//   exports ::= {name : interface, ...}
-// A frozen type is one that is fully determined. Unification does not
-// allow to turn non-const values into const, or adding additional exports to
-// frozen interfaces. Otherwise, unifying modules merges their exports.
-// Undetermined types are unification variables that can be unified freely.
-// There is a natural subsort lattice that reflects the increase of knowledge:
-//
-//            undetermined
-//           //     |    \\                                                    .
-//       value  (frozen)  module
-//      //   \\  /    \  //
-//  const   fr.value  fr.module
-//      \\    /
-//     fr.const
-//
-// where the bold lines are the only transitions allowed.
+class AstRawString;
 
+
+// This class represents the interface of a module: a set of exported names.
+//
+// TODO(adamk): Rename this to ModuleRecord, ModuleDescriptor, or similar.
 class Interface : public ZoneObject {
  public:
   // ---------------------------------------------------------------------------
   // Factory methods.
 
-  static Interface* NewUnknown(Zone* zone) {
-    return new(zone) Interface(NONE);
-  }
-
-  static Interface* NewValue();
-
-  static Interface* NewConst();
-
-  static Interface* NewModule(Zone* zone) {
-    return new(zone) Interface(MODULE);
-  }
+  static Interface* New(Zone* zone) { return new (zone) Interface(); }
 
   // ---------------------------------------------------------------------------
   // Mutators.
 
-  // Add a name to the list of exports. If it already exists, unify with
-  // interface, otherwise insert unless this is closed.
-  void Add(const AstRawString* name, Interface* interface, Zone* zone,
-           bool* ok) {
-    DoAdd(name, name->hash(), interface, zone, ok);
-  }
-
-  // Unify with another interface. If successful, both interface objects will
-  // represent the same type, and changes to one are reflected in the other.
-  void Unify(Interface* that, Zone* zone, bool* ok);
-
-  // Determine this interface to be a value interface.
-  void MakeValue(bool* ok) {
-    *ok = !IsModule();
-    if (*ok) Chase()->flags_ |= VALUE;
-  }
-
-  // Determine this interface to be an immutable interface.
-  void MakeConst(bool* ok) {
-    *ok = !IsModule() && (IsConst() || !IsFrozen());
-    if (*ok) Chase()->flags_ |= VALUE + CONST;
-  }
-
-  // Determine this interface to be a module interface.
-  void MakeModule(bool* ok) {
-    *ok = !IsValue();
-    if (*ok) Chase()->flags_ |= MODULE;
-  }
+  // Add a name to the list of exports. If it already exists, or this interface
+  // is frozen, that's an error.
+  void Add(const AstRawString* name, Zone* zone, bool* ok);
 
   // Do not allow any further refinements, directly or through unification.
-  void Freeze(bool* ok) {
-    *ok = IsValue() || IsModule();
-    if (*ok) Chase()->flags_ |= FROZEN;
-  }
+  void Freeze() { frozen_ = true; }
 
   // Assign an index.
   void Allocate(int index) {
-    DCHECK(IsModule() && IsFrozen() && Chase()->index_ == -1);
-    Chase()->index_ = index;
+    DCHECK(IsFrozen() && index_ == -1);
+    index_ = index;
   }
 
   // ---------------------------------------------------------------------------
   // Accessors.
 
-  // Check whether this is still a fully undetermined type.
-  bool IsUnknown() { return Chase()->flags_ == NONE; }
-
-  // Check whether this is a value type.
-  bool IsValue() { return Chase()->flags_ & VALUE; }
-
-  // Check whether this is a constant type.
-  bool IsConst() { return Chase()->flags_ & CONST; }
-
-  // Check whether this is a module type.
-  bool IsModule() { return Chase()->flags_ & MODULE; }
-
   // Check whether this is closed (i.e. fully determined).
-  bool IsFrozen() { return Chase()->flags_ & FROZEN; }
-
-  bool IsUnified(Interface* that) {
-    return Chase() == that->Chase()
-        || (this->IsValue() == that->IsValue() &&
-            this->IsConst() == that->IsConst());
-  }
+  bool IsFrozen() { return frozen_; }
 
   int Length() {
-    DCHECK(IsModule() && IsFrozen());
-    ZoneHashMap* exports = Chase()->exports_;
+    DCHECK(IsFrozen());
+    ZoneHashMap* exports = exports_;
     return exports ? exports->occupancy() : 0;
   }
 
   // The context slot in the hosting script context pointing to this module.
   int Index() {
-    DCHECK(IsModule() && IsFrozen());
-    return Chase()->index_;
+    DCHECK(IsFrozen());
+    return index_;
   }
 
-  // Look up an exported name. Returns NULL if not (yet) defined.
-  Interface* Lookup(Handle<String> name, Zone* zone);
-
   // ---------------------------------------------------------------------------
   // Iterators.
 
@@ -145,10 +72,6 @@ class Interface : public ZoneObject {
       DCHECK(!done());
       return static_cast<const AstRawString*>(entry_->key);
     }
-    Interface* interface() const {
-      DCHECK(!done());
-      return static_cast<Interface*>(entry_->value);
-    }
     void Advance() { entry_ = exports_->Next(entry_); }
 
    private:
@@ -171,42 +94,16 @@ class Interface : public ZoneObject {
   // ---------------------------------------------------------------------------
   // Implementation.
  private:
-  struct Cache;
-
-  enum Flags {    // All flags are monotonic
-    NONE = 0,
-    VALUE = 1,    // This type describes a value
-    CONST = 2,    // This type describes a constant
-    MODULE = 4,   // This type describes a module
-    FROZEN = 8    // This type is fully determined
-  };
-
-  int flags_;
-  Interface* forward_;     // Unification link
+  bool frozen_;
   ZoneHashMap* exports_;   // Module exports and their types (allocated lazily)
   int index_;
 
-  explicit Interface(int flags)
-    : flags_(flags),
-      forward_(NULL),
-      exports_(NULL),
-      index_(-1) {
+  Interface() : frozen_(false), exports_(NULL), index_(-1) {
 #ifdef DEBUG
     if (FLAG_print_interface_details)
       PrintF("# Creating %p\n", static_cast<void*>(this));
 #endif
   }
-
-  Interface* Chase() {
-    Interface* result = this;
-    while (result->forward_ != NULL) result = result->forward_;
-    if (result != this) forward_ = result;  // On-the-fly path compression.
-    return result;
-  }
-
-  void DoAdd(const void* name, uint32_t hash, Interface* interface, Zone* zone,
-             bool* ok);
-  void DoUnify(Interface* that, bool* ok, Zone* zone);
 };
 
 } }  // namespace v8::internal
index b554175bccf21b27e295adb7517c192566a0a01e..19d61041d1942c400b9fce07e56ca39a2130d38a 100644 (file)
@@ -175,7 +175,6 @@ var kMessages = {
   symbol_to_primitive:           ["Cannot convert a Symbol wrapper object to a primitive value"],
   symbol_to_number:              ["Cannot convert a Symbol value to a number"],
   invalid_module_path:           ["Module does not export '", "%0", "', or export is not itself a module"],
-  module_type_error:             ["Module '", "%0", "' used improperly"],
   module_export_undefined:       ["Export '", "%0", "' is not defined in module"],
   unexpected_super:              ["'super' keyword unexpected here"],
   extends_value_not_a_function:  ["Class extends value ", "%0", " is not a function or null"],
index b20e15a2171ad3a9cc208d7652a4443a9aad5487..494c65da194433e84166d6de53e23f675f7a7b08 100644 (file)
@@ -950,15 +950,16 @@ void FullCodeGenerator::VisitFunctionDeclaration(
 
 void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) {
   Variable* variable = declaration->proxy()->var();
+  Interface* interface = declaration->module()->interface();
   DCHECK(variable->location() == Variable::CONTEXT);
-  DCHECK(variable->interface()->IsFrozen());
+  DCHECK(interface->IsFrozen());
 
   Comment cmnt(masm_, "[ ModuleDeclaration");
   EmitDebugCheckDeclarationContext(variable);
 
   // Load instance object.
   __ LoadContext(a1, scope_->ContextChainLength(scope_->ScriptScope()));
-  __ lw(a1, ContextOperand(a1, variable->interface()->Index()));
+  __ lw(a1, ContextOperand(a1, interface->Index()));
   __ lw(a1, ContextOperand(a1, Context::EXTENSION_INDEX));
 
   // Assign it.
index 67e4aaed35202a8842bd5ee484ac51de72dfba56..ca9fb2ae661d7496b38be66b0ac9eb9c9bda9be6 100644 (file)
@@ -947,14 +947,15 @@ void FullCodeGenerator::VisitFunctionDeclaration(
 
 void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) {
   Variable* variable = declaration->proxy()->var();
+  Interface* interface = declaration->module()->interface();
   DCHECK(variable->location() == Variable::CONTEXT);
-  DCHECK(variable->interface()->IsFrozen());
+  DCHECK(interface->IsFrozen());
   Comment cmnt(masm_, "[ ModuleDeclaration");
   EmitDebugCheckDeclarationContext(variable);
 
   // Load instance object.
   __ LoadContext(a1, scope_->ContextChainLength(scope_->ScriptScope()));
-  __ ld(a1, ContextOperand(a1, variable->interface()->Index()));
+  __ ld(a1, ContextOperand(a1, interface->Index()));
   __ ld(a1, ContextOperand(a1, Context::EXTENSION_INDEX));
 
   // Assign it.
index e886e3a7d33fab1c6378aa366f6e1c0245b00bca..87561ad2d25f75a0eb924fffeac3e767f108fcf3 100644 (file)
@@ -710,20 +710,14 @@ Expression* ParserTraits::ExpressionFromIdentifier(const AstRawString* name,
                                                    int pos, Scope* scope,
                                                    AstNodeFactory* factory) {
   if (parser_->fni_ != NULL) parser_->fni_->PushVariableName(name);
-  // The name may refer to a module instance object, so its type is unknown.
-#ifdef DEBUG
-  if (FLAG_print_interface_details)
-    PrintF("# Variable %.*s ", name->length(), name->raw_data());
-#endif
-  Interface* interface = Interface::NewUnknown(parser_->zone());
 
   // Arrow function parameters are parsed as an expression. When
   // parsing lazily, it is enough to create a VariableProxy in order
   // for Traits::DeclareArrowParametersFromExpression() to be able to
   // pick the names of the parameters.
   return parser_->parsing_lazy_arrow_parameters_
-      ? factory->NewVariableProxy(name, false, interface, pos)
-      : scope->NewUnresolved(factory, name, interface, pos);
+             ? factory->NewVariableProxy(name, false, pos)
+             : scope->NewUnresolved(factory, name, pos);
 }
 
 
@@ -1294,10 +1288,7 @@ Statement* Parser::ParseModule(bool* ok) {
     }
   }
 
-  interface->MakeModule(ok);
-  DCHECK(*ok);
-  interface->Freeze(ok);
-  DCHECK(*ok);
+  scope->interface()->Freeze();
   return body;
 }
 
@@ -1621,11 +1612,9 @@ Statement* Parser::ParseExportDeclaration(bool* ok) {
       if (FLAG_print_interface_details)
         PrintF("# Export %.*s ", names[i]->length(), names[i]->raw_data());
 #endif
-      Interface* inner = Interface::NewUnknown(zone());
-      interface->Add(names[i], inner, zone(), CHECK_OK);
-      if (!*ok) return NULL;
-      VariableProxy* proxy = NewUnresolved(names[i], LET, inner);
-      USE(proxy);
+      // TODO(adamk): Make early errors here provide the right error message
+      // (duplicate exported names).
+      interface->Add(names[i], zone(), CHECK_OK);
       // TODO(rossberg): Rethink whether we actually need to store export
       // declarations (for compilation?).
       // ExportDeclaration* declaration =
@@ -1777,14 +1766,13 @@ Statement* Parser::ParseSubStatement(ZoneList<const AstRawString*>* labels,
 
 
 VariableProxy* Parser::NewUnresolved(const AstRawString* name,
-                                     VariableMode mode, Interface* interface) {
+                                     VariableMode mode) {
   // If we are inside a function, a declaration of a var/const variable is a
   // truly local variable, and the scope of the variable is always the function
   // scope.
   // Let/const variables in harmony mode are always added to the immediately
   // enclosing scope.
-  return DeclarationScope(mode)->NewUnresolved(
-      factory(), name, interface, position());
+  return DeclarationScope(mode)->NewUnresolved(factory(), name, position());
 }
 
 
@@ -1813,9 +1801,8 @@ void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) {
     var = declaration_scope->LookupLocal(name);
     if (var == NULL) {
       // Declare the name.
-      var = declaration_scope->DeclareLocal(name, mode,
-                                            declaration->initialization(),
-                                            kNotAssigned, proxy->interface());
+      var = declaration_scope->DeclareLocal(
+          name, mode, declaration->initialization(), kNotAssigned);
     } else if (IsLexicalVariableMode(mode) || IsLexicalVariableMode(var->mode())
                || ((mode == CONST_LEGACY || var->mode() == CONST_LEGACY) &&
                    !declaration_scope->is_script_scope())) {
@@ -1870,9 +1857,8 @@ void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) {
     // For global const variables we bind the proxy to a variable.
     DCHECK(resolve);  // should be set by all callers
     Variable::Kind kind = Variable::NORMAL;
-    var = new (zone())
-        Variable(declaration_scope, name, mode, true, kind,
-                 kNeedsInitialization, kNotAssigned, proxy->interface());
+    var = new (zone()) Variable(declaration_scope, name, mode, true, kind,
+                                kNeedsInitialization, kNotAssigned);
   } else if (declaration_scope->is_eval_scope() &&
              is_sloppy(declaration_scope->language_mode())) {
     // For variable declarations in a sloppy eval scope the proxy is bound
@@ -1881,8 +1867,7 @@ void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) {
     Variable::Kind kind = Variable::NORMAL;
     // TODO(sigurds) figure out if kNotAssigned is OK here
     var = new (zone()) Variable(declaration_scope, name, mode, true, kind,
-                                declaration->initialization(), kNotAssigned,
-                                proxy->interface());
+                                declaration->initialization(), kNotAssigned);
     var->AllocateTo(Variable::LOOKUP, -1);
     resolve = true;
   }
@@ -1913,29 +1898,6 @@ void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) {
   // runtime needs to provide both.
   if (resolve && var != NULL) {
     proxy->BindTo(var);
-
-    if (FLAG_harmony_modules) {
-      bool ok;
-#ifdef DEBUG
-      if (FLAG_print_interface_details) {
-        PrintF("# Declare %.*s ", var->raw_name()->length(),
-               var->raw_name()->raw_data());
-      }
-#endif
-      proxy->interface()->Unify(var->interface(), zone(), &ok);
-      if (!ok) {
-#ifdef DEBUG
-        if (FLAG_print_interfaces) {
-          PrintF("DECLARE TYPE ERROR\n");
-          PrintF("proxy: ");
-          proxy->interface()->Print();
-          PrintF("var: ");
-          var->interface()->Print();
-        }
-#endif
-        ParserTraits::ReportMessage("module_type_error", name);
-      }
-    }
   }
 }
 
@@ -1970,7 +1932,7 @@ Statement* Parser::ParseNativeDeclaration(bool* ok) {
   // TODO(1240846): It's weird that native function declarations are
   // introduced dynamically when we meet their declarations, whereas
   // other functions are set up when entering the surrounding scope.
-  VariableProxy* proxy = NewUnresolved(name, VAR, Interface::NewValue());
+  VariableProxy* proxy = NewUnresolved(name, VAR);
   Declaration* declaration =
       factory()->NewVariableDeclaration(proxy, VAR, scope_, pos);
   Declare(declaration, true, CHECK_OK);
@@ -2013,7 +1975,7 @@ Statement* Parser::ParseFunctionDeclaration(
                 scope_->is_function_scope())
           ? LET
           : VAR;
-  VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue());
+  VariableProxy* proxy = NewUnresolved(name, mode);
   Declaration* declaration =
       factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos);
   Declare(declaration, true, CHECK_OK);
@@ -2051,7 +2013,7 @@ Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names,
   ClassLiteral* value = ParseClassLiteral(name, scanner()->location(),
                                           is_strict_reserved, pos, CHECK_OK);
 
-  VariableProxy* proxy = NewUnresolved(name, LET, Interface::NewValue());
+  VariableProxy* proxy = NewUnresolved(name, LET);
   Declaration* declaration =
       factory()->NewVariableDeclaration(proxy, LET, scope_, pos);
   Declare(declaration, true, CHECK_OK);
@@ -2260,9 +2222,7 @@ Block* Parser::ParseVariableDeclarations(
       needs_init = false;
     }
 
-    Interface* interface =
-        is_const ? Interface::NewConst() : Interface::NewValue();
-    VariableProxy* proxy = NewUnresolved(name, mode, interface);
+    VariableProxy* proxy = NewUnresolved(name, mode);
     Declaration* declaration =
         factory()->NewVariableDeclaration(proxy, mode, scope_, pos);
     Declare(declaration, mode != VAR, CHECK_OK);
@@ -2426,7 +2386,7 @@ Block* Parser::ParseVariableDeclarations(
       // if they are inside a 'with' statement - they may change a 'with' object
       // property).
       VariableProxy* proxy =
-          initialization_scope->NewUnresolved(factory(), name, interface);
+          initialization_scope->NewUnresolved(factory(), name);
       Assignment* assignment =
           factory()->NewAssignment(init_op, proxy, value, pos);
       block->AddStatement(
@@ -3062,8 +3022,7 @@ Statement* Parser::DesugarLetBindingsInForStatement(
   // For each let variable x:
   //   make statement: temp_x = x.
   for (int i = 0; i < names->length(); i++) {
-    VariableProxy* proxy =
-        NewUnresolved(names->at(i), LET, Interface::NewValue());
+    VariableProxy* proxy = NewUnresolved(names->at(i), LET);
     Variable* temp = scope_->DeclarationScope()->NewTemporary(temp_name);
     VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
     Assignment* assignment = factory()->NewAssignment(
@@ -3107,8 +3066,7 @@ Statement* Parser::DesugarLetBindingsInForStatement(
   // For each let variable x:
   //    make statement: let x = temp_x.
   for (int i = 0; i < names->length(); i++) {
-    VariableProxy* proxy =
-        NewUnresolved(names->at(i), LET, Interface::NewValue());
+    VariableProxy* proxy = NewUnresolved(names->at(i), LET);
     Declaration* declaration =
         factory()->NewVariableDeclaration(proxy, LET, scope_, pos);
     Declare(declaration, true, CHECK_OK);
@@ -3259,7 +3217,6 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
   if (peek() != Token::SEMICOLON) {
     if (peek() == Token::VAR ||
         (peek() == Token::CONST && is_sloppy(language_mode()))) {
-      bool is_const = peek() == Token::CONST;
       const AstRawString* name = NULL;
       VariableDeclarationProperties decl_props = kHasNoInitializers;
       Block* variable_statement =
@@ -3270,8 +3227,6 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
       int each_pos = position();
 
       if (name != NULL && CheckInOrOf(accept_OF, &mode)) {
-        Interface* interface =
-            is_const ? Interface::NewConst() : Interface::NewValue();
         ForEachStatement* loop =
             factory()->NewForEachStatement(mode, labels, stmt_pos);
         Target target(&this->target_stack_, loop);
@@ -3279,8 +3234,7 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
         Expression* enumerable = ParseExpression(true, CHECK_OK);
         Expect(Token::RPAREN, CHECK_OK);
 
-        VariableProxy* each =
-            scope_->NewUnresolved(factory(), name, interface, each_pos);
+        VariableProxy* each = scope_->NewUnresolved(factory(), name, each_pos);
         Statement* body = ParseSubStatement(NULL, CHECK_OK);
         InitializeForEachStatement(loop, each, enumerable, body);
         Block* result =
@@ -3338,8 +3292,7 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
         scope_ = for_scope;
         Expect(Token::RPAREN, CHECK_OK);
 
-        VariableProxy* each = scope_->NewUnresolved(
-            factory(), name, Interface::NewValue(), each_pos);
+        VariableProxy* each = scope_->NewUnresolved(factory(), name, each_pos);
         Statement* body = ParseSubStatement(NULL, CHECK_OK);
         Block* body_block =
             factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition);
@@ -3780,8 +3733,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
       DCHECK(function_name != NULL);
       fvar = new (zone())
           Variable(scope_, function_name, fvar_mode, true /* is valid LHS */,
-                   Variable::NORMAL, kCreatedInitialized, kNotAssigned,
-                   Interface::NewConst());
+                   Variable::NORMAL, kCreatedInitialized, kNotAssigned);
       VariableProxy* proxy = factory()->NewVariableProxy(fvar);
       VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration(
           proxy, fvar_mode, scope_, RelocInfo::kNoPosition);
@@ -3972,8 +3924,7 @@ ZoneList<Statement*>* Parser::ParseEagerFunctionBody(
   ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
   ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8, zone());
   if (fvar != NULL) {
-    VariableProxy* fproxy = scope_->NewUnresolved(
-        factory(), function_name, Interface::NewConst());
+    VariableProxy* fproxy = scope_->NewUnresolved(factory(), function_name);
     fproxy->BindTo(fvar);
     body->Add(factory()->NewExpressionStatement(
         factory()->NewAssignment(fvar_init_op,
@@ -4103,7 +4054,7 @@ ClassLiteral* Parser::ParseClassLiteral(const AstRawString* name,
 
   VariableProxy* proxy = NULL;
   if (name != NULL) {
-    proxy = NewUnresolved(name, CONST, Interface::NewConst());
+    proxy = NewUnresolved(name, CONST);
     Declaration* declaration =
         factory()->NewVariableDeclaration(proxy, CONST, block_scope, pos);
     Declare(declaration, true, CHECK_OK);
index 343da07e89ee319f2738b2d48abbbf8603b57cdb..ff36fe90e0b0cd1c9a5c44f6086b7dc6ba069e33 100644 (file)
@@ -798,9 +798,7 @@ class Parser : public ParserBase<ParserTraits> {
   void CheckConflictingVarDeclarations(Scope* scope, bool* ok);
 
   // Parser support
-  VariableProxy* NewUnresolved(const AstRawString* name,
-                               VariableMode mode,
-                               Interface* interface);
+  VariableProxy* NewUnresolved(const AstRawString* name, VariableMode mode);
   void Declare(Declaration* declaration, bool resolve, bool* ok);
 
   bool TargetStackContainsLabel(const AstRawString* label);
index 69bcc05749f1dcb8d311f945760f4db5cdb55f75..c71a95f6bff10a89bfbe488463e99c4b323c568d 100644 (file)
@@ -890,15 +890,16 @@ void FullCodeGenerator::VisitFunctionDeclaration(
 
 void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) {
   Variable* variable = declaration->proxy()->var();
+  Interface* interface = declaration->module()->interface();
   DCHECK(variable->location() == Variable::CONTEXT);
-  DCHECK(variable->interface()->IsFrozen());
+  DCHECK(interface->IsFrozen());
 
   Comment cmnt(masm_, "[ ModuleDeclaration");
   EmitDebugCheckDeclarationContext(variable);
 
   // Load instance object.
   __ LoadContext(r4, scope_->ContextChainLength(scope_->ScriptScope()));
-  __ LoadP(r4, ContextOperand(r4, variable->interface()->Index()));
+  __ LoadP(r4, ContextOperand(r4, interface->Index()));
   __ LoadP(r4, ContextOperand(r4, Context::EXTENSION_INDEX));
 
   // Assign it.
index 8a260bd6514d891ccaba432139b26e1db6e9663a..da43d0eb0f870ad7097f80277d09f46fad47c41d 100644 (file)
@@ -118,11 +118,6 @@ void CallPrinter::VisitModuleLiteral(ModuleLiteral* node) {
 }
 
 
-void CallPrinter::VisitModuleVariable(ModuleVariable* node) {
-  Find(node->proxy());
-}
-
-
 void CallPrinter::VisitModulePath(ModulePath* node) { Find(node->module()); }
 
 
@@ -503,11 +498,6 @@ void PrettyPrinter::VisitModuleLiteral(ModuleLiteral* node) {
 }
 
 
-void PrettyPrinter::VisitModuleVariable(ModuleVariable* node) {
-  Visit(node->proxy());
-}
-
-
 void PrettyPrinter::VisitModulePath(ModulePath* node) {
   Visit(node->module());
   Print(".");
@@ -523,8 +513,6 @@ void PrettyPrinter::VisitModuleUrl(ModuleUrl* node) {
 
 void PrettyPrinter::VisitModuleStatement(ModuleStatement* node) {
   Print("module ");
-  PrintLiteral(node->proxy()->name(), false);
-  Print(" ");
   Visit(node->body());
 }
 
@@ -1241,12 +1229,6 @@ void AstPrinter::VisitModuleLiteral(ModuleLiteral* node) {
 }
 
 
-void AstPrinter::VisitModuleVariable(ModuleVariable* node) {
-  IndentedScope indent(this, "MODULE VARIABLE");
-  Visit(node->proxy());
-}
-
-
 void AstPrinter::VisitModulePath(ModulePath* node) {
   IndentedScope indent(this, "MODULE PATH");
   PrintIndentedVisit("MODULE PATH PARENT", node->module());
@@ -1261,7 +1243,6 @@ void AstPrinter::VisitModuleUrl(ModuleUrl* node) {
 
 void AstPrinter::VisitModuleStatement(ModuleStatement* node) {
   IndentedScope indent(this, "MODULE STATEMENT");
-  PrintLiteralIndented("NAME", node->proxy()->name(), true);
   PrintStatements(node->body()->statements());
 }
 
index 66961278a76f0161e5152b7f5ce10aea7efc22b5..c81950e8ed6b2f597a0bc4a2b0ad265962c7c48b 100644 (file)
@@ -206,7 +206,6 @@ void Processor::VisitModuleDeclaration(ModuleDeclaration* node) {}
 void Processor::VisitImportDeclaration(ImportDeclaration* node) {}
 void Processor::VisitExportDeclaration(ExportDeclaration* node) {}
 void Processor::VisitModuleLiteral(ModuleLiteral* node) {}
-void Processor::VisitModuleVariable(ModuleVariable* node) {}
 void Processor::VisitModulePath(ModulePath* node) {}
 void Processor::VisitModuleUrl(ModuleUrl* node) {}
 void Processor::VisitEmptyStatement(EmptyStatement* node) {}
index 1062719a00a163962a245e20bb71e5fe455321f2..7eb2e0cfc1703940ec9e5a0231a17248b7df3d15 100644 (file)
@@ -801,13 +801,6 @@ RUNTIME_FUNCTION(Runtime_DeclareModules) {
           USE(result);
           break;
         }
-        case MODULE: {
-          Object* referenced_context = Context::cast(host_context)->get(index);
-          Handle<JSModule> value(Context::cast(referenced_context)->module());
-          JSObject::SetOwnPropertyIgnoreAttributes(module, name, value, FROZEN)
-              .Assert();
-          break;
-        }
         case INTERNAL:
         case TEMPORARY:
         case DYNAMIC:
index 81aedb3e673c0ebb03825d0cdd876b7376b3c88c..2c4cc69c8d2345c8b1ff05746da291c9f0fddb52 100644 (file)
@@ -562,15 +562,8 @@ Handle<ModuleInfo> ModuleInfo::Create(
     Variable* var = scope->LookupLocal(it.name());
     info->set_name(i, *(it.name()->string()));
     info->set_mode(i, var->mode());
-    DCHECK((var->mode() == MODULE) == (it.interface()->IsModule()));
-    if (var->mode() == MODULE) {
-      DCHECK(it.interface()->IsFrozen());
-      DCHECK(it.interface()->Index() >= 0);
-      info->set_index(i, it.interface()->Index());
-    } else {
-      DCHECK(var->index() >= 0);
-      info->set_index(i, var->index());
-    }
+    DCHECK(var->index() >= 0);
+    info->set_index(i, var->index());
   }
   DCHECK(i == info->length());
   return info;
index 8462548d9d1cf444f1084fedea8be65bd37770c9..cfdd4b68dd64baf02d8b874b482b2c42e5a430ff 100644 (file)
@@ -6,6 +6,7 @@
 #define V8_SCOPEINFO_H_
 
 #include "src/allocation.h"
+#include "src/interface.h"
 #include "src/variables.h"
 
 namespace v8 {
index 05cd2e7c16ef50b2a0375f1db55c32a2c82e93b5..b9301d833bcd01b35da59cd6602ceb65a317cf93 100644 (file)
@@ -34,8 +34,7 @@ Variable* VariableMap::Declare(Scope* scope, const AstRawString* name,
                                VariableMode mode, bool is_valid_lhs,
                                Variable::Kind kind,
                                InitializationFlag initialization_flag,
-                               MaybeAssignedFlag maybe_assigned_flag,
-                               Interface* interface) {
+                               MaybeAssignedFlag maybe_assigned_flag) {
   // AstRawStrings are unambiguous, i.e., the same string is always represented
   // by the same AstRawString*.
   // FIXME(marja): fix the type of Lookup.
@@ -44,9 +43,8 @@ Variable* VariableMap::Declare(Scope* scope, const AstRawString* name,
   if (p->value == NULL) {
     // The variable has not been declared yet -> insert it.
     DCHECK(p->key == name);
-    p->value = new (zone())
-        Variable(scope, name, mode, is_valid_lhs, kind, initialization_flag,
-                 maybe_assigned_flag, interface);
+    p->value = new (zone()) Variable(scope, name, mode, is_valid_lhs, kind,
+                                     initialization_flag, maybe_assigned_flag);
   }
   return reinterpret_cast<Variable*>(p->value);
 }
@@ -76,7 +74,7 @@ Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type,
       params_(4, zone),
       unresolved_(16, zone),
       decls_(4, zone),
-      interface_(scope_type == MODULE_SCOPE ? Interface::NewModule(zone)
+      interface_(scope_type == MODULE_SCOPE ? Interface::New(zone)
                                             : NULL),
       already_resolved_(false),
       ast_value_factory_(ast_value_factory),
@@ -469,8 +467,7 @@ Variable* Scope::DeclareParameter(const AstRawString* name, VariableMode mode,
 
 Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode,
                               InitializationFlag init_flag,
-                              MaybeAssignedFlag maybe_assigned_flag,
-                              Interface* interface) {
+                              MaybeAssignedFlag maybe_assigned_flag) {
   DCHECK(!already_resolved());
   // This function handles VAR, LET, and CONST modes.  DYNAMIC variables are
   // introduces during variable allocation, INTERNAL variables are allocated
@@ -478,7 +475,7 @@ Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode,
   DCHECK(IsDeclaredVariableMode(mode));
   ++num_var_or_const_;
   return variables_.Declare(this, name, mode, true, Variable::NORMAL, init_flag,
-                            maybe_assigned_flag, interface);
+                            maybe_assigned_flag);
 }
 
 
@@ -1095,42 +1092,6 @@ bool Scope::ResolveVariable(CompilationInfo* info, VariableProxy* proxy,
   DCHECK(var != NULL);
   if (proxy->is_assigned()) var->set_maybe_assigned();
 
-  if (FLAG_harmony_modules) {
-    bool ok;
-#ifdef DEBUG
-    if (FLAG_print_interface_details) {
-      PrintF("# Resolve %.*s:\n", var->raw_name()->length(),
-             var->raw_name()->raw_data());
-    }
-#endif
-    proxy->interface()->Unify(var->interface(), zone(), &ok);
-    if (!ok) {
-#ifdef DEBUG
-      if (FLAG_print_interfaces) {
-        PrintF("SCOPES TYPE ERROR\n");
-        PrintF("proxy: ");
-        proxy->interface()->Print();
-        PrintF("var: ");
-        var->interface()->Print();
-      }
-#endif
-
-      // Inconsistent use of module. Throw a syntax error.
-      // TODO(rossberg): generate more helpful error message.
-      MessageLocation location(
-          info->script(), proxy->position(), proxy->position());
-      Isolate* isolate = info->isolate();
-      Factory* factory = isolate->factory();
-      Handle<JSArray> array = factory->NewJSArray(1);
-      JSObject::SetElement(array, 0, var->name(), NONE, STRICT).Assert();
-      Handle<Object> error;
-      MaybeHandle<Object> maybe_error =
-          factory->NewSyntaxError("module_type_error", array);
-      if (maybe_error.ToHandle(&error)) isolate->Throw(*error, &location);
-      return false;
-    }
-  }
-
   proxy->BindTo(var);
 
   return true;
index c3f4f8e2661eb3cade34529ba6df9fa9f8aa14f9..a0d5ff5021846faa95de8c55f7a2926048f0bb0e 100644 (file)
@@ -24,8 +24,7 @@ class VariableMap: public ZoneHashMap {
   Variable* Declare(Scope* scope, const AstRawString* name, VariableMode mode,
                     bool is_valid_lhs, Variable::Kind kind,
                     InitializationFlag initialization_flag,
-                    MaybeAssignedFlag maybe_assigned_flag = kNotAssigned,
-                    Interface* interface = Interface::NewValue());
+                    MaybeAssignedFlag maybe_assigned_flag = kNotAssigned);
 
   Variable* Lookup(const AstRawString* name);
 
@@ -132,8 +131,7 @@ class Scope: public ZoneObject {
   // declared before, the previously declared variable is returned.
   Variable* DeclareLocal(const AstRawString* name, VariableMode mode,
                          InitializationFlag init_flag,
-                         MaybeAssignedFlag maybe_assigned_flag = kNotAssigned,
-                         Interface* interface = Interface::NewValue());
+                         MaybeAssignedFlag maybe_assigned_flag = kNotAssigned);
 
   // Declare an implicit global variable in this scope which must be a
   // script scope.  The variable was introduced (possibly from an inner
@@ -144,14 +142,12 @@ class Scope: public ZoneObject {
   // Create a new unresolved variable.
   VariableProxy* NewUnresolved(AstNodeFactory* factory,
                                const AstRawString* name,
-                               Interface* interface = Interface::NewValue(),
                                int position = RelocInfo::kNoPosition) {
     // Note that we must not share the unresolved variables with
     // the same name because they may be removed selectively via
     // RemoveUnresolved().
     DCHECK(!already_resolved());
-    VariableProxy* proxy =
-        factory->NewVariableProxy(name, false, interface, position);
+    VariableProxy* proxy = factory->NewVariableProxy(name, false, position);
     unresolved_.Add(proxy, zone_);
     return proxy;
   }
index 0a7ba618390a8df4852be5b1f6da35832f6bb740..48528705bf1e1abb605d2a243199eb7a7ab05e30 100644 (file)
@@ -797,10 +797,6 @@ void AstTyper::VisitModuleLiteral(ModuleLiteral* module) {
 }
 
 
-void AstTyper::VisitModuleVariable(ModuleVariable* module) {
-}
-
-
 void AstTyper::VisitModulePath(ModulePath* module) {
   RECURSE(Visit(module->module()));
 }
index 3b1559d8645301d8f3e152bb69433a1baede518f..2351e529a24c8c1bd19c6cc47351df3e3f6ab06c 100644 (file)
@@ -20,7 +20,6 @@ const char* Variable::Mode2String(VariableMode mode) {
     case CONST_LEGACY: return "CONST_LEGACY";
     case LET: return "LET";
     case CONST: return "CONST";
-    case MODULE: return "MODULE";
     case DYNAMIC: return "DYNAMIC";
     case DYNAMIC_GLOBAL: return "DYNAMIC_GLOBAL";
     case DYNAMIC_LOCAL: return "DYNAMIC_LOCAL";
@@ -35,7 +34,7 @@ const char* Variable::Mode2String(VariableMode mode) {
 Variable::Variable(Scope* scope, const AstRawString* name, VariableMode mode,
                    bool is_valid_ref, Kind kind,
                    InitializationFlag initialization_flag,
-                   MaybeAssignedFlag maybe_assigned_flag, Interface* interface)
+                   MaybeAssignedFlag maybe_assigned_flag)
     : scope_(scope),
       name_(name),
       mode_(mode),
@@ -48,8 +47,7 @@ Variable::Variable(Scope* scope, const AstRawString* name, VariableMode mode,
       force_context_allocation_(false),
       is_used_(false),
       initialization_flag_(initialization_flag),
-      maybe_assigned_(maybe_assigned_flag),
-      interface_(interface) {
+      maybe_assigned_(maybe_assigned_flag) {
   // Var declared variables never need initialization.
   DCHECK(!(mode == VAR && initialization_flag == kNeedsInitialization));
 }
index e35ae7d1cc377f823cf57837574c00b1cf14f953..1adeb1f0f417cc0d8bcdf6a19a2f688f1195e477 100644 (file)
@@ -6,7 +6,6 @@
 #define V8_VARIABLES_H_
 
 #include "src/ast-value-factory.h"
-#include "src/interface.h"
 #include "src/zone.h"
 
 namespace v8 {
@@ -50,8 +49,7 @@ class Variable: public ZoneObject {
 
   Variable(Scope* scope, const AstRawString* name, VariableMode mode,
            bool is_valid_ref, Kind kind, InitializationFlag initialization_flag,
-           MaybeAssignedFlag maybe_assigned_flag = kNotAssigned,
-           Interface* interface = Interface::NewValue());
+           MaybeAssignedFlag maybe_assigned_flag = kNotAssigned);
 
   // Printing support
   static const char* Mode2String(VariableMode mode);
@@ -123,7 +121,6 @@ class Variable: public ZoneObject {
   InitializationFlag initialization_flag() const {
     return initialization_flag_;
   }
-  Interface* interface() const { return interface_; }
 
   void AllocateTo(Location location, int index) {
     location_ = location;
@@ -155,9 +152,6 @@ class Variable: public ZoneObject {
   bool is_used_;
   InitializationFlag initialization_flag_;
   MaybeAssignedFlag maybe_assigned_;
-
-  // Module type info.
-  Interface* interface_;
 };
 
 
index d2a3b71123df9d25b3f6978be90811396252bc74..790fed4a1c88dfe88bd3be1857ff292e7f92ecb1 100644 (file)
@@ -917,15 +917,16 @@ void FullCodeGenerator::VisitFunctionDeclaration(
 
 void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) {
   Variable* variable = declaration->proxy()->var();
+  Interface* interface = declaration->module()->interface();
   DCHECK(variable->location() == Variable::CONTEXT);
-  DCHECK(variable->interface()->IsFrozen());
+  DCHECK(interface->IsFrozen());
 
   Comment cmnt(masm_, "[ ModuleDeclaration");
   EmitDebugCheckDeclarationContext(variable);
 
   // Load instance object.
   __ LoadContext(rax, scope_->ContextChainLength(scope_->ScriptScope()));
-  __ movp(rax, ContextOperand(rax, variable->interface()->Index()));
+  __ movp(rax, ContextOperand(rax, interface->Index()));
   __ movp(rax, ContextOperand(rax, Context::EXTENSION_INDEX));
 
   // Assign it.
index 0b43f8439f008942ea75e377b3f2c8383da5ec4f..6171240e7864329f1f938a79e3f9e894fb303ef8 100644 (file)
@@ -886,15 +886,16 @@ void FullCodeGenerator::VisitFunctionDeclaration(
 
 void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) {
   Variable* variable = declaration->proxy()->var();
+  Interface* interface = declaration->module()->interface();
   DCHECK(variable->location() == Variable::CONTEXT);
-  DCHECK(variable->interface()->IsFrozen());
+  DCHECK(interface->IsFrozen());
 
   Comment cmnt(masm_, "[ ModuleDeclaration");
   EmitDebugCheckDeclarationContext(variable);
 
   // Load instance object.
   __ LoadContext(eax, scope_->ContextChainLength(scope_->ScriptScope()));
-  __ mov(eax, ContextOperand(eax, variable->interface()->Index()));
+  __ mov(eax, ContextOperand(eax, interface->Index()));
   __ mov(eax, ContextOperand(eax, Context::EXTENSION_INDEX));
 
   // Assign it.
index 95ce793405b9d28f74175ccfb0a564796519ed3a..b6c427fff9e20189b1a2debbeaf007ea47fb8946 100644 (file)
@@ -5210,6 +5210,7 @@ TEST(ImportExportParsingErrors) {
       "export { for as foo }",
       "export { arguments }",
       "export { arguments as foo }",
+      "var a; export { a, a };",
 
       "import from;",
       "import from 'm.js';",