| Index: src/interface.h
|
| diff --git a/src/interface.h b/src/interface.h
|
| index 2670e7428d9f91f7cd00c437e7819299ca07cd2f..94ef11ba5c29d40f40e3755cafd16f2837252cfc 100644
|
| --- a/src/interface.h
|
| +++ b/src/interface.h
|
| @@ -36,25 +36,41 @@ namespace internal {
|
|
|
| // 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) {
|
| @@ -80,6 +96,12 @@ class Interface : public ZoneObject {
|
| 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();
|
| @@ -107,6 +129,9 @@ class Interface : public ZoneObject {
|
| // 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 @@ class Interface : public ZoneObject {
|
| 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_;
|
|
|