VSL - The prelude.cabi.record Structure
# Copyright 2011 Petter Urkedal
#
# This file is part of the Viz Standard Library <http://www.vizlang.org/>.
#
# The Viz Standard Library (VSL) is free software: you can redistribute it
# and/or modify it under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation, either version 3 of the License,
# or (at your option) any later version.
#
# The VSL is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
# more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with the VSL. If not, see <http://www.gnu.org/licenses/>.
open ubiquitous
open field_allocation
open record_sigs
open phantoms
open effect
sealed with
include a_record_architecture
type alignment := int
type offset := int
val record_size : is_record δ → offset
val record_alignment : is_record δ → offset
val field_offset : has_field δ δ' → offset
val elements_offset : has_elements σ δ → offset
val unsafe_conjecture_etype : int → is_record δ
val unsafe_conjecture_field : is_record ε → offset → has_field δ ε
in int8_t include a_foreign_type.[t = int]
in uint8_t include a_foreign_type.[t = int]
in int16_t include a_foreign_type.[t = int]
in uint16_t include a_foreign_type.[t = int]
in int32_t include a_foreign_type.[t = int32]
in uint32_t include a_foreign_type.[t = nat32]
in int64_t include a_foreign_type.[t = int64]
in uint64_t include a_foreign_type.[t = nat64]
in sshort include a_foreign_type.[t = nint]
in ushort include a_foreign_type.[t = nnat]
in sint include a_foreign_type.[t = nint]
in uint include a_foreign_type.[t = nnat]
in slong include a_foreign_type.[t = nint]
in ulong include a_foreign_type.[t = nnat]
in ptrdiff_t include a_foreign_type.[t = nint]
in size_t include a_foreign_type.[t = nnat]
in intptr_t include a_foreign_type.[t = nint]
in uintptr_t include a_foreign_type.[t = nnat]
type alignment := int
type offset := int
in offset include int
# 0.0. Internal Helpers
let unbounded be -1
## The value used in place of the array size for spill-arrays.
in alignment
include int
let none be zero
let is_none be eq zero
let align al' off
let al be offset.of_int al'
let 2'+ , 2'- be offset.add, offset.sub
be offset.bitand (off + al - offset.one) (offset.bitnot (al - offset.one))
# 0.0. Propositions
type is_record δ inj record_sc : alignment → offset → is_record δ
type has_field δ ε inj field_sc : offset → has_field δ ε
type has_components δ ε inj components_sc : int → offset → has_components δ ε
type has_elements σ ε inj elements_sc : offset → offset → has_elements σ ε
let unsafe_conjecture_etype s be record_sc (offset.as_int s) s
let record_size (record_sc al sz) be sz
let record_alignment (record_sc al sz) be al
let field_offset (field_sc off) be off
let elements_offset (elements_sc off sz) be off
let unsafe_conjecture_field d off be field_sc off
# 0.0. Axioms
let field_is_transitive (field_sc offA) (field_sc offB)
be field_sc (offset.add offA offB)
let components_are_elements (components_sc n sz)
be elements_sc offset.zero sz
let record_ptr_ev r be unsafe_conjecture_etype memory.sizeof_ptr
let record_value_ev r be unsafe_conjecture_etype memory.sizeof_ptr
let forward_ptr_ev r be unsafe_conjecture_etype memory.sizeof_ptr
let forward_value_ev r be unsafe_conjecture_etype memory.sizeof_ptr
let unit_ev be record_sc alignment.one offset.zero
let value_ev be unsafe_conjecture_etype memory.sizeof_ptr
let int_ev be unsafe_conjecture_etype memory.sizeof_clong
let nint_ev be unsafe_conjecture_etype memory.sizeof_clong
# Compounds
let array_ev n (record_sc alE szE)
be (record_sc alE (offset.mul (offset.of_int n) szE), components_sc n szE)
let spill_ev (record_sc alM szM) (record_sc alS szS)
be (field_sc offset.zero, elements_sc (align alS szM) szS)
let spill_ptr_ev _ _ be unsafe_conjecture_etype memory.sizeof_ptr
sig a_fabric
type ph := unit
val ptr_ev : is_record (ptr_ph ph)
val value_ev : is_record (value_ph ph)
val acquire : is_record δ → io (has_field ph δ)
val realize : io (is_record ph)
in! make_fabric.(A : a_field_allocator.[alignment = alignment]
.[offset = offset])
let _state do ref.init (A.empty, false)
let ptr_ev be record_ptr_ev ()
let value_ev be record_value_ev ()
let! acquire (record_sc al sz)
let (state, complete) do ref.get _state
if complete fail "Attempt to extend a realized record."
let (offset, state') be A.alloc al sz state
do ref.set _state (state', false)
be field_sc offset
let! realize
let (state, complete) do ref.get _state
if complete fail "Attempt to realize a record multiple times."
do ref.set _state (state, true)
be record_sc (A.alignment state) (A.size state)
in! fabric
type ph := unit
include! make_fabric.(monotonic_field_allocator.(int))
# 0.0. Lens
in lens
# Should be abstract, but value restriction kicks in below.
type R Ψ δ := unit
type r ψ δ := R (hot ψ) δ
type t δ := R cold δ
val:cs cmp : R Ψ δ → R Ψ' δ → torder := "vsls_lens_cmp"
val:cs _focus : offset → R Ψ δ → R Ψ δ' := "vsls_lens_focus"
let focus_field (field_sc off) p be _focus off p
let focus_component (components_sc _ sz) n p
be _focus (offset.mul sz (offset.of_int n)) p
let focus_element (elements_sc off sz) n p
be _focus (offset.add off (offset.mul sz (offset.of_int n))) p
let unsafe_defocus_field (field_sc off) p be _focus (offset.neg off) p
val:cs get_ptr : t (ptr_ph δ) → t δ := "vsls_lens_load_ptr"
val:cs load_ptr : r ψ (ptr_ph δ) → effect ψ (r ψ δ) := "vsls_lens_load_ptr"
val:cs store_ptr : r ψ δ → r ψ (ptr_ph δ) → effect ψ unit
:= "vsls_lens_store_ptr"
val:cs get_value : t (value_ph α) → α := "vsls_lens_load_value"
val:cs load_value : r ψ (value_ph α) → effect ψ α := "vsls_lens_load_value"
val:cs store_value : α → r ψ (value_ph α) → effect ψ unit
:= "vsls_lens_store_value"
val:cs unsafe_get_null : unit → R Ψ δ := "vsls_lens_get_null"
let unsafe_null be unsafe_get_null ()
val:cs unsafe_cast : R Ψ δ → R Ψ δ' := "%identity"
val:cs unsafe_freeze : R Ψ δ → t δ := "%identity"
val:cs unsafe_thaw : R Ψ δ → r ψ δ := "%identity"
# 0.0. Primitive Type Conversions
sig a_foreign_type
type ph
type t
val ev : is_record ph
val get : lens.t ph → t
val load : lens.r ψ ph → effect ψ t
val store : t → lens.r ψ ph → effect ψ unit
# 0.0. Construction and Inspection
in record
# Should be abstract, but value restriction kicks in below.
type R Ψ δ := unit
type r ψ δ := R (hot ψ) δ
type t δ := R cold δ
val:cs prim_alloc : offset → effect ψ (R Ψ δ) := "vsls_record_alloc"
val:cs prim_alloc_finalized :
offset → (r ψ δ → unit) → effect ψ (r ψ δ) :=
"vsls_record_alloc_finalized"
val:cs focus : R Ψ δ → lens.R Ψ δ := "vsls_record_focus"
let alloc (record_sc al sz) be prim_alloc sz
let alloc_finalized (record_sc al sz) f
be prim_alloc_finalized sz (__builtin_effect_run ∘ f)
let init (record_sc al sz) (f : ∀ψ. lens.r ψ δ → effect ψ α)
be observe (that : ∀ψ. effect ψ (α × R Ψ δ)) which!
let p do prim_alloc sz
let x do f (focus p)
be (x, p)
let! alloc_spilled (record_sc al sz) n (record_sc alE szE)
let offE be align alE sz
do prim_alloc (offset.add offE (offset.mul (offset.of_int n) szE))
let init_spilled (record_sc al sz) n (record_sc alE szE)
(f : ∀ψ. lens.r ψ (spill_ph δ ε) → effect ψ α)
be observe (that : ∀ψ. effect ψ (α × R Ψ δ)) which!
let offE be align alE sz
let p do prim_alloc (offset.add offE (offset.mul (offset.of_int n) szE))
let x do f (focus p)
be (x, p)
# 0.0.0. Generic Types
in int8_t
type ph inj _int8_ph
type t := int
let ev be unsafe_conjecture_etype (offset.of_int 1)
val:cs get : lens.t ph → t := "vsls_int8_t_load_int"
val:cs load : lens.r ψ ph → effect ψ t := "vsls_int8_t_load_int"
val:cs store : t → lens.r ψ ph → effect ψ unit := "vsls_int8_t_store_int"
in uint8_t
type ph inj _nat8_ph
type t := int
let ev be unsafe_conjecture_etype (offset.of_int 1)
val:cs get : lens.t ph → t := "vsls_uint8_t_load_int"
val:cs load : lens.r ψ ph → effect ψ t := "vsls_uint8_t_load_int"
val:cs store : t → lens.r ψ ph → effect ψ unit := "vsls_uint8_t_store_int"
in int16_t
type ph inj _int16_ph
type t := int
let ev be unsafe_conjecture_etype (offset.of_int 2)
val:cs get : lens.t ph → t := "vsls_int16_t_load_int"
val:cs load : lens.r ψ ph → effect ψ t := "vsls_int16_t_load_int"
val:cs store : t → lens.r ψ ph → effect ψ unit := "vsls_int16_t_store_int"
in uint16_t
type ph inj _nat16_ph
type t := int
let ev be unsafe_conjecture_etype (offset.of_int 2)
val:cs get : lens.t ph → t := "vsls_uint16_t_load_int"
val:cs load : lens.r ψ ph → effect ψ t := "vsls_uint16_t_load_int"
val:cs store : t → lens.r ψ ph → effect ψ unit := "vsls_uint16_t_store_int"
in int32_t
type ph inj _int32_ph
type t := int32
let ev be unsafe_conjecture_etype (offset.of_int 4)
val:cs get : lens.t ph → t := "vsls_xint32_t_load_int32"
val:cs load : lens.r ψ ph → effect ψ t := "vsls_xint32_t_load_int32"
val:cs store : t → lens.r ψ ph → effect ψ unit := "vsls_xint32_t_store_int32"
in uint32_t
type ph inj _nat32_ph
type t := nat32
let ev be unsafe_conjecture_etype (offset.of_int 4)
val:cs get : lens.t ph → t := "vsls_xint32_t_load_int32"
val:cs load : lens.r ψ ph → effect ψ t := "vsls_xint32_t_load_int32"
val:cs store : t → lens.r ψ ph → effect ψ unit := "vsls_xint32_t_store_int32"
in int64_t
type ph inj _int64_ph
type t := int64
let ev be unsafe_conjecture_etype (offset.of_int 8)
val:cs get : lens.t ph → int64 := "vsls_xint64_t_load_int64"
val:cs load : lens.r ψ ph → effect ψ int64 := "vsls_xint64_t_load_int64"
val:cs store : t → lens.r ψ ph → effect ψ unit := "vsls_xint64_t_store_int64"
in uint64_t
type ph inj _nat64_ph
type t := nat64
let ev be unsafe_conjecture_etype (offset.of_int 8)
val:cs get : lens.t ph → t := "vsls_xint64_t_load_int64"
val:cs load : lens.r ψ ph → effect ψ t := "vsls_xint64_t_load_int64"
val:cs store : t → lens.r ψ ph → effect ψ unit := "vsls_xint64_t_store_int64"
# 0.0.0. C-Specific Types
in sshort
type ph inj _sshort_ph
type t := nint
let ev be unsafe_conjecture_etype (offset.of_int memory.sizeof_cshort)
val:cs get : lens.t ph → t := "vsls_sshort_load_nint"
val:cs load : lens.r ψ ph → effect ψ t := "vsls_sshort_load_nint"
val:cs store : t → lens.r ψ ph → effect ψ unit := "vsls_sshort_store_nint"
in ushort
type ph inj _ushort_ph
type t := nnat
let ev be unsafe_conjecture_etype (offset.of_int memory.sizeof_cshort)
val:cs get : lens.t ph → t := "vsls_ushort_load_nnat"
val:cs load : lens.r ψ ph → effect ψ t := "vsls_ushort_load_nnat"
val:cs store : t → lens.r ψ ph → effect ψ unit := "vsls_ushort_store_nnat"
in sint
type ph inj _sint_ph
type t := nint
let ev be unsafe_conjecture_etype (offset.of_int memory.sizeof_cint)
val:cs get : lens.t ph → t := "vsls_sint_load_nint"
val:cs load : lens.r ψ ph → effect ψ t := "vsls_sint_load_nint"
val:cs store : t → lens.r ψ ph → effect ψ unit := "vsls_sint_store_nint"
in uint
type ph inj _uint_ph
type t := nnat
let ev be unsafe_conjecture_etype (offset.of_int memory.sizeof_cint)
val:cs get : lens.t ph → t := "vsls_uint_load_nnat"
val:cs load : lens.r ψ ph → effect ψ t := "vsls_uint_load_nnat"
val:cs store : t → lens.r ψ ph → effect ψ unit := "vsls_uint_store_nnat"
in slong
type ph inj _slong_ph
type t := nint
let ev be unsafe_conjecture_etype (offset.of_int memory.sizeof_clong)
val:cs get : lens.t ph → t := "vsls_slong_load_nint"
val:cs load : lens.r ψ ph → effect ψ t := "vsls_slong_load_nint"
val:cs store : t → lens.r ψ ph → effect ψ unit := "vsls_slong_store_nint"
in ulong
type ph inj _ulong_ph
type t := nnat
let ev be unsafe_conjecture_etype (offset.of_int memory.sizeof_clong)
val:cs get : lens.t ph → t := "vsls_ulong_load_nnat"
val:cs load : lens.r ψ ph → effect ψ t := "vsls_ulong_load_nnat"
val:cs store : t → lens.r ψ ph → effect ψ unit := "vsls_ulong_store_nnat"
{#
in slonglong
type ph inj _slonglong_ph
type t := nint
let ev be unsafe_conjecture_etype (offset.of_int memory.sizeof_clonglong)
val:cs get : lens.t ph → t := "vsls_slonglong_load_nint"
val:cs load : lens.r ψ ph → effect ψ t := "vsls_slonglong_load_nint"
val:cs store : t → lens.r ψ ph → effect ψ unit := "vsls_slonglong_store_nint"
in ulonglong
type ph inj _ulonglong_ph
type t := nint
let ev be unsafe_conjecture_etype (offset.of_int memory.sizeof_clonglong)
val:cs get : lens.t ph → t := "vsls_ulonglong_load_nint"
val:cs load : lens.r ψ ph → effect ψ t := "vsls_ulonglong_load_nint"
val:cs store : t → lens.r ψ ph → effect ψ unit := "vsls_ulonglong_store_nint"
#}
in ptrdiff_t
type ph inj _ptrdiff_t_ph
type t := nint
let ev be unsafe_conjecture_etype (offset.of_int memory.sizeof_ptrdiff_t)
val:cs get : lens.t ph → t := "vsls_ptrdiff_t_load_nint"
val:cs load : lens.r ψ ph → effect ψ t := "vsls_ptrdiff_t_load_nint"
val:cs store : t → lens.r ψ ph → effect ψ unit := "vsls_ptrdiff_t_store_nint"
in size_t
type ph inj _size_t_ph
type t := nnat
let ev be unsafe_conjecture_etype (offset.of_int memory.sizeof_size_t)
val:cs get : lens.t ph → t := "vsls_size_t_load_nnat"
val:cs load : lens.r ψ ph → effect ψ t := "vsls_size_t_load_nnat"
val:cs store : t → lens.r ψ ph → effect ψ unit := "vsls_size_t_store_nnat"
in intptr_t
type ph inj _sintptr_ph
type t := nint
let ev be unsafe_conjecture_etype (offset.of_int memory.sizeof_cintptr)
val:cs get : lens.t ph → t := "vsls_intptr_t_load_nint"
val:cs load : lens.r ψ ph → effect ψ t := "vsls_intptr_t_load_nint"
val:cs store : t → lens.r ψ ph → effect ψ unit := "vsls_intptr_t_store_nint"
in uintptr_t
type ph inj _uintptr_ph
type t := nnat
let ev be unsafe_conjecture_etype (offset.of_int memory.sizeof_cintptr)
val:cs get : lens.t ph → t := "vsls_uintptr_t_load_nnat"
val:cs load : lens.r ψ ph → effect ψ t := "vsls_uintptr_t_load_nnat"
val:cs store : t → lens.r ψ ph → effect ψ unit := "vsls_uintptr_t_store_nnat"
{#
in sintmax
type ph inj _sintmax_ph
type t := nint
let ev be unsafe_conjecture_etype (offset.of_int memory.sizeof_cintmax)
val:cs get : lens.t ph → t := "vsls_sintmax_load_nint"
val:cs load : lens.r ψ ph → effect ψ t := "vsls_sintmax_load_nint"
val:cs store : t → lens.r ψ ph → effect ψ unit := "vsls_sintmax_store_nint"
in uintmax
type ph inj _uintmax_ph
type t := nint
let ev be unsafe_conjecture_etype (offset.of_int memory.sizeof_cintmax)
val:cs get : lens.t ph → t := "vsls_uintmax_load_nint"
val:cs load : lens.r ψ ph → effect ψ t := "vsls_uintmax_load_nint"
val:cs store : t → lens.r ψ ph → effect ψ unit := "vsls_uintmax_store_nint"
#}