0

While I am very excited about the concept of WebAssembly and being able to code for the browser in C, I am disappointed that it only supports simple numeric data types.

For instance, see the answer to this question, which says

WebAssembly doesn't natively support a string type, it rather supports i32 / i64 / f32 / f64 value types as well as i8 / i16 for storage.

Obviously, there will be requirements to pass in JavaScript lists/arrays/objects and return, among others, C strings, arrays and structs.

Since these can be represented as an array of bytes, there should be little problem conerting them.

However, before I develop the mawg wheel, I thought it best to ask if anyone has already released any library for doing so.

I am currently coding Angular Js v1.X, so straight JS should handle that just fine. However, I am also planning to move to Angular 4 (or whatever number they have given it this month) and am not so sure about Type Script.

I will code my Web Assembly in C, making C support a "must have", while C++ support would be "nice to have".

  • 1
    If you're upgrading to modern Angular, use TypeScript. Angular utilizes TS's features to give you better tooling and such. – CAD97 Dec 6 '17 at 7:55
  • Thanks. I had sort of figured that out, but am still in the middle of two 1.X projects. I had been afraid to move until a few libraries that I use were ported, but that seems to have been done now. I will finish those two off & learn (sigh) yet another programming language. Yours was a good comment, for others reading this (+1) – Mawg Dec 6 '17 at 8:09
  • 1
    FWIW, TypeScript is very easy to start, coming from JavaScript. You can start off just writing JavaScript in a .ts file, and add type machinery incrementally on top as you want to. – CAD97 Dec 6 '17 at 8:12
  • And, let's see how much of that I can replace by WebAssembly? :-) Web development is just a hobby/side gig. My daytime breadwinner is coding embedded systems, mainly in C or C++. – Mawg Dec 6 '17 at 8:15
1

If you're using Emscripten already (or even if you aren't), their preamble offers some convenient extensions to WebAssembly.Module on the JavaScript side to make interacting with C FFI compatible functions easier. Namely (abreviated, see links for more information):

ccall(ident, returnType, argTypes, args, opts)

Call a compiled C function from JavaScript. The function executes a compiled C function from JavaScript and returns the result.

returnType and argTypes let you specify the types of parameters and the return value. The possible types are "number", "string" or "array", which correspond to the appropriate JavaScript types. Use "number" for any numeric type or C pointer, "string" for C char* that represent strings, and "array" for JavaScript arrays and typed arrays; for typed arrays, it must be a Uint8Array or Int8Array.

cwrap(ident, returnType, argTypes)

Returns a native JavaScript wrapper for a C function. This is similar to ccall(), but returns a JavaScript function that can be reused as many time as needed.

Notably, using the "string" argument/return value handles conversion between JavaScript strings and C char* (to stack space) strings.

As of current, I do not believe there are any pre-existing libraries for handling FFI for larger types. node-ffi exists as a library for handling FFI between the NodeJS runtime and dynamic libraries, and some of its machinery may be reusable for interfacing with a WASM runtime.

However, I think you may have misunderstood the purpose of WebAssembly. WebAssembly does not replace JavaScript.

Is WebAssembly trying to replace JavaScript?

No! WebAssembly is designed to be a complement to, not replacement of, JavaScript. While WebAssembly will, over time, allow many languages to be compiled to the Web, JavaScript has an incredible amount of momentum and will remain the single, privileged (as described above) dynamic language of the Web. Furthermore, it is expected that JavaScript and WebAssembly will be used together in a number of configurations:

  • Whole, compiled C++ apps that leverage JavaScript to glue things together.
  • HTML/CSS/JavaScript UI around a main WebAssembly-controlled center canvas, allowing developers to leverage the power of web frameworks to build accessible, web-native-feeling experiences.
  • Mostly HTML/CSS/JavaScript app with a few high-performance WebAssembly modules (e.g., graphing, simulation, image/sound/video processing, visualization, animation, compression, etc., examples which we can already see in asm.js today) allowing developers to reuse popular WebAssembly libraries just like JavaScript libraries today.
  • When WebAssembly gains the ability to access garbage-collected objects 🦄, those objects will be shared with JavaScript, and not live in a walled-off world of their own.

Even with that said, all JavaScript libraries are built around the expressiveness of the JavaScript language, and won't translate well into other languages. Libraries like React, Angular, and Vue use JavaScript's dynamic typing to enable key parts of their functionality.

Still, I'm open to see what's possible. WASM is still a young, growing beast, and what's a pipe dream today may be possible in the coming years. If you do something cool, make sure to share it!

  • 1
    My earlier answer to Alternative to JavaScript's side note about WASM may have misrepresented its scope. To that point I added a second answer from another point of view that clarifies WASM a bit and answers that original question in a separate manner from my first answer as well. – CAD97 Dec 6 '17 at 8:45
1

There is now a library that does much of this (for Rust)!

stdweb: https://github.com/koute/stdweb

Design goals

  • Expose a full suite of Web APIs as exposed by web browsers.

  • Try to follow the original JavaScript conventions and structure as much as possible, except in cases where doing otherwise results in a clearly superior design.

  • Be a building block from which higher level frameworks and libraries can be built.

  • Make it convenient and easy to embed JavaScript code directly into Rust and to marshal data between the two.

  • Integrate with the wider Rust ecosystem, e.g. support marshaling of structs which implement serde's Serializable.

  • Put Rust in the driver's seat where a non-trivial Web application can be written without touching JavaScript at all.

  • Allow Rust to take part in the upcoming WebAssembly (re)volution.

  • Make it possible to trivially create standalone libraries which are easily callable from JavaScript.

1

Following up on @CAD97's answer, wasm-bindgen is now available. It does its best to expose all javascript functionality to Rust applications compiled to WebAssembly.

Documented here is an example of using a serde macro to automatically encode and decode structs to/from javascript objects.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.