Appearance
| 1 | namespace IR.Values is | |
| 2 | use Semantic.Types.Type | |
| 3 | ||
| 4 | // Coerce a reference-typed `T?` into the unconstrained-T optional | |
| 5 | // carrier `Ghul.MAYBE[T]`. A reference optional carries absence as | |
| 6 | // a null reference and MAYBE as a zeroed struct, so the two are | |
| 7 | // bridged by a null test: the present path wraps the reference | |
| 8 | // with MAYBE<T>::.ctor(T), the absent path yields the empty MAYBE. | |
| 9 | // | |
| 10 | // <value IL> // [..., a] | |
| 11 | // dup // [..., a, a] | |
| 12 | // brtrue <present> // pops one a | |
| 13 | // pop // [...] | |
| 14 | // <absent IL> // [..., empty MAYBE] | |
| 15 | // br <end> | |
| 16 | // <present>: | |
| 17 | // newobj MAYBE<T>::.ctor(T) | |
| 18 | // <end>: | |
| 19 | // | |
| 20 | // Built by VALUE_BOXER.wrap_if_needed. The value-type optional | |
| 21 | // sources (NULLABLE[T], another MAYBE instantiation) go through | |
| 22 | // NULL_COALESCE_VALUE instead, since presence there is a member | |
| 23 | // read off the struct's address rather than a null test. | |
| 24 | class WRAP_MAYBE: Value is | |
| 25 | value: Value | |
| 26 | _maybe_type: Type | |
| 27 | _absent: Value | |
| 28 | ||
| 29 | type: Type => _maybe_type | |
| 30 | is_value_type: bool => true | |
| 31 | is_lightweight_pure: bool => false | |
| 32 | ||
| 33 | init( | |
| 34 | maybe_type: Type, | |
| 35 | value: Value | |
| 36 | ) is | |
| 37 | super.init() | |
| 38 | ||
| 39 | self._maybe_type = maybe_type | |
| 40 | self.value = value | |
| 41 | self._absent = Values.DEFAULT(maybe_type) | |
| 42 | si | |
| 43 | ||
| 44 | gen(context: IR.CONTEXT) is | |
| 45 | let present_label = IR.LABEL() | |
| 46 | let end_label = IR.LABEL() | |
| 47 | ||
| 48 | gen(value, context) | |
| 49 | ||
| 50 | let body = context.current_srm_body_emitter! | |
| 51 | body.op(System.Reflection.Metadata.ILOpCode.DUP) | |
| 52 | body.branch(System.Reflection.Metadata.ILOpCode.BRTRUE, present_label) | |
| 53 | body.op(System.Reflection.Metadata.ILOpCode.POP) | |
| 54 | gen(_absent, context) | |
| 55 | body.branch(System.Reflection.Metadata.ILOpCode.BR, end_label) | |
| 56 | body.mark_label(present_label) | |
| 57 | body.new_object(context.resolve_generic_constructor(_maybe_type, 1)) | |
| 58 | body.mark_label(end_label) | |
| 59 | si | |
| 60 | ||
| 61 | to_string() -> string => | |
| 62 | "wrap-maybe:[{_maybe_type}]({value})" | |
| 63 | si | |
| 64 | si |