File: wasm.R

package info (click to toggle)
r-cran-v8 6.0.2%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 436 kB
  • sloc: javascript: 980; cpp: 424; sh: 23; makefile: 8
file content (54 lines) | stat: -rw-r--r-- 1,886 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#' Experimental WebAssembly
#'
#' Experimental wrapper to load a WebAssembly program. Returns a list of
#' exported functions. This will probably be moved into it's own package
#' once WebAssembly matures.
#'
#' The `wasm_features()` function uses the [wasm-feature-detect](https://github.com/GoogleChromeLabs/wasm-feature-detect)
#' JavaScript library to test which WASM capabilities are supported in the
#' current version of libv8.
#'
#' @export
#' @rdname wasm
#' @param data either raw vector or file path with the binary wasm program
#' @examples # Load example wasm program
#' instance <- wasm(system.file('wasm/add.wasm', package = 'V8'))
#' instance$exports$add(12, 30)
wasm <- function(data){
  if(is.character(data))
    data <- readBin(normalizePath(data, mustWork = TRUE), raw(), file.info(data)$size)
  if(!is.raw(data))
    stop("Data must be file path or raw vector")
  ctx <- v8()
  ctx$assign('bytes', data)
  ctx$eval('let module = new WebAssembly.Module(bytes);')
  ctx$eval('let instance = new WebAssembly.Instance(module);')
  function_names <- ctx$get('Object.keys(instance.exports)')
  exports <- structure(lapply(function_names, function(f){
    body <- sprintf('call("instance.exports.%s", ...)', f)
    fun <- list(... = substitute(), parse(text = body)[[1]])
    as.function(fun, envir = environment(ctx$call))
  }), names = function_names)
  list(
    exports = exports
  )
}

#' @export
#' @rdname wasm
#' @examples wasm_features()
wasm_features <- function(){
  ctx <- v8()
  ctx$source(system.file('js/wasm-feature-detect.js', package = 'V8'))
  wrapper <- "async function test_wasm_features() {
  let out = {};
  keys = Object.keys(wasmFeatureDetect);
  for (var i = 0; i < keys.length; i++) {
    var key = keys[i];
    out[key] = await wasmFeatureDetect[key]()
  }
  return out;
}"
  ctx$eval(wrapper)
  ctx$call('test_wasm_features', await = TRUE)
}