Skip to content

Commit 7b17760

Browse files
committed
[assembler] More consistent detection of oversize RC-block.
1 parent 257fa84 commit 7b17760

File tree

4 files changed

+47
-32
lines changed

4 files changed

+47
-32
lines changed

assembler/src/asmlib/ast.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,11 @@ pub(crate) enum RcWordSource {
3131
}
3232

3333
pub(crate) trait RcAllocator {
34-
fn allocate(&mut self, source: RcWordSource, value: Unsigned36Bit) -> Address;
34+
fn allocate(
35+
&mut self,
36+
source: RcWordSource,
37+
value: Unsigned36Bit,
38+
) -> Result<Address, MachineLimitExceededFailure>;
3539
}
3640

3741
pub(crate) trait RcUpdater {

assembler/src/asmlib/driver.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,11 @@ fn inconsistent_origin_definition(
442442
struct NoRcBlock {}
443443

444444
impl RcAllocator for NoRcBlock {
445-
fn allocate(&mut self, _source: RcWordSource, _value: Unsigned36Bit) -> Address {
445+
fn allocate(
446+
&mut self,
447+
_source: RcWordSource,
448+
_value: Unsigned36Bit,
449+
) -> Result<Address, MachineLimitExceededFailure> {
446450
panic!("Cannot allocate an RC-word before we know the address of the RC block");
447451
}
448452
}
@@ -503,10 +507,14 @@ fn assemble_pass3(
503507
)?;
504508

505509
for (_, directive_block) in memory_map.values_mut() {
506-
directive_block.assign_rc_words(symtab, &mut rcblock)?;
510+
if let Err(e) = directive_block.assign_rc_words(symtab, &mut rcblock) {
511+
return Err(AssemblerFailure::MachineLimitExceeded(e));
512+
}
507513
}
508514

509-
assign_default_rc_word_tags(symtab, &mut rcblock, &mut final_symbols);
515+
if let Err(e) = assign_default_rc_word_tags(symtab, &mut rcblock, &mut final_symbols) {
516+
return Err(AssemblerFailure::MachineLimitExceeded(e));
517+
}
510518

511519
// Emit the binary code.
512520
for (block_id, (maybe_origin, directive_block)) in memory_map.into_iter() {

assembler/src/asmlib/eval.rs

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -187,21 +187,22 @@ pub(crate) struct RcBlock {
187187
}
188188

189189
impl RcBlock {
190-
fn end(&self) -> Address {
191-
match Unsigned18Bit::try_from(self.words.len()) {
192-
Ok(offset) => self.address.index_by(offset),
193-
Err(_) => {
194-
panic!("program is too large"); // TODO: fixme: use Result
195-
}
196-
}
190+
fn end(&self) -> Result<Address, MachineLimitExceededFailure> {
191+
Unsigned18Bit::try_from(self.words.len())
192+
.map(|offset| self.address.index_by(offset))
193+
.map_err(|_| MachineLimitExceededFailure::RcBlockTooLarge)
197194
}
198195
}
199196

200197
impl RcAllocator for RcBlock {
201-
fn allocate(&mut self, source: RcWordSource, value: Unsigned36Bit) -> Address {
202-
let addr = self.end();
198+
fn allocate(
199+
&mut self,
200+
source: RcWordSource,
201+
value: Unsigned36Bit,
202+
) -> Result<Address, MachineLimitExceededFailure> {
203+
let addr = self.end()?;
203204
self.words.push((source, value));
204-
addr
205+
Ok(addr)
205206
}
206207
}
207208

@@ -220,8 +221,8 @@ impl RcUpdater for RcBlock {
220221
}
221222
None => {
222223
panic!(
223-
"out of range access to address {address} of RC-block ending at {}",
224-
self.end()
224+
"out of range access to offset {offset} of RC-block having length {}",
225+
self.words.len()
225226
);
226227
}
227228
},
@@ -1230,7 +1231,7 @@ impl LocatedBlock {
12301231
&mut self,
12311232
symtab: &mut SymbolTable,
12321233
rc_allocator: &mut R,
1233-
) -> Result<(), AssemblerFailure> {
1234+
) -> Result<(), MachineLimitExceededFailure> {
12341235
for (_span, ref mut statement) in self.statements.iter_mut() {
12351236
statement.assign_rc_words(symtab, rc_allocator)?;
12361237
}
@@ -1243,7 +1244,7 @@ impl Statement {
12431244
&mut self,
12441245
symtab: &mut SymbolTable,
12451246
rc_allocator: &mut R,
1246-
) -> Result<(), AssemblerFailure> {
1247+
) -> Result<(), MachineLimitExceededFailure> {
12471248
match self {
12481249
Statement::Instruction(inst) => inst.assign_rc_words(symtab, rc_allocator),
12491250
}
@@ -1255,7 +1256,7 @@ impl TaggedProgramInstruction {
12551256
&mut self,
12561257
symtab: &mut SymbolTable,
12571258
rc_allocator: &mut R,
1258-
) -> Result<(), AssemblerFailure> {
1259+
) -> Result<(), MachineLimitExceededFailure> {
12591260
for inst in self.instructions.iter_mut() {
12601261
inst.assign_rc_words(symtab, rc_allocator)?;
12611262
}
@@ -1268,7 +1269,7 @@ impl CommaDelimitedInstruction {
12681269
&mut self,
12691270
symtab: &mut SymbolTable,
12701271
rc_allocator: &mut R,
1271-
) -> Result<(), AssemblerFailure> {
1272+
) -> Result<(), MachineLimitExceededFailure> {
12721273
self.instruction.assign_rc_words(symtab, rc_allocator)
12731274
}
12741275
}
@@ -1278,7 +1279,7 @@ impl UntaggedProgramInstruction {
12781279
&mut self,
12791280
symtab: &mut SymbolTable,
12801281
rc_allocator: &mut R,
1281-
) -> Result<(), AssemblerFailure> {
1282+
) -> Result<(), MachineLimitExceededFailure> {
12821283
self.inst.assign_rc_words(symtab, rc_allocator)
12831284
}
12841285
}
@@ -1288,7 +1289,7 @@ impl InstructionFragment {
12881289
&mut self,
12891290
symtab: &mut SymbolTable,
12901291
rc_allocator: &mut R,
1291-
) -> Result<(), AssemblerFailure> {
1292+
) -> Result<(), MachineLimitExceededFailure> {
12921293
use InstructionFragment::*;
12931294
match self {
12941295
Null | DeferredAddressing => Ok(()),
@@ -1315,10 +1316,10 @@ impl RegisterContaining {
13151316
source: RcWordSource,
13161317
symtab: &mut SymbolTable,
13171318
rc_allocator: &mut R,
1318-
) -> Result<RegisterContaining, AssemblerFailure> {
1319+
) -> Result<RegisterContaining, MachineLimitExceededFailure> {
13191320
match self {
13201321
RegisterContaining::Unallocated(mut tpibox) => {
1321-
let addr: Address = rc_allocator.allocate(source, Unsigned36Bit::ZERO);
1322+
let addr: Address = rc_allocator.allocate(source, Unsigned36Bit::ZERO)?;
13221323
tpibox.assign_rc_words(symtab, rc_allocator)?;
13231324
let tpi: Box<TaggedProgramInstruction> = tpibox;
13241325
Ok(RegisterContaining::Allocated(addr, tpi))
@@ -1334,7 +1335,7 @@ impl RegistersContaining {
13341335
span: Span,
13351336
symtab: &mut SymbolTable,
13361337
rc_allocator: &mut R,
1337-
) -> Result<(), AssemblerFailure> {
1338+
) -> Result<(), MachineLimitExceededFailure> {
13381339
let source = RcWordSource::Braces(span);
13391340
for rc in self.words_mut() {
13401341
*rc = rc
@@ -1350,7 +1351,7 @@ impl ArithmeticExpression {
13501351
&mut self,
13511352
symtab: &mut SymbolTable,
13521353
rc_allocator: &mut R,
1353-
) -> Result<(), AssemblerFailure> {
1354+
) -> Result<(), MachineLimitExceededFailure> {
13541355
self.first.assign_rc_words(symtab, rc_allocator)?;
13551356
for (_op, atom) in self.tail.iter_mut() {
13561357
atom.assign_rc_words(symtab, rc_allocator)?;
@@ -1364,7 +1365,7 @@ impl ConfigValue {
13641365
&mut self,
13651366
symtab: &mut SymbolTable,
13661367
rc_allocator: &mut R,
1367-
) -> Result<(), AssemblerFailure> {
1368+
) -> Result<(), MachineLimitExceededFailure> {
13681369
self.expr.assign_rc_words(symtab, rc_allocator)
13691370
}
13701371
}
@@ -1374,7 +1375,7 @@ impl SignedAtom {
13741375
&mut self,
13751376
symtab: &mut SymbolTable,
13761377
rc_allocator: &mut R,
1377-
) -> Result<(), AssemblerFailure> {
1378+
) -> Result<(), MachineLimitExceededFailure> {
13781379
self.magnitude.assign_rc_words(symtab, rc_allocator)
13791380
}
13801381
}
@@ -1384,7 +1385,7 @@ impl Atom {
13841385
&mut self,
13851386
symtab: &mut SymbolTable,
13861387
rc_allocator: &mut R,
1387-
) -> Result<(), AssemblerFailure> {
1388+
) -> Result<(), MachineLimitExceededFailure> {
13881389
match self {
13891390
Atom::SymbolOrLiteral(thing) => thing.assign_rc_words(symtab, rc_allocator),
13901391
Atom::Parens(_, _, expr) => expr.assign_rc_words(symtab, rc_allocator),
@@ -1398,7 +1399,7 @@ impl SymbolOrLiteral {
13981399
&mut self,
13991400
_symtab: &mut SymbolTable,
14001401
_rc_allocator: &mut R,
1401-
) -> Result<(), AssemblerFailure> {
1402+
) -> Result<(), MachineLimitExceededFailure> {
14021403
Ok(())
14031404
}
14041405
}

assembler/src/asmlib/symtab.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -716,15 +716,16 @@ pub(super) fn assign_default_rc_word_tags<R: RcAllocator>(
716716
symtab: &mut SymbolTable,
717717
rcblock: &mut R,
718718
final_symbols: &mut FinalSymbolTable,
719-
) {
719+
) -> Result<(), MachineLimitExceededFailure> {
720720
for (name, def) in symtab.definitions.iter_mut() {
721721
*def = match &def {
722722
InternalSymbolDef {
723723
span,
724724
def: SymbolDefinition::Undefined(context),
725725
} if context.requires_rc_word_allocation() => {
726726
let value = Unsigned36Bit::ZERO;
727-
let addr = rcblock.allocate(RcWordSource::DefaultAssignment(name.clone()), value);
727+
let addr =
728+
rcblock.allocate(RcWordSource::DefaultAssignment(name.clone()), value)?;
728729
final_symbols.define(
729730
name.clone(),
730731
FinalSymbolType::Equality,
@@ -740,4 +741,5 @@ pub(super) fn assign_default_rc_word_tags<R: RcAllocator>(
740741
other => (*other).clone(),
741742
}
742743
}
744+
Ok(())
743745
}

0 commit comments

Comments
 (0)