Skip to main content

dxil_reader/
module.rs

1//! LLVM 3.7 IR as DXIL stores it, read from the bitstream tree: the type table, module values (globals, functions,
2//! constants), metadata, value names and function bodies. Only what DXIL programs use is decoded; any other record in a
3//! function body is refused by name. The blocks of a function body that say nothing a reader of the program's behaviour needs (its metadata, the
4//! metadata attached to its instructions and its use-list order) are the only things skipped.
5use crate::bitstream::{Block, Record};
6use crate::{Result, error};
7
8const MODULE: u64 = 8;
9const PARAMATTR: u64 = 9;
10const PARAMATTR_GROUP: u64 = 10;
11const CONSTANTS: u64 = 11;
12const FUNCTION: u64 = 12;
13const VALUE_SYMTAB: u64 = 14;
14const METADATA: u64 = 15;
15const METADATA_ATTACHMENT: u64 = 16;
16const TYPES: u64 = 17;
17const USELIST: u64 = 18;
18const BLOCKINFO: u64 = 0;
19
20/// Values a module may hold (globals, constants and function-body values together).
21const MAX_VALUES: usize = 1 << 22;
22const MAX_TYPES: usize = 1 << 16;
23
24/// An index into [`Module::types`].
25pub type TypeId = usize;
26/// An index into the values: the module's [`Module::values`], then a function body's own [`Function::locals`].
27pub type ValueId = usize;
28/// An index into [`Module::metadata`].
29pub type MetadataId = usize;
30
31/// A type of the module's type table.
32#[derive(Clone, Debug, PartialEq, Eq)]
33pub enum Type {
34    /// `void`.
35    Void,
36    /// `label`, the type of a basic block.
37    Label,
38    /// `metadata`.
39    Metadata,
40    /// `half`.
41    Half,
42    /// `float`.
43    Float,
44    /// `double`.
45    Double,
46    /// An integer of this many bits (1 to 64).
47    Integer(u32),
48    /// A pointer to the type, in this LLVM address space (the `TYPE_CODE_POINTER` record's second operand). Pointers to
49    /// one type in two spaces are two types.
50    Pointer(TypeId, u32),
51    /// An array of this many elements of the type.
52    Array(u64, TypeId),
53    /// A vector of this many lanes of the type.
54    Vector(u64, TypeId),
55    /// A structure.
56    Struct {
57        /// Its name, where it has one.
58        name: Option<String>,
59        /// The types of its fields, in order.
60        elements: Vec<TypeId>,
61    },
62    /// A named structure without a body.
63    Opaque(Option<String>),
64    /// A function type.
65    Function {
66        /// Whether it takes a variable argument list.
67        vararg: bool,
68        /// The return type.
69        ret: TypeId,
70        /// The parameter types.
71        params: Vec<TypeId>,
72    },
73}
74
75/// A module-level constant.
76#[derive(Clone, Debug, PartialEq)]
77pub enum Constant {
78    /// The null value of the constant's type (zero).
79    Null,
80    /// An undefined value.
81    Undef,
82    /// An integer's bits, sign-extended from its width.
83    Integer(i64),
84    /// A float's bits (half, float or double by its type).
85    Float(u64),
86    /// An array, structure or vector of other constants (value ids).
87    Aggregate(Vec<ValueId>),
88    /// A constant array or vector of numbers, as stored (the bits of each element).
89    Data(Vec<u64>),
90    /// A string constant, as stored.
91    String(Vec<u8>),
92    /// A constant `getelementptr`: the base (a global) and its indices (module constants).
93    Gep {
94        /// The base global.
95        base: ValueId,
96        /// The index constants.
97        indices: Vec<ValueId>,
98    },
99    /// A constant cast of a module value (to the type of the constant).
100    Cast {
101        /// The cast.
102        op: CastOp,
103        /// The value cast.
104        value: ValueId,
105    },
106    /// A constant binary operation on module values.
107    Binary {
108        /// The operation.
109        op: BinaryOp,
110        /// The left operand.
111        lhs: ValueId,
112        /// The right operand.
113        rhs: ValueId,
114    },
115}
116
117/// A value the module numbers.
118#[derive(Clone, Debug, PartialEq)]
119pub enum Value {
120    /// A function, defined or declared.
121    Function {
122        /// Its function type.
123        ty: TypeId,
124        /// Whether it is only declared (it has no body).
125        declaration: bool,
126    },
127    /// A global variable.
128    Global {
129        /// The global's type: a pointer to `value_ty`.
130        ty: TypeId,
131        /// The type of the value it holds.
132        value_ty: TypeId,
133        /// Its initial value (a module constant), if it has one.
134        init: Option<ValueId>,
135        /// Whether it is a constant (read only).
136        constant: bool,
137        /// LLVM's address space: 0 the default, 3 group shared. No other space occurs in the programs of the games read.
138        address_space: u32,
139    },
140    /// A constant.
141    Constant(Constant),
142    /// A function argument or an instruction's result.
143    Local,
144}
145
146/// A metadata record.
147#[derive(Clone, Debug, PartialEq)]
148pub enum Metadata {
149    /// A metadata string, as stored (not checked to be UTF-8 here).
150    String(Vec<u8>),
151    /// A value as metadata.
152    Value {
153        /// The value's type.
154        ty: TypeId,
155        /// The value.
156        value: ValueId,
157    },
158    /// Operands; `None` is a null operand.
159    Node(Vec<Option<MetadataId>>),
160}
161
162/// A binary operator code (LLVM's `BinaryOpcodes`).
163#[derive(Clone, Copy, Debug, PartialEq, Eq)]
164pub enum BinaryOp {
165    /// Addition.
166    Add,
167    /// Subtraction.
168    Sub,
169    /// Multiplication.
170    Mul,
171    /// Unsigned division.
172    UDiv,
173    /// Signed division.
174    SDiv,
175    /// Unsigned remainder.
176    URem,
177    /// Signed remainder.
178    SRem,
179    /// Shift left.
180    Shl,
181    /// Logical shift right.
182    LShr,
183    /// Arithmetic shift right.
184    AShr,
185    /// Bitwise and.
186    And,
187    /// Bitwise or.
188    Or,
189    /// Bitwise exclusive or.
190    Xor,
191}
192/// A cast opcode (LLVM's `CastOpcodes`).
193#[derive(Clone, Copy, Debug, PartialEq, Eq)]
194pub enum CastOp {
195    /// Truncate an integer.
196    Trunc,
197    /// Zero-extend an integer.
198    ZExt,
199    /// Sign-extend an integer.
200    SExt,
201    /// Float to unsigned integer.
202    FpToUi,
203    /// Float to signed integer.
204    FpToSi,
205    /// Unsigned integer to float.
206    UiToFp,
207    /// Signed integer to float.
208    SiToFp,
209    /// Truncate a float.
210    FpTrunc,
211    /// Extend a float.
212    FpExt,
213    /// Pointer to integer.
214    PtrToInt,
215    /// Integer to pointer.
216    IntToPtr,
217    /// Reinterpret the bits as another type.
218    BitCast,
219}
220
221/// An instruction, with the value ids (absolute) and block numbers it names.
222#[derive(Clone, Debug, PartialEq)]
223pub enum Op {
224    /// Integer opcodes apply to integers; for floating types Add, Sub, Mul, (S)Div, (S)Rem are the float forms.
225    Binary {
226        /// The operation.
227        op: BinaryOp,
228        /// The left operand.
229        lhs: ValueId,
230        /// The right operand.
231        rhs: ValueId,
232    },
233    /// A conversion.
234    Cast {
235        /// The conversion.
236        op: CastOp,
237        /// The value converted; the instruction's result type is the target.
238        value: ValueId,
239    },
240    /// A comparison by its LLVM predicate (0..15 float, 32..41 integer).
241    Compare {
242        /// The predicate.
243        predicate: u64,
244        /// The left operand.
245        lhs: ValueId,
246        /// The right operand.
247        rhs: ValueId,
248    },
249    /// `select`: one of two values by a condition.
250    Select {
251        /// The condition (an `i1`).
252        condition: ValueId,
253        /// The value when the condition is true.
254        then: ValueId,
255        /// The value when it is false.
256        otherwise: ValueId,
257    },
258    /// A field or element of an aggregate.
259    ExtractValue {
260        /// The aggregate.
261        aggregate: ValueId,
262        /// The indices into it, outermost first.
263        indices: Vec<u64>,
264    },
265    /// An aggregate with one field or element replaced.
266    InsertValue {
267        /// The aggregate.
268        aggregate: ValueId,
269        /// The new field or element.
270        value: ValueId,
271        /// The indices of the replaced one, outermost first.
272        indices: Vec<u64>,
273    },
274    /// One lane of a vector.
275    ExtractElement {
276        /// The vector.
277        vector: ValueId,
278        /// The lane number.
279        index: ValueId,
280    },
281    /// A vector with one lane replaced.
282    InsertElement {
283        /// The vector.
284        vector: ValueId,
285        /// The new lane.
286        value: ValueId,
287        /// The lane number.
288        index: ValueId,
289    },
290    /// The lanes of two vectors the mask (a constant vector of lane numbers) picks.
291    ShuffleVector {
292        /// The first vector.
293        first: ValueId,
294        /// The second vector.
295        second: ValueId,
296        /// The constant vector of lane numbers.
297        mask: ValueId,
298    },
299    /// A call.
300    Call {
301        /// The callee.
302        function: ValueId,
303        /// The arguments, one per parameter.
304        args: Vec<ValueId>,
305    },
306    /// The value from the predecessor block control came from: (value, block) pairs.
307    Phi {
308        /// The (value, predecessor block) pairs.
309        incoming: Vec<(ValueId, usize)>,
310    },
311    /// `ret`, with the value returned where there is one.
312    Return(Option<ValueId>),
313    /// An unconditional branch.
314    Branch {
315        /// The block branched to.
316        target: usize,
317    },
318    /// A conditional branch.
319    CondBranch {
320        /// The condition (an `i1`).
321        condition: ValueId,
322        /// The block when it is true.
323        then: usize,
324        /// The block when it is false.
325        otherwise: usize,
326    },
327    /// A multi-way branch: the value, the default block and the (case constant, block) pairs.
328    Switch {
329        /// The value switched on.
330        value: ValueId,
331        /// The block when no case matches.
332        default: usize,
333        /// The (case constant, block) pairs.
334        cases: Vec<(ValueId, usize)>,
335    },
336    /// `unreachable`.
337    Unreachable,
338    /// A local variable of this type (the result is a pointer to it).
339    Alloca {
340        /// The type of the variable.
341        ty: TypeId,
342    },
343    /// A load.
344    Load {
345        /// The pointer loaded from; the result type is the loaded type.
346        pointer: ValueId,
347    },
348    /// A store.
349    Store {
350        /// The pointer stored to.
351        pointer: ValueId,
352        /// The value stored.
353        value: ValueId,
354    },
355    /// `getelementptr`: the base pointer and its indices (the first steps over the pointer itself).
356    Gep {
357        /// The base pointer.
358        base: ValueId,
359        /// The indices.
360        indices: Vec<ValueId>,
361    },
362    /// `atomicrmw`: the operation (LLVM's code: 0 xchg, 1 add, 2 sub, 3 and, 4 nand, 5 or, 6 xor, 7 max, 8 min, 9 umax,
363    /// 10 umin); the result is the value the pointer held.
364    AtomicRmw {
365        /// The pointer.
366        pointer: ValueId,
367        /// The value operated with.
368        value: ValueId,
369        /// The operation code.
370        op: u64,
371    },
372    /// `cmpxchg`: the result is the pair (the value the pointer held, whether it was swapped).
373    CmpXchg {
374        /// The pointer.
375        pointer: ValueId,
376        /// The value compared with.
377        compare: ValueId,
378        /// The new value stored where the comparison holds.
379        value: ValueId,
380    },
381    /// `fence`: ordering between invocations, which a lockstep reading does not have.
382    Fence,
383}
384
385impl Op {
386    /// The values the operation reads (a call's arguments, not its callee; a phi's incoming values).
387    pub fn operands(&self) -> Vec<ValueId> {
388        match self {
389            Op::Binary { lhs, rhs, .. } | Op::Compare { lhs, rhs, .. } => vec![*lhs, *rhs],
390            Op::Cast { value, .. } => vec![*value],
391            Op::Select {
392                condition,
393                then,
394                otherwise,
395            } => vec![*condition, *then, *otherwise],
396            Op::ExtractValue { aggregate, .. } => vec![*aggregate],
397            Op::InsertValue { aggregate, value, .. } => vec![*aggregate, *value],
398            Op::ExtractElement { vector, index } => vec![*vector, *index],
399            Op::InsertElement { vector, value, index } => vec![*vector, *value, *index],
400            Op::ShuffleVector { first, second, mask } => vec![*first, *second, *mask],
401            Op::Call { args, .. } => args.clone(),
402            Op::Phi { incoming } => incoming.iter().map(|(v, _)| *v).collect(),
403            Op::Return(value) => value.iter().copied().collect(),
404            Op::CondBranch { condition, .. } => vec![*condition],
405            Op::Switch { value, cases, .. } => std::iter::once(*value)
406                .chain(cases.iter().map(|(c, _)| *c))
407                .collect(),
408            Op::Load { pointer } => vec![*pointer],
409            Op::Store { pointer, value } | Op::AtomicRmw { pointer, value, .. } => vec![*pointer, *value],
410            Op::Gep { base, indices } => std::iter::once(*base).chain(indices.iter().copied()).collect(),
411            Op::CmpXchg {
412                pointer,
413                compare,
414                value,
415            } => vec![*pointer, *compare, *value],
416            Op::Branch { .. } | Op::Unreachable | Op::Alloca { .. } | Op::Fence => Vec::new(),
417        }
418    }
419
420    /// The basic blocks the operation names (a branch's targets, a phi's predecessors).
421    pub fn blocks(&self) -> Vec<usize> {
422        match self {
423            Op::Branch { target } => vec![*target],
424            Op::CondBranch { then, otherwise, .. } => vec![*then, *otherwise],
425            Op::Switch { default, cases, .. } => std::iter::once(*default)
426                .chain(cases.iter().map(|(_, b)| *b))
427                .collect(),
428            Op::Phi { incoming } => incoming.iter().map(|(_, b)| *b).collect(),
429            _ => Vec::new(),
430        }
431    }
432}
433
434/// An instruction of a function body.
435#[derive(Clone, Debug, PartialEq)]
436pub struct Instruction {
437    /// What it does.
438    pub op: Op,
439    /// The result's value id and type, when the instruction produces one.
440    pub result: Option<(ValueId, TypeId)>,
441    /// The basic block it belongs to.
442    pub block: usize,
443    /// Bit offset of its record.
444    pub at: usize,
445}
446
447/// A function body.
448#[derive(Clone, Debug, PartialEq)]
449pub struct Function {
450    /// The function's module value id.
451    pub value: ValueId,
452    /// The number of basic blocks.
453    pub blocks: usize,
454    /// The instructions of all blocks, in order.
455    pub instructions: Vec<Instruction>,
456    /// The body's own values (arguments, constants, instruction results) and their types; their ids start at
457    /// `first`, after the module's values.
458    pub first: ValueId,
459    /// The values of the body.
460    pub locals: Vec<Value>,
461    /// The types of [`Function::locals`].
462    pub local_types: Vec<TypeId>,
463}
464
465/// A module: its types, values, metadata and function bodies.
466#[derive(Clone, Debug, Default, PartialEq)]
467pub struct Module {
468    /// The type table.
469    pub types: Vec<Type>,
470    /// The module's values by id (globals, functions, module constants); a function body's own values continue the
471    /// numbering in its [`Function`].
472    pub values: Vec<Value>,
473    /// Each value's type.
474    pub value_types: Vec<TypeId>,
475    /// The symbol table: the name of the values that have one.
476    pub names: Vec<(ValueId, String)>,
477    /// The metadata records, by [`MetadataId`].
478    pub metadata: Vec<Metadata>,
479    /// The bit of the bitcode each metadata record (by id) starts at, for the locations of reflection errors.
480    pub metadata_at: Vec<usize>,
481    /// The named metadata (`dx.entryPoints`, ...): the name and the records it lists.
482    pub named_metadata: Vec<(String, Vec<MetadataId>)>,
483    /// The bit each named metadata record (by index in `named_metadata`) starts at.
484    pub named_metadata_at: Vec<usize>,
485    /// The bit of the bitcode the module block starts at: where a record the module lacks would be.
486    pub at: usize,
487    /// The function bodies, in the order of their definitions.
488    pub functions: Vec<Function>,
489}
490
491fn op(r: &Record, i: usize) -> Result<u64> {
492    r.operands
493        .get(i)
494        .copied()
495        .ok_or_else(|| error(r.at, format!("record {} lacks operand {i}", r.code)))
496}
497fn text(ops: &[u64], at: usize) -> Result<Vec<u8>> {
498    ops.iter()
499        .map(|&c| u8::try_from(c).map_err(|_| error(at, "character above 255")))
500        .collect()
501}
502fn utf8(bytes: Vec<u8>, at: usize) -> Result<String> {
503    String::from_utf8(bytes).map_err(|_| error(at, "name is not UTF-8"))
504}
505fn signed_vbr(v: u64) -> i64 {
506    if v & 1 == 0 {
507        i64::try_from(v >> 1).unwrap_or(i64::MAX)
508    } else if v == 1 {
509        i64::MIN
510    } else {
511        i64::try_from(v >> 1).map_or(i64::MIN, i64::wrapping_neg)
512    }
513}
514
515impl Module {
516    fn ty(&self, id: u64, at: usize) -> Result<TypeId> {
517        let id = usize::try_from(id).map_err(|_| error(at, "type id"))?;
518        if id < self.types.len() {
519            Ok(id)
520        } else {
521            Err(error(at, format!("type {id} undefined")))
522        }
523    }
524    /// The type `id`, which an earlier record has already checked against the table (an error where it has not).
525    fn type_at(&self, id: TypeId, at: usize) -> Result<&Type> {
526        self.types
527            .get(id)
528            .ok_or_else(|| error(at, format!("type {id} of {} types", self.types.len())))
529    }
530    /// The id of the type `ty`, appended to the table where it is not there yet.
531    fn intern(&mut self, ty: Type) -> TypeId {
532        match self.types.iter().position(|x| *x == ty) {
533            Some(p) => p,
534            None => {
535                self.types.push(ty);
536                self.types.len().saturating_sub(1)
537            }
538        }
539    }
540    /// The module's name for a value, where its symbol table has one.
541    pub fn name(&self, value: ValueId) -> Option<&str> {
542        self.names
543            .iter()
544            .find(|(v, _)| *v == value)
545            .map(|(_, n)| n.as_str())
546    }
547    fn push(&mut self, value: Value, ty: TypeId, at: usize) -> Result<ValueId> {
548        if self.values.len() >= MAX_VALUES {
549            return Err(error(at, "too many values"));
550        }
551        self.values.push(value);
552        self.value_types.push(ty);
553        Ok(self.values.len().saturating_sub(1))
554    }
555
556    fn read_types(&mut self, block: &Block) -> Result<()> {
557        let mut struct_name: Option<String> = None;
558        for r in block.records() {
559            if self.types.len() >= MAX_TYPES {
560                return Err(error(r.at, "too many types"));
561            }
562            let t = match r.code {
563                1 => continue, // NUMENTRY
564                2 => Type::Void,
565                3 => Type::Float,
566                4 => Type::Double,
567                5 => Type::Label,
568                6 => Type::Opaque(struct_name.take()),
569                7 => Type::Integer(
570                    u32::try_from(op(r, 0)?)
571                        .ok()
572                        .filter(|w| (1..=64).contains(w))
573                        .ok_or_else(|| error(r.at, "integer width"))?,
574                ),
575                8 => Type::Pointer(
576                    self.ty(op(r, 0)?, r.at)?,
577                    u32::try_from(op(r, 1)?).map_err(|_| error(r.at, "pointer address space"))?,
578                ),
579                10 => Type::Half,
580                11 => Type::Array(op(r, 0)?, self.ty(op(r, 1)?, r.at)?),
581                12 => Type::Vector(op(r, 0)?, self.ty(op(r, 1)?, r.at)?),
582                16 => Type::Metadata,
583                18 | 20 => Type::Struct {
584                    name: if r.code == 20 { struct_name.take() } else { None },
585                    elements: r
586                        .operands
587                        .get(1..)
588                        .unwrap_or_default()
589                        .iter()
590                        .map(|&t| self.ty(t, r.at))
591                        .collect::<Result<_>>()?,
592                },
593                19 => {
594                    struct_name = Some(utf8(text(&r.operands, r.at)?, r.at)?);
595                    continue;
596                }
597                21 => Type::Function {
598                    vararg: op(r, 0)? != 0,
599                    ret: self.ty(op(r, 1)?, r.at)?,
600                    params: r
601                        .operands
602                        .get(2..)
603                        .unwrap_or_default()
604                        .iter()
605                        .map(|&t| self.ty(t, r.at))
606                        .collect::<Result<_>>()?,
607                },
608                other => return Err(error(r.at, format!("type record {other}"))),
609            };
610            self.types.push(t);
611        }
612        Ok(())
613    }
614
615    /// Read a constants block, appending its values. Value ids inside aggregates are absolute.
616    fn read_constants(&mut self, block: &Block) -> Result<()> {
617        let mut ty: Option<TypeId> = None;
618        for r in block.records() {
619            let id = |v: u64| usize::try_from(v).map_err(|_| error(r.at, "value id"));
620            if r.code == 1 {
621                ty = Some(self.ty(op(r, 0)?, r.at)?);
622                continue;
623            }
624            let t = ty.ok_or_else(|| error(r.at, "constant before SETTYPE"))?;
625            let c = match r.code {
626                2 => Constant::Null,
627                3 => Constant::Undef,
628                4 => Constant::Integer(signed_vbr(op(r, 0)?)),
629                6 => Constant::Float(op(r, 0)?),
630                7 => Constant::Aggregate(
631                    r.operands
632                        .iter()
633                        .map(|&v| usize::try_from(v).map_err(|_| error(r.at, "value id")))
634                        .collect::<Result<_>>()?,
635                ),
636                8 | 9 => Constant::String(text(&r.operands, r.at)?),
637                22 => Constant::Data(r.operands.clone()),
638                // CE_GEP and CE_INBOUNDS_GEP: [source type,] then (type, value) pairs, the first the base
639                12 | 20 => {
640                    let ops = r
641                        .operands
642                        .get(usize::from(r.operands.len() % 2 == 1)..)
643                        .unwrap_or_default();
644                    let (pairs, rest) = ops.as_chunks::<2>();
645                    let ([_, base], true) = (
646                        pairs.first().unwrap_or(&[0, 0]),
647                        rest.is_empty() && !pairs.is_empty(),
648                    ) else {
649                        return Err(error(r.at, "constant getelementptr operands"));
650                    };
651                    Constant::Gep {
652                        base: id(*base)?,
653                        indices: pairs
654                            .iter()
655                            .skip(1)
656                            .map(|[_, index]| id(*index))
657                            .collect::<Result<_>>()?,
658                    }
659                }
660                // CE_BINOP: [opcode, lhs, rhs, flags?]
661                10 => Constant::Binary {
662                    op: binary(op(r, 0)?, r.at)?,
663                    lhs: id(op(r, 1)?)?,
664                    rhs: id(op(r, 2)?)?,
665                },
666                // CE_CAST: [opcode, operand type, operand]
667                11 => Constant::Cast {
668                    op: cast(op(r, 0)?, r.at)?,
669                    value: id(op(r, 2)?)?,
670                },
671                other => {
672                    return Err(error(
673                        r.at,
674                        format!("constant record {other} (constant expressions are not supported)"),
675                    ));
676                }
677            };
678            self.push(Value::Constant(c), t, r.at)?;
679        }
680        Ok(())
681    }
682
683    fn read_metadata(&mut self, block: &Block) -> Result<()> {
684        let mut name: Option<String> = None;
685        let md = |v: u64, at: usize| usize::try_from(v).map_err(|_| error(at, "metadata id"));
686        for r in block.records() {
687            match r.code {
688                1 => {
689                    self.metadata.push(Metadata::String(text(&r.operands, r.at)?));
690                    self.metadata_at.push(r.at);
691                }
692                2 => {
693                    self.metadata.push(Metadata::Value {
694                        ty: self.ty(op(r, 0)?, r.at)?,
695                        value: md(op(r, 1)?, r.at)?,
696                    });
697                    self.metadata_at.push(r.at);
698                }
699                3 | 5 => {
700                    self.metadata.push(Metadata::Node(
701                        r.operands
702                            .iter()
703                            .map(|&v| {
704                                if v == 0 {
705                                    Ok(None)
706                                } else {
707                                    md(v.saturating_sub(1), r.at).map(Some)
708                                }
709                            })
710                            .collect::<Result<_>>()?,
711                    ));
712                    self.metadata_at.push(r.at);
713                }
714                4 => name = Some(utf8(text(&r.operands, r.at)?, r.at)?),
715                10 => {
716                    let n = name
717                        .take()
718                        .ok_or_else(|| error(r.at, "named node without a name"))?;
719                    let nodes = r.operands.iter().map(|&v| md(v, r.at)).collect::<Result<_>>()?;
720                    self.named_metadata.push((n, nodes));
721                    self.named_metadata_at.push(r.at);
722                }
723                6 => {} // KIND: names of attachment kinds
724                other => return Err(error(r.at, format!("metadata record {other}"))),
725            }
726        }
727        Ok(())
728    }
729
730    fn read_symbols(&mut self, block: &Block, base: usize) -> Result<()> {
731        for r in block.records() {
732            match r.code {
733                1 | 3 => {
734                    let value = usize::try_from(op(r, 0)?).map_err(|_| error(r.at, "value id"))?;
735                    let skip = if r.code == 3 { 2 } else { 1 };
736                    let n = utf8(text(r.operands.get(skip..).unwrap_or_default(), r.at)?, r.at)?;
737                    let id = base.checked_add(value).ok_or_else(|| error(r.at, "value id"))?;
738                    self.names.push((id, n));
739                }
740                2 => {} // basic-block names
741                other => return Err(error(r.at, format!("symbol record {other}"))),
742            }
743        }
744        Ok(())
745    }
746}
747
748/// Function-body decoding state: relative value numbering (module version 1).
749struct Body<'m> {
750    m: &'m mut Module,
751    block: usize,
752    blocks: usize,
753}
754impl Body<'_> {
755    fn next(&self) -> usize {
756        self.m.values.len()
757    }
758    /// A relative operand (absolute = next - operand), with its explicit type following when it is a forward
759    /// reference (a value defined later in the function's layout). Returns the value id and its type, and advances `i`.
760    fn value_type(&self, r: &Record, i: &mut usize) -> Result<(ValueId, TypeId)> {
761        let id = self.absolute(op(r, *i)?, r.at)?;
762        *i = i.saturating_add(1);
763        if id < self.next() {
764            let t = self
765                .m
766                .value_types
767                .get(id)
768                .copied()
769                .ok_or_else(|| error(r.at, format!("value {id} has no type")))?;
770            Ok((id, t))
771        } else {
772            let t = self.m.ty(op(r, *i)?, r.at)?;
773            *i = i.saturating_add(1);
774            Ok((id, t))
775        }
776    }
777    /// A relative operand whose type is known from another operand: a forward reference carries none.
778    fn value(&self, r: &Record, i: &mut usize) -> Result<ValueId> {
779        let id = self.absolute(op(r, *i)?, r.at)?;
780        *i = i.saturating_add(1);
781        Ok(id)
782    }
783    /// The absolute id a relative operand names: the next id minus the operand, in 32 bits as LLVM writes it (a value
784    /// defined later is a forward reference, which wraps).
785    fn absolute(&self, relative: u64, at: usize) -> Result<ValueId> {
786        let relative = u32::try_from(relative)
787            .map_err(|_| error(at, format!("relative value id {relative} wider than 32 bits")))?;
788        let next = u32::try_from(self.next()).map_err(|_| error(at, "too many values"))?;
789        Ok(next.wrapping_sub(relative) as usize)
790    }
791    /// The type of a value defined before this point, or of a forward reference by the type given.
792    fn pointer_to(&mut self, t: TypeId) -> TypeId {
793        self.m.intern(Type::Pointer(t, 0))
794    }
795    /// The index a constant integer value stands for, if it is one defined in the module or this function.
796    fn constant_index(&self, v: ValueId) -> Option<usize> {
797        match self.m.values.get(v) {
798            Some(Value::Constant(Constant::Integer(i))) => usize::try_from(*i).ok(),
799            Some(Value::Constant(Constant::Null)) => Some(0),
800            _ => None,
801        }
802    }
803    fn result(&mut self, ty: TypeId, at: usize) -> Result<Option<(ValueId, TypeId)>> {
804        if *self.m.type_at(ty, at)? == Type::Void {
805            return Ok(None);
806        }
807        Ok(Some((self.m.push(Value::Local, ty, at)?, ty)))
808    }
809}
810
811fn binary(code: u64, at: usize) -> Result<BinaryOp> {
812    Ok(match code {
813        0 => BinaryOp::Add,
814        1 => BinaryOp::Sub,
815        2 => BinaryOp::Mul,
816        3 => BinaryOp::UDiv,
817        4 => BinaryOp::SDiv,
818        5 => BinaryOp::URem,
819        6 => BinaryOp::SRem,
820        7 => BinaryOp::Shl,
821        8 => BinaryOp::LShr,
822        9 => BinaryOp::AShr,
823        10 => BinaryOp::And,
824        11 => BinaryOp::Or,
825        12 => BinaryOp::Xor,
826        other => return Err(error(at, format!("binary opcode {other}"))),
827    })
828}
829fn cast(code: u64, at: usize) -> Result<CastOp> {
830    Ok(match code {
831        0 => CastOp::Trunc,
832        1 => CastOp::ZExt,
833        2 => CastOp::SExt,
834        3 => CastOp::FpToUi,
835        4 => CastOp::FpToSi,
836        5 => CastOp::UiToFp,
837        6 => CastOp::SiToFp,
838        7 => CastOp::FpTrunc,
839        8 => CastOp::FpExt,
840        9 => CastOp::PtrToInt,
841        10 => CastOp::IntToPtr,
842        11 => CastOp::BitCast,
843        other => return Err(error(at, format!("cast opcode {other}"))),
844    })
845}
846/// The name of a function-body record code this reader refuses.
847fn refused(code: u64) -> &'static str {
848    match code {
849        4 | 30 => "getelementptr (old form)",
850        13 => "invoke",
851        41 => "load (atomic)",
852        23 => "va_arg",
853        24 | 42 | 45 => "store (atomic)",
854        31 => "indirectbr",
855        37 => "cmpxchg (old form)",
856        59 => "atomicrmw (new form)",
857        39 => "resume",
858        40 | 47 => "landingpad",
859        _ => "unknown instruction record",
860    }
861}
862
863impl Module {
864    fn read_function(&mut self, block: &Block, value: ValueId) -> Result<Function> {
865        let fty = match self.value_types.get(value).and_then(|&t| self.types.get(t)) {
866            Some(Type::Pointer(t, _)) => *t,
867            _ => return Err(error(block.at, "function value is not a function pointer")),
868        };
869        let params = match self.type_at(fty, block.at)? {
870            Type::Function { params, .. } => params.clone(),
871            _ => return Err(error(block.at, "function type")),
872        };
873        let base = self.values.len();
874        for p in params {
875            self.push(Value::Local, p, block.at)?;
876        }
877        let mut body = Body {
878            m: self,
879            block: 0,
880            blocks: 0,
881        };
882        let mut instructions = Vec::new();
883        for e in &block.elements {
884            let r = match e {
885                crate::bitstream::Element::Block(b) => {
886                    match b.id {
887                        CONSTANTS => body.m.read_constants(b)?,
888                        VALUE_SYMTAB => body.m.read_symbols(b, 0)?,
889                        METADATA | METADATA_ATTACHMENT | USELIST => {}
890                        other => return Err(error(b.at, format!("block {other} in a function"))),
891                    }
892                    continue;
893                }
894                crate::bitstream::Element::Record(r) => r,
895            };
896            let mut i = 0;
897            let (op, ty): (Op, Option<TypeId>) = match r.code {
898                1 => {
899                    body.blocks = usize::try_from(op(r, 0)?)
900                        .ok()
901                        .filter(|&n| n > 0 && n <= 1 << 16)
902                        .ok_or_else(|| error(r.at, "basic block count"))?;
903                    continue;
904                }
905                33 | 35 => continue, // debug locations
906                2 => {
907                    let (lhs, t) = body.value_type(r, &mut i)?;
908                    let rhs = body.value(r, &mut i)?;
909                    let o = binary(op(r, i)?, r.at)?;
910                    (Op::Binary { op: o, lhs, rhs }, Some(t))
911                }
912                3 => {
913                    let value = body.value(r, &mut i)?;
914                    let to = body.m.ty(op(r, i)?, r.at)?;
915                    let o = cast(op(r, i.saturating_add(1))?, r.at)?;
916                    (Op::Cast { op: o, value }, Some(to))
917                }
918                9 | 28 => {
919                    let (lhs, t) = body.value_type(r, &mut i)?;
920                    let rhs = body.value(r, &mut i)?;
921                    let predicate = op(r, i)?;
922                    let bool_ty = match body.m.type_at(t, r.at)? {
923                        Type::Vector(..) => {
924                            return Err(error(r.at, "vector comparison"));
925                        }
926                        _ => body
927                            .m
928                            .types
929                            .iter()
930                            .position(|x| *x == Type::Integer(1))
931                            .ok_or_else(|| error(r.at, "no i1 type for a comparison"))?,
932                    };
933                    (Op::Compare { predicate, lhs, rhs }, Some(bool_ty))
934                }
935                29 => {
936                    let (then, t) = body.value_type(r, &mut i)?;
937                    let otherwise = body.value(r, &mut i)?;
938                    let condition = body.value(r, &mut i)?;
939                    (
940                        Op::Select {
941                            condition,
942                            then,
943                            otherwise,
944                        },
945                        Some(t),
946                    )
947                }
948                26 => {
949                    let (aggregate, mut t) = body.value_type(r, &mut i)?;
950                    let indices = r.operands.get(i..).unwrap_or_default().to_vec();
951                    for &k in &indices {
952                        t = match body.m.type_at(t, r.at)? {
953                            Type::Struct { elements, .. } => *usize::try_from(k)
954                                .ok()
955                                .and_then(|k| elements.get(k))
956                                .ok_or_else(|| error(r.at, "extractvalue index"))?,
957                            Type::Array(n, e) if k < *n => *e,
958                            _ => return Err(error(r.at, "extractvalue index")),
959                        };
960                    }
961                    (Op::ExtractValue { aggregate, indices }, Some(t))
962                }
963                6 => {
964                    let (vector, t) = body.value_type(r, &mut i)?;
965                    let (index, _) = body.value_type(r, &mut i)?;
966                    let Type::Vector(_, element) = *body.m.type_at(t, r.at)? else {
967                        return Err(error(r.at, "extractelement of something that is not a vector"));
968                    };
969                    (Op::ExtractElement { vector, index }, Some(element))
970                }
971                7 => {
972                    let (vector, t) = body.value_type(r, &mut i)?;
973                    let value = body.value(r, &mut i)?;
974                    let (index, _) = body.value_type(r, &mut i)?;
975                    (Op::InsertElement { vector, value, index }, Some(t))
976                }
977                8 => {
978                    let (first, t) = body.value_type(r, &mut i)?;
979                    let second = body.value(r, &mut i)?;
980                    let (mask, mask_ty) = body.value_type(r, &mut i)?;
981                    let (Type::Vector(_, element), Type::Vector(lanes, _)) = (
982                        body.m.type_at(t, r.at)?.clone(),
983                        body.m.type_at(mask_ty, r.at)?.clone(),
984                    ) else {
985                        return Err(error(r.at, "shufflevector of something that is not a vector"));
986                    };
987                    let result = body
988                        .m
989                        .types
990                        .iter()
991                        .position(|x| *x == Type::Vector(lanes, element))
992                        .ok_or_else(|| error(r.at, "no type for the shuffled vector"))?;
993                    (Op::ShuffleVector { first, second, mask }, Some(result))
994                }
995                27 => {
996                    let (aggregate, t) = body.value_type(r, &mut i)?;
997                    let value = body.value(r, &mut i)?;
998                    let indices = r.operands.get(i..).unwrap_or_default().to_vec();
999                    (
1000                        Op::InsertValue {
1001                            aggregate,
1002                            value,
1003                            indices,
1004                        },
1005                        Some(t),
1006                    )
1007                }
1008                34 => {
1009                    i = 1; // paramattrs
1010                    let cc = op(r, i)?;
1011                    i = i.saturating_add(1);
1012                    if cc & (1 << 17) != 0 {
1013                        i = i.saturating_add(1); // fast-math flags
1014                    }
1015                    let explicit = if cc & (1 << 15) != 0 {
1016                        let t = body.m.ty(op(r, i)?, r.at)?;
1017                        i = i.saturating_add(1);
1018                        Some(t)
1019                    } else {
1020                        None
1021                    };
1022                    let (function, callee_ty) = body.value_type(r, &mut i)?;
1023                    let fty = match (explicit, body.m.type_at(callee_ty, r.at)?) {
1024                        (Some(t), _) => t,
1025                        (None, Type::Pointer(t, _)) => *t,
1026                        _ => return Err(error(r.at, "callee is not a function pointer")),
1027                    };
1028                    let (ret, params, vararg) = match body.m.type_at(fty, r.at)? {
1029                        Type::Function { ret, params, vararg } => (*ret, params.clone(), *vararg),
1030                        _ => return Err(error(r.at, "call through a non-function type")),
1031                    };
1032                    if vararg {
1033                        return Err(error(r.at, "vararg call"));
1034                    }
1035                    let mut args = Vec::with_capacity(params.len());
1036                    for p in &params {
1037                        // a fixed parameter carries no type, even for a value defined later in the layout
1038                        let a = body.value(r, &mut i)?;
1039                        if a < body.next() && body.m.value_types.get(a) != Some(p) {
1040                            return Err(error(r.at, "call argument type"));
1041                        }
1042                        args.push(a);
1043                    }
1044                    if i != r.operands.len() {
1045                        return Err(error(r.at, "call operands left over"));
1046                    }
1047                    (Op::Call { function, args }, Some(ret))
1048                }
1049                16 => {
1050                    let t = body.m.ty(op(r, 0)?, r.at)?;
1051                    let pairs = r.operands.get(1..).unwrap_or_default();
1052                    if pairs.is_empty() || pairs.len() % 2 != 0 {
1053                        return Err(error(r.at, "phi operands"));
1054                    }
1055                    let next = i64::try_from(body.next()).map_err(|_| error(r.at, "too many values"))?;
1056                    let mut incoming = Vec::with_capacity(pairs.len() / 2);
1057                    for pair in pairs.as_chunks::<2>().0 {
1058                        // Signed and relative to the phi itself; it may name a value defined later.
1059                        let id = next
1060                            .checked_sub(signed_vbr(pair[0]))
1061                            .and_then(|v| usize::try_from(v).ok())
1062                            .ok_or_else(|| error(r.at, "phi value"))?;
1063                        let block = usize::try_from(pair[1])
1064                            .ok()
1065                            .filter(|&b| b < body.blocks)
1066                            .ok_or_else(|| error(r.at, "phi block"))?;
1067                        incoming.push((id, block));
1068                    }
1069                    (Op::Phi { incoming }, Some(t))
1070                }
1071                10 => {
1072                    if r.operands.is_empty() {
1073                        (Op::Return(None), None)
1074                    } else {
1075                        (Op::Return(Some(body.value(r, &mut i)?)), None)
1076                    }
1077                }
1078                11 => {
1079                    let target = |v: u64| -> Result<usize> {
1080                        usize::try_from(v)
1081                            .ok()
1082                            .filter(|&b| b < body.blocks)
1083                            .ok_or_else(|| error(r.at, "branch target"))
1084                    };
1085                    if r.operands.len() == 1 {
1086                        (
1087                            Op::Branch {
1088                                target: target(op(r, 0)?)?,
1089                            },
1090                            None,
1091                        )
1092                    } else {
1093                        let then = target(op(r, 0)?)?;
1094                        let otherwise = target(op(r, 1)?)?;
1095                        i = 2;
1096                        let condition = body.value(r, &mut i)?;
1097                        (
1098                            Op::CondBranch {
1099                                condition,
1100                                then,
1101                                otherwise,
1102                            },
1103                            None,
1104                        )
1105                    }
1106                }
1107                12 => {
1108                    // [type, value, default block, (case constant, block)*]; case constants are absolute ids
1109                    let block = |v: u64| -> Result<usize> {
1110                        usize::try_from(v)
1111                            .ok()
1112                            .filter(|&b| b < body.blocks)
1113                            .ok_or_else(|| error(r.at, "switch target"))
1114                    };
1115                    i = 1;
1116                    let value = body.value(r, &mut i)?;
1117                    let default = block(op(r, i)?)?;
1118                    let pairs = r.operands.get(i.saturating_add(1)..).unwrap_or_default();
1119                    if pairs.len() % 2 != 0 {
1120                        return Err(error(r.at, "switch cases"));
1121                    }
1122                    let cases = pairs
1123                        .as_chunks::<2>()
1124                        .0
1125                        .iter()
1126                        .map(|p| {
1127                            Ok((
1128                                usize::try_from(p[0]).map_err(|_| error(r.at, "case value"))?,
1129                                block(p[1])?,
1130                            ))
1131                        })
1132                        .collect::<Result<Vec<_>>>()?;
1133                    (
1134                        Op::Switch {
1135                            value,
1136                            default,
1137                            cases,
1138                        },
1139                        None,
1140                    )
1141                }
1142                15 => (Op::Unreachable, None),
1143                19 => {
1144                    // [allocated type, size type, size (absolute id), alignment]
1145                    let ty = body.m.ty(op(r, 0)?, r.at)?;
1146                    (Op::Alloca { ty }, Some(body.pointer_to(ty)))
1147                }
1148                20 => {
1149                    let (pointer, pt) = body.value_type(r, &mut i)?;
1150                    let _ = pt;
1151                    let ty = body.m.ty(op(r, i)?, r.at)?;
1152                    (Op::Load { pointer }, Some(ty))
1153                }
1154                44 => {
1155                    let (pointer, _) = body.value_type(r, &mut i)?;
1156                    let (value, _) = body.value_type(r, &mut i)?;
1157                    (Op::Store { pointer, value }, None)
1158                }
1159                // atomicrmw (LLVM 3.7): [pointer with its type, value, operation, volatile, ordering, scope]
1160                38 => {
1161                    let (pointer, _) = body.value_type(r, &mut i)?;
1162                    let value = body.value(r, &mut i)?;
1163                    let op = op(r, i)?;
1164                    let ty = body.m.value_types.get(value).copied();
1165                    let ty = match ty {
1166                        Some(t) if value < body.next() => t,
1167                        _ => return Err(error(r.at, "an atomicrmw of a value defined later")),
1168                    };
1169                    (Op::AtomicRmw { pointer, value, op }, Some(ty))
1170                }
1171                // cmpxchg: [pointer with its type, compare with its type, new value, volatile, orderings, ...]; the
1172                // result is a structure of the value and a flag
1173                46 => {
1174                    let (pointer, _) = body.value_type(r, &mut i)?;
1175                    let (compare, ty) = body.value_type(r, &mut i)?;
1176                    let value = body.value(r, &mut i)?;
1177                    let flag = body
1178                        .m
1179                        .types
1180                        .iter()
1181                        .position(|t| *t == Type::Integer(1))
1182                        .ok_or_else(|| error(r.at, "a cmpxchg without a boolean type"))?;
1183                    let pair = Type::Struct {
1184                        name: None,
1185                        elements: vec![ty, flag],
1186                    };
1187                    let result = body.m.intern(pair);
1188                    (
1189                        Op::CmpXchg {
1190                            pointer,
1191                            compare,
1192                            value,
1193                        },
1194                        Some(result),
1195                    )
1196                }
1197                36 => (Op::Fence, None),
1198                43 => {
1199                    // [inbounds, source element type, then each operand with its type when a forward reference]
1200                    i = 2;
1201                    let source = body.m.ty(op(r, 1)?, r.at)?;
1202                    let (base, _) = body.value_type(r, &mut i)?;
1203                    let mut indices = Vec::new();
1204                    while i < r.operands.len() {
1205                        indices.push(body.value_type(r, &mut i)?.0);
1206                    }
1207                    // the result points at what the indices reach: the first steps over the pointer, the rest into
1208                    // arrays, vectors and structures
1209                    let mut t = source;
1210                    for &index in indices.iter().skip(1) {
1211                        t = match body.m.type_at(t, r.at)?.clone() {
1212                            Type::Array(_, e) | Type::Vector(_, e) => e,
1213                            Type::Struct { elements, .. } => {
1214                                let k = match body.constant_index(index) {
1215                                    Some(k) => k,
1216                                    None => {
1217                                        return Err(error(r.at, "a structure index that is not constant"));
1218                                    }
1219                                };
1220                                *elements
1221                                    .get(k)
1222                                    .ok_or_else(|| error(r.at, "getelementptr structure index"))?
1223                            }
1224                            _ => return Err(error(r.at, "getelementptr into a scalar")),
1225                        };
1226                    }
1227                    (Op::Gep { base, indices }, Some(body.pointer_to(t)))
1228                }
1229                other => {
1230                    return Err(error(
1231                        r.at,
1232                        format!("instruction {} (record {other}) is not supported", refused(other)),
1233                    ));
1234                }
1235            };
1236            let result = match ty {
1237                Some(t) => body.result(t, r.at)?,
1238                None => None,
1239            };
1240            let terminator = matches!(
1241                op,
1242                Op::Return(_)
1243                    | Op::Branch { .. }
1244                    | Op::CondBranch { .. }
1245                    | Op::Switch { .. }
1246                    | Op::Unreachable
1247            );
1248            instructions.push(Instruction {
1249                op,
1250                result,
1251                block: body.block,
1252                at: r.at,
1253            });
1254            if terminator {
1255                body.block = body.block.saturating_add(1);
1256            }
1257        }
1258        if body.block != body.blocks {
1259            return Err(error(block.at, "basic blocks without terminators"));
1260        }
1261        let end = body.next();
1262        let blocks = body.blocks;
1263        // everything an instruction names is something the function has: a value (an earlier one, or a later one a phi
1264        // or a loop reads), a basic block, and a callee taking the arguments it is given
1265        for inst in &instructions {
1266            if inst.block >= blocks {
1267                return Err(error(inst.at, "an instruction after the last terminator"));
1268            }
1269            if let Some(v) = inst.op.operands().into_iter().find(|v| *v >= end) {
1270                return Err(error(inst.at, format!("value {v} of {end} values")));
1271            }
1272            if let Some(b) = inst.op.blocks().into_iter().find(|b| *b >= blocks) {
1273                return Err(error(inst.at, format!("basic block {b} of {blocks}")));
1274            }
1275            if let Op::Call { function, args } = &inst.op {
1276                if *function >= end {
1277                    return Err(error(inst.at, format!("callee {function} of {end} values")));
1278                }
1279                if let Some(Value::Function { ty, .. }) = self.values.get(*function)
1280                    && let Some(Type::Function {
1281                        vararg: false,
1282                        params,
1283                        ..
1284                    }) = self.types.get(*ty)
1285                    && params.len() != args.len()
1286                {
1287                    return Err(error(
1288                        inst.at,
1289                        format!(
1290                            "a call of {} arguments to a function of {} parameters",
1291                            args.len(),
1292                            params.len()
1293                        ),
1294                    ));
1295                }
1296            }
1297        }
1298        let locals = self.values.split_off(base);
1299        let local_types = self.value_types.split_off(base);
1300        Ok(Function {
1301            value,
1302            blocks,
1303            instructions,
1304            first: base,
1305            locals,
1306            local_types,
1307        })
1308    }
1309
1310    /// Read a module from the bitcode's top-level blocks.
1311    pub fn read(top: &[Block]) -> Result<Self> {
1312        let module = match top {
1313            [m] if m.id == MODULE => m,
1314            _ => return Err(error(0, "bitcode is not one module block")),
1315        };
1316        let mut m = Module {
1317            at: module.at,
1318            ..Module::default()
1319        };
1320        let mut bodies: Vec<ValueId> = Vec::new();
1321        let mut version = None;
1322        for e in &module.elements {
1323            match e {
1324                crate::bitstream::Element::Record(r) => match r.code {
1325                    1 => version = Some(op(r, 0)?),
1326                    2..=6 | 11 | 13 | 16 => {} // triple, datalayout, asm, section, deplib, gc, source file
1327                    7 => {
1328                        // GLOBALVAR: [type, flags (bit 0 constant, bit 1 explicit type, from bit 2 the address space),
1329                        // initial value + 1 or 0, ...]
1330                        let t = m.ty(op(r, 0)?, r.at)?;
1331                        let flags = op(r, 1)?;
1332                        let address_space =
1333                            u32::try_from(flags >> 2).map_err(|_| error(r.at, "address space"))?;
1334                        let (ty, value_ty) = if flags & 2 != 0 {
1335                            let pointer = m.intern(Type::Pointer(t, address_space));
1336                            (pointer, t)
1337                        } else {
1338                            match m.type_at(t, r.at)? {
1339                                Type::Pointer(inner, _) => (t, *inner),
1340                                _ => return Err(error(r.at, "a global whose type is not a pointer")),
1341                            }
1342                        };
1343                        let init = match op(r, 2)? {
1344                            0 => None,
1345                            n => Some(
1346                                usize::try_from(n.saturating_sub(1))
1347                                    .map_err(|_| error(r.at, "initial value id"))?,
1348                            ),
1349                        };
1350                        m.push(
1351                            Value::Global {
1352                                ty,
1353                                value_ty,
1354                                init,
1355                                constant: flags & 1 != 0,
1356                                address_space,
1357                            },
1358                            ty,
1359                            r.at,
1360                        )?;
1361                    }
1362                    8 => {
1363                        // FUNCTION: [function type, cc, isproto, ...]
1364                        let t = m.ty(op(r, 0)?, r.at)?;
1365                        let pointer = m.intern(Type::Pointer(t, 0));
1366                        let declaration = op(r, 2)? != 0;
1367                        let v = m.push(Value::Function { ty: t, declaration }, pointer, r.at)?;
1368                        if !declaration {
1369                            bodies.push(v);
1370                        }
1371                    }
1372                    other => return Err(error(r.at, format!("module record {other}"))),
1373                },
1374                crate::bitstream::Element::Block(b) => match b.id {
1375                    BLOCKINFO | PARAMATTR | PARAMATTR_GROUP | USELIST => {}
1376                    TYPES => m.read_types(b)?,
1377                    CONSTANTS => m.read_constants(b)?,
1378                    METADATA => m.read_metadata(b)?,
1379                    VALUE_SYMTAB => m.read_symbols(b, 0)?,
1380                    FUNCTION => {
1381                        if version != Some(1) {
1382                            return Err(error(b.at, "only relative value ids (module version 1)"));
1383                        }
1384                        // Bodies are stored in the order of their definitions (a hull program has two).
1385                        if bodies.is_empty() {
1386                            return Err(error(b.at, "function body without a definition"));
1387                        }
1388                        let value = bodies.remove(0);
1389                        // A body's values are its own; the next body numbers from the module's values again.
1390                        let f = m.read_function(b, value)?;
1391                        m.functions.push(f);
1392                    }
1393                    other => return Err(error(b.at, format!("module block {other}"))),
1394                },
1395            }
1396        }
1397        if !bodies.is_empty() {
1398            return Err(error(module.at, "a defined function has no body"));
1399        }
1400        Ok(m)
1401    }
1402}