In-memory compilation and execution

I have to dynamically build small FSM automata, then run them within the same program. I have no concern about the resource it takes to build them. But I want them to be as efficient as possible when they run.

Since each FSM can be fully determined (number of states, transition, messages signatures, etc). My guess is that the best way to achieve this tradeoff is to produce ad-hoc Rust code for each FSM (with hardcoded states and transitions), compile it down to optimized binary with rustc then run it as subprocess.

How difficult would it be? How much more difficult would it be if I want to avoid writing source files and binaries to the disk? I guess this would require “in-memory compilation”, with the source code held by a string and the compiled code written to an… executable bytes array? Or maybe a bytes array wrapped into a function or into a trait object?

Is this possible? Why and how?

I think using rustc for compilation would be difficult: it’s a huge dependency. Perhaps you can use crane-lift: a compact code-generator written in Rust?


Thank you for reactivity <3 I’m currently having a look at it and at wikipedia page for JIT for I’m not sure exactly what those are yet X) I’ll be back here if I have more questions.

JIT for some other language might be a better option. If you want to go with Rust, you could also compile a library instead of creating a new process each time. Getting compiler to output to memory won’t be possible, but if you use Linux you could use tmpfs or something similar, though its probably not worth the effort.

What exactly do you mean by “compile a library instead”? Would this make it possible for the compiler to output to memory?

With “JIT for some other language”, I’m not sure I understand whether you’re suggesting:

  • to pick another programming language (not Rust) that features JIT, or
  • to design a new, small dedicated language to express my FSM, then try to compile it down to machine code?

What exactly do you mean by “compile a library instead”?

Create shared object and load into your process instead of creating and running new one (cargo new --lib).

There is no JIT for Rust, so you’d need to use one for another language.
Writing your own compiler would be a lot more work.

What about leveraging an existing WASM runtime? There are quite a few which have been written in Rust and feature JIT compilers, and they make it quite easy to generate/execute WASM code at runtime.

1 Like

So I would have to compile my program to WASM instead of LLVM -> assembly, right? I think I understand :slight_smile: