Hi,
I have a question about when a post-return
is needed, especially for the case of a struct.
Suppose I have the following WIT:
world app {
record point {
x: u32,
y: u32,
}
export add: func(a: point, b: point) -> point;
}
It seems that since it's returning a struct containing two fields, a return pointer is needed. However, the guest_export_needs_post_return
decided that it does not need post-return
since neither the field inside the struct needs one. So my question is, who is responsible for freeing this area? Because I didn't see a cabi_realloc
call in the transpiled js, either.
Thanks.
The guest_export_needs_post_return
function is mostly a heuristic and it's not required to be used. The post-return feature is always optional. Rust for example allocates this return area in static memory so it doesn't need a dynamic allocation, but other languages can customize as needed.
Alex Crichton said:
The
guest_export_needs_post_return
function is mostly a heuristic and it's not required to be used. The post-return feature is always optional. Rust for example allocates this return area in static memory so it doesn't need a dynamic allocation, but other languages can customize as needed.
I see. But is there a size there will be big enough? For example, if there's a struct containing 100 fields with u64?
Also I tried to add post-return function, and this is what I got with the transpiled JS:
function add(arg0, arg1) {
var {x: v0_0, y: v0_1 } = arg0;
var {x: v1_0, y: v1_1 } = arg1;
const ret = exports0.add(toUint32(v0_0), toUint32(v0_1), toUint32(v1_0), toUint32(v1_1));
postReturn0(ret);
return {
x: dataView(memory0).getInt32(ret + 0, true) >>> 0,
y: dataView(memory0).getInt32(ret + 4, true) >>> 0,
};
}
I wonder who's responsible for freeing the point
?
I mean, if the post return is called before the dataView is accessed?
The return area is allocated per-function IIRC and is appropriately sized to that function. Either that or it's a maximal size for a set of functions, I forget which. Regardless though you would have to make sure it's big enough yeah.
I mean, if the post return is called before the dataView is accessed?
ah yes postReturn0 would have to be called after the return value is constructed
Alex Crichton said:
I mean, if the post return is called before the dataView is accessed?
ah yes postReturn0 would have to be called after the return value is constructed
I created an issue about this: https://github.com/bytecodealliance/jco/issues/484
Alex Crichton said:
The return area is allocated per-function IIRC and is appropriately sized to that function. Either that or it's a maximal size for a set of functions, I forget which. Regardless though you would have to make sure it's big enough yeah.
I see what you mean. I suppose that's also what teavm-java has done. I'll see what I can do on my side.
I may be wrong, but from what I see, the abi::Generator.post_return
doesn't seem to deallocate the pointer of the return area either.
I think this ought to be pointed out in the documentation that the return area is not expected to be allocated/deallocated dynamically for exportation.
whether or not it's allocated dynamically is up to the guest, the component model doesn't prescribe that it either is or isn't. In Rust at least the area is statically allocated so post-return is cleaning up the return values rather than the area itself. There's no reason it couldn't be dynamically allocated though
Zihang Ye has marked this topic as resolved.
Last updated: Dec 23 2024 at 12:05 UTC