Difference between revisions of "WebAssembly/JS"

From Free Pascal wiki
Jump to navigationJump to search
(Created page with "The primary target for WebAssembly is the browser. WebAssembly is not a Javascript, it's only an addition to Javascript. WebAssembly is not asm.js. ==API== The primary API...")
 
Line 8: Line 8:
 
The primary API for dealing with WebAssembly (.wasm) files is [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly WebAssembly JS] standard
 
The primary API for dealing with WebAssembly (.wasm) files is [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly WebAssembly JS] standard
 
==Dependencies==
 
==Dependencies==
 +
As of 2019 there's no "out-of-the-box" way to resolve WebAssembly file '''import''' dependencies.
 +
 +
WebAssembly expects an import to be resolved by providing the import module name. The import module name doesn't have to be a WebAssembly module, it can be a plain JavaScript function as well. And the name of the object (i.e. function of memory) WebAssembly is trying to access.
 +
 +
<source lang="javascript">
 +
async function runWasm()
 +
{
 +
  var r = await fetch('../out/main.wasm'); // Promise() object handling getting of the file
 +
  var bytes = await r.arrayBuffer();
 +
  var mainmod = await WebAssembly.compile(bytes);
 +
  // console.log(mainmod); // print the main module
 +
 
 +
  var impobj = {};
 +
  var imports = WebAssembly.Module.imports(mainmod);
 +
  // console.log(imports); // print dependencies list
 +
  var loadedInst = [];
 +
 +
  // loading dependencies should be recursive!
 +
  for (var i = 0; i < imports.length; i++)
 +
  {
 +
      var dep  = imports[i];
 +
 +
      var subinst = loadedInst[dep.module];
 +
      if (!subinst)
 +
      {
 +
        var rr = await fetch('../out/'+dep.module+'.wasm');
 +
        var buf = await rr.arrayBuffer();
 +
        var submod = await WebAssembly.instantiate(buf);
 +
        subinst = submod.instance;
 +
        loadedInst[dep.module] = subinst;
 +
      }
 +
      //console.log(subinst); // print the sub module instance
 +
 +
      var impmod = impobj[dep.module];
 +
      if (!impmod) {
 +
        impmod = {};
 +
        impobj[dep.module] = impmod;
 +
      }
 +
      impmod[dep.name] = await subinst.exports[dep.name];
 +
      impobj[dep.module] = impmod;
 +
  }
 +
  // console.log(impobj); // print of imported object object
 +
 +
  var maininst = await WebAssembly.instantiate(mainmod, impobj);
 +
  // console.log(maininst); // print of the main instance object
 +
 +
  // calling the main() function of the main unit
 +
  document.getElementById("container").textContent = maininst.exports.$main();
 +
}
 +
runWasm();
 +
</source>
 +
 
==See Also==
 
==See Also==
 
*[[WebAsembly]]
 
*[[WebAsembly]]
 
*[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly WebAssembly JS] at MDN
 
*[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly WebAssembly JS] at MDN
 
[[Category:WebAssembly]]
 
[[Category:WebAssembly]]

Revision as of 18:55, 5 September 2019

The primary target for WebAssembly is the browser.

WebAssembly is not a Javascript, it's only an addition to Javascript.

WebAssembly is not asm.js.

API

The primary API for dealing with WebAssembly (.wasm) files is WebAssembly JS standard

Dependencies

As of 2019 there's no "out-of-the-box" way to resolve WebAssembly file import dependencies.

WebAssembly expects an import to be resolved by providing the import module name. The import module name doesn't have to be a WebAssembly module, it can be a plain JavaScript function as well. And the name of the object (i.e. function of memory) WebAssembly is trying to access.

async function runWasm()
{
   var r = await fetch('../out/main.wasm'); // Promise() object handling getting of the file
   var bytes = await r.arrayBuffer();
   var mainmod = await WebAssembly.compile(bytes);
   // console.log(mainmod); // print the main module
   
   var impobj = {};
   var imports = WebAssembly.Module.imports(mainmod);
   // console.log(imports); // print dependencies list
   var loadedInst = [];

   // loading dependencies should be recursive!
   for (var i = 0; i < imports.length; i++)
   {
      var dep  = imports[i];

      var subinst = loadedInst[dep.module];
      if (!subinst) 
      {
        var rr = await fetch('../out/'+dep.module+'.wasm');
        var buf = await rr.arrayBuffer();
        var submod = await WebAssembly.instantiate(buf);
        subinst = submod.instance;
        loadedInst[dep.module] = subinst;
      }
      //console.log(subinst); // print the sub module instance

      var impmod = impobj[dep.module];
      if (!impmod) {
        impmod = {};
        impobj[dep.module] = impmod;
      } 
      impmod[dep.name] = await subinst.exports[dep.name];
      impobj[dep.module] = impmod;
   }
   // console.log(impobj); // print of imported object object

   var maininst = await WebAssembly.instantiate(mainmod, impobj);
   // console.log(maininst); // print of the main instance object

   // calling the main() function of the main unit
   document.getElementById("container").textContent = maininst.exports.$main();
}
runWasm();

See Also