OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_EFFECTS_H_ | 5 #ifndef V8_EFFECTS_H_ |
6 #define V8_EFFECTS_H_ | 6 #define V8_EFFECTS_H_ |
7 | 7 |
8 #include "src/types.h" | 8 #include "src/ast/ast-types.h" |
9 | 9 |
10 namespace v8 { | 10 namespace v8 { |
11 namespace internal { | 11 namespace internal { |
12 | 12 |
13 | 13 |
14 // A simple struct to represent (write) effects. A write is represented as a | 14 // A simple struct to represent (write) effects. A write is represented as a |
15 // modification of type bounds (e.g. of a variable). | 15 // modification of type bounds (e.g. of a variable). |
16 // | 16 // |
17 // An effect can either be definite, if the write is known to have taken place, | 17 // An effect can either be definite, if the write is known to have taken place, |
18 // or 'possible', if it was optional. The difference is relevant when composing | 18 // or 'possible', if it was optional. The difference is relevant when composing |
19 // effects. | 19 // effects. |
20 // | 20 // |
21 // There are two ways to compose effects: sequentially (they happen one after | 21 // There are two ways to compose effects: sequentially (they happen one after |
22 // the other) or alternatively (either one or the other happens). A definite | 22 // the other) or alternatively (either one or the other happens). A definite |
23 // effect cancels out any previous effect upon sequencing. A possible effect | 23 // effect cancels out any previous effect upon sequencing. A possible effect |
24 // merges into a previous effect, i.e., type bounds are merged. Alternative | 24 // merges into a previous effect, i.e., type bounds are merged. Alternative |
25 // composition always merges bounds. It yields a possible effect if at least | 25 // composition always merges bounds. It yields a possible effect if at least |
26 // one was only possible. | 26 // one was only possible. |
27 struct Effect { | 27 struct Effect { |
28 enum Modality { POSSIBLE, DEFINITE }; | 28 enum Modality { POSSIBLE, DEFINITE }; |
29 | 29 |
30 Modality modality; | 30 Modality modality; |
31 Bounds bounds; | 31 AstBounds bounds; |
32 | 32 |
33 Effect() : modality(DEFINITE) {} | 33 Effect() : modality(DEFINITE) {} |
34 explicit Effect(Bounds b, Modality m = DEFINITE) : modality(m), bounds(b) {} | 34 explicit Effect(AstBounds b, Modality m = DEFINITE) |
| 35 : modality(m), bounds(b) {} |
35 | 36 |
36 // The unknown effect. | 37 // The unknown effect. |
37 static Effect Unknown(Zone* zone) { | 38 static Effect Unknown(Zone* zone) { |
38 return Effect(Bounds::Unbounded(), POSSIBLE); | 39 return Effect(AstBounds::Unbounded(), POSSIBLE); |
39 } | 40 } |
40 | 41 |
41 static Effect Forget(Zone* zone) { | 42 static Effect Forget(Zone* zone) { |
42 return Effect(Bounds::Unbounded(), DEFINITE); | 43 return Effect(AstBounds::Unbounded(), DEFINITE); |
43 } | 44 } |
44 | 45 |
45 // Sequential composition, as in 'e1; e2'. | 46 // Sequential composition, as in 'e1; e2'. |
46 static Effect Seq(Effect e1, Effect e2, Zone* zone) { | 47 static Effect Seq(Effect e1, Effect e2, Zone* zone) { |
47 if (e2.modality == DEFINITE) return e2; | 48 if (e2.modality == DEFINITE) return e2; |
48 return Effect(Bounds::Either(e1.bounds, e2.bounds, zone), e1.modality); | 49 return Effect(AstBounds::Either(e1.bounds, e2.bounds, zone), e1.modality); |
49 } | 50 } |
50 | 51 |
51 // Alternative composition, as in 'cond ? e1 : e2'. | 52 // Alternative composition, as in 'cond ? e1 : e2'. |
52 static Effect Alt(Effect e1, Effect e2, Zone* zone) { | 53 static Effect Alt(Effect e1, Effect e2, Zone* zone) { |
53 return Effect( | 54 return Effect(AstBounds::Either(e1.bounds, e2.bounds, zone), |
54 Bounds::Either(e1.bounds, e2.bounds, zone), | 55 e1.modality == POSSIBLE ? POSSIBLE : e2.modality); |
55 e1.modality == POSSIBLE ? POSSIBLE : e2.modality); | |
56 } | 56 } |
57 }; | 57 }; |
58 | 58 |
59 | 59 |
60 // Classes encapsulating sets of effects on variables. | 60 // Classes encapsulating sets of effects on variables. |
61 // | 61 // |
62 // Effects maps variables to effects and supports sequential and alternative | 62 // Effects maps variables to effects and supports sequential and alternative |
63 // composition. | 63 // composition. |
64 // | 64 // |
65 // NestedEffects is an incremental representation that supports persistence | 65 // NestedEffects is an incremental representation that supports persistence |
(...skipping 11 matching lines...) Expand all Loading... |
77 class EffectsMixin: public Base { | 77 class EffectsMixin: public Base { |
78 public: | 78 public: |
79 explicit EffectsMixin(Zone* zone) : Base(zone) {} | 79 explicit EffectsMixin(Zone* zone) : Base(zone) {} |
80 | 80 |
81 Effect Lookup(Var var) { | 81 Effect Lookup(Var var) { |
82 Locator locator; | 82 Locator locator; |
83 return this->Find(var, &locator) | 83 return this->Find(var, &locator) |
84 ? locator.value() : Effect::Unknown(Base::zone()); | 84 ? locator.value() : Effect::Unknown(Base::zone()); |
85 } | 85 } |
86 | 86 |
87 Bounds LookupBounds(Var var) { | 87 AstBounds LookupBounds(Var var) { |
88 Effect effect = Lookup(var); | 88 Effect effect = Lookup(var); |
89 return effect.modality == Effect::DEFINITE | 89 return effect.modality == Effect::DEFINITE ? effect.bounds |
90 ? effect.bounds : Bounds::Unbounded(); | 90 : AstBounds::Unbounded(); |
91 } | 91 } |
92 | 92 |
93 // Sequential composition. | 93 // Sequential composition. |
94 void Seq(Var var, Effect effect) { | 94 void Seq(Var var, Effect effect) { |
95 Locator locator; | 95 Locator locator; |
96 if (!this->Insert(var, &locator)) { | 96 if (!this->Insert(var, &locator)) { |
97 effect = Effect::Seq(locator.value(), effect, Base::zone()); | 97 effect = Effect::Seq(locator.value(), effect, Base::zone()); |
98 } | 98 } |
99 locator.set_value(effect); | 99 locator.set_value(effect); |
100 } | 100 } |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
326 result.pop(); | 326 result.pop(); |
327 DCHECK(!this->is_empty()); | 327 DCHECK(!this->is_empty()); |
328 return result; | 328 return result; |
329 } | 329 } |
330 }; | 330 }; |
331 | 331 |
332 } // namespace internal | 332 } // namespace internal |
333 } // namespace v8 | 333 } // namespace v8 |
334 | 334 |
335 #endif // V8_EFFECTS_H_ | 335 #endif // V8_EFFECTS_H_ |
OLD | NEW |