Revision: 12078
Author:   [email protected]
Date:     Fri Jul 13 02:29:43 2012
Log:      Incorporate constness into inferred interfaces
(in preparation for handling imports).

[email protected]
BUG=v8:1569
TEST=

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

Modified:
 /branches/bleeding_edge/src/ast.cc
 /branches/bleeding_edge/src/ast.h
 /branches/bleeding_edge/src/interface.cc
 /branches/bleeding_edge/src/interface.h
 /branches/bleeding_edge/src/parser.cc
 /branches/bleeding_edge/src/parser.h
 /branches/bleeding_edge/src/rewriter.cc
 /branches/bleeding_edge/src/scopes.h

=======================================
--- /branches/bleeding_edge/src/ast.cc  Wed Jul 11 07:27:53 2012
+++ /branches/bleeding_edge/src/ast.cc  Fri Jul 13 02:29:43 2012
@@ -85,8 +85,8 @@
 VariableProxy::VariableProxy(Isolate* isolate,
                              Handle<String> name,
                              bool is_this,
-                             int position,
-                             Interface* interface)
+                             Interface* interface,
+                             int position)
     : Expression(isolate),
       name_(name),
       var_(NULL),
=======================================
--- /branches/bleeding_edge/src/ast.h   Tue Jul 10 02:15:03 2012
+++ /branches/bleeding_edge/src/ast.h   Fri Jul 13 02:29:43 2012
@@ -1496,8 +1496,8 @@
   VariableProxy(Isolate* isolate,
                 Handle<String> name,
                 bool is_this,
-                int position,
-                Interface* interface);
+                Interface* interface,
+                int position);

   Handle<String> name_;
   Variable* var_;  // resolved variable, or NULL
@@ -2846,11 +2846,10 @@

   VariableProxy* NewVariableProxy(Handle<String> name,
                                   bool is_this,
-                                  int position = RelocInfo::kNoPosition,
-                                  Interface* interface =
-                                      Interface::NewValue()) {
+ Interface* interface = Interface::NewValue(),
+                                  int position = RelocInfo::kNoPosition) {
     VariableProxy* proxy =
- new(zone_) VariableProxy(isolate_, name, is_this, position, interface); + new(zone_) VariableProxy(isolate_, name, is_this, interface, position);
     VISIT_AND_RETURN(VariableProxy, proxy)
   }

=======================================
--- /branches/bleeding_edge/src/interface.cc    Mon Jun 11 05:42:31 2012
+++ /branches/bleeding_edge/src/interface.cc    Fri Jul 13 02:29:43 2012
@@ -124,8 +124,16 @@

   *ok = true;
   if (this == that) return;
