Stream: git-wasmtime

Topic: wasmtime / issue #10396 borrow handles still remain at th...


view this post on Zulip Wasmtime GitHub notifications bot (Mar 14 2025 at 09:34):

sammyne opened issue #10396:

Based on this awesome sdk, I build a project (https://github.com/sammyne/cc-wasip2-borrow-handles-remain-at-the-end-of-the-call) demo simple component using borrowed resource.
It failed the wasmtime post-return with error as

borrow handles still remain at the end of the call

Environment

Brief

Guest component

WIT

package sammyne:helloworld@1.0.0;

interface greeter {
    use types.{context, hello-request, hello-reply};

    say-hello: func(ctx: borrow<context>, req: hello-request) -> hello-reply;
}

interface types {
    record hello-request {
        name: string,
    }

    record hello-reply {
        message: string,
    }

    resource context {
        request-id: func() -> s64;
    }
}

/// An example world for the component to target.
world helloworld {
    export greeter;
}

C++ implementation

#include <iostream>
#include <string>

#include "helloworld.h"

void exports_sammyne_helloworld_greeter_say_hello(
    exports_sammyne_helloworld_greeter_borrow_context_t ctx,
    exports_sammyne_helloworld_greeter_hello_request_t *req,
    exports_sammyne_helloworld_greeter_hello_reply_t *ret) {
  auto request_id = sammyne_helloworld_types_method_context_request_id(ctx);
  printf("request-id = %lld\n", request_id);

  std::string message((const char *)(req->name.ptr), req->name.len);

  message = std::string("Hello ") + message + std::string(" with request-id=") +
            std::to_string(request_id);

  helloworld_string_dup(&ret->message, message.c_str());
}

Reproduction

Build the component written in C++ in the guest foler and the host written in Rust in the host-rs folder with the
following command

make run

It will output sample errors as

borrow handles still remain at the end of the call

Really apprecate if someone could help me out~

view this post on Zulip Wasmtime GitHub notifications bot (Mar 14 2025 at 14:23):

alexcrichton closed issue #10396:

Based on this awesome sdk, I build a project (https://github.com/sammyne/cc-wasip2-borrow-handles-remain-at-the-end-of-the-call) demo simple component using borrowed resource.
It failed the wasmtime post-return with error as

borrow handles still remain at the end of the call

Environment

Brief

Guest component

WIT

package sammyne:helloworld@1.0.0;

interface greeter {
    use types.{context, hello-request, hello-reply};

    say-hello: func(ctx: borrow<context>, req: hello-request) -> hello-reply;
}

interface types {
    record hello-request {
        name: string,
    }

    record hello-reply {
        message: string,
    }

    resource context {
        request-id: func() -> s64;
    }
}

/// An example world for the component to target.
world helloworld {
    export greeter;
}

C++ implementation

#include <iostream>
#include <string>

#include "helloworld.h"

void exports_sammyne_helloworld_greeter_say_hello(
    exports_sammyne_helloworld_greeter_borrow_context_t ctx,
    exports_sammyne_helloworld_greeter_hello_request_t *req,
    exports_sammyne_helloworld_greeter_hello_reply_t *ret) {
  auto request_id = sammyne_helloworld_types_method_context_request_id(ctx);
  printf("request-id = %lld\n", request_id);

  std::string message((const char *)(req->name.ptr), req->name.len);

  message = std::string("Hello ") + message + std::string(" with request-id=") +
            std::to_string(request_id);

  helloworld_string_dup(&ret->message, message.c_str());
}

Reproduction

Build the component written in C++ in the guest foler and the host written in Rust in the host-rs folder with the
following command

make run

It will output sample errors as

borrow handles still remain at the end of the call

Really apprecate if someone could help me out~

view this post on Zulip Wasmtime GitHub notifications bot (Mar 14 2025 at 14:23):

alexcrichton commented on issue #10396:

Thanks for the report! If you plan on using C and/or C++ bindings for component APIs you'll need to become very familiar with the upstream definition of the canonical ABI. There are requirements that guests need to uphold that are automatically handled in languages like JS and Rust but when using the C bindings for wit-bindgen you'll need to manually handle all of it.

For example in this case the canonical ABI dictates that when given a borrow<T> you're required to drop that borrow before the call returns. Here you're not dropping the borrow, hence the trap.

This is currently expected behavior so I'm going to close this, but feel free to follow-up here if there's more questions.

view this post on Zulip Wasmtime GitHub notifications bot (Mar 17 2025 at 11:18):

sammyne commented on issue #10396:

Thanks for the report! If you plan on using C and/or C++ bindings for component APIs you'll need to become very familiar with the upstream definition of the canonical ABI. There are requirements that guests need to uphold that are automatically handled in languages like JS and Rust but when using the C bindings for wit-bindgen you'll need to manually handle all of it.

For example in this case the canonical ABI dictates that when given a borrow<T> you're required to drop that borrow before the call returns. Here you're not dropping the borrow, hence the trap.

This is currently expected behavior so I'm going to close this, but feel free to follow-up here if there's more questions.

Which API can be used to drop the borrow<T>? @alexcrichton

view this post on Zulip Wasmtime GitHub notifications bot (Mar 17 2025 at 11:22):

sammyne edited a comment on issue #10396:

Thanks for the report! If you plan on using C and/or C++ bindings for component APIs you'll need to become very familiar with the upstream definition of the canonical ABI. There are requirements that guests need to uphold that are automatically handled in languages like JS and Rust but when using the C bindings for wit-bindgen you'll need to manually handle all of it.

For example in this case the canonical ABI dictates that when given a borrow<T> you're required to drop that borrow before the call returns. Here you're not dropping the borrow, hence the trap.

This is currently expected behavior so I'm going to close this, but feel free to follow-up here if there's more questions.

So I need to drop the borrow<context> in func exports_sammyne_helloworld_greeter_say_hello before return.

Which API can be used to drop the borrow<T>? @alexcrichton

view this post on Zulip Wasmtime GitHub notifications bot (Mar 17 2025 at 11:37):

sammyne edited a comment on issue #10396:

Thanks for the report! If you plan on using C and/or C++ bindings for component APIs you'll need to become very familiar with the upstream definition of the canonical ABI. There are requirements that guests need to uphold that are automatically handled in languages like JS and Rust but when using the C bindings for wit-bindgen you'll need to manually handle all of it.

For example in this case the canonical ABI dictates that when given a borrow<T> you're required to drop that borrow before the call returns. Here you're not dropping the borrow, hence the trap.

This is currently expected behavior so I'm going to close this, but feel free to follow-up here if there's more questions.

Adding the --autodrop-borrows option to wit-bindgen c would generated the necessary stub dropping the borrow. Great thanks~


Last updated: Apr 19 2025 at 23:03 UTC