StaticTools

Documentation for StaticTools.

Bumper.AllocBufferImpl.AllocBufferType
AllocBuffer(::Type{MallocVector}, n::Int=1048576)

Create an AllocBuffer backed by a MallocArray. This buffer should be manually free once you're done with it.

source
StaticTools.MallocArrayType
MallocArray{T,N} <: DenseArray{T,N} <: AbstractArray{T,N}

N-dimensional dense heap-allocated array with elements of type T.

Much like Base.Array, except (1) backed by memory that is not tracked by the Julia garbage collector (is directly allocated with malloc) so is StaticCompiler-safe, (2) should be freed when no longer in use, and (3) contiguous slice indexing returns ArrayViews rather than copies.

Indexing a MallocArray out of bounds does not throw a BoundsError; much as if @inbounds were enabled, indexing a MallocArray incurs a strict promise by the programmer that the specified index is inbounds. Breaking this promise will result in segfaults or memory corruption.

source
StaticTools.MallocArrayMethod
MallocArray(data::AbstractArray{T,N})

Construct a MallocArray of eltype T from an existing AbstractArray.

Examples

julia> a = szeros(Int, 5,5)
5×5 StackMatrix{Int64, 25, (5, 5)}:
 0  0  0  0  0
 0  0  0  0  0
 0  0  0  0  0
 0  0  0  0  0
 0  0  0  0  0

julia> MallocArray(a)
5×5 MallocMatrix{Int64}:
 0  0  0  0  0
 0  0  0  0  0
 0  0  0  0  0
 0  0  0  0  0
 0  0  0  0  0
source
StaticTools.MallocArrayMethod
MallocArray(T, dims) do A
    ...
end
MallocArray{T}(undef, dims)
MallocArray{T,N}(undef, dims)
MallocArray{T}(zeros, dims)
MallocArray{T,N}(zeros, dims)

Construct an uninitialized (undef) or zero-initialized (zeros) N-dimensional MallocArray containing elements of type T. N can either be supplied explicitly, as in Array{T,N}(undef, dims), or be determined by the length or number of dims. dims may be a tuple or a series of integer arguments corresponding to the lengths in each dimension. If the rank N is supplied explicitly, then it must match the length or number of dims.

Here undef is the UndefInitializer and signals that malloc should be used to obtain the underlying memory, while zeros is the Base function zeros and flags that calloc should be used to obtain and zero-initialize the underlying memory.

Attempting to create a MallocArray with dimensions larger than can be successfully allocated will return an empty MallocArray with size 0 in all dimensions and pointer null.

Examples

julia> A = MallocArray{Float64}(undef, 3,3) # implicit N
3×3 MallocMatrix{Float64}:
 3.10504e231   6.95015e-310   2.12358e-314
 1.73061e-77   6.95015e-310   5.56271e-309
 6.95015e-310  0.0           -1.29074e-231

julia> free(A)
0

julia> A = MallocArray{Float64, 3}(zeros, 2,2,2) # explicit N, zero initialize
2×2×2 MallocArray{Float64, 3}:
[:, :, 1] =
 0.0  0.0
 0.0  0.0

[:, :, 2] =
 0.0  0.0
 0.0  0.0

julia> free(A)
0

To avoid having to manually free allocated memory, it is recommended to use the following supported do-block syntax whenever possible, i.e.

julia> MallocArray(Float64, 2, 2) do A
           A .= 0
           printf(A)
       end
0.000000e+00    0.000000e+00
0.000000e+00    0.000000e+00
0
source
StaticTools.MallocMatrixType
MallocMatrix{T} <: AbstractMatrix{T}

Two-dimensional dense heap-allocated array with elements of type T. As Base.Matrix is to Base.Array, but with MallocArray.

source
StaticTools.MallocSlabBufferType
MallocSlabBuffer(;slab_size::Int = 1_048_576, slabs_max_length::Int=8, custom_slabs_max_length::Int=64)

A StaticCompiler.jl friendly version of SlabBuffer from Bumper.jl. This should be the preferred way to manage dynamically sized memory without support from the julia runtime.

MallocSlabBuffer is what's known as a slab-based bump allocator. It stores a list of fixed size memory 'slabs' (of size slab_size bytes), and memory can be requested from those slabs very fast. For allocations larger than half the slab_size, we do a size-specific malloc call and store the pointer in a separate list of custom sized slabs. At the end of a @no_escape block (see Bumper.jl), any unneeded slabs (custom or fixed-size) are freed.

The keyword arguments slabs_max_length and custom_slabs_max_length determine how many slabs and custom slabs the allocator is set to be able to initially store. If you dynamically allocate more slabs or custom slabs than these parameters, the MallocSlabBuffer will automatically resize itself to be able to store more slabs. These parameters are just heuristics for the initial creation of the allocator.

MallocSlabBuffers should be freed once you are done with them.


Example usage:

function slab_benchmark(argc::Int, argv::Ptr{Ptr{UInt8}})
    argc == 2 || return printf(c"Incorrect number of command-line arguments

") Nevals = argparse(Int64, argv, 2) # First command-line argument # Create a slab buffer buf = MallocSlabBuffer() @noescape buf begin # Create some vector x of length 10 containing all 1s. x = @alloc(Int, 10) x .= 1 for i ∈ 1:Nevals # Start a new noescape block so that allocations created during this # block get freed up at the end @noescape buf begin # Do some allocating operations in the loop y = @alloc(Int, 10) y .= x .+ 1 # It's vital that we never allow an array created by alloc to ever # escape a @noescape block! sum(y) end end nothing end # release the buffer once you're done with it. free(buf) end

julia> compile_executable(slab_benchmark, (Int64, Ptr{Ptr{UInt8}}), "./");

shell> time ./slab_benchmark 1000000000
real    0m2.417s
user    0m2.408s
sys     0m0.000s

Implementation notes:

  • MallocSlabBuffer stores a pointer to a MallocSlabBufferData so it can mutate the object without being a mutable type.
  • It stores a set of memory "slabs" of size slab_size (default 1 megabyte).
  • the current field is the currently active pointer that a newly @alloc'd object will aquire, if the object fits between current and slab_end.
  • If the object does not fit between current and slab_end, but is smaller than slab_size, we'll malloc a new slab, and add it to slabs (reallocating the slabs pointer if there's not enough room, as determined by max_slabs_length) and then set that thing as the current pointer, and provide that to the object.
  • If the object is bigger than slab_size, then we malloc a pointer of the requested size, and add it to the custom_slabs pointer (also reallocating that pointer if necessary), leaving current and slab_end unchanged.
  • When a @no_escape block ends, we reset current, and slab_end to their old values, and if slabs or custom_slabs have grown, we free all the pointers that weren't present before, and reset their respective lengths (but not max_sizes).
