emscripten-core / emscripten

Emscripten: An LLVM-to-WebAssembly Compiler
Other
25.74k stars 3.3k forks source link

Web-IDL: `sequence<long>` converted to just `int` in `glue.cpp` #20987

Open abhi-kr-2100 opened 9 months ago

abhi-kr-2100 commented 9 months ago

Version of emscripten/emsdk:

emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.51 (c0c2ca1314672a25699846b4663701bcb6f69cca)
clang version 18.0.0git (https://github.com/llvm/llvm-project f2464ca317bfeeedddb7cbdea3c2c8ec487890bb)
Target: wasm32-unknown-emscripten
Thread model: posix

Failing command line in full: tools/webidl_binder MyContainer.idl glue

The above command generates an incorrect glue.cpp file.

Source files:

// MyContainer.hpp
#include <array>

constexpr auto N = 1000;

class MyContainer {
public:
  void load(const std::array<int, N> &vals);
  const std::array<std::array<int, N>, N> &dump() const;

private:
  std::array<std::array<int, N>, N> elems;
};
// MyContainer.cpp
#include "MyContainer.hpp"
#include <array>

using std::array;
using std::size_t;

void MyContainer::load(const array<int, N> &vals) {
  for (size_t i = 0; i < N; ++i) {
    for (size_t j = 0; j < N; ++j) {
      elems[i][j] = vals[i];
    }
  }
}

const array<array<int, N>, N> &MyContainer::dump() const { return elems; }
// MyContainer.idl
interface MyContainer {
    void MyContainer();
    void load(sequence<long> vals);
    sequence<sequence<long>> dump();
};
// glue.cpp

#include <emscripten.h>
#include <stdlib.h>

EM_JS_DEPS(webidl_binder, "$intArrayFromString,$UTF8ToString");

extern "C" {

// Define custom allocator functions that we can force export using
// EMSCRIPTEN_KEEPALIVE.  This avoids all webidl users having to add
// malloc/free to -sEXPORTED_FUNCTIONS.
EMSCRIPTEN_KEEPALIVE void webidl_free(void* p) { free(p); }
EMSCRIPTEN_KEEPALIVE void* webidl_malloc(size_t len) { return malloc(len); }

// VoidPtr

void EMSCRIPTEN_KEEPALIVE emscripten_bind_VoidPtr___destroy___0(void** self) {
  delete self;
}

// MyContainer

MyContainer* EMSCRIPTEN_KEEPALIVE emscripten_bind_MyContainer_MyContainer_0() {
  return new MyContainer();
}

void EMSCRIPTEN_KEEPALIVE emscripten_bind_MyContainer_load_1(MyContainer* self, int vals) {
  self->load(vals);
}

int EMSCRIPTEN_KEEPALIVE emscripten_bind_MyContainer_dump_0(MyContainer* self) {
  return self->dump();
}

void EMSCRIPTEN_KEEPALIVE emscripten_bind_MyContainer___destroy___0(MyContainer* self) {
  delete self;
}

}
sbc100 commented 9 months ago

I doesn't look like we have any support yet for sequence in webidl_binder.py. At least we don't do any testing of it. It does look like we support arrays though using [] syntax: https://github.com/emscripten-core/emscripten/blob/2f102befe3745e2145ce97cfe9b947a7f31a64e6/test/webidl/test.idl#L147-L153.

@kripken is this a known/expected limitation?

kripken commented 9 months ago

Yes, I believe we only support very few types, and not arbitrary sequences. Simple ones as in long[] should work as you said @sbc100 , but I doubt anything else.