I have functions A and B, and B uses a pointer to A (but does not call it!). How do I need to declare A in B? I generate code for A before B in the same module, which looks like
function u0:34(i64, i64) -> i64 system_v {
sig0 = (i64) -> i64 system_v
fn0 = u0:0 sig0
block0(v0: i64, v2: i64):
v1 = load.i64 v0+8
v3 = iadd v1, v2
return v3
}
Now when generating B
I use Variable(34)
(which is the previous function shown above), but it fails with variable Variable(34) is used but its type has not been declared
.
@osa1 You need to use module.declare_func_in_func(a_func_id, &mut b_func)
to get a FuncRef
to A.
I'm confused, why do I need a FuncRef
? I'm not calling it, I'm just returning it.
In that case you can use the func_addr
instruction to get the address of the function from the FuncRef
.
What is the iAddr
argument for in func_addr
?
The pointer type. Eg i64
on 64bit systems and i32
on 32bit systems.
So if I understand this correctly, I need to get a FuncId for every function in this compilation unit first, and then maintain a map from my variable type to FuncIds, and check, on every use, whether the used variable is a function
If it is then I need to first import it (declare_func_in_func) and then get address of it using func_addr
In my language I don't do direct calls (maybe later after optimizations)
Yes, you need to use declare_func_in_func
followed by func_addr
to get the address of a function.
Thank you! Really helpful
When building a module with multiple functions do I have to use https://docs.rs/cranelift-codegen/0.63.0/cranelift_codegen/struct.Context.html or can I create a FunctionBuilder
for every function?
So instead of FunctionBuilder::new(&mut context.func, ...);
can I do let mut func = Function::with_name_signature(...); let mut builder = FunctionBuilder::new(&mut func, &mut fn_builder_ctx);
?
Is the "entry basic block" stuff gone in the latest version? Saw that in an older code
You can reuse Context
for multiple functions if you call .clear()
in between. This is not necessary, but improves performance. You can't reuse FunctionBuilder
. Everything that is reusable for cranelift-frontend
is stored in FunctionBuilderContext
instead.
What do you mean with "entry basic block" stuff?
create_ebb
and append_ebb_params_for_function_params
, they seem to be gone now
How do I create an entry basic block and declare function arguments there in the latest version on crates.io?
If I want the function parameters to be available in all blocks of the function do I need to do `builder.append_block_params_for_function_params(block); for every block?
create_ebb
has been renamed to create_block
.
osa1 said:
If I want the function parameters to be available in all blocks of the function do I need to do `builder.append_block_params_for_function_params(block); for every block?
Only do it for the entry block. You can the access the params from all blocks.
I don't understand how to do that. Since entry block creating is not different than others, how do I specify which block is the entry block?
Just use builder.block_params(entry_block)[0]
to get the first param.
The first block inserted is the entry block.
How do I insert a block?
aka the first time you call switch_to_block
that block will become the entry block.
The first block created?
Ah
I still can't use arguments ...
variable Variable(12) is used but its type has not been declared
Hmm
How do I get Value
s of the arguments after append_block_params_for_function_params
?
Where does Variable(12)
come from?
Ahh! Found ti!
Thanks @bjorn3
I'll get the values of args using entry_block.block_params()
, right?
Do I really ahve to invent Variable numbers myself or is there a method in cranelift for that?
In other words, if I ahve let x = y
in my language, do I have to invent a cranelift Variable
for that x
myself? Any invariants about the u32 for it? (e.g. should variable u32s be consecutive or can I pick 100 for the first var and 123123 for the second?)
What does this mean: assertion failed: func_ctx.is_empty()
?
Figured out the func_ctx.is_empty()
stuff. Still a bit confused about variables though
Given a FuncId is there a way to get the signature of the function?
Welp unimplemented type: types::INVALID
...
But the good news is I can generate 2 functions before this error :grinning_face_with_smiling_eyes:
osa1 said:
I'll get the values of args using
entry_block.block_params()
, right?
yes
osa1 said:
In other words, if I ahve
let x = y
in my language, do I have to invent a craneliftVariable
for thatx
myself? Any invariants about the u32 for it? (e.g. should variable u32s be consecutive or can I pick 100 for the first var and 123123 for the second?)
yes, you can use arbitrary numbers, but the memory usage is proportional to the largest number you choose I believe.
osa1 said:
Given a FuncId is there a way to get the signature of the function?
I don't think so
OK back at yak shaving -- @bjorn3 do you know what this error means: unimplemented type: types::INVALID
Happens on seal_block()
I think I'm not initializing something that I'm supposed to but I don't know what
@osa1 Is there a backtrace?
Probably here: https://github.com/bytecodealliance/wasmtime/blob/0592b5a9956a7f8b51abf79830d3b70521c9aa4d/cranelift/frontend/src/ssa.rs#L206
Did you call builder.declare_var
with the type of the variable before you used it?
Hmm I think that's the problem, yes. I have some built-in functions (implemented in C), I think I"m not declaring it currently
Hmm I think that's the problem, yes. I have some built-in functions (implemented in C), I think I"m not declaring it currently
Last updated: Dec 23 2024 at 13:07 UTC