Module Ocaml_typing.Scalar
This module defines: The scalar types intrinsic to the OCaml compiler, and all of the primitive operations defined on them.
Overview: This module provides a comprehensive type system for scalar values in OCaml.
Type Hierarchy:
- Scalar.t
- Integral: Integer types
- Taggable (fits in word_size-1 bits): Int8, Int16, Int
- Boxable (requires boxing): Int32, Int64, Nativeint
- Floating: Float32, Float64
Representation Forms:
- Value: Tagged (small integers) or boxed representation
- Naked: Untagged (<=31 bits) or unboxed (>31 bits) representation
Operations:
- Unary: Negation, successor/predecessor, byte swap, static cast
- Binary: Arithmetic (add, sub, mul, div), bitwise (and, or, xor), shift (lsl, asr, lsr), comparisons (integer and float)
The locality parameter tracks where boxed values are allocated.
A Scalar.t represents a particular OCaml type that represents a scalar value. It might be tagged, boxed, or neither. There is also a type parameter for the locality of the scalar value, which represents the location in which that boxed values are allocated.
The important consideration is for a Scalar.t to represent all of the argument and return types of all the primitives that we want to support. The submodules are organized to make it easy for use different subsets of scalars in different places. Some examples:
- Primitive arguments don't depend on the locality of their arguments, but the results do. This is achieved using
ignore_locality : _ t -> any_locality_mode tto convert arguments toany_locality_modewhen defining primitives, e.g.:Icmp (Scalar.Integral.ignore_locality size, cmp)
- Some primitives only take integers, some take only floats, and Three_way_compare takes any scalar type. This is represented using specialized operation types:
Intrinsic.Binary.Int_op.tfor integer-only ops (Add, Sub, Mul, etc.)Intrinsic.Binary.Float_op.tfor float-only opsIntrinsic.Binary.Three_way_compare of any_locality_mode taccepts any scalar
- The bytecode compiler wants to easily map unboxed/untagged values to their
valueequivalents. This is supported byMaybe_naked.t: Value of 'arepresents boxed/tagged valuesNaked of 'brepresents unboxed/untagged values Example:Scalar.Maybe_naked.Value (Integral.Width.Taggable Int)vsScalar.Maybe_naked.Naked (Integral.Width.Taggable Int)
- The middle-end wants to easily cast between any integral values using only certain primitives. This is enabled by
Intrinsic.Unary.Static_cast:Static_cast { src : any_locality_mode t; dst : 'mode t }which allows casting between different scalar types, e.g., from Int8 to Int32. See jane/doc/scalars.md for documentation on the semantics.
In some cases, only the number of bits used in the container (e.g. a machine register or stack slot) is important. We use Width for this. Width.t always represents the width of a scalar layout -- it has exactly one constuctor for each bit-width of the corresponding scalar. The type parameter is irrelevant within the Width module, that's why it's usually fixed to any_locality_mode when the corresponding function is expecting a simple sum type (e.g., to_string).
val equal_any_locality_mode :
Ocaml_typing.Scalar.any_locality_mode ->
Ocaml_typing.Scalar.any_locality_mode ->
boolmodule Maybe_naked : sig ... endval naked : 'a -> (_, 'a) Ocaml_typing.Scalar.Maybe_naked.tmodule type S := sig ... endmodule Integral : sig ... endmodule Floating : sig ... endmodule Width : sig ... endinclude Ocaml_typing.Scalar.S
with type 'a width := 'a Ocaml_typing.Scalar.Width.t
val all : Ocaml_typing.Scalar.any_locality_mode Ocaml_typing.Scalar.t listval map : 'a Ocaml_typing.Scalar.t -> f:('a -> 'b) -> 'b Ocaml_typing.Scalar.tval ignore_locality :
_ Ocaml_typing.Scalar.t ->
Ocaml_typing.Scalar.any_locality_mode Ocaml_typing.Scalar.tval to_string :
Ocaml_typing.Scalar.any_locality_mode Ocaml_typing.Scalar.t ->
stringval equal :
('a -> 'b -> bool) ->
'a Ocaml_typing.Scalar.t ->
'b Ocaml_typing.Scalar.t ->
boolval integral : 'a Ocaml_typing.Scalar.Integral.t -> 'a Ocaml_typing.Scalar.tval floating : 'a Ocaml_typing.Scalar.Floating.t -> 'a Ocaml_typing.Scalar.tmodule Signedness : sig ... endmodule Integer_comparison : sig ... endmodule Float_comparison : sig ... endtype 'a scalar := 'a Ocaml_typing.Scalar.tmodule Operation : sig ... end