Appearance
| 1 | namespace IR.Values is | |
| 2 | use Semantic.Types.Type | |
| 3 | ||
| 4 | // The check a narrowed value needs when the narrowing reached its | |
| 5 | // type by eliminating every other alternative of a closed | |
| 6 | // hierarchy. Nothing checked the value on the way, and in a | |
| 7 | // session a later cell can add an alternative the elimination | |
| 8 | // never saw, so the use is of a type the value may not have. | |
| 9 | // | |
| 10 | // Emitted at the load rather than at each kind of use, because | |
| 11 | // every use - a call, a member read, passing it on, storing it - | |
| 12 | // goes through one. An ordinary build knows the whole hierarchy | |
| 13 | // and emits nothing. | |
| 14 | class NARROW_GUARD is | |
| 15 | emit(narrowed: Type?, context: IR.CONTEXT) static is | |
| 16 | if !context.is_submission then | |
| 17 | return | |
| 18 | fi | |
| 19 | ||
| 20 | if !IoC.CONTAINER.instance.complement_singletons.contains(narrowed) then | |
| 21 | return | |
| 22 | fi | |
| 23 | ||
| 24 | let body = context.current_srm_body_emitter! | |
| 25 | ||
| 26 | // A value type reached through a wider slot is boxed there, | |
| 27 | // so the check and the unboxing are the same instruction. | |
| 28 | if narrowed!.is_value_type then | |
| 29 | body.unbox_any(context.resolve_type_token(narrowed!)) | |
| 30 | else | |
| 31 | body.cast_class(context.resolve_type_token(narrowed!)) | |
| 32 | fi | |
| 33 | si | |
| 34 | si | |
| 35 | si |