source
StaticTools.MallocStringType
struct MallocString
    pointer::Ptr{UInt8}
    length::Int
end

A stringy object that contains length bytes (i.e., UInt8s, including the final null-termination 0x00), at a location in memory specified by pointer.

A MallocString should generally behave like a base Julia String, but is explicitly null-terminated, mutable, standalone-StaticCompiler-safe (does not require libjulia) and backed by malloced memory which is not tracked by the GC and should be freed when no longer in use.

Can be constructed with the m"..." string macro.

Unlike base Julia Strings, slicing does not create a copy, but rather a view. You are responsible for ensuring that any such views are null-terminated if you wish to pass them to any functions (including most libc/system IO) that expect null-termination.

Indexing a MallocString out of bounds does not throw a BoundsError; much as if @inbounds were enabled, indexing a MallocString incurs a strict promise by the programmer that the specified index is inbounds. Breaking this promise will result in segfaults or memory corruption.

Examples

julia> s = m"Hello world!"
m"Hello world!"

julia> s[8:12] = c"there"; s
m"Hello there!"

julia> s[1:5]
StringView: "Hello"

julia> s[1:5] == "Hello"
true

julia> StaticString(s[1:5])
c"Hello"

julia> free(s)
0
source
StaticTools.MallocStringMethod
MallocString(undef, N)

Construct an uninitialized N-byte (including null-termination!) MallocString. Here undef is the UndefInitializer.

Examples

julia> s = MallocString(undef, 10)
m""

julia> free(s)
0
source
StaticTools.MallocStringMethod
MallocString(data::NTuple{N, UInt8})

Construct a MallocString containing the N bytes specified by data. To yield a valid string, data must be null-terminated, i.e., end in 0x00.

MallocString(s::AbstractStaticString)

Construct a MallocString containing the same data as the existing string s

Examples

julia> data = (0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21, 0x00);

julia> s = MallocString(data)
m"Hello world!"

julia> s2 = MallocString(s[1:5])
m"Hello"

julia> free(s)
0

julia> free(s2)
0
source
StaticTools.MallocVectorType
MallocVector{T} <: AbstractVector{T}

Two-dimensional dense heap-allocated array with elements of type T. As Base.Vector is to Base.Array, but with MallocArray.

source
StaticTools.SplitMix64Type
SplitMix64([seed::Bits64])

Initialize the internal state of a StaticCompiler-safe (non-allocating) SplitMix64 deterministic pseudorandom number generator, optionally specifying a 64-bit seed (which may be a Float64, Int64, or UInt64).

If a seed is not specified, StaticTools.time() will be used, which returns the current Unix epoch time in seconds.

See also:

splitmix64, rand

Examples

julia> seed = StaticTools.time() # Pick a seed
1649890154

julia> rng = SplitMix64(seed) # Initialize the generator
SplitMix64{Int64}((1649890154,))

julia> splitmix64(rng) # Draw a pseudorandom `UInt64` from the generator
0xca764ac7b7ea31e8

julia> rand(rng) # Draw a `Float64` between 0 and 1
0.8704883051360292
source
StaticTools.StackArrayType
StackArray{T,N,L,D} <: DenseTupleArray{T,N,L,D} <: DenseStaticArray{T,N} <: DenseArray{T,N} <: AbstractArray{T,N}

N-dimensional dense stack-allocated array with elements of type T.

Much like Base.Array, except (1) backed by memory that is not tracked by the Julia garbage collector (is stack allocated by alloca), so is StaticCompiler-friendly, and (2) contiguous slice indexing returns ArrayViews rather than copies.

Indexing a StackArray out of bounds does not throw a BoundsError; much as if @inbounds were enabled, indexing a StackArray incurs a strict promise by the programmer that the specified index is inbounds. Breaking this promise will result in segfaults or memory corruption.

source
StaticTools.StackArrayMethod
StackArray(data::NTuple{L,T})
StackArray(data::NTuple{L,T}, dims)
StackArray(data::AbstractArray{T,N})

Construct a StackArray with eltype T from an existing Tuple or AbstractArray.

Examples

julia> a = ntuple(i->0, 25)
(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)

julia> StackArray(a, 5,5)
5×5 StackMatrix{Int64, 25, (5, 5)}:
 0  0  0  0  0
 0  0  0  0  0
 0  0  0  0  0
 0  0  0  0  0
 0  0  0  0  0
source
StaticTools.StackArrayMethod
StackArray{T}(undef, dims)
StackArray{T,N}(undef, dims)
StackArray{T,N,L,D}(undef)

Construct an uninitialized N-dimensional StackArray containing elements of type T with N dimensions, length L and dimensions D. Dimensionality N can either be supplied explicitly, as in Array{T,N}(undef, dims), or be determined by the length or number of dims. dims may be a tuple or a series of integer arguments corresponding to the lengths in each dimension. If the rank N is supplied explicitly, then it must match the length or number of dims.

Examples

julia> StackArray{Float64}(undef, 3,3)
3×3 StackMatrix{Float64, 9, (3, 3)}:
 0.0  0.0  0.0
 0.0  0.0  0.0
 0.0  0.0  0.0
source
StaticTools.StackMatrixType
StackMatrix{T} <: AbstractMatrix{T}

Two-dimensional dense stack-allocated array with elements of type T. As Base.Matrix is to Base.Array, but with StackArray.

source
StaticTools.StackVectorType
StackVector{T} <: AbstractVector{T}

Two-dimensional dense stack-allocated array with elements of type T. As Base.Vector is to Base.Array, but with StackArray.

source
StaticTools.StaticStringType
StaticString{N}

A stringy type which should generally behave like a base Julia String, but is explicitly null-terminated, mutable, and standalone-StaticCompiler safe (does not require libjulia).

Can be constructed with the c"..." string macro.

Unlike base Julia Strings, slicing does not create a copy, but rather a view. You are responsible for ensuring that any such views are null-terminated if you wish to pass them to any functions (including most system IO) that expect null-termination.

Indexing a StaticString out of bounds does not throw a BoundsError; much as if @inbounds were enabled, indexing a StaticString incurs a strict promise by the programmer that the specified index is inbounds. Breaking this promise will result in segfaults or memory corruption.

Examples

julia> s = c"Hello world!"
c"Hello world!"

julia> s[8:12] = c"there"; s
c"Hello there!"

julia> s[1:5]
StringView: "Hello"

julia> s[1:5] == "Hello"
true

julia> StaticString(s[1:5])
c"Hello"
source
StaticTools.StaticStringMethod
StaticString{N}(undef)

Construct an uninitialized N-byte StaticString

