leaningtech / cheerp-meta

Cheerp - a C/C++ compiler for Web applications - compiles to WebAssembly and JavaScript
https://labs.leaningtech.com/cheerp
Other
1.02k stars 50 forks source link

Multiparameter callback C++ lambdas ignore arguments except the first #91

Closed yeputons closed 5 years ago

yeputons commented 5 years ago

Example code:

#include <cheerp/client.h>

namespace client {
    void bar(Object*);
};

void webMain() {
    int xxx = 10000;
    auto x = cheerp::Callback([xxx](int a, int b, int c) {
        client::console.log("a", a);
        client::console.log("b", b);
        client::console.log("c", c);
        client::console.log("xxx", xxx);
    });
    __asm__("function bar(f) { f(1, 2, 3); }" ::: "f");
    client::bar(x);
}

I expect it to either produce a compilation error or print 1 2 3 10000. However, when compiled with "C:\cheerp\bin\clang++.exe" -target cheerp -cheerp-pretty-code -O2 -o a.js a.cpp it prints:

a 1
b undefined
c undefined
xxx 10000

I think cheerpCreateClosure* are fishy: they create a closure which only takes one parameter:

function cheerpCreateClosureSplit(func, obj, objo){return function(e){func(obj,objo,e);};}

The code works as expected after modifying it manually to

function cheerpCreateClosureSplit(func, obj, objo){return function(){func(obj,objo,...arguments);};}

Note that this uses spread syntax from ECMAScript2015, so you may want to rewrite it with Function.apply instead.

alexp-sssup commented 5 years ago

This is a known bug, but thanks for creating the issue, we will close this when it's eventually fixed.

alexp-sssup commented 5 years ago

As a workaround you can simply use [[cheerp::jsexport]] to make C++ functions available on the JS side.

alexp-sssup commented 5 years ago

This issue is fixed in current master