OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 18 matching lines...) Expand all Loading... |
29 #define V8_INTERFACE_H_ | 29 #define V8_INTERFACE_H_ |
30 | 30 |
31 #include "zone-inl.h" // For operator new. | 31 #include "zone-inl.h" // For operator new. |
32 | 32 |
33 namespace v8 { | 33 namespace v8 { |
34 namespace internal { | 34 namespace internal { |
35 | 35 |
36 | 36 |
37 // This class implements the following abstract grammar of interfaces | 37 // This class implements the following abstract grammar of interfaces |
38 // (i.e. module types): | 38 // (i.e. module types): |
39 // interface ::= UNDETERMINED | VALUE | MODULE(exports) | 39 // interface ::= UNDETERMINED | VALUE | CONST | MODULE(exports) |
40 // exports ::= {name : interface, ...} | 40 // exports ::= {name : interface, ...} |
41 // A frozen module type is one that is fully determined. Unification does not | 41 // A frozen type is one that is fully determined. Unification does not |
42 // allow adding additional exports to frozen interfaces. | 42 // allow to turn non-const values into const, or adding additional exports to |
43 // Otherwise, unifying modules merges their exports. | 43 // frozen interfaces. Otherwise, unifying modules merges their exports. |
44 // Undetermined types are unification variables that can be unified freely. | 44 // Undetermined types are unification variables that can be unified freely. |
| 45 // There is a natural subsort lattice that reflects the increase of knowledge: |
| 46 // |
| 47 // undetermined |
| 48 // // | \\ . |
| 49 // value (frozen) module |
| 50 // // \\ / \ // |
| 51 // const fr.value fr.module |
| 52 // \\ / |
| 53 // fr.const |
| 54 // |
| 55 // where the bold lines are the only transitions allowed. |
45 | 56 |
46 class Interface : public ZoneObject { | 57 class Interface : public ZoneObject { |
47 public: | 58 public: |
48 // --------------------------------------------------------------------------- | 59 // --------------------------------------------------------------------------- |
49 // Factory methods. | 60 // Factory methods. |
50 | 61 |
| 62 static Interface* NewUnknown(Zone* zone) { |
| 63 return new(zone) Interface(NONE); |
| 64 } |
| 65 |
51 static Interface* NewValue() { | 66 static Interface* NewValue() { |
52 static Interface value_interface(VALUE + FROZEN); // Cached. | 67 static Interface value_interface(VALUE + FROZEN); // Cached. |
53 return &value_interface; | 68 return &value_interface; |
54 } | 69 } |
55 | 70 |
56 static Interface* NewUnknown(Zone* zone) { | 71 static Interface* NewConst() { |
57 return new(zone) Interface(NONE); | 72 static Interface value_interface(VALUE + CONST + FROZEN); // Cached. |
| 73 return &value_interface; |
58 } | 74 } |
59 | 75 |
60 static Interface* NewModule(Zone* zone) { | 76 static Interface* NewModule(Zone* zone) { |
61 return new(zone) Interface(MODULE); | 77 return new(zone) Interface(MODULE); |
62 } | 78 } |
63 | 79 |
64 // --------------------------------------------------------------------------- | 80 // --------------------------------------------------------------------------- |
65 // Mutators. | 81 // Mutators. |
66 | 82 |
67 // Add a name to the list of exports. If it already exists, unify with | 83 // Add a name to the list of exports. If it already exists, unify with |
68 // interface, otherwise insert unless this is closed. | 84 // interface, otherwise insert unless this is closed. |
69 void Add(Handle<String> name, Interface* interface, Zone* zone, bool* ok) { | 85 void Add(Handle<String> name, Interface* interface, Zone* zone, bool* ok) { |
70 DoAdd(name.location(), name->Hash(), interface, zone, ok); | 86 DoAdd(name.location(), name->Hash(), interface, zone, ok); |
71 } | 87 } |
72 | 88 |
73 // Unify with another interface. If successful, both interface objects will | 89 // Unify with another interface. If successful, both interface objects will |
74 // represent the same type, and changes to one are reflected in the other. | 90 // represent the same type, and changes to one are reflected in the other. |
75 void Unify(Interface* that, Zone* zone, bool* ok); | 91 void Unify(Interface* that, Zone* zone, bool* ok); |
76 | 92 |
77 // Determine this interface to be a value interface. | 93 // Determine this interface to be a value interface. |
78 void MakeValue(bool* ok) { | 94 void MakeValue(bool* ok) { |
79 *ok = !IsModule(); | 95 *ok = !IsModule(); |
80 if (*ok) Chase()->flags_ |= VALUE; | 96 if (*ok) Chase()->flags_ |= VALUE; |
81 } | 97 } |
82 | 98 |
| 99 // Determine this interface to be an immutable interface. |
| 100 void MakeConst(bool* ok) { |
| 101 *ok = !IsModule() && (IsConst() || !IsFrozen()); |
| 102 if (*ok) Chase()->flags_ |= VALUE + CONST; |
| 103 } |
| 104 |
83 // Determine this interface to be a module interface. | 105 // Determine this interface to be a module interface. |
84 void MakeModule(bool* ok) { | 106 void MakeModule(bool* ok) { |
85 *ok = !IsValue(); | 107 *ok = !IsValue(); |
86 if (*ok) Chase()->flags_ |= MODULE; | 108 if (*ok) Chase()->flags_ |= MODULE; |
87 } | 109 } |
88 | 110 |
89 // Set associated instance object. | 111 // Set associated instance object. |
90 void MakeSingleton(Handle<JSModule> instance, bool* ok) { | 112 void MakeSingleton(Handle<JSModule> instance, bool* ok) { |
91 *ok = IsModule() && Chase()->instance_.is_null(); | 113 *ok = IsModule() && Chase()->instance_.is_null(); |
92 if (*ok) Chase()->instance_ = instance; | 114 if (*ok) Chase()->instance_ = instance; |
93 } | 115 } |
94 | 116 |
95 // Do not allow any further refinements, directly or through unification. | 117 // Do not allow any further refinements, directly or through unification. |
96 void Freeze(bool* ok) { | 118 void Freeze(bool* ok) { |
97 *ok = IsValue() || IsModule(); | 119 *ok = IsValue() || IsModule(); |
98 if (*ok) Chase()->flags_ |= FROZEN; | 120 if (*ok) Chase()->flags_ |= FROZEN; |
99 } | 121 } |
100 | 122 |
101 // --------------------------------------------------------------------------- | 123 // --------------------------------------------------------------------------- |
102 // Accessors. | 124 // Accessors. |
103 | 125 |
104 // Check whether this is still a fully undetermined type. | 126 // Check whether this is still a fully undetermined type. |
105 bool IsUnknown() { return Chase()->flags_ == NONE; } | 127 bool IsUnknown() { return Chase()->flags_ == NONE; } |
106 | 128 |
107 // Check whether this is a value type. | 129 // Check whether this is a value type. |
108 bool IsValue() { return Chase()->flags_ & VALUE; } | 130 bool IsValue() { return Chase()->flags_ & VALUE; } |
109 | 131 |
| 132 // Check whether this is a constant type. |
| 133 bool IsConst() { return Chase()->flags_ & CONST; } |
| 134 |
110 // Check whether this is a module type. | 135 // Check whether this is a module type. |
111 bool IsModule() { return Chase()->flags_ & MODULE; } | 136 bool IsModule() { return Chase()->flags_ & MODULE; } |
112 | 137 |
113 // Check whether this is closed (i.e. fully determined). | 138 // Check whether this is closed (i.e. fully determined). |
114 bool IsFrozen() { return Chase()->flags_ & FROZEN; } | 139 bool IsFrozen() { return Chase()->flags_ & FROZEN; } |
115 | 140 |
116 Handle<JSModule> Instance() { return Chase()->instance_; } | 141 Handle<JSModule> Instance() { return Chase()->instance_; } |
117 | 142 |
118 // Look up an exported name. Returns NULL if not (yet) defined. | 143 // Look up an exported name. Returns NULL if not (yet) defined. |
119 Interface* Lookup(Handle<String> name, Zone* zone); | 144 Interface* Lookup(Handle<String> name, Zone* zone); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
154 #ifdef DEBUG | 179 #ifdef DEBUG |
155 void Print(int n = 0); // n = indentation; n < 0 => don't print recursively | 180 void Print(int n = 0); // n = indentation; n < 0 => don't print recursively |
156 #endif | 181 #endif |
157 | 182 |
158 // --------------------------------------------------------------------------- | 183 // --------------------------------------------------------------------------- |
159 // Implementation. | 184 // Implementation. |
160 private: | 185 private: |
161 enum Flags { // All flags are monotonic | 186 enum Flags { // All flags are monotonic |
162 NONE = 0, | 187 NONE = 0, |
163 VALUE = 1, // This type describes a value | 188 VALUE = 1, // This type describes a value |
164 MODULE = 2, // This type describes a module | 189 CONST = 2, // This type describes a constant |
165 FROZEN = 4 // This type is fully determined | 190 MODULE = 4, // This type describes a module |
| 191 FROZEN = 8 // This type is fully determined |
166 }; | 192 }; |
167 | 193 |
168 int flags_; | 194 int flags_; |
169 Interface* forward_; // Unification link | 195 Interface* forward_; // Unification link |
170 ZoneHashMap* exports_; // Module exports and their types (allocated lazily) | 196 ZoneHashMap* exports_; // Module exports and their types (allocated lazily) |
171 Handle<JSModule> instance_; | 197 Handle<JSModule> instance_; |
172 | 198 |
173 explicit Interface(int flags) | 199 explicit Interface(int flags) |
174 : flags_(flags), | 200 : flags_(flags), |
175 forward_(NULL), | 201 forward_(NULL), |
(...skipping 12 matching lines...) Expand all Loading... |
188 } | 214 } |
189 | 215 |
190 void DoAdd(void* name, uint32_t hash, Interface* interface, Zone* zone, | 216 void DoAdd(void* name, uint32_t hash, Interface* interface, Zone* zone, |
191 bool* ok); | 217 bool* ok); |
192 void DoUnify(Interface* that, bool* ok, Zone* zone); | 218 void DoUnify(Interface* that, bool* ok, Zone* zone); |
193 }; | 219 }; |
194 | 220 |
195 } } // namespace v8::internal | 221 } } // namespace v8::internal |
196 | 222 |
197 #endif // V8_INTERFACE_H_ | 223 #endif // V8_INTERFACE_H_ |
OLD | NEW |