perf(lang): Narrow speculative parser snapshots

a084814327fdb33b1827f62b1a57dbbf887d43102d6ea048dd434937cad69ba2
Save only parser fields that speculative parsing can mutate. Avoid copying the fixed parser error array for generic arguments, returns, and panic expressions.
Alexis Sellier committed ago 1 parent 88ab8cc1
lib/std/lang/parser.rad +23 -3
85 85
    count: u32,
86 86
}
87 87
88 88
/// Snapshot of parser state for speculative parsing.
89 89
record SavedState {
90 -
    parser: Parser,
90 +
    /// Scanner position before speculative parsing.
91 +
    scanner: scanner::Scanner,
92 +
    /// Current token before speculative parsing.
93 +
    current: scanner::Token,
94 +
    /// Previous token before speculative parsing.
95 +
    previous: scanner::Token,
96 +
    /// Number of parser errors before speculative parsing.
97 +
    /// Error entries at or above this count are inactive.
98 +
    errorCount: u32,
99 +
    /// Parsing context before speculative parsing.
100 +
    context: Context,
101 +
    /// Arena position before speculative parsing.
91 102
    arena: u32,
103 +
    /// Next node identifier before speculative parsing.
92 104
    nextId: u32,
93 105
}
94 106
95 107
/// Operator metadata for precedence climbing.
96 108
record OpInfo {
1116 1128
}
1117 1129
1118 1130
/// Save parser state for speculative parsing.
1119 1131
fn saveState(p: *Parser) -> SavedState {
1120 1132
    return SavedState {
1121 -
        parser: *p,
1133 +
        scanner: p.scanner,
1134 +
        current: p.current,
1135 +
        previous: p.previous,
1136 +
        errorCount: p.errors.count,
1137 +
        context: p.context,
1122 1138
        arena: alloc::save(&p.arena.arena),
1123 1139
        nextId: p.arena.nextId,
1124 1140
    };
1125 1141
}
1126 1142
1127 1143
/// Restore parser state from a snapshot, fully undoing any
1128 1144
/// side effects of a failed speculative parse.
1129 1145
fn restoreState(p: *mut Parser, s: *SavedState) {
1130 -
    set *p = s.parser;
1146 +
    set p.scanner = s.scanner;
1147 +
    set p.current = s.current;
1148 +
    set p.previous = s.previous;
1149 +
    set p.errors.count = s.errorCount;
1150 +
    set p.context = s.context;
1131 1151
    alloc::restore(&mut p.arena.arena, s.arena);
1132 1152
    set p.arena.nextId = s.nextId;
1133 1153
}
1134 1154
1135 1155
/// Report a parser error.