StaticString(data::NTuple{N,UInt8})

Construct a StaticString containing the N bytes specified by data. To yield a valid string, data must be null-terminated, i.e., end in 0x00.

StaticString(s::AbstractStaticString)

Construct a StaticString containing the same data as the input string s.

Examples

julia> data = (0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21, 0x00);

julia> s = StaticString(data)
c"Hello world!"

julia> StaticString(s[1:5])
c"Hello"
source
StaticTools.Xoshiro256✴︎✴︎Type
Xoshiro256✴︎✴︎(seed::NTuple{4,Bits64})

Initialize the internal state of a StaticCompiler-safe (non-allocating) Xoshiro256✴︎✴︎ deterministic pseudorandom number generator, specifying a 256-bit seed, which should be specified as an NTuple of four 64-bit numbers (all either Float64, Int64, or UInt64).

See also:

xoshiro256✴︎✴︎, static_rng, rand

Examples

julia> seed = (0x9b134eccd2e63538, 0xd74ab64b2c3ecc9b, 0x70ba9c07628c27bf, 0x270a2eb658e6130b)
(0x9b134eccd2e63538, 0xd74ab64b2c3ecc9b, 0x70ba9c07628c27bf, 0x270a2eb658e6130b)

julia> rng = Xoshiro256✴︎✴︎(seed) # Initialize the generator
Xoshiro256✴︎✴︎{UInt64}((0x9b134eccd2e63538, 0xd74ab64b2c3ecc9b, 0x70ba9c07628c27bf, 0x270a2eb658e6130b))

julia> xoshiro256✴︎✴︎(rng) # Draw a pseudorandom `UInt64` from the generator
0x11059b6384fba06a

julia> rand(rng) # Draw a `Float64` between 0 and 1
0.9856766307398369
source
Base.iterateFunction
iterate(s::AbstractStaticString, i=firstindex(s))

Adapted form Julia's stdlib.

Examples

julia> s = c"foo"
c"foo"

julia> iterate(s, 1)
('f', 2)

julia> iterate(s, 99999)
source
Base.nextindFunction
nextind(s::AbstractString, i::Int, n::Int=1) -> Int

Adapted form Julia's stdlib, but made type-stable.

Type-stability and exceptions

The interface is a bit different from Base. To make it compile-able, we need to remove all throw cases. The method behaves as close as it can from the original.

The method won't throw BoundsError anymore, but will return the closest index (0 or ncodeunits(s)+1).

Examples

julia> nextind(c"α", 0)
1
julia> nextind(c"α", 1)
3
julia> nextind(c"α", 3)
3
julia> nextind(c"α", 0, 2)
3
julia> nextind(c"α", 1, 2)
4
source
Base.parseMethod
parse(::Type{T}, s::Union{StaticString, MallocString})

Parse a number from a StaticString or MallocString s.

Examples

julia> parse(Float64, c"3.141592")
3.141592

julia> parse(Int64, c"3.141592")
3
source
Base.previndFunction
prevind(str::AbstractStaticString, i::Integer, n::Integer=1) -> Int

Adapted form Julia's stdlib, but made type-stable.

Type-stability and exceptions

The interface is a bit different from Base. To make it compile-able, we need to remove all throw cases. The method behaves as close as it can from the original.

The method won't throw BoundsError anymore, but will return the closest index (0 or ncodeunits(s)+1).

Examples

julia> prevind(c"α", 3)
1
julia> prevind(c"α", 1)
0
julia> prevind(c"α", 0)
0
julia> prevind(c"α", 2, 2)
0
julia> prevind(c"α", 2, 3)
-1
source
Base.readMethod
read(filename::AbstractStaticString, MallocString)
read(filename::AbstractStaticString, MallocArray{T})

Read filename in its entirety to a MallocString or MallocArray{T} with eltype T.

source
Base.readMethod
read(fp::Ptr{FILE}, MallocString)
read(fp::Ptr{FILE}, MallocArray{T})

Read fp in its entirety to a MallocString or MallocArray{T} with eltype T.

source
Base.readMethod
read(fp::Ptr{FILE}, UInt8)

Read a single byte (as a single UInt8) from file pointer fp.

source
Base.readlineMethod
readline(fp::Ptr{FILE})

Read characters from file pointer fp until a unix newline ( ) is encountered and copy the results to a MallocString

See also readline! / gets! for a more efficient in-place version.

Examples

julia> fp = fopen(c"testfile.txt", c"w+")
Ptr{FILE} @0x00007fffb05f1148

julia> printf(fp, c"Here is a line of text!")
23

julia> frewind(fp)
0

julia> readline(fp)
m"Here is a line of text!"
source
Base.unsafe_wrapMethod
unsafe_wrap(MallocArray, ptr::Ptr{T}, dims)

Create a MallocArray{T} wrapping around ptr

source
StaticTools.:⅋Method
⅋(x)

A convenience function to obtain the most relevant properly-typed pointer available for a given object or reference.

"⅋" can be typed at the repl as \upand<tab>.

julia> x = Ref(1)
Base.RefValue{Int64}(1)

julia> ⅋(x)
Ptr{Int64} @0x000000015751af00
source
StaticTools.callocMethod
calloc([n], size::Integer)

Libc calloc function, accessed by direct StaticCompiler-safe llvmcall.

Allocate size bytes of zero-initialized memory and return a pointer to that memory. As malloc, but initializes the memory to all zero.

See also: malloc, free.

Examples

julia> p = calloc(100*sizeof(Int64))
Ptr{UInt8} @0x00007fb74ff04360

julia> MallocArray{Int64}(p, 10, 10)
10×10 MallocMatrix{Int64}:
 0  0  0  0  0  0  0  0  0  0
 0  0  0  0  0  0  0  0  0  0
 0  0  0  0  0  0  0  0  0  0
 0  0  0  0  0  0  0  0  0  0
 0  0  0  0  0  0  0  0  0  0
 0  0  0  0  0  0  0  0  0  0
 0  0  0  0  0  0  0  0  0  0
 0  0  0  0  0  0  0  0  0  0
 0  0  0  0  0  0  0  0  0  0
 0  0  0  0  0  0  0  0  0  0

julia> free(p)
0
source
StaticTools.dlcloseMethod
dlclose(lib::Ptr{DYLIB})

Libc dlclose function, accessed by direct StaticCompiler-safe llvmcall.

Close a shared library lib given a pointer (handle) previously obtained from StaticTools.dlopen.

See also: StaticTools.dlopen, StaticTools.dlsym, StaticTools.@ptrcall

Examples

julia> lib = StaticTools.dlopen(c"libc.dylib") # on macOS
Ptr{StaticTools.DYLIB} @0x000000010bf49b78

