| 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 |