This repository has been archived by the owner on Jan 10, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
README.Rmd
142 lines (109 loc) · 3.87 KB
/
README.Rmd
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
---
output: github_document
---
<!-- README.md is generated from README.Rmd. Please edit that file -->
```{r, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
fig.path = "man/figures/README-",
out.width = "100%"
)
```
# WebAssembly in R using wasmer
<!-- badges: start -->
[![Lifecycle: experimental](https://img.shields.io/badge/lifecycle-experimental-orange.svg)](https://www.tidyverse.org/lifecycle/#experimental)
[![Travis build status](https://travis-ci.org/dirkschumacher/wasmr.svg?branch=master)](https://travis-ci.org/dirkschumacher/wasmr)
<!-- badges: end -->
The goal of `wasmr` is to run [WebAssembly](https://developer.mozilla.org/en-US/docs/WebAssembly/Concepts) code from R using the [wasmer](https://wasmer.io/) runtime.
This is a early version with probably bugs, missing features and not the best code quality. But it already works and I am happy to hear feedback. The goal is that this package evolves into something stable.
The package is mainly written in C++ using the C API of the `wasmer` runtime which is written in `rust`. You therefore need a rust compiler to install the package.
## Installation
``` r
remotes::install_github("dirkschumacher/wasmr")
```
Also make sure to have a very recent rust compiler. The best way to install the rust toolchain is to use [rustup](https://rustup.rs/).
## Example
```{r example}
library(wasmr)
```
```{r}
f <- system.file("examples/sum.wasm", package = "wasmr")
instance <- instantiate(f)
instance$exports$sum(10, 20)
```
```{r}
f <- system.file("examples/hello.wasm", package = "wasmr")
instance <- instantiate(f)
memory_pointer <- instance$exports$hello()
hi <- instance$memory$get_memory_view(memory_pointer)
rawToChar(hi$get(1:11))
```
```{r}
f <- system.file("examples/fib.wasm", package = "wasmr")
instance <- instantiate(f)
instance$exports$fib(20)
fib <- function(n) {
if (n < 2) return(n)
fib(n - 1) + fib(n - 2)
}
microbenchmark::microbenchmark(
instance$exports$fib(20),
fib(20)
)
```
## Memory
```{r}
f <- system.file("examples/fib.wasm", package = "wasmr")
instance <- instantiate(f)
instance$memory$get_memory_length()
# grow the number of pages
instance$memory$grow(1)
instance$memory$get_memory_length()
```
```{r}
f <- system.file("examples/hello.wasm", package = "wasmr")
instance <- instantiate(f)
memory_pointer <- instance$exports$hello()
memory <- instance$memory$get_memory_view(memory_pointer)
memory$get(1:11)
rawToChar(memory$get(1:11))
# you can also write to the internal memory
memory$set(5:6, charToRaw("o_"))
rawToChar(memory$get(1:11))
```
### Imports
```{r}
set.seed(42)
imports <- list(
env = list(
add = typed_function(
function(a, b) {
# use R's RNG to add a random number to the result
a + b * as.integer(runif(1) * 100)
},
param_types = c("I32", "I32"),
return_type = "I32"
)
)
)
f <- system.file("examples/sum_import.wasm", package = "wasmr")
instance <- instantiate(f, imports)
# sum: add(a, b) + 42
instance$exports$sum(1, 5)
```
## Caveats and limitations
* It is not feature complete and does not support everything that `wasm` supports
* Imported functions can only have integer parameters
* No globals
* There is hardly any documentation except for the examples
* `I32/I64` are mapped to `IntegerVector` and `F32/F64` to `NumericVector`. Currently no way to differentiate.
* WIP
## Inspiration and References
* [wasmer Python](https://github.com/wasmerio/python-ext-wasm) - haven't tried it but looked at the API/examples
* [wasmer](https://github.com/wasmerio/wasmer) - especially the C api and the tests give some good examples.
* @jeroen 's [rust template](https://github.com/r-rust/hellorust)
## Contribute
While this is work in progress, the best way to contribute is to test the package and write/comment on issues. Before sending a PR it would great to post an issue first to discuss.
## License
MIT just like wasmer.