julia> fp = StaticTools.dlsym(lib, c"time")
Ptr{Nothing} @0x00007fffa773dfa4

julia> dltime() = @ptrcall fp(C_NULL::Ptr{Nothing})::Int
dltime (generic function with 1 method)

julia> dltime()
1654320146

julia> StaticTools.dlclose(lib)
0
source
StaticTools.dlopenFunction
dlopen(name::AbstractString, flag=RTLD_LOCAL|RTLD_LAZY)

Libc dlopen function, accessed by direct llvmcall.

Returns a handle (pointer) to a .so/.dylib shared library specified by name opened with the mode or combination of modes specified by flag. Returns C_NULL on failure. Valid modes include:

Required:

RTLD_LOCAL (default): Symbols will not be made available for subsequently loaded libraries. The opposite of RTLD_GLOBAL.

RTLD_GLOBAL: Symbols will be made available for subsequently loaded libraries. The opposite of RTLD_LOCAL.

Optional:

RTLD_LAZY (default): Lazy binding: only resolve symbols as the code that references them is executed. The opposite of RLTD_NOW.

RTLD_NOW: Eager binding: resolve all symbols before dlopen returns. The opposite of RTLD_LAZY

Modes from the two categories can be combined with bitwise or (|)

See also: StaticTools.dlsym, StaticTools.@ptrcall, StaticTools.dlclose

Examples

julia> lib = StaticTools.dlopen(c"libc.dylib") # on macOS
Ptr{StaticTools.DYLIB} @0x000000010bf49b78

julia> fp = StaticTools.dlsym(lib, c"time")
Ptr{Nothing} @0x00007fffa773dfa4

julia> dltime() = @ptrcall fp(C_NULL::Ptr{Nothing})::Int
ctime (generic function with 1 method)

julia> dltime()
1654320146

julia> StaticTools.dlclose(lib)
0
source
StaticTools.dlsymMethod
dlsym(lib::Ptr{DYLIB}, symbol::AbstractString)

Libc dlsym function, accessed by direct StaticCompiler-safe llvmcall.

Takes a handle (lib) to a .so/.dylib shared library previously opened with StaticTools.dlopen, along with a null-terminated symbol name string (symbol), and returns the location in memory of that symbol. Returns C_NULL on failure.

Optionally, a constant pseudo-pointer RTLD_DEFAULT is provided which can be used in place of the library lib. This instructs dlsym to search for the next occurrence of the specified symbol in the default search path, starting from the beginning of the search path.

See also: StaticTools.dlopen, StaticTools.@ptrcall, StaticTools.dlclose

Examples

julia> lib = StaticTools.dlopen(c"libc.dylib") # on macOS
Ptr{StaticTools.DYLIB} @0x000000010bf49b78

julia> fp = StaticTools.dlsym(lib, c"time")
Ptr{Nothing} @0x00007fffa773dfa4

julia> dltime() = @ptrcall fp(C_NULL::Ptr{Nothing})::Int
dltime (generic function with 1 method)

julia> dltime()
1654320146

julia> StaticTools.dlclose(lib)
0
source
StaticTools.fcloseMethod
fclose(fp::Ptr{FILE})

Libc fclose function, accessed by direct llvmcall.

Closes a file that has been previously opened by fopen, given a file pointer.

Returns 0 on success.

See also: fopen, fseek

Examples

julia> fp = fopen(c"testfile.txt", c"w")
Ptr{StaticTools.FILE} @0x00007fffc92bd0b0

julia> printf(fp, c"Here is a string")
16

julia> fclose(fp)
0

shell> cat testfile.txt
Here is a string
source
StaticTools.fopenMethod
fopen(name::AbstractString, mode::AbstractString)

Libc fopen function, accessed by direct llvmcall.

Returns a file pointer to a file at location specified by name opened for reading, writing, or both as specified by mode. Valid modes include:

c"r": Read, from an existing file.

c"w": Write. If the file exists, it will be overwritten.

c"a": Append, to the end of an existing file.

as well as "r+", c"w+", and "a+", which enable both reading and writing.

See also: fclose, fseek

Examples

julia> fp = fopen(c"testfile.txt", c"w")
Ptr{StaticTools.FILE} @0x00007fffc92bd0b0

julia> printf(fp, c"Here is a string")
16

julia> fclose(fp)
0

shell> cat testfile.txt
Here is a string
source
StaticTools.fread!Method
fread!(buffer::MallocString, fp::Ptr{FILE}, [n=length(buffer)])
fread!(buffer::MallocArray{T}, fp::Ptr{FILE}, [n=length(buffer)])
fread!(buffer, size::Int64, n::Int64, fp::Ptr{FILE})

Libc fread function, accessed by direct llvmcall.

Read n elements of size bytes each from the filestream specified by file pointer fp to the buffer specified as the first argument.

When not otherwise specified, a size equal to sizeof(eltype(b)) is used, or sizeof(UInt8) == 1 for strings.

See also: fwrite

Examples

julia> fp = fopen(c"testfile.b", c"rwb")
Ptr{StaticTools.FILE} @0x00007fffa35730c8

julia> fwrite(fp, (1:5)*(1:5)'); frewind(fp)
0

julia> a = szeros(Int,5,5);

julia> fread!(a, fp); a
5×5 StackMatrix{Int64, 25, (5, 5)}:
 1   2   3   4   5
 2   4   6   8  10
 3   6   9  12  15
 4   8  12  16  20
 5  10  15  20  25

julia> fclose(fp)
0
source
StaticTools.freeMethod
free(ptr::Ptr)

Libc free function, accessed by direct StaticCompiler-safe llvmcall.

Free memory that has been previously allocated with malloc.

See also: calloc, malloc.

Examples

julia> p = malloc(500)
Ptr{UInt8} @0x00007ff0e9e74290

julia> free(p)
0
source
StaticTools.fseekFunction
fseek(fp::Ptr{FILE}, offset::Int64, whence::Int32=SEEK_CUR)

Libc fseek function, accessed by direct llvmcall.

Move position within a file given a file pointer fp obtained from fopen. The new position will be offset bytes (or characters, in the event that all characters are non-unicode ASCII characters encoded as UInt8s) away from the position specified by whence.

The position reference whence can take on values of either:

SEEK_SET = Int32(0) File start

SEEK_CUR = Int32(1) Current position

SEEK_END = Int32(2) File end

where SEEK_CUR is the default value.

Returns 0 on success.

See also: fopen, fclose

Examples

julia> fp = fopen(c"testfile.txt", c"w+")
Ptr{StaticTools.FILE} @0x00007fffc92bd148

julia> printf(fp, c"Here is a string!")
17

julia> fseek(fp, -2)
0

julia> Char(getc(fp))
'g': ASCII/Unicode U+0067 (category Ll: Letter, lowercase)

julia> fclose(fp)
0
source
StaticTools.ftellMethod
ftell(fp::Ptr{FILE})

Libc ftell function, accessed by direct llvmcall.

Return the current position of the file pointer fp, in bytes from the start of the file.

Examples

julia> fp = fopen(c"testfile.txt", c"w")
Ptr{StaticTools.FILE} @0x00007fffc92bd0b0

julia> ftell(fp)
0

julia> printf(fp, c"Here is a string")
16

julia> ftell(fp)
16

julia> fclose(fp)
0
source
StaticTools.fwriteMethod
fwrite(filepath::AbstractString, data...)
fwrite(fp::Ptr{FILE}, data::AbstractString)
fwrite(fp::Ptr{FILE}, data::AbstractArray{T})
fwrite(fp::Ptr{FILE}, data, size::Int64, n::Int64)

Libc fwrite function, accessed by direct llvmcall.

Write n elements of size bytes each to the filestream specified by file pointer fp or name filepath from the string or array data. Where not otherwise specified, a size equal to sizeof(eltype(data)) is used, or sizeof(UInt8) == 1 for strings.

See also: fread!

Examples

julia> fp = fopen(c"testfile.b", c"rwb")
Ptr{StaticTools.FILE} @0x00007fffa35730c8

julia> fwrite(fp, (1:5)*(1:5)'); frewind(fp)
0

julia> a = szeros(Int,5,5);

julia> fread!(a, fp); a
5×5 StackMatrix{Int64, 25, (5, 5)}:
 1   2   3   4   5
 2   4   6   8  10
 3   6   9  12  15
 4   8  12  16  20
 5  10  15  20  25

julia> fclose(fp)
0
source
StaticTools.getcMethod
getc(fp::Ptr{FILE})

Libc getc function, accessed by direct llvmcall.

Reads a single character from file pointer fp, returning as Int32 (-1 on EOF).

Examples

julia> getc(stdinp())
c
99
source
StaticTools.getcharMethod
getchar()

Libc getchar function, accessed by direct llvmcall.

Reads a single character from standard input stdin, returning as UInt8.

Examples

julia> getchar()
c
0x63
source
StaticTools.gets!Function
gets!(s::MallocString, fp::Ptr{FILE}, n::Integer=length(s))

Libc fgets function, accessed by direct llvmcall.

Read up to n characters from the filestream specified by file pointer fp to the MallocString s. Stops when a newline is encountered, end-of-file is reached, or n characters have been read (whichever comes first).

Examples

julia> s = MallocString(undef, 100)
m""

julia> gets!(s, stdinp(), 3)
Ptr{UInt8} @0x00007fb15afce550

julia> s
m"
"
source
StaticTools.mallocMethod
malloc(size::Integer)

Libc malloc function, accessed by direct StaticCompiler-safe llvmcall.

Allocate size bytes of memory and return a pointer to that memory.

See also: calloc, free.

Examples

julia> p = malloc(500)
Ptr{UInt8} @0x00007ff0e9e74290

julia> free(p)
0
source
StaticTools.memcmpMethod
memcmp(a, b, n::Int64)

Libc memcmp function, accessed by direct StaticCompiler-safe llvmcall.

Compare the first n bytes of a and b, returning

  • a positive value if the first n bytes of a are greater than the first n bytes of b
  • a negative value if the first n bytes of a are less than the first n bytes of b
  • 0 the first n bytes of a are equal to the first n bytes of b

Examples

julia> memcmp(c"foo", c"foo", 3)
0

julia> memcmp(c"foo", c"bar", 3)
4
source
StaticTools.memcpy!Method
memcpy!(a, b, n=length(b))

Libc memcpy function, accessed by direct StaticCompiler-safe llvmcall.

Copy n elements from array b to array a.

Examples

julia> a = rand(3)
3-element Vector{Float64}:
 0.8559883493421137
 0.4203692766310769
 0.5728354965961716

julia> memcpy!(a, ones(3))
0

julia> a
3-element Vector{Float64}:
 1.0
 1.0
 1.0
source
StaticTools.memset!Function
memset!(a, char::Integer, nbytes::Integer=sizeof(a))

Libc memset function, accessed by direct StaticCompiler-safe llvmcall.

Set nbytes bytes of the array or memory region a to the Char/UInt8 conversion of the integer char.

Examples

julia> a = rand(5,5)
5×5 Matrix{Float64}:
 0.252808   0.6125    0.947215   0.0966341  0.637651
 0.736149   0.527729  0.928291   0.725644   0.832734
 0.704827   0.990302  0.0380948  0.768337   0.891583
 0.0826808  0.833624  0.364925   0.230345   0.366826
 0.301975   0.113886  0.329196   0.772636   0.0156762

julia> memset!(a, 0)
0

julia> a
5×5 Matrix{Float64}:
 0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0
source
StaticTools.meyeMethod
meye([T=Float64,] dims) do A
    ...
end
meye([T=Float64,] dim::Int)

Create a MallocArray{T} containing an identity matrix of type T, of size dim x dim.

Examples

julia> A = meye(Int32, 2)

2×2 MallocMatrix{Int32}:
 1  0
 0  1

julia> free(A)
0

To avoid having to manually free allocated memory, it is recommended to use the following supported do-block syntax whenever possible, i.e.

julia> meye(2) do A
           printf(A)
       end
1.000000e+00    0.000000e+00
0.000000e+00    1.000000e+00
0
source
StaticTools.mfillMethod
mfill(x::T, dims::Tuple)
mfill(x::T, dims...)

Create a MallocArray{T} of size dims, filled with the value x, where x is of type T. As Base.fill, but returning a MallocArray instead of an Array.

See also mzeros, mones.

Examples

julia> mfill(3, 2, 2)
2×2 MallocMatrix{Int64}:
 3  3
 3  3

To avoid having to manually free allocated memory, it is recommended to use the following supported do-block syntax whenever possible, i.e.

julia> mfill(1.5, 2,2) do A
           printf(A)
       end
1.500000e+00    1.500000e+00
1.500000e+00    1.500000e+00
0
source
StaticTools.monesMethod
mones([T=Float64,] dims) do A
    ...
end
mones([T=Float64,] dims::Tuple)
mones([T=Float64,] dims...)

Create a MallocArray{T} containing all zeros of type T, of size dims. As Base.zeros, but returning a MallocArray instead of an Array.

See also mzeros, mfill.

Examples

julia> A = mones(Int32, 2,2)
2×2 MallocMatrix{Int32}:
 1  1
 1  1

julia> free(A)
0

To avoid having to manually free allocated memory, it is recommended to use the following supported do-block syntax whenever possible, i.e.

julia> mones(2,2) do A
           printf(A)
       end
1.000000e+00    1.000000e+00
1.000000e+00    1.000000e+00
0
source
StaticTools.mzerosMethod
mzeros([T], dims) do A
    ...
end
mzeros([T=Float64,] dims::Tuple)
mzeros([T=Float64,] dims...)

Create a MallocArray{T} containing all zeros of type T, of size dims. As Base.zeros, but returning a MallocArray instead of an Array.

See also mones, mfill.

Examples

julia> mzeros(Int32, 2,2)
2×2 MallocMatrix{Int32}:
 0  0
 0  0

To avoid having to manually free allocated memory, it is recommended to use the following supported do-block syntax whenever possible, i.e.

julia> mzeros(2,2) do A
           printf(A)
       end
0.000000e+00    0.000000e+00
0.000000e+00    0.000000e+00
0
source
StaticTools.newlineMethod
newline([fp::Ptr{FILE}])

Prints a single newline () to a file pointer fp, defaulting to stdout if not specified.

Returns 0 on success.

Examples

julia> putchar('C')
0

julia> newline() # flushes stdout
C
0
source
StaticTools.parsedlmMethod
parsedlm([T::Type], filepath::String, delimiter::Char)

Parse a delimited text file, given a filepath and delimiter, and return the parsed contents as a MallocMatrix{T}, that is a 2D MallocArray containing numbers of type T.

If not specified, the parse type T will default to Float64.

Examples

julia> using StaticTools

julia> m = (1:10) * (1:10)';

julia> fp = fopen(c"testfile.tsv", c"w"); printf(fp, m); fclose(fp);

julia> parsedlm(Int32, c"testfile.tsv", '	')
10×10 MallocMatrix{Int32}:
  1   2   3   4   5   6   7   8   9   10
  2   4   6   8  10  12  14  16  18   20
  3   6   9  12  15  18  21  24  27   30
  4   8  12  16  20  24  28  32  36   40
  5  10  15  20  25  30  35  40  45   50
  6  12  18  24  30  36  42  48  54   60
  7  14  21  28  35  42  49  56  63   70
  8  16  24  32  40  48  56  64  72   80
  9  18  27  36  45  54  63  72  81   90
 10  20  30  40  50  60  70  80  90  100
source
StaticTools.perrorMethod
perror(s)

Print the string s to the standard error filestream, stderr.

Returns 0 on success.

Examples

julia> StaticTools.perror(c"ERROR: could not do thing
")
ERROR: could not do thing
0
source
StaticTools.printdlmFunction
printdlm(filepath, data, [delim='	'])

Print a vector or matrix data as delimited ASCII text to a new file name with delimiter delim Returns 0 on success.

Examples

julia> a = szeros(3,3)
3×3 StackMatrix{Float64, 9, (3, 3)}:
 0.0  0.0  0.0
 0.0  0.0  0.0
 0.0  0.0  0.0

julia> printdlm(c"foo.csv", a, ',')
0

shell> cat foo.csv
0.000000e+00,0.000000e+00,0.000000e+00,
0.000000e+00,0.000000e+00,0.000000e+00,
0.000000e+00,0.000000e+00,0.000000e+00,

julia> parsedlm(c"foo.csv", ',')
3×3 MallocMatrix{Float64}:
 0.0  0.0  0.0
 0.0  0.0  0.0
 0.0  0.0  0.0
source
StaticTools.printfMethod
printf ([fp::Ptr{FILE}], [fmt::AbstractString], s)

Libc printf function, accessed by direct llvmcall.

Prints a string s (specified either as a raw Ptr{UInt8} to a valid null-terminated string in memory or else a string type such as StaticString or MallocString for which a valid pointer can be obtained) to a filestream specified by the file pointer fp, defaulting to the current standard output stdout if not specified.

Optionally, a C-style format specifier string fmt may be provided as well.

Returns the number of characters printed on success.

Examples

julia> printf(c"Hello there!
")
Hello there!
13
source
StaticTools.printfMethod
printf([fp::Ptr{FILE}], [fmt], n::Number)

Libc printf function, accessed by direct llvmcall.

Prints a number n to a filestream specified by the file pointer fp, defaulting to the current standard output stdout if not specified.

Optionally, a C-style format specifier string fmt may be provided as well.

Returns 0 on success.

Examples

julia> printf(1)
1
0

julia> printf(1/3)
3.333333e-01
0

julia> printf(c"%f
", 1/3)
0.333333
0
source
StaticTools.printfMethod
printf([fp::Ptr{FILE}], a::AbstractArray{<:Number})

Print a matrix or vector of numbers a to a filestream specified by the file pointer fp, defaulting to the current standard output stdout if not specified.

Returns 0 on success.

Examples

julia> printf(rand(5,5))
5.500186e-02    8.425572e-01    3.871220e-01    5.442254e-01    5.990694e-02
5.848425e-01    6.714915e-01    5.616896e-01    6.668248e-01    2.643873e-01
9.156712e-01    1.276033e-01    3.350369e-01    6.513146e-01    9.999104e-01
3.301038e-01    6.027120e-01    5.139433e-01    2.219796e-01    4.057417e-01
2.821340e-01    9.258760e-01    7.950481e-01    1.152236e-01    7.949463e-01
0
source
StaticTools.printfMethod
printf([fp::Ptr{FILE}], things::Tuple)

Print any number of things, optionally to a file specified by fp.

Examples

julia> printf((c"Sphinx ", c"of ", c"black ", c"quartz, ", c"judge ", c"my ", c"vow!
"))
Sphinx of black quartz, judge my vow!
0

julia> x = 1
1

julia> printf((c"The value of x is currently ", x, c"
"))
The value of x is currently 1
0
source
StaticTools.putcharMethod
putchar([fp::Ptr{FILE}], c::Union{Char,UInt8})

Libc putchar / fputc function, accessed by direct llvmcall.

Prints a single character c (either a Char or a raw UInt8) to a file pointer fp, defaulting to the current standard output stdout if not specified.

Returns 0 on success.

Examples

julia> putchar('C')
0

julia> putchar(0x63)
0

julia> putchar('
') # Newline, flushes stdout
Cc
0
source
StaticTools.putsMethod
puts([fp::Ptr{FILE}], s::AbstractString)

Libc puts/fputs function, accessed by direct llvmcall.

Prints a string s (specified either as a raw Ptr{UInt8} to a valid null-terminated string in memory or elseor else a string type such as StaticString or MallocString for which a valid pointer can be obtained) followed by a newline () to a filestream specified by the file pointer fp, defaulting to the current standard output stdout if not specified.

Returns 0 on success.

Examples

julia> puts(c"Hello there!")
Hello there!
0
source
StaticTools.seyeMethod
seye([T=Float64,] dim::Int)

Create a StackArray{T} containing an identity matrix of type T, of size dim x dim.

Examples

julia> seye(Int32, 2)
2×2 StackMatrix{Int32, 4, (2, 2)}:
 1  0
 0  1
source
StaticTools.sfillMethod
sfill(x::T, dims::Tuple)
sfill(x::T, dims...)

Create a StackArray{T} of size dims, filled with the value x, where x is of type T. As Base.fill, but returning a StackArray instead of an Array.

See also szeros, sones.

Examples

julia> sfill(3, 2, 2)
2×2 StackMatrix{Int64, 4, (2, 2)}:
 3  3
 3  3
source
StaticTools.sonesMethod
szeros([T=Float64,] dims::Tuple)
szeros([T=Float64,] dims...)

Create a StackArray{T} containing all zeros of type T, of size dims. As Base.zeros, but returning a StackArray instead of an Array.

See also sones, sfill.

Examples

julia> szeros(Int32, 2,2)
2×2 StackMatrix{Int32, 4, (2, 2)}:
 0  0
 0  0
source
StaticTools.splitmix64Function
splitmix64([rng::SplitMix64])

A StaticCompiler-safe (non-allocating) implementation of the SplitMix64 deterministic pseudorandom number generator.

See also:

SplitMix64, rand

Examples

julia> seed = StaticTools.time() # Pick a seed
1649890154

julia> rng = SplitMix64(seed) # Initialize the generator
SplitMix64{Int64}((1649890154,))

julia> splitmix64(rng) # Draw a pseudorandom `UInt64` from the generator
0xca764ac7b7ea31e8

julia> rand(rng) # Draw a `Float64` between 0 and 1
0.8704883051360292
source
StaticTools.static_rngFunction
static_rng([seed::Bits64])

Initialize a StaticCompiler-safe (non-allocating) deterministic pseudorandom number generator, optionally specifying a 64-bit seed (which may be any 64-bit primitive numeric type – that is, Float64, Int64, or UInt64).

In particular, static_rng uses the specified seed value (or if not specified, the current result of StaticTools.time()) to initialize a simple SplitMix64 generator, which is then in turn used to bootstrap the larger seed required for a Xoshiro256✴︎✴︎ generator.

Examples

julia> rng = static_rng()
Xoshiro256✴︎✴︎{UInt64}((0x2d4c7aa97cc1a621, 0x63460fc58ff25249, 0x81498572d44bd2ec, 0x2d4e96d3a7e9fdd2))

julia> rand(rng) # Draw a `Float64` between 0 and 1
0.6577585429879329

julia> rand(rng)
0.4711097758403277
source
StaticTools.static_typeMethod
static_type(ctx::StaticContext, x)
static_type(x)

Returns an object similar to x with contents converted based on rules specified by ctx. static_type can be used for types or for objects.

For the default case, this converts Arrays to MallocArrays and Strings to MallocStrings.

To define your own rules, create a new StaticContext and then define two versions of static_type for each type you would like to convert. One converts the value, and one converts the type. Here is the builtin example for converting Arrays:

struct MyCtx <: StaticContext end
static_type(ctx::MyCtx, x::Array) = MallocArray(x)
static_type(ctx::MyCtx, ::Type{Array{T,N}}) where {T,N} = MallocArray{T,N}

For this context struct, inherit from StaticTools.DefaultStaticContext to build on the defaults, or inherit from StaticTools.StaticContext to define rules from scratch.

static_type is mainly useful for converting objects that are heavily paramaterized. The SciML infrastructure has a lot of this. The main objects like a DiffEq.Integrator has many type parameters, and by default, some are not amenable to static compilation. static_type can be used to convert them to forms that can help numerical code to be statically compiled.

static_type cannot convert all objects automatically. It transforms all type parameters and the contents of each field in an object (recursively). But, some objects do not define a "fully specified" constructor. In some cases, another method, static_type_contents can help by returning the components to help for a manual invocation of the constructor.

Note that any Malloc-objects created through this function must still be freed manually if you do not wish to leak memory.

source
StaticTools.static_type_contentsMethod
static_type_contents(ctx::StaticContext, x)
static_type_contents(x)

Returns a tuple with:

  • a vector of type parameters for x transformed by static_type
  • a vector of the contents of the fields in x transformed by static_type

Results can be useful for defining objects that do not define a fully specified constructor.

source
StaticTools.stderrpMethod
stderrp()

Zero-argument function which returns a raw pointer to the current standard error filestream, stderr.

Examples

julia> stderrp()
Ptr{StaticTools.FILE} @0x00007fffc92b9240

julia> printf(stderrp(), c"Hi there!
")
Hi there!
10
source
StaticTools.stdinpMethod
stdinp()

Zero-argument function which returns a raw pointer to the current standard input filestream, stdin.

Examples

julia> stdinp()
Ptr{StaticTools.FILE} @0x00007fffc92b9110
source
StaticTools.stdoutpMethod
stdoutp()

Zero-argument function which returns a raw pointer to the current standard output filestream, stdout.

Examples

julia> stdoutp()
Ptr{StaticTools.FILE} @0x00007fffc92b91a8

julia> printf(stdoutp(), c"Hi there!
")
Hi there!
10
source
StaticTools.strlenMethod
strlen(s)

Libc strlen function, accessed by direct StaticCompiler-safe llvmcall.

Returns the length in bytes of the null-terminated string s, not counting the terminating null character.

Examples

julia> strlen("foo") # Not documented, but Julia strings are null-terminated in practice every time I've checked
3

julia> strlen(c"foo")
3
source
StaticTools.strtodMethod
strtod(s)

Libc strtod function, accessed by direct StaticCompiler-safe llvmcall.

Returns a Float64 ("double") containing the number written out in decimal form in null-terminated string s.

Examples

julia> num, pbuf = StaticTools.strtod(c"3.1415")
(3.1415, ManualMemory.MemoryBuffer{1, Ptr{UInt8}}((Ptr{UInt8} @0x000000010aeee946,)))

julia> num, pbuf = StaticTools.strtod(c"5")
(5.0, ManualMemory.MemoryBuffer{1, Ptr{UInt8}}((Ptr{UInt8} @0x000000010d8f2bb1,)))
source
StaticTools.strtolMethod
strtol(s)

Libc strtol function, accessed by direct StaticCompiler-safe llvmcall.

Returns an Int64 ("long") containing the number written out in decimal form in null-terminated string s.

Examples

julia> num, pbuf = StaticTools.strtol(c"3.1415")
(3, ManualMemory.MemoryBuffer{1, Ptr{UInt8}}((Ptr{UInt8} @0x000000010dd827f1,)))

julia> num, pbuf = StaticTools.strtol(c"5")
(5, ManualMemory.MemoryBuffer{1, Ptr{UInt8}}((Ptr{UInt8} @0x000000015dbdda41,)))
source
StaticTools.strtoulMethod
strtoul(s)

Libc strtol function, accessed by direct StaticCompiler-safe llvmcall.

Returns an UInt64 ("unsigned long") containing the number written out in decimal form in null-terminated string s.

Examples

julia> num, pbuf = StaticTools.strtoul(c"3.1415")
(0x0000000000000003, ManualMemory.MemoryBuffer{1, Ptr{UInt8}}((Ptr{UInt8} @0x000000010d6976a1,)))

julia> num, pbuf = StaticTools.strtoul(c"5")
(0x0000000000000005, ManualMemory.MemoryBuffer{1, Ptr{UInt8}}((Ptr{UInt8} @0x000000015ed45d11,)))
source
StaticTools.systemMethod
system(s)

Libc system function, accessed by direct StaticCompiler-safe llvmcall.

Pass the null-terminated string (or pointer thereto) s to the libc system function for evaluation.

Returns 0 on success.

Examples

julia> StaticTools.system(c"time echo hello")
hello

real    0m0.001s
user    0m0.000s
sys 0m0.000s
0
source
StaticTools.szerosMethod
sones([T=Float64,] dims::Tuple)
sones([T=Float64,] dims...)

Create a StackArray{T} containing all zeros of type T, of size dims. As Base.zeros, but returning a StackArray instead of an Array.

See also szeros, sfill.

Examples

julia> sones(Int32, 2,2)
2×2 StackMatrix{Int32, 4, (2, 2)}:
 1  1
 1  1
source
StaticTools.timeMethod
time()

Libc time function, accessed by direct StaticCompiler-safe llvmcall.

Return, as an Int64, the current time in seconds since the beginning of the current Unix epoch on 00:00:00 UTC, January 1, 1970.

Examples

julia> StaticTools.time()
1651105298
source
StaticTools.usleepMethod
usleep(μsec::Integer)

Libc usleep function, accessed by direct StaticCompiler-safe llvmcall.

Suspend execution of the calling thread for (at least) μsec microseconds.

Examples

julia> usleep(1000000)
0
source
StaticTools.xoshiro256✴︎✴︎Method
xoshiro256✴︎✴︎(rng::Xoshiro256✴︎✴︎)

A StaticCompiler-safe (non-allocating) implementation of the Xoshiro256✴︎✴︎ deterministic pseudorandom number generator, written in LLVM IR and invoked via llvmcall.

See also:

Xoshiro256✴︎✴︎, static_rng, rand

Examples

julia> seed = (0x9b134eccd2e63538, 0xd74ab64b2c3ecc9b, 0x70ba9c07628c27bf, 0x270a2eb658e6130b);

julia> rng = Xoshiro256✴︎✴︎(seed) # Initialize the generator
Xoshiro256✴︎✴︎{UInt64}((0x9b134eccd2e63538, 0xd74ab64b2c3ecc9b, 0x70ba9c07628c27bf, 0x270a2eb658e6130b))

julia> xoshiro256✴︎✴︎(rng) # Draw a pseudorandom `UInt64` from the generator
0x11059b6384fba06a

julia> rand(rng) # Draw a `Float64` between 0 and 1
0.9856766307398369
source
StaticTools.@c_strMacro
@c_str -> StaticString

Construct a StaticString, such as c"Foo".

A StaticString should generally behave like a base Julia String, but is explicitly null-terminated, mutable, and standalone-StaticCompiler safe (does not require libjulia).

Examples

julia> c"Hello there!"
c"Hello there!"

julia> c"foo" == "foo"
true
source
StaticTools.@externloadMacro
@externload symbol::T

Load an LLVM external global variable with name symbol and type T

Examples

julia> foo() = @externload __stderrp::Ptr{UInt8} # macos syntax
foo (generic function with 1 method)

julia> foo()
Ptr{UInt8} @0x00007fffadb8a240

julia> foo() == stderrp()
true
source
StaticTools.@externptrMacro
@externptr symbol::T

Return the pointer to an LLVM external global variable with name symbol and type T

Examples

julia> foo() = @externptr __stderrp::Ptr{UInt8} # macos syntax
foo (generic function with 1 method)

julia> foo()
Ptr{Ptr{UInt8}} @0x00007fffadb8a9a0

julia> Base.unsafe_load(foo()) == stderrp()
true
source
StaticTools.@m_strMacro
@m_str -> MallocString

Construct a MallocString, such as m"Foo".

A MallocString should generally behave like a base Julia String, but is explicitly null-terminated, mutable, standalone-StaticCompiler-safe (does not require libjulia) and is backed by mallocd memory which is not tracked by the GC and should be freed when no longer in use.

Examples

julia> s = m"Hello there!"
m"Hello there!"

julia> s == "Hello there!"
true

julia> free(s)
0
source
StaticTools.@ptrcallMacro
@ptrcall function_pointer(argvalue1::Type1, ...)::ReturnType

Call a function pointer (e.g., as obtained from dlsym) via macro-constructed llvmcall.

See also: StaticTools.dlopen, StaticTools.dlsym, StaticTools.dlclose c.f.: @ccall, StaticTools.@symbolcall

Examples

julia> lib = StaticTools.dlopen(c"libc.dylib") # on macOS
Ptr{StaticTools.DYLIB} @0x000000010bf49b78

julia> fp = StaticTools.dlsym(lib, c"time")
Ptr{Nothing} @0x00007fffa773dfa4

julia> dltime() = @ptrcall fp(C_VOID::Ptr{Nothing})::Int
dltime (generic function with 1 method)

julia> dltime()
1654320146

julia> StaticTools.dlclose(lib)
0
source
StaticTools.@symbolcallMacro
@symbolcall symbol(argvalue1::Type1, ...)::ReturnType

Call a function by symbol/name in LLVM IR, via macro-constructed llvmcall

See also: @ccall, StaticTools.@ptrcall

Examples

julia> ctime() = @symbolcall time()::Int
ctime (generic function with 1 method)

julia> ctime()
1654322507

julia> @macroexpand @symbolcall time()::Int
:(Base.llvmcall(("declare i64 @time()

define i64 @main() #0 {
  
  %result = call i64 () @time()
  ret i64 %result
}
attributes #0 = { alwaysinline nounwind ssp uwtable }
", "main"), Int, Tuple{}))
source