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