The document discusses the creation of a custom domain-specific language (DSL) in Rust, detailing its abstract syntax tree (AST) representation and parsing techniques using libraries like Nom and Combine. It also explores various methods of interpreting, compiling, and running the DSL, including bytecode interpretation and just-in-time (JIT) compilation using LLVM and Cranelift. Additionally, it provides code examples and performance metrics for the different compilation techniques used.
JIT compilation
https://github.com/CraneStation/cranelift:
Cranelift isdesigned to be a code generator for WebAssembly, but it is general enough to be
useful elsewhere too. The initial planned uses that affected its design are:
• WebAssembly compiler for the SpiderMonkey engine in Firefox.
66.
JIT compilation
https://github.com/CraneStation/cranelift:
Cranelift isdesigned to be a code generator for WebAssembly, but it is general enough to be
useful elsewhere too. The initial planned uses that affected its design are:
• WebAssembly compiler for the SpiderMonkey engine in Firefox.
• Backend for the IonMonkey JavaScript JIT compiler in Firefox.
67.
JIT compilation
https://github.com/CraneStation/cranelift:
Cranelift isdesigned to be a code generator for WebAssembly, but it is general enough to be
useful elsewhere too. The initial planned uses that affected its design are:
• WebAssembly compiler for the SpiderMonkey engine in Firefox.
• Backend for the IonMonkey JavaScript JIT compiler in Firefox.
• Debug build backend for the Rust compiler.
68.
JIT compilation
https://github.com/CraneStation/cranelift:
Cranelift isdesigned to be a code generator for WebAssembly, but it is general enough to be
useful elsewhere too. The initial planned uses that affected its design are:
• WebAssembly compiler for the SpiderMonkey engine in Firefox.
• Backend for the IonMonkey JavaScript JIT compiler in Firefox.
• Debug build backend for the Rust compiler.
...
Cranelift's APIs are not yet stable.
69.
Cranelift
let builder =SimpleJITBuilder ::new();
let mut module: Module<SimpleJITBackend> = Module ::new(builder);
let mut ctx = module.make_context();
let mut func_builder_ctx = FunctionBuilderContext ::new();
70.
Cranelift
let sig =&mut ctx.func.signature;
sig.params.push(AbiParam ::new(types ::F64)); // X
sig.params.push(AbiParam ::new(types ::F64)); // Y
sig.returns.push(AbiParam ::new(types ::F64));
Cranelift
let entry_ebb =builder.create_ebb();
builder.append_ebb_params_for_function_params(entry_ebb);
builder.switch_to_block(entry_ebb);
builder.seal_block(entry_ebb);
let result = ...;
builder.ins().return_(&[result]);
builder.finalize();
73.
Cranelift
Expr ::Literal(lit) =>{
let ins = builder.ins();
ins.f64const(Ieee64 ::with_float(*lit))
}
Expr ::Variable(var) => builder.ebb_params(ebb)[ ...],
Expr ::Binary { lhs, op, rhs } => {
let lhs = lhs.compile( ...);
let rhs = rhs.compile( ...);
let ins = builder.ins();
match op {
BinOp ::Add => ins.fadd(lhs, rhs),
...
}
}