emscripten-core / emscripten

Emscripten: An LLVM-to-WebAssembly Compiler
Other
25.91k stars 3.32k forks source link

Smart pointer has empty PTR and COUNT properties #18498

Open paulocoutinhox opened 1 year ago

paulocoutinhox commented 1 year ago

Hi,

I have a problem with smart-pointer. When i pass it for a JS function, the PTR is undefined and COUNT is undefined.

image

The class that receive the smart-ptr is OK, but the method that receive a smart-ptr is wrong.

The bind code is:

EMSCRIPTEN_BINDINGS(xplpc_proxy_platform_proxy_callback)
{
    em::class_<xplpc::proxy::PlatformProxyCallback>("PlatformProxyCallback")
        .constructor<const std::function<void(const std::string &)> &&>()
        .smart_ptr<std::shared_ptr<xplpc::proxy::PlatformProxyCallback>>("shared_ptr<PlatformProxyCallback>")
        .function("call", &xplpc::proxy::PlatformProxyCallback::call);
}

File: https://github.com/xplpc/xplpc/blob/wasm-mapping/wasm/lib/src/bind.cpp#L33-L39

The javascript function is:

onRemoteProxyCallAsync: function (data: string, callback: XWebPlatformProxyCallback) {
    console.log("[XWebPlatformProxy : onRemoteProxyCallAsync] This: ", this);
    console.log("[XWebPlatformProxy : onRemoteProxyCallAsync] Callback: ", callback);
}

File: https://github.com/xplpc/xplpc/blob/wasm-mapping/wasm/sample/src/xplpc/proxy/platform-proxy.ts#L31-L33

The C++ code that call the JS function is:

void callProxyAsync(const std::string &data, std::shared_ptr<xplpc::proxy::PlatformProxyCallback> callback)
{
    // the count is 2
    spdlog::info("[callProxyAsync 1] Callback Smart Ptr Count: {}", callback.use_count());

    call<void>("onRemoteProxyCallAsync", data, callback);

    spdlog::info("[callProxyAsync 2]");
}

If need build my sample only need do this:

git clone https://github.com/xplpc/xplpc.git -b wasm-mapping
cd wasm-mapping
python3 xplpc.py wasm-build

Requirements: python3, cmake, emsdk, node-js, npm

What im doing wrong? Thanks.

sbc100 commented 1 year ago

I don't think anything has changed recently that might effect embind and smart pointers. You best bet might be trying to bisect to find out exactly when this broke: https://emscripten.org/docs/contributing/developers_guide.html#bisecting

paulocoutinhox commented 1 year ago

Yes, when i try old version, it still. There is a problem on all versions.

sbc100 commented 1 year ago

I assumed because you said "Since version 3.1.28 i have a problem with smart-pointer." that this code worked prior to 3.1.28?

I'm afraid I can't see at first glance what you might be doing wrong here. @brendandahl might be able to spot it.

paulocoutinhox commented 1 year ago

You are correct. I updated the title/description and add the sample on end.

@brendandahl can you help pls?

paulocoutinhox commented 1 year ago

@sbc100 and @brendandahl the problem is here:

void callProxyAsync(const std::string &data, std::shared_ptr<xplpc::proxy::PlatformProxyCallback> callback)
{
    call<void>("onRemoteProxyCallAsync", data, callback);
}

I need convert callback to em::val manually. Make sense?

void callProxyAsync(const std::string &data, std::shared_ptr<xplpc::proxy::PlatformProxyCallback> callback)
{
    call<void>("onRemoteProxyCallAsync", data, em::val(callback));
}

It can be a bug? Because it is registered with embind, but i need force it be em::val. Something is wrong, but it don't understand what:

EMSCRIPTEN_BINDINGS(xplpc_proxy_platform_proxy_callback)
{
    em::class_<xplpc::proxy::PlatformProxyCallback>("PlatformProxyCallback")
        .constructor<const std::function<void(const std::string &)> &&>()
        .smart_ptr<std::shared_ptr<xplpc::proxy::PlatformProxyCallback>>("shared_ptr<PlatformProxyCallback>")
        .function("call", &xplpc::proxy::PlatformProxyCallback::call);
}
brendandahl commented 1 year ago

I don't see anything obviously wrong, but there's quite a bit of code in that project. Can you make a single file example that illustrates the issue?