Implements the framework for just-in-time (JIT) code-generation for the VM. Both procedures and standalone statements/expressions are supported as input.
When a procedure is requested that hasn't been processed by the JIT compiler, it is transformed, pre-processed (MIR passes applied, etc.), and then the bytecode for it is generated. If code generation succeeds, all not- already-seen dependencies (like globals, constants, etc.) of the procedure are collected, registered with the JIT state, and loaded into the VM's execution environment, meaning that the requested procedure can be immediately invoked after.
Both compile-time code execution and running NimScript files make use of the JIT compiler.
Imports
-
../ast/ast_types, ../ast/ast_query, ../backend/backends, ../backend/cgir, ../front/in_options, ../mir/datatables, ../mir/mirbodies, ../mir/mirbridge, ../mir/mirenv, ../mir/mirgen, ../mir/mirpasses, ../mir/mirtrees, ../mir/mirtypes, ../modules/magicsys, ../modules/modulegraphs, ../sem/transf, identpatterns, vmaux, vmserialize, vmdef, vmgen, vmjit_checks, vmmemory, vmtypegen, ../ast/ast, ../sem/semdata, ../sem/parampatterns
Types
JitState = object gen: CodeGenCtx ## code generator state
- State of the VM's just-in-time compiler that is kept across invocations. Source Edit
Procs
proc compile(jit: var JitState; c: var TCtx; fnc: FunctionIndex): VmGenResult {....raises: [ Exception, ERecoverableError, KeyError, ValueError, ResultErrorRef[system.void]], tags: [RootEffect, ReadDirEffect].}
- Generates code for the the given function and updates the execution environment. In addition, the function's table entry is updated with the bytecode position and execution requirements (i.e. register count). Make sure to only use compile when you're sure the function wasn't generated yet Source Edit
proc constDataToMir(c: var TCtx; jit: var JitState; e: PNode): MirTree {. ...raises: [Exception, ERecoverableError, KeyError], tags: [RootEffect, ReadDirEffect].}
- Translates the constant expression e to a MIR constant expression and returns it. Entities referenced by the constant expression (e.g., procedures), are direclty registered with the environment. Source Edit
proc genExpr(jit: var JitState; c: var TCtx; n: PNode): VmGenResult {....raises: [ ResultErrorRef[system.void], Exception, ERecoverableError, KeyError, ValueError, ResultErrorRef[vmdef.VmGenDiag]], tags: [RootEffect, ReadDirEffect].}
- Generates and emits code for the standalone expression n Source Edit
proc genStmt(jit: var JitState; c: var TCtx; n: PNode): VmGenResult {....raises: [ ResultErrorRef[system.void], Exception, ERecoverableError, KeyError, ValueError, ResultErrorRef[vmdef.VmGenDiag]], tags: [RootEffect, ReadDirEffect].}
- Generates and emits code for the standalone top-level statement n. Source Edit
func getGlobal(jit: JitState; g: PSym): LinkIndex {....raises: [KeyError], tags: [].}
- Returns the link index for the symbol g. g must be known to jit. Source Edit
proc initJit(graph: ModuleGraph): JitState {. ...raises: [KeyError, Exception, ERecoverableError], tags: [ReadDirEffect, RootEffect].}
- Returns an initialized JitState instance. Source Edit
func isAvailable(jit: JitState; c: TCtx; prc: PSym): bool {....raises: [KeyError], tags: [].}
- Returns whether the bytecode for prc is already available. Source Edit
proc loadProc(jit: var JitState; c: var TCtx; sym: PSym): VmGenResult {....raises: [ Exception, ERecoverableError, KeyError, ValueError, ResultErrorRef[system.void]], tags: [RootEffect, ReadDirEffect].}
- The main entry point into the JIT code-generator. Retrieves the information required for executing sym. A function table entry is created first if it doesn't exist yet, and the procedure is also generated via compile if it wasn't already Source Edit
proc registerCallback(c: var TCtx; pattern: string; callback: VmCallback) {. ...raises: [], tags: [].}
- Registers the callback with c. After the registerCallback call, when a procedures of which the fully qualified identifier matches pattern is added to the VM's function table, all invocations of the procedure at run-time will invoke the callback instead. Source Edit
proc registerProcedure(jit: var JitState; c: var TCtx; prc: PSym): FunctionIndex {. ...raises: [Exception, ERecoverableError, KeyError], tags: [RootEffect].}
- If it hasn't been already, adds prc to the set of procedures the JIT code-generator knowns about and sets up a function-table entry. jit is required to not be in the process of generating code. Source Edit