Difference between revisions of "Generating WebAssembly with LDC"

From D Wiki
Jump to: navigation, search
m (Test in HTML page)
m
Line 5: Line 5:
 
Let's generate a .wasm file for this D code (<tt>wasm.d</tt>):
 
Let's generate a .wasm file for this D code (<tt>wasm.d</tt>):
  
<pre>
+
<syntaxhighlight lang="D">
 
extern(C): // disable D mangling
 
extern(C): // disable D mangling
  
Line 12: Line 12:
 
// seems to be the required entry point
 
// seems to be the required entry point
 
void _start() {}
 
void _start() {}
</pre>
+
</syntaxhighlight>
  
Invoke <tt>ldc2 -mtriple=wasm32-unknown-unknown-wasm -betterC -link-internally wasm.d</tt>, this generates a <tt>wasm.wasm</tt> file.
+
Build <tt>wasm.wasm</tt>:
 +
 
 +
<pre>ldc2 -mtriple=wasm32-unknown-unknown-wasm -betterC -link-internally wasm.d</pre>
  
 
In case LDC errors out (e.g., with unsupported <tt>-link-internally</tt>), try an [https://github.com/ldc-developers/ldc/releases/ official prebuilt release package].
 
In case LDC errors out (e.g., with unsupported <tt>-link-internally</tt>), try an [https://github.com/ldc-developers/ldc/releases/ official prebuilt release package].
Line 22: Line 24:
 
Let's test it with a little HTML page, loading and invoking the WebAssembly via JavaScript. Generate an .html file in the same directory as the .wasm file, with the following contents:
 
Let's test it with a little HTML page, loading and invoking the WebAssembly via JavaScript. Generate an .html file in the same directory as the .wasm file, with the following contents:
  
<pre>
+
<syntaxhighlight lang="HTML">
 
<html>
 
<html>
 
   <head>
 
   <head>
Line 51: Line 53:
 
   </body>
 
   </body>
 
</html>
 
</html>
</pre>
+
</syntaxhighlight>
  
 
Note that <tt>fetch()</tt> doesn't work for files in the local filesystem, but <tt>XMLHttpRequest</tt> does in Firefox (not in Chrome though IIRC).
 
Note that <tt>fetch()</tt> doesn't work for files in the local filesystem, but <tt>XMLHttpRequest</tt> does in Firefox (not in Chrome though IIRC).
 +
 
Open the HTML page; the JavaScript console should show:
 
Open the HTML page; the JavaScript console should show:
  

Revision as of 16:24, 15 July 2018

Starting with v1.11, LDC supports compiling and linking directly to WebAssembly. This page shows how to get started.

Building WebAssembly

Let's generate a .wasm file for this D code (wasm.d):

extern(C): // disable D mangling

double add(double a, double b) { return a + b; }

// seems to be the required entry point
void _start() {}

Build wasm.wasm:

ldc2 -mtriple=wasm32-unknown-unknown-wasm -betterC -link-internally wasm.d

In case LDC errors out (e.g., with unsupported -link-internally), try an official prebuilt release package.

Test in HTML page

Let's test it with a little HTML page, loading and invoking the WebAssembly via JavaScript. Generate an .html file in the same directory as the .wasm file, with the following contents:

<html>
  <head>
    <script>

const request = new XMLHttpRequest();
request.open('GET', 'wasm.wasm');
request.responseType = 'arraybuffer';
request.onload = () => {
  console.log('response received');
  const bytes = request.response;
  const importObject = {};
  WebAssembly.instantiate(bytes, importObject).then(result => {
    console.log('instantiated');
    const { exports } = result.instance;
    // finally, call the add() function implemented in D:
    const r = exports.add(42, -2.5);
    console.log('r = ' + r);
  });
};
request.send();
console.log('request sent');

    </script>
  </head>
  <body>
    Test page
  </body>
</html>

Note that fetch() doesn't work for files in the local filesystem, but XMLHttpRequest does in Firefox (not in Chrome though IIRC).

Open the HTML page; the JavaScript console should show:

request sent
response received
instantiated
r = 39.5