I am not sure if this is the best place to ask for help.
I am writing a language that uses Cranelift's JIT functionality and I have ran into a problem when trying to convert my bytecode for a while loop into Cranelift.
I am currently trying to convert my bytecode linearly. Each time I encounter a branching op, I create the required blocks for that particular instruction (mine map well to Cranelift: Goto = jump, If = If). I have a special op that tells the converter to start adding to that block. However, despite not passing in any block parameters for jump or if, I am getting extra block parameters and I am not exactly sure how they are appearing. My current suspicions are that using variables is creating extra parameters.
Is this intended behavior? If so could this information be added to the docs?
Any help is much appreciated.
Those extra block params are introduced in order to turn variables into SSA form as clif ir is an SSA form ir.
Thank you. How can I work with that in mind. I was looking at the JIT demo and it doesn't look like it has the same problem that I am having.
The extra block parameters should be harmless. Are you perhaps trying to inspect which block params exist as part of building the ir? If so try avoiding that. And make sure to use builder.ins() rather than builder.cursor() when inserting instructions.
I am using builder.ins(). The issue I am having is that I am not sure what the block arguments should be.
If you didn't manually add block arguments on the block itself, you should pass an empty list when inserting the jump and branch instructions. cranelift-frontend will itself add the values for the block arguments it added to the blocks you defined.
The issue with passing an empty list is that Cranelift still expects there to be block arguments somehow.
I have commented out all of the code that could add block arguments and pass in empty lists for jump and if but it still expects there to be block arguments that I am passing it.
cranelift-frontend will add those block arguments.
Are you maybe forgetting to finalize the function builder?
In my code, JITModule's define_function is creating the error.
which occurs before finalize is called.
I figured it out. It was because I wasn't sealing all of the blocks.
Thank you for your time and help.
You should call https://docs.rs/cranelift-frontend/latest/cranelift_frontend/struct.FunctionBuilder.html#method.finalize before passing the Function to define_function and after sealing all blocks.
I'll be sure to do that, thanks.
This function does a bunch of debug asserts and resets the state of the FunctionBuilderContext such that you can reuse it for a future FunctionBuilder::new call. Reusing FunctionBuilderContext saves some memory allocations, improving performance a tiny bit.
Last updated: Dec 06 2025 at 07:03 UTC