-  if (this->IsValue()) return that->MakeValue(ok);
-  if (that->IsValue()) return this->MakeValue(ok);
+  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) {
@@ -214,6 +222,8 @@

   if (IsUnknown()) {
     PrintF("unknown\n");
+  } else if (IsConst()) {
+    PrintF("const\n");
   } else if (IsValue()) {
     PrintF("value\n");
   } else if (IsModule()) {
=======================================
--- /branches/bleeding_edge/src/interface.h     Mon Jun 11 05:42:31 2012
+++ /branches/bleeding_edge/src/interface.h     Fri Jul 13 02:29:43 2012
@@ -36,25 +36,41 @@

 // This class implements the following abstract grammar of interfaces
 // (i.e. module types):
-//   interface ::= UNDETERMINED | VALUE | MODULE(exports)
+//   interface ::= UNDETERMINED | VALUE | CONST | MODULE(exports)
 //   exports ::= {name : interface, ...}
-// A frozen module type is one that is fully determined. Unification does not
-// allow adding additional exports to frozen interfaces.
-// Otherwise, unifying modules merges their exports.
+// 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 Interface : public ZoneObject {
  public:
// ---------------------------------------------------------------------------
   // Factory methods.

+  static Interface* NewUnknown(Zone* zone) {
+    return new(zone) Interface(NONE);
+  }
+
   static Interface* NewValue() {
     static Interface value_interface(VALUE + FROZEN);  // Cached.
     return &value_interface;
   }

-  static Interface* NewUnknown(Zone* zone) {
-    return new(zone) Interface(NONE);
+  static Interface* NewConst() {
+    static Interface value_interface(VALUE + CONST + FROZEN);  // Cached.
+    return &value_interface;
   }

   static Interface* NewModule(Zone* zone) {
@@ -79,6 +95,12 @@
     *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) {
@@ -106,6 +128,9 @@

   // 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; }
@@ -161,8 +186,9 @@
   enum Flags {    // All flags are monotonic
     NONE = 0,
     VALUE = 1,    // This type describes a value
-    MODULE = 2,   // This type describes a module
-    FROZEN = 4    // This type is fully determined
+    CONST = 2,    // This type describes a constant
+    MODULE = 4,   // This type describes a module
+    FROZEN = 8    // This type is fully determined
   };

   int flags_;
=======================================
--- /branches/bleeding_edge/src/parser.cc       Tue Jul 10 05:24:17 2012
+++ /branches/bleeding_edge/src/parser.cc       Fri Jul 13 02:29:43 2012
@@ -1408,8 +1408,8 @@
     PrintF("# Module variable %s ", name->ToAsciiArray());
 #endif
   VariableProxy* proxy = top_scope_->NewUnresolved(
-      factory(), name, scanner().location().beg_pos,
-      Interface::NewModule(zone()));
+      factory(), name, Interface::NewModule(zone()),
+      scanner().location().beg_pos);

   return factory()->NewModuleVariable(proxy);
 }
@@ -1499,7 +1499,6 @@
     Declaration* declaration =
         factory()->NewImportDeclaration(proxy, module, top_scope_);
     Declare(declaration, true, CHECK_OK);
-    // TODO(rossberg): Add initialization statement to block.
   }

   return block;
@@ -1740,7 +1739,7 @@
// Let/const variables in harmony mode are always added to the immediately
   // enclosing scope.
   return DeclarationScope(mode)->NewUnresolved(
-      factory(), name, scanner().location().beg_pos, interface);
+      factory(), name, interface, scanner().location().beg_pos);
 }


@@ -1954,7 +1953,7 @@
   // 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);
+  VariableProxy* proxy = NewUnresolved(name, VAR, Interface::NewValue());
   Declaration* declaration =
       factory()->NewVariableDeclaration(proxy, VAR, top_scope_);
   Declare(declaration, true, CHECK_OK);
@@ -1983,7 +1982,7 @@
   // scope, we treat is as such and introduce the function with it's
   // initial value upon entering the corresponding scope.
   VariableMode mode = is_extended_mode() ? LET : VAR;
-  VariableProxy* proxy = NewUnresolved(name, mode);
+  VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue());
   Declaration* declaration =
       factory()->NewFunctionDeclaration(proxy, mode, fun, top_scope_);
   Declare(declaration, true, CHECK_OK);
@@ -2215,7 +2214,9 @@
     // For let/const declarations in harmony mode, we can also immediately
     // pre-resolve the proxy because it resides in the same scope as the
     // declaration.
-    VariableProxy* proxy = NewUnresolved(name, mode);
+    Interface* interface =
+        is_const ? Interface::NewConst() : Interface::NewValue();
+    VariableProxy* proxy = NewUnresolved(name, mode, interface);
     Declaration* declaration =
         factory()->NewVariableDeclaration(proxy, mode, top_scope_);
     Declare(declaration, mode != VAR, CHECK_OK);
@@ -2376,7 +2377,7 @@
// if they are inside a 'with' statement - they may change a 'with' object
       // property).
       VariableProxy* proxy =
-          initialization_scope->NewUnresolved(factory(), name);
+          initialization_scope->NewUnresolved(factory(), name, interface);
       Assignment* assignment =
           factory()->NewAssignment(init_op, proxy, value, position);
       block->AddStatement(factory()->NewExpressionStatement(assignment),
@@ -2884,12 +2885,16 @@
   for_scope->set_start_position(scanner().location().beg_pos);
   if (peek() != Token::SEMICOLON) {
     if (peek() == Token::VAR || peek() == Token::CONST) {
+      bool is_const = peek() == Token::CONST;
       Handle<String> name;
       Block* variable_statement =
ParseVariableDeclarations(kForStatement, NULL, NULL, &name, CHECK_OK);

       if (peek() == Token::IN && !name.is_null()) {
-        VariableProxy* each = top_scope_->NewUnresolved(factory(), name);
+        Interface* interface =
+            is_const ? Interface::NewConst() : Interface::NewValue();
+        VariableProxy* each =
+            top_scope_->NewUnresolved(factory(), name, interface);
         ForInStatement* loop = factory()->NewForInStatement(labels);
         Target target(&this->target_stack_, loop);

@@ -2936,7 +2941,9 @@
         // implementing stack allocated block scoped variables.
Variable* temp = top_scope_->DeclarationScope()->NewTemporary(name);
         VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
-        VariableProxy* each = top_scope_->NewUnresolved(factory(), name);
+        Interface* interface = Interface::NewValue();
+        VariableProxy* each =
+            top_scope_->NewUnresolved(factory(), name, interface);
         ForInStatement* loop = factory()->NewForInStatement(labels);
         Target target(&this->target_stack_, loop);

@@ -3671,7 +3678,7 @@
 #endif
       Interface* interface = Interface::NewUnknown(zone());
       result = top_scope_->NewUnresolved(
-          factory(), name, scanner().location().beg_pos, interface);
+          factory(), name, interface, scanner().location().beg_pos);
       break;
     }

@@ -4517,7 +4524,7 @@
       VariableMode fvar_mode = is_extended_mode() ? CONST_HARMONY : CONST;
       fvar = new(zone()) Variable(top_scope_,
          function_name, fvar_mode, true /* is valid LHS */,
-         Variable::NORMAL, kCreatedInitialized);
+         Variable::NORMAL, kCreatedInitialized, Interface::NewConst());
       VariableProxy* proxy = factory()->NewVariableProxy(fvar);
       VariableDeclaration* fvar_declaration =
           factory()->NewVariableDeclaration(proxy, fvar_mode, top_scope_);
@@ -4607,8 +4614,8 @@
     if (!is_lazily_compiled) {
       body = new(zone()) ZoneList<Statement*>(8, zone());
       if (fvar != NULL) {
-        VariableProxy* fproxy =
-            top_scope_->NewUnresolved(factory(), function_name);
+        VariableProxy* fproxy = top_scope_->NewUnresolved(
+            factory(), function_name, Interface::NewConst());
         fproxy->BindTo(fvar);
         body->Add(factory()->NewExpressionStatement(
             factory()->NewAssignment(fvar_init_op,
=======================================
--- /branches/bleeding_edge/src/parser.h        Mon Jul  9 01:59:03 2012
+++ /branches/bleeding_edge/src/parser.h        Fri Jul 13 02:29:43 2012
@@ -771,7 +771,7 @@
   // Parser support
   VariableProxy* NewUnresolved(Handle<String> name,
                                VariableMode mode,
- Interface* interface = Interface::NewValue());
+                               Interface* interface);
   void Declare(Declaration* declaration, bool resolve, bool* ok);

   bool TargetStackContainsLabel(Handle<String> label);
=======================================
--- /branches/bleeding_edge/src/rewriter.cc     Wed Jun 20 01:58:41 2012
+++ /branches/bleeding_edge/src/rewriter.cc     Fri Jul 13 02:29:43 2012
@@ -257,7 +257,7 @@
// coincides with the end of the with scope which is the position of '1'.
       int position = function->end_position();
       VariableProxy* result_proxy = processor.factory()->NewVariableProxy(
-          result->name(), false, position);
+          result->name(), false, Interface::NewValue(), position);
       result_proxy->BindTo(result);
       Statement* result_statement =
           processor.factory()->NewReturnStatement(result_proxy);
=======================================
--- /branches/bleeding_edge/src/scopes.h        Mon Jul  9 01:59:03 2012
+++ /branches/bleeding_edge/src/scopes.h        Fri Jul 13 02:29:43 2012
@@ -166,14 +166,14 @@
   template<class Visitor>
   VariableProxy* NewUnresolved(AstNodeFactory<Visitor>* factory,
                                Handle<String> name,
-                               int position = RelocInfo::kNoPosition,
- Interface* interface = Interface::NewValue()) { + 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().
     ASSERT(!already_resolved());
     VariableProxy* proxy =
-        factory->NewVariableProxy(name, false, position, interface);
+        factory->NewVariableProxy(name, false, interface, position);
     unresolved_.Add(proxy, zone_);
     return proxy;
   }

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

Reply via email to