torch2424 / wasm-by-example

Wasm By Example is a website with a set of hands-on introduction examples and tutorials for WebAssembly (Wasm)
https://wasmbyexample.dev/
492 stars 121 forks source link

Add Emscripten Examples #3

Open torch2424 opened 5 years ago

torch2424 commented 5 years ago

Was going to do this in the MVP. But honestly, I know nothing about Emscripten :joy:

Thus, I think I will go ahead, launch, and get the hype going, and then teach myself emscripten to make the demos :+1:

datalowe commented 8 months ago

Hi, thanks for putting together the project/examples :) I don't know how active this project is, but in case it's helpful for anyone else then here's a quick emscripten version of the "linear memory" example for Rust.

// linmem.cpp
#include <iostream>

const int WASM_MEMORY_BUFFER_SIZE {2};
uint8_t buffer[WASM_MEMORY_BUFFER_SIZE] {0};

extern "C" {
  void put_buffer_index_zero(uint8_t val) {
    buffer[0] = val;
  }

  uint8_t* get_buffer_ptr() {
    return buffer;
  }

  uint8_t get_buffer_index_one() {
    return buffer[1];
  }
}
// use_wasm.js
(async () => {
  const resp = await fetch("linmem.wasm");
  const fileBuf = await resp.arrayBuffer();
  const linMemModule = await WebAssembly.instantiate(fileBuf);
  const {
    memory,
    put_buffer_index_zero,
    get_buffer_ptr,
    get_buffer_index_one,
  } = linMemModule.instance.exports;

  const p1 = document.createElement("p");
  p1.appendChild(
    document.createTextNode(
      `Initial value at buffer index 1: ${get_buffer_index_one()}`
    )
  );
  document.body.appendChild(p1);

  const ptr = get_buffer_ptr();
  const memBuffer = new Uint8Array(memory.buffer);

  put_buffer_index_zero(200);
  const p2 = document.createElement("p");
  p2.appendChild(
    document.createTextNode(
      `Inserted value at buffer index 0: ${memBuffer[ptr + 0]}`
    )
  );
  document.body.appendChild(p2);

  memBuffer[ptr + 1] = 15;
  const p3 = document.createElement("p");
  p3.appendChild(
    document.createTextNode(
      `Directly updated value at buffer index 1: ${get_buffer_index_one()}`
    )
  );
  document.body.appendChild(p3);
})();
<!-- index.html -->
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Linear Memory - Emscripten</title>
    <script type="module" src="./use_wasm.js"></script>
  </head>
  <body></body>
</html>
emcc -O3 -s STANDALONE_WASM -s EXPORTED_FUNCTIONS="['_put_buffer_index_zero', '_get_buffer_ptr', '_get_buffer_index_one']" -Wl,--no-entry linmem.cpp -o "linmem.wasm"
# serving files in the current dir with Python, but any other HTTP server will do
python -m http.server --bind 127.0.0.1 8080