Typed byte regions¶
Unmaterialized byte sequences. The specification's bulk data lives in named host regions. A slice's nominal type identifies its region; the semantic value contains only a source coordinate and a length. There is deliberately no generic slice and no runtime source discriminant.
The standard C ABI lowers the coordinate to an offset in the named region. The fixed-capacity optimized C ABI lowers the same coordinate to a validated absolute pointer, after allocating every mutable region before Sail execution. This representation choice is not part of the protocol semantics: subslicing is coordinate addition in both builds, and the nominal type retains provenance.
Constants¶
The fixed lengths identify addresses, words, limbs, and double words.
type StatelessInputSliceFields¶
A range in the immutable stateless-input envelope. Its source is carried by the nominal type rather than a runtime field.
struct StatelessInputSliceFields('off : Int, 'len : Int), stateless_input_valid_range('off, 'len) = {
bytes : int('off),
len : int('len),
}Whether an offset/length pair is contained by the immutable stateless-input envelope.
type stateless_input_valid_range('off : Int, 'len : Int) -> Bool =
0 <= 'off & 0 <= 'len & 'off + 'len <= stateless_input_region_boundtype StatelessInputSlice¶
A stateless-input range with its coordinate and length packed existentially.
type StatelessInputSlice = {
'off 'len,
stateless_input_valid_range('off, 'len).
StatelessInputSliceFields('off, 'len)
}A range in the immutable stateless-input envelope. Its source is carried by the nominal type rather than a runtime field.
struct StatelessInputSliceFields('off : Int, 'len : Int), stateless_input_valid_range('off, 'len) = {
bytes : int('off),
len : int('len),
}Whether an offset/length pair is contained by the immutable stateless-input envelope.
type stateless_input_valid_range('off : Int, 'len : Int) -> Bool =
0 <= 'off & 0 <= 'len & 'off + 'len <= stateless_input_region_boundtype StatelessInputSliceLength¶
A stateless-input range of exactly 'required bytes.
type StatelessInputSliceLength('required : Int) = {
'off 'len,
stateless_input_valid_range('off, 'len) & 'len == 'required.
StatelessInputSliceFields('off, 'len)
}A range in the immutable stateless-input envelope. Its source is carried by the nominal type rather than a runtime field.
struct StatelessInputSliceFields('off : Int, 'len : Int), stateless_input_valid_range('off, 'len) = {
bytes : int('off),
len : int('len),
}Whether an offset/length pair is contained by the immutable stateless-input envelope.
type stateless_input_valid_range('off : Int, 'len : Int) -> Bool =
0 <= 'off & 0 <= 'len & 'off + 'len <= stateless_input_region_boundtype StatelessInputSliceAtLeast¶
A stateless-input range of at least 'minimum bytes.
type StatelessInputSliceAtLeast('minimum : Int) = {
'off 'len,
stateless_input_valid_range('off, 'len) & 0 <= 'minimum & 'minimum <= 'len.
StatelessInputSliceFields('off, 'len)
}A range in the immutable stateless-input envelope. Its source is carried by the nominal type rather than a runtime field.
struct StatelessInputSliceFields('off : Int, 'len : Int), stateless_input_valid_range('off, 'len) = {
bytes : int('off),
len : int('len),
}Whether an offset/length pair is contained by the immutable stateless-input envelope.
type stateless_input_valid_range('off : Int, 'len : Int) -> Bool =
0 <= 'off & 0 <= 'len & 'off + 'len <= stateless_input_region_boundtype StatelessInputSliceAtMost¶
A stateless-input range of at most 'maximum bytes.
type StatelessInputSliceAtMost('maximum : Int) = {
'off 'len,
stateless_input_valid_range('off, 'len) & 0 <= 'maximum & 'len <= 'maximum.
StatelessInputSliceFields('off, 'len)
}A range in the immutable stateless-input envelope. Its source is carried by the nominal type rather than a runtime field.
struct StatelessInputSliceFields('off : Int, 'len : Int), stateless_input_valid_range('off, 'len) = {
bytes : int('off),
len : int('len),
}Whether an offset/length pair is contained by the immutable stateless-input envelope.
type stateless_input_valid_range('off : Int, 'len : Int) -> Bool =
0 <= 'off & 0 <= 'len & 'off + 'len <= stateless_input_region_boundtype ScratchSliceFields¶
A range in the executor's reusable scratch arena. Its source is carried by the nominal type rather than a runtime field.
struct ScratchSliceFields('off : Int, 'len : Int), scratch_valid_range('off, 'len) = {
bytes : int('off),
len : int('len),
}Whether an offset/length pair is contained by the executor scratch arena.
type scratch_valid_range('off : Int, 'len : Int) -> Bool =
0 <= 'off & 0 <= 'len & 'off + 'len <= scratch_region_boundtype ScratchSlice¶
A scratch-arena range with its coordinate and length packed existentially.
type ScratchSlice = {
'off 'len,
scratch_valid_range('off, 'len).
ScratchSliceFields('off, 'len)
}A range in the executor's reusable scratch arena. Its source is carried by the nominal type rather than a runtime field.
struct ScratchSliceFields('off : Int, 'len : Int), scratch_valid_range('off, 'len) = {
bytes : int('off),
len : int('len),
}Whether an offset/length pair is contained by the executor scratch arena.
type scratch_valid_range('off : Int, 'len : Int) -> Bool =
0 <= 'off & 0 <= 'len & 'off + 'len <= scratch_region_boundtype ScratchSliceLength¶
A scratch-arena range of exactly 'required bytes.
type ScratchSliceLength('required : Int) = {
'off 'len,
scratch_valid_range('off, 'len) & 'len == 'required.
ScratchSliceFields('off, 'len)
}A range in the executor's reusable scratch arena. Its source is carried by the nominal type rather than a runtime field.
struct ScratchSliceFields('off : Int, 'len : Int), scratch_valid_range('off, 'len) = {
bytes : int('off),
len : int('len),
}Whether an offset/length pair is contained by the executor scratch arena.
type scratch_valid_range('off : Int, 'len : Int) -> Bool =
0 <= 'off & 0 <= 'len & 'off + 'len <= scratch_region_boundtype ScratchSliceAtLeast¶
A scratch-arena range of at least 'minimum bytes.
type ScratchSliceAtLeast('minimum : Int) = {
'off 'len,
scratch_valid_range('off, 'len) & 0 <= 'minimum & 'minimum <= 'len.
ScratchSliceFields('off, 'len)
}A range in the executor's reusable scratch arena. Its source is carried by the nominal type rather than a runtime field.
struct ScratchSliceFields('off : Int, 'len : Int), scratch_valid_range('off, 'len) = {
bytes : int('off),
len : int('len),
}Whether an offset/length pair is contained by the executor scratch arena.
type scratch_valid_range('off : Int, 'len : Int) -> Bool =
0 <= 'off & 0 <= 'len & 'off + 'len <= scratch_region_boundtype EvmMemorySliceFields¶
A borrowed range in the shared EVM-memory arena. Its coordinate is absolute
within the arena (an offset in the standard ABI and a stable pointer in the
optimized ABI), so calldata borrowed from a suspended parent remains valid
while a child frame is active. The machine carries only memory_height;
this pointer-bearing value exists at derived-view boundaries.
struct EvmMemorySliceFields('off : Int, 'len : Int), memory_region_valid_range('off, 'len) = {
bytes : int('off),
len : int('len),
}Whether an offset/length pair is contained by the shared EVM-memory arena.
type memory_region_valid_range('off : Int, 'len : Int) -> Bool =
0 <= 'off & 0 <= 'len & 'off + 'len <= memory_region_boundtype EvmMemorySlice¶
An EVM-memory range with its coordinate and length packed existentially.
type EvmMemorySlice = {
'off 'len,
memory_region_valid_range('off, 'len).
EvmMemorySliceFields('off, 'len)
}A borrowed range in the shared EVM-memory arena. Its coordinate is absolute
within the arena (an offset in the standard ABI and a stable pointer in the
optimized ABI), so calldata borrowed from a suspended parent remains valid
while a child frame is active. The machine carries only memory_height;
this pointer-bearing value exists at derived-view boundaries.
struct EvmMemorySliceFields('off : Int, 'len : Int), memory_region_valid_range('off, 'len) = {
bytes : int('off),
len : int('len),
}Whether an offset/length pair is contained by the shared EVM-memory arena.
type memory_region_valid_range('off : Int, 'len : Int) -> Bool =
0 <= 'off & 0 <= 'len & 'off + 'len <= memory_region_boundtype EvmMemorySliceLength¶
An EVM-memory range of exactly 'required bytes.
type EvmMemorySliceLength('required : Int) = {
'off 'len,
memory_region_valid_range('off, 'len) & 'len == 'required.
EvmMemorySliceFields('off, 'len)
}A borrowed range in the shared EVM-memory arena. Its coordinate is absolute
within the arena (an offset in the standard ABI and a stable pointer in the
optimized ABI), so calldata borrowed from a suspended parent remains valid
while a child frame is active. The machine carries only memory_height;
this pointer-bearing value exists at derived-view boundaries.
struct EvmMemorySliceFields('off : Int, 'len : Int), memory_region_valid_range('off, 'len) = {
bytes : int('off),
len : int('len),
}Whether an offset/length pair is contained by the shared EVM-memory arena.
type memory_region_valid_range('off : Int, 'len : Int) -> Bool =
0 <= 'off & 0 <= 'len & 'off + 'len <= memory_region_boundtype EvmMemorySliceAtLeast¶
An EVM-memory range of at least 'minimum bytes.
type EvmMemorySliceAtLeast('minimum : Int) = {
'off 'len,
memory_region_valid_range('off, 'len) & 0 <= 'minimum & 'minimum <= 'len.
EvmMemorySliceFields('off, 'len)
}A borrowed range in the shared EVM-memory arena. Its coordinate is absolute
within the arena (an offset in the standard ABI and a stable pointer in the
optimized ABI), so calldata borrowed from a suspended parent remains valid
while a child frame is active. The machine carries only memory_height;
this pointer-bearing value exists at derived-view boundaries.
struct EvmMemorySliceFields('off : Int, 'len : Int), memory_region_valid_range('off, 'len) = {
bytes : int('off),
len : int('len),
}Whether an offset/length pair is contained by the shared EVM-memory arena.
type memory_region_valid_range('off : Int, 'len : Int) -> Bool =
0 <= 'off & 0 <= 'len & 'off + 'len <= memory_region_boundtype CodeRegionSliceFields¶
A range in the content-addressed executable-code arena.
struct CodeRegionSliceFields('off : Int, 'len : Int), code_region_valid_range('off, 'len) = {
bytes : int('off),
len : int('len),
}Whether an offset/length pair is contained by the executable-code arena.
type code_region_valid_range('off : Int, 'len : Int) -> Bool =
0 <= 'off & 0 <= 'len & 'off + 'len <= code_region_boundtype CodeRegionSlice¶
A code-region range with its coordinate and length packed existentially.
type CodeRegionSlice = {
'off 'len,
code_region_valid_range('off, 'len).
CodeRegionSliceFields('off, 'len)
}A range in the content-addressed executable-code arena.
struct CodeRegionSliceFields('off : Int, 'len : Int), code_region_valid_range('off, 'len) = {
bytes : int('off),
len : int('len),
}Whether an offset/length pair is contained by the executable-code arena.
type code_region_valid_range('off : Int, 'len : Int) -> Bool =
0 <= 'off & 0 <= 'len & 'off + 'len <= code_region_boundtype LogDataSliceFields¶
A range in the transaction-log data arena.
struct LogDataSliceFields('off : Int, 'len : Int), log_data_valid_range('off, 'len) = {
bytes : int('off),
len : int('len),
}Whether an offset/length pair is contained by retained log-data storage.
type log_data_valid_range('off : Int, 'len : Int) -> Bool =
0 <= 'off & 0 <= 'len & 'off + 'len <= log_data_region_boundtype LogDataSlice¶
A log-data range with its coordinate and length packed existentially.
type LogDataSlice = {
'off 'len,
log_data_valid_range('off, 'len).
LogDataSliceFields('off, 'len)
}A range in the transaction-log data arena.
struct LogDataSliceFields('off : Int, 'len : Int), log_data_valid_range('off, 'len) = {
bytes : int('off),
len : int('len),
}Whether an offset/length pair is contained by retained log-data storage.
type log_data_valid_range('off : Int, 'len : Int) -> Bool =
0 <= 'off & 0 <= 'len & 'off + 'len <= log_data_region_boundtype LogDataSliceLength¶
A log-data range of exactly 'required bytes.
type LogDataSliceLength('required : Int) = {
'off,
log_data_valid_range('off, 'required).
LogDataSliceFields('off, 'required)
}A range in the transaction-log data arena.
struct LogDataSliceFields('off : Int, 'len : Int), log_data_valid_range('off, 'len) = {
bytes : int('off),
len : int('len),
}Whether an offset/length pair is contained by retained log-data storage.
type log_data_valid_range('off : Int, 'len : Int) -> Bool =
0 <= 'off & 0 <= 'len & 'off + 'len <= log_data_region_boundtype OutputSliceFields¶
A range in the frame-output buffer.
struct OutputSliceFields('off : Int, 'len : Int), output_region_valid_range('off, 'len) = {
bytes : int('off),
len : int('len),
}Whether an offset/length pair is contained by the guest output region.
type output_region_valid_range('off : Int, 'len : Int) -> Bool =
0 <= 'off & 0 <= 'len & 'off + 'len <= output_region_boundtype OutputSlice¶
A frame-output range with its coordinate and length packed existentially.
type OutputSlice = {
'off 'len,
output_region_valid_range('off, 'len).
OutputSliceFields('off, 'len)
}A range in the frame-output buffer.
struct OutputSliceFields('off : Int, 'len : Int), output_region_valid_range('off, 'len) = {
bytes : int('off),
len : int('len),
}Whether an offset/length pair is contained by the guest output region.
type output_region_valid_range('off : Int, 'len : Int) -> Bool =
0 <= 'off & 0 <= 'len & 'off + 'len <= output_region_boundtype CalldataSlice¶
Calldata is either the immutable top-level transaction input or a frozen range of the suspended caller's memory. The variants state the only two protocol-valid provenances instead of exposing the host's region enum.
union CalldataSlice = {
/* the immutable top-level transaction input */
InputCalldata : StatelessInputSlice,
/* a frozen range of the suspended caller's memory */
MemoryCalldata : EvmMemorySlice,
}An EVM-memory range with its coordinate and length packed existentially.
type EvmMemorySlice = {
'off 'len,
memory_region_valid_range('off, 'len).
EvmMemorySliceFields('off, 'len)
}A stateless-input range with its coordinate and length packed existentially.
type StatelessInputSlice = {
'off 'len,
stateless_input_valid_range('off, 'len).
StatelessInputSliceFields('off, 'len)
}function calldata_slice_length¶
The byte length of a calldata slice, independent of its provenance.
function calldata_slice_length(s : CalldataSlice) -> source_length =
match s {
InputCalldata(bytes) => bytes.len,
MemoryCalldata(bytes) => bytes.len,
}Calldata is either the immutable top-level transaction input or a frozen range of the suspended caller's memory. The variants state the only two protocol-valid provenances instead of exposing the host's region enum.
union CalldataSlice = {
/* the immutable top-level transaction input */
InputCalldata : StatelessInputSlice,
/* a frozen range of the suspended caller's memory */
MemoryCalldata : EvmMemorySlice,
}A byte length or regular-layout count derived from a source region.
type source_length = range(0, default_host_region_bound)function stateless_input_slice_length¶
The byte length of a stateless-input slice.
function stateless_input_slice_length(s : StatelessInputSlice) -> source_length =
s.lenA stateless-input range with its coordinate and length packed existentially.
type StatelessInputSlice = {
'off 'len,
stateless_input_valid_range('off, 'len).
StatelessInputSliceFields('off, 'len)
}A byte length or regular-layout count derived from a source region.
type source_length = range(0, default_host_region_bound)let ADDRESS_BYTE_LENGTH¶
let ADDRESS_BYTE_LENGTH : int(20) = 20let WORD_BYTE_LENGTH¶
let WORD_BYTE_LENGTH : int(32) = 32let EIGHT_BYTE_LENGTH¶
let EIGHT_BYTE_LENGTH : int(8) = 8let DOUBLE_WORD_BYTE_LENGTH¶
let DOUBLE_WORD_BYTE_LENGTH : int(64) = 64function stateless_input_slice¶
function stateless_input_slice(off, len) =
struct { bytes = off, len = len }function stateless_input_slice(off, len) =
struct { bytes = off, len = len }function scratch_slice¶
function scratch_slice(off, len) =
struct { bytes = off, len = len }function scratch_slice(off, len) =
struct { bytes = off, len = len }function evm_memory_slice¶
function evm_memory_slice(off, len) =
struct { bytes = off, len = len }function evm_memory_slice(off, len) =
struct { bytes = off, len = len }function code_region_slice¶
function code_region_slice(off, len) =
struct { bytes = off, len = len }function code_region_slice(off, len) =
struct { bytes = off, len = len }function log_data_slice¶
function log_data_slice(off, len) =
struct { bytes = off, len = len }function log_data_slice(off, len) =
struct { bytes = off, len = len }function output_slice¶
function output_slice(off, len) =
struct { bytes = off, len = len }function output_slice(off, len) =
struct { bytes = off, len = len }let EMPTY_STATELESS_INPUT_SLICE¶
let EMPTY_STATELESS_INPUT_SLICE : StatelessInputSliceFields(0, 0) = stateless_input_slice(0, 0)function stateless_input_slice(off, len) =
struct { bytes = off, len = len }A range in the immutable stateless-input envelope. Its source is carried by the nominal type rather than a runtime field.
struct StatelessInputSliceFields('off : Int, 'len : Int), stateless_input_valid_range('off, 'len) = {
bytes : int('off),
len : int('len),
}let EMPTY_SCRATCH_SLICE¶
let EMPTY_SCRATCH_SLICE : ScratchSliceFields(0, 0) = scratch_slice(0, 0)function scratch_slice(off, len) =
struct { bytes = off, len = len }A range in the executor's reusable scratch arena. Its source is carried by the nominal type rather than a runtime field.
struct ScratchSliceFields('off : Int, 'len : Int), scratch_valid_range('off, 'len) = {
bytes : int('off),
len : int('len),
}let EMPTY_EVM_MEMORY_SLICE¶
let EMPTY_EVM_MEMORY_SLICE : EvmMemorySliceFields(0, 0) = evm_memory_slice(0, 0)function evm_memory_slice(off, len) =
struct { bytes = off, len = len }A borrowed range in the shared EVM-memory arena. Its coordinate is absolute
within the arena (an offset in the standard ABI and a stable pointer in the
optimized ABI), so calldata borrowed from a suspended parent remains valid
while a child frame is active. The machine carries only memory_height;
this pointer-bearing value exists at derived-view boundaries.
struct EvmMemorySliceFields('off : Int, 'len : Int), memory_region_valid_range('off, 'len) = {
bytes : int('off),
len : int('len),
}let EMPTY_CODE_REGION_SLICE¶
let EMPTY_CODE_REGION_SLICE : CodeRegionSliceFields(0, 0) = code_region_slice(0, 0)function code_region_slice(off, len) =
struct { bytes = off, len = len }A range in the content-addressed executable-code arena.
struct CodeRegionSliceFields('off : Int, 'len : Int), code_region_valid_range('off, 'len) = {
bytes : int('off),
len : int('len),
}let EMPTY_LOG_DATA_SLICE¶
let EMPTY_LOG_DATA_SLICE : LogDataSliceFields(0, 0) = log_data_slice(0, 0)function log_data_slice(off, len) =
struct { bytes = off, len = len }A range in the transaction-log data arena.
struct LogDataSliceFields('off : Int, 'len : Int), log_data_valid_range('off, 'len) = {
bytes : int('off),
len : int('len),
}let EMPTY_OUTPUT_SLICE¶
let EMPTY_OUTPUT_SLICE : OutputSliceFields(0, 0) = output_slice(0, 0)function output_slice(off, len) =
struct { bytes = off, len = len }A range in the frame-output buffer.
struct OutputSliceFields('off : Int, 'len : Int), output_region_valid_range('off, 'len) = {
bytes : int('off),
len : int('len),
}let EMPTY_CALLDATA¶
let EMPTY_CALLDATA : CalldataSlice = InputCalldata(EMPTY_STATELESS_INPUT_SLICE)let EMPTY_STATELESS_INPUT_SLICE : StatelessInputSliceFields(0, 0) = stateless_input_slice(0, 0)Calldata is either the immutable top-level transaction input or a frozen range of the suspended caller's memory. The variants state the only two protocol-valid provenances instead of exposing the host's region enum.
union CalldataSlice = {
/* the immutable top-level transaction input */
InputCalldata : StatelessInputSlice,
/* a frozen range of the suspended caller's memory */
MemoryCalldata : EvmMemorySlice,
}function stateless_input_sub_slice¶
function stateless_input_sub_slice(s, off, len) =
struct { bytes = s.bytes + off, len = len }function stateless_input_sub_slice(s, off, len) =
struct { bytes = s.bytes + off, len = len }function scratch_sub_slice¶
function scratch_sub_slice(s, off, len) =
struct { bytes = s.bytes + off, len = len }function scratch_sub_slice(s, off, len) =
struct { bytes = s.bytes + off, len = len }function memory_sub_slice¶
function memory_sub_slice(s, off, len) =
struct { bytes = s.bytes + off, len = len }function memory_sub_slice(s, off, len) =
struct { bytes = s.bytes + off, len = len }function log_data_sub_slice¶
function log_data_sub_slice(s, off, len) =
struct { bytes = s.bytes + off, len = len }function log_data_sub_slice(s, off, len) =
struct { bytes = s.bytes + off, len = len }function calldata_sub_slice¶
function calldata_sub_slice(s, off, len) = {
match s {
InputCalldata(bytes) => if off + len <= bytes.len then {
let subslice = stateless_input_sub_slice(bytes, off, len);
InputCalldata(subslice)
} else {
assert(false, "calldata sub-slice bounds");
EMPTY_CALLDATA
},
MemoryCalldata(bytes) => if off + len <= bytes.len then {
let subslice = memory_sub_slice(bytes, off, len);
MemoryCalldata(subslice)
} else {
assert(false, "calldata sub-slice bounds");
EMPTY_CALLDATA
},
}
}function calldata_sub_slice(s, off, len) = {
match s {
InputCalldata(bytes) => if off + len <= bytes.len then {
let subslice = stateless_input_sub_slice(bytes, off, len);
InputCalldata(subslice)
} else {
assert(false, "calldata sub-slice bounds");
EMPTY_CALLDATA
},
MemoryCalldata(bytes) => if off + len <= bytes.len then {
let subslice = memory_sub_slice(bytes, off, len);
MemoryCalldata(subslice)
} else {
assert(false, "calldata sub-slice bounds");
EMPTY_CALLDATA
},
}
}function memory_sub_slice(s, off, len) =
struct { bytes = s.bytes + off, len = len }function stateless_input_sub_slice(s, off, len) =
struct { bytes = s.bytes + off, len = len }let EMPTY_CALLDATA : CalldataSlice = InputCalldata(EMPTY_STATELESS_INPUT_SLICE)Calldata is either the immutable top-level transaction input or a frozen range of the suspended caller's memory. The variants state the only two protocol-valid provenances instead of exposing the host's region enum.
union CalldataSlice = {
/* the immutable top-level transaction input */
InputCalldata : StatelessInputSlice,
/* a frozen range of the suspended caller's memory */
MemoryCalldata : EvmMemorySlice,
}function stateless_input_slice_suffix¶
function stateless_input_slice_suffix(s, off) =
struct { bytes = s.bytes + off, len = s.len - off }function stateless_input_slice_suffix(s, off) =
struct { bytes = s.bytes + off, len = s.len - off }function scratch_slice_suffix¶
function scratch_slice_suffix(s, off) =
struct { bytes = s.bytes + off, len = s.len - off }function scratch_slice_suffix(s, off) =
struct { bytes = s.bytes + off, len = s.len - off }type LogData¶
A log payload retained by the host: either an existing byte slice or the canonical big-endian bytes of one EVM word used by system logs.
union LogData = {
/* an EVM-memory payload copied into retained log storage */
LogDataMemory : EvmMemorySlice,
/* the canonical big-endian bytes of one EVM word */
LogDataWord : word,
}An EVM-memory range with its coordinate and length packed existentially.
type EvmMemorySlice = {
'off 'len,
memory_region_valid_range('off, 'len).
EvmMemorySliceFields('off, 'len)
}The EVM 256-bit machine word (YP ยง9.1). A transparent range keeps the mathematical subtype relation visible: narrower non-negative ranges can be passed as words without a model-level conversion.
type word = range(0, 2 ^ 256 - 1)