JIT

public final class JIT

A JIT is a Just-In-Time compiler that will compile and execute LLVM IR that has been generated in a Module. It can execute arbitrary functions and return the value the function generated, allowing you to write interactive programs that will run as soon as they are compiled.

The JIT is fundamentally lazy, and allows control over when and how symbols are resolved.

  • A type that represents an address, either symbolically within the JIT or physically in the execution environment.

    See more

    Declaration

    Swift

    public struct TargetAddress : Comparable
  • Represents a handle to a module owned by the JIT stack.

    Declaration

    Swift

    public struct ModuleHandle
  • Create and initialize a JIT with this target machine’s representation.

    Declaration

    Swift

    public convenience init(machine: TargetMachine)

Symbols

  • Mangles the given symbol name according to the data layout of the JIT’s target machine.

    Declaration

    Swift

    public func mangle(symbol: String) -> String

    Parameters

    symbol

    The symbol name to mangle.

    Return Value

    A mangled representation of the given symbol name.

  • Computes the address of the given symbol, optionally restricting the search for its address to a particular module. If this symbol does not exist, an address of 0 is returned.

    Declaration

    Swift

    public func address(of symbol: String, in module: ModuleHandle? = nil) throws -> TargetAddress

    Parameters

    symbol

    The symbol name to search for.

    module

    An optional value describing the module in which to restrict the search, if any.

    Return Value

    The address of the symbol, or 0 if it does not exist.

Lazy Compilation

  • Registers a lazy compile callback that can be used to get the target address of a trampoline function. When that trampoline address is called, the given compilation callback is fired.

    Normally, the trampoline function is a known stub that has been previously registered with the JIT. The callback then computes the address of a known entry point and sets the address of the stub to it. See JIT.createIndirectStub to create a stub function and JIT.setIndirectStubPointer to set the address of a stub.

    Declaration

    Swift

    public func registerLazyCompile(_ callback: @escaping (JIT) -> TargetAddress) throws -> TargetAddress

    Parameters

    callback

    A callback that returns the actual address of the trampoline function.

    Return Value

    The target address representing a stub. Calling this stub forces the given compilation callback to fire.

Stubs

  • Creates a new named indirect stub pointing to the given target address.

    An indirect stub may be resolved to a different address at any time by invoking JIT.setIndirectStubPointer.

    Declaration

    Swift

    public func createIndirectStub(named name: String, address: TargetAddress) throws

    Parameters

    name

    The name of the indirect stub.

    address

    The address of the indirect stub.

  • Resets the address of an indirect stub.

    Warning

    The indirect stub must be registered with a call to JIT.createIndirectStub. Failure to do so will result in undefined behavior.

    Declaration

    Swift

    public func setIndirectStubPointer(named name: String, address: TargetAddress) throws

    Parameters

    name

    The name of an indirect stub.

    address

    The address to set the indirect stub to point to.

Adding Code to the JIT

  • Adds the IR from a given module to the JIT, consuming it in the process.

    Despite the name of this function, the callback to compile the symbols in the module is not necessarily called immediately. It is called at least when a given symbol’s address is requested, either by the JIT or by the user e.g. JIT.address(of:).

    The callback function is required to compute the address of the given symbol. The symbols are passed in mangled form. Use JIT.mangle(symbol:) to request the mangled name of a symbol.

    Warning

    The JIT invalidates the underlying reference to the provided module. Further references to the module are thus dangling pointers and may be a source of subtle memory bugs. This will be addressed in a future revision of LLVM.

    Declaration

    Swift

    public func addEagerlyCompiledIR(_ module: Module, _ callback: @escaping (String) -> TargetAddress) throws -> ModuleHandle

    Parameters

    module

    The module to compile.

    callback

    A function that is called by the JIT to compute the address of symbols.

  • Adds the IR from a given module to the JIT, consuming it in the process.

    This function differs from JIT.addEagerlyCompiledIR in that the callback to request the address of symbols is only executed when that symbol is called, either in user code or by the JIT.

    The callback function is required to compute the address of the given symbol. The symbols are passed in mangled form. Use JIT.mangle(symbol:) to request the mangled name of a symbol.

    Warning

    The JIT invalidates the underlying reference to the provided module. Further references to the module are thus dangling pointers and may be a source of subtle memory bugs. This will be addressed in a future revision of LLVM.

    Declaration

    Swift

    public func addLazilyCompiledIR(_ module: Module, _ callback: @escaping (String) -> TargetAddress) throws -> ModuleHandle

    Parameters

    module

    The module to compile.

    callback

    A function that is called by the JIT to compute the address of symbols.

  • Adds the executable code from an object file to ths JIT, consuming it in the process.

    The callback function is required to compute the address of the given symbol. The symbols are passed in mangled form. Use JIT.mangle(symbol:) to request the mangled name of a symbol.

    Warning

    The JIT invalidates the underlying reference to the provided memory buffer. Further references to the buffer are thus dangling pointers and may be a source of subtle memory bugs. This will be addressed in a future revision of LLVM.

    Declaration

    Swift

    public func addObjectFile(_ buffer: MemoryBuffer, _ callback: @escaping (String) -> TargetAddress) throws -> ModuleHandle

    Parameters

    buffer

    A buffer containing an object file.

    callback

    A function that is called by the JIT to compute the address of symbols.

  • Remove previously-added code from the JIT.

    Warning

    Removing a module handle consumes the handle. Further use of the handle will then result in undefined behavior.

    Declaration

    Swift

    public func removeModule(_ handle: ModuleHandle) throws

    Parameters

    handle

    A handle to previously-added module.