@ -3,7 +3,8 @@ use std::sync::Arc;
use crate ::asm ::data ::literal ::{ Addr , Label , RoutineName } ;
use crate ::asm ::data ::literal ::{ Addr , Label , RoutineName } ;
use crate ::asm ::instr ::Op ;
use crate ::asm ::instr ::Op ;
use crate ::builtin ::defs ::{ BuiltinOp , Barrier } ;
use crate ::asm ::instr ::op ::OpKind ;
use crate ::builtin ::defs ::{ Barrier , BuiltinOp } ;
use crate ::module ::CrsnExtension ;
use crate ::module ::CrsnExtension ;
use crate ::runtime ::fault ::Fault ;
use crate ::runtime ::fault ::Fault ;
@ -12,7 +13,6 @@ pub struct Program {
pub ops : Vec < Op > ,
pub ops : Vec < Op > ,
pub extensions : Arc < Vec < Box < dyn CrsnExtension > > > ,
pub extensions : Arc < Vec < Box < dyn CrsnExtension > > > ,
routines : HashMap < RoutineName , Addr > ,
routines : HashMap < RoutineName , Addr > ,
local_labels : HashMap < Label , Addr > ,
far_labels : HashMap < Label , Addr > ,
far_labels : HashMap < Label , Addr > ,
/// Barriers from-to (inclusive).
/// Barriers from-to (inclusive).
/// Standalone barriers have both addresses the same.
/// Standalone barriers have both addresses the same.
@ -25,7 +25,6 @@ impl Program {
ops ,
ops ,
extensions ,
extensions ,
routines : Default ::default ( ) ,
routines : Default ::default ( ) ,
local_labels : Default ::default ( ) ,
far_labels : Default ::default ( ) ,
far_labels : Default ::default ( ) ,
barriers : Default ::default ( ) ,
barriers : Default ::default ( ) ,
} ;
} ;
@ -35,23 +34,23 @@ impl Program {
/// Find all the named things
/// Find all the named things
fn scan ( & mut self ) -> anyhow ::Result < ( ) > {
fn scan ( & mut self ) -> anyhow ::Result < ( ) > {
let mut barrier_starts : HashMap < & Label , Addr > = HashMap ::new ( ) ;
let mut barrier_starts : HashMap < & Label , Addr > = HashMap ::new ( ) ;
for ( pos , op ) in self . ops . iter ( ) . enumerate ( ) {
for ( pos , op ) in self . ops . iter ( ) . enumerate ( ) {
match op {
match & op . kind {
Op ::BuiltIn ( BuiltinOp ::FarLabel ( name ) ) = > {
OpKind ::BuiltIn ( BuiltinOp ::FarLabel ( name ) ) = > {
self . far_labels . insert ( name . clone ( ) , pos . into ( ) ) ;
self . far_labels . insert ( name . clone ( ) , pos . into ( ) ) ;
}
}
Op ::BuiltIn ( BuiltinOp ::Routine ( name ) ) = > {
OpKind ::BuiltIn ( BuiltinOp ::Routine ( name ) ) = > {
self . routines . insert ( name . clone ( ) , pos . into ( ) ) ;
self . routines . insert ( name . clone ( ) , pos . into ( ) ) ;
}
}
Op ::BuiltIn (
OpKind ::BuiltIn (
BuiltinOp ::Barrier {
BuiltinOp ::Barrier {
kind : Barrier ::Open ( lbl ) , ..
kind : Barrier ::Open ( lbl ) , ..
}
}
) = > {
) = > {
barrier_starts . insert ( lbl , pos . into ( ) ) ;
barrier_starts . insert ( lbl , pos . into ( ) ) ;
}
}
Op ::BuiltIn (
OpKind ::BuiltIn (
BuiltinOp ::Barrier {
BuiltinOp ::Barrier {
kind : Barrier ::Close ( lbl ) ,
kind : Barrier ::Close ( lbl ) ,
msg ,
msg ,
@ -64,7 +63,7 @@ impl Program {
anyhow ::bail ! ( "Block barrier \"{:?}\" closed without being open!" , msg ) ;
anyhow ::bail ! ( "Block barrier \"{:?}\" closed without being open!" , msg ) ;
}
}
}
}
Op ::BuiltIn (
OpKind ::BuiltIn (
BuiltinOp ::Barrier {
BuiltinOp ::Barrier {
kind : Barrier ::Standalone ,
kind : Barrier ::Standalone ,
..
..
@ -80,7 +79,7 @@ impl Program {
anyhow ::bail ! ( "Some block barriers open without being closed!" ) ;
anyhow ::bail ! ( "Some block barriers open without being closed!" ) ;
}
}
debug ! ( "Program scanned: {:?}" , self ) ;
trace ! ( "Program scanned: {:?}" , self ) ;
Ok ( ( ) )
Ok ( ( ) )
}
}
@ -88,7 +87,7 @@ impl Program {
/// Read a program instruction at address
/// Read a program instruction at address
pub fn read ( & self , addr : Addr ) -> & Op {
pub fn read ( & self , addr : Addr ) -> & Op {
if addr . 0 > = self . ops . len ( ) as u64 {
if addr . 0 > = self . ops . len ( ) as u64 {
& Op ::BuiltIn ( BuiltinOp ::Halt )
& Op { kind : OpKind ::BuiltIn ( BuiltinOp ::Halt ) , cond : None }
} else {
} else {
& self . ops [ addr . 0 as usize ]
& self . ops [ addr . 0 as usize ]
}
}
@ -104,7 +103,7 @@ impl Program {
if b0 ! = b1 {
if b0 ! = b1 {
// block barrier that only partially intersects the jump
// block barrier that only partially intersects the jump
if ( * b0 > = from & & * b0 < = to ) ! = ( * b1 > = from & & * b1 < = to ) {
if ( * b0 > = from & & * b0 < = to ) ! = ( * b1 > = from & & * b1 < = to ) {
if let Op ::BuiltIn ( BuiltinOp ::Barrier { msg , .. } ) = self . read ( * b0 ) {
if let OpKind ::BuiltIn ( BuiltinOp ::Barrier { msg , .. } ) = & self . read ( * b0 ) . kind {
return Err ( Fault ::JumpThroughBarrier {
return Err ( Fault ::JumpThroughBarrier {
msg : msg . clone ( ) . unwrap_or ( "BLOCK BARRIER" . into ( ) )
msg : msg . clone ( ) . unwrap_or ( "BLOCK BARRIER" . into ( ) )
} ) ;
} ) ;
@ -115,7 +114,7 @@ impl Program {
} else {
} else {
// point barrier
// point barrier
if * b0 > = from & & * b0 < = to {
if * b0 > = from & & * b0 < = to {
if let Op ::BuiltIn ( BuiltinOp ::Barrier { msg , .. } ) = self . read ( * b0 ) {
if let OpKind ::BuiltIn ( BuiltinOp ::Barrier { msg , .. } ) = & self . read ( * b0 ) . kind {
return Err ( Fault ::JumpThroughBarrier {
return Err ( Fault ::JumpThroughBarrier {
msg : msg . clone ( ) . unwrap_or ( "POINT BARRIER" . into ( ) )
msg : msg . clone ( ) . unwrap_or ( "POINT BARRIER" . into ( ) )
} ) ;
} ) ;