wasmer 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/documentation.yml +50 -0
- data/.github/workflows/test.yml +34 -61
- data/CHANGELOG.md +89 -29
- data/Cargo.lock +812 -380
- data/Cargo.toml +7 -20
- data/Gemfile +2 -3
- data/README.md +1 -0
- data/Rakefile +4 -3
- data/crates/rutie-derive-macros/Cargo.toml +19 -0
- data/crates/rutie-derive-macros/README.md +4 -0
- data/crates/rutie-derive-macros/src/class.rs +156 -0
- data/crates/rutie-derive-macros/src/function.rs +178 -0
- data/crates/rutie-derive-macros/src/lib.rs +27 -0
- data/crates/rutie-derive-macros/src/methods.rs +282 -0
- data/crates/rutie-derive/Cargo.toml +14 -0
- data/crates/rutie-derive/README.md +97 -0
- data/crates/rutie-derive/src/lib.rs +4 -0
- data/crates/rutie-derive/src/upcast.rs +47 -0
- data/crates/rutie-test/Cargo.toml +10 -0
- data/crates/rutie-test/src/lib.rs +38 -0
- data/crates/wasmer/Cargo.toml +27 -0
- data/crates/wasmer/README.md +228 -0
- data/crates/wasmer/src/doc.rs +1512 -0
- data/crates/wasmer/src/error.rs +55 -0
- data/crates/wasmer/src/exports.rs +107 -0
- data/crates/wasmer/src/externals/function.rs +159 -0
- data/crates/wasmer/src/externals/global.rs +62 -0
- data/crates/wasmer/src/externals/memory.rs +117 -0
- data/crates/wasmer/src/externals/mod.rs +9 -0
- data/crates/wasmer/src/externals/table.rs +41 -0
- data/crates/wasmer/src/import_object.rs +78 -0
- data/crates/wasmer/src/instance.rs +45 -0
- data/crates/wasmer/src/lib.rs +307 -0
- data/crates/wasmer/src/memory/mod.rs +1 -0
- data/crates/wasmer/src/memory/views.rs +112 -0
- data/crates/wasmer/src/module.rs +106 -0
- data/crates/wasmer/src/prelude.rs +3 -0
- data/crates/wasmer/src/store.rs +22 -0
- data/crates/wasmer/src/types.rs +390 -0
- data/crates/wasmer/src/values.rs +84 -0
- data/crates/wasmer/src/wasi.rs +226 -0
- data/crates/wasmer/src/wat.rs +20 -0
- data/justfile +7 -1
- data/lib/wasmer.rb +29 -3
- data/wasmer.gemspec +6 -10
- metadata +45 -47
- data/README.md +0 -332
- data/lib/wasmer/version.rb +0 -3
- data/src/error.rs +0 -16
- data/src/instance/exports.rs +0 -215
- data/src/instance/globals.rs +0 -234
- data/src/instance/mod.rs +0 -141
- data/src/lib.rs +0 -162
- data/src/memory/mod.rs +0 -158
- data/src/memory/view.rs +0 -145
- data/src/module.rs +0 -28
@@ -0,0 +1,41 @@
|
|
1
|
+
use crate::{
|
2
|
+
error::{to_ruby_err, RuntimeError},
|
3
|
+
prelude::*,
|
4
|
+
store::Store,
|
5
|
+
types::TableType,
|
6
|
+
values::Value,
|
7
|
+
};
|
8
|
+
use rutie::AnyObject;
|
9
|
+
|
10
|
+
#[rubyclass(module = "Wasmer")]
|
11
|
+
pub struct Table {
|
12
|
+
inner: wasmer::Table,
|
13
|
+
}
|
14
|
+
|
15
|
+
impl Table {
|
16
|
+
pub fn raw_new(inner: wasmer::Table) -> Self {
|
17
|
+
Self { inner }
|
18
|
+
}
|
19
|
+
|
20
|
+
pub(crate) fn inner(&self) -> &wasmer::Table {
|
21
|
+
&self.inner
|
22
|
+
}
|
23
|
+
}
|
24
|
+
|
25
|
+
#[rubymethods]
|
26
|
+
impl Table {
|
27
|
+
pub fn new(
|
28
|
+
store: &Store,
|
29
|
+
table_type: &TableType,
|
30
|
+
initial_value: &Value,
|
31
|
+
) -> RubyResult<AnyObject> {
|
32
|
+
Ok(Table::ruby_new(Table::raw_new(
|
33
|
+
wasmer::Table::new(
|
34
|
+
store.inner(),
|
35
|
+
table_type.into(),
|
36
|
+
initial_value.inner().clone(),
|
37
|
+
)
|
38
|
+
.map_err(to_ruby_err::<RuntimeError, _>)?,
|
39
|
+
)))
|
40
|
+
}
|
41
|
+
}
|
@@ -0,0 +1,78 @@
|
|
1
|
+
use crate::{
|
2
|
+
error::{to_ruby_err, unwrap_or_raise, TypeError},
|
3
|
+
externals::{function::RubyFunction, global::RubyGlobal, memory::RubyMemory, table::RubyTable},
|
4
|
+
prelude::*,
|
5
|
+
};
|
6
|
+
use rutie::{AnyObject, Boolean, Hash, NilClass, Object, RString, Symbol};
|
7
|
+
|
8
|
+
#[rubyclass(module = "Wasmer")]
|
9
|
+
pub struct ImportObject {
|
10
|
+
inner: wasmer::ImportObject,
|
11
|
+
}
|
12
|
+
|
13
|
+
impl ImportObject {
|
14
|
+
pub(crate) fn raw_new(inner: wasmer::ImportObject) -> Self {
|
15
|
+
Self { inner }
|
16
|
+
}
|
17
|
+
|
18
|
+
pub(crate) fn inner(&self) -> &wasmer::ImportObject {
|
19
|
+
&self.inner
|
20
|
+
}
|
21
|
+
}
|
22
|
+
|
23
|
+
#[rubymethods]
|
24
|
+
impl ImportObject {
|
25
|
+
pub fn new() -> RubyResult<AnyObject> {
|
26
|
+
Ok(ImportObject::ruby_new(ImportObject {
|
27
|
+
inner: Default::default(),
|
28
|
+
}))
|
29
|
+
}
|
30
|
+
|
31
|
+
pub fn contains_namespace(&self, namespace_name: &RString) -> RubyResult<Boolean> {
|
32
|
+
Ok(Boolean::new(
|
33
|
+
self.inner().contains_namespace(namespace_name.to_str()),
|
34
|
+
))
|
35
|
+
}
|
36
|
+
|
37
|
+
pub fn register(&mut self, namespace_name: &RString, namespace: &Hash) -> RubyResult<NilClass> {
|
38
|
+
let mut wasmer_namespace = wasmer::Exports::new();
|
39
|
+
|
40
|
+
namespace.each(|key, value| {
|
41
|
+
unwrap_or_raise(|| {
|
42
|
+
let name = if let Ok(name) = key.try_convert_to::<RString>() {
|
43
|
+
name.to_string()
|
44
|
+
} else if let Ok(name) = key.try_convert_to::<Symbol>() {
|
45
|
+
name.to_string()
|
46
|
+
} else {
|
47
|
+
return Err(to_ruby_err::<TypeError, _>(format!(
|
48
|
+
"`ImportObject` cannot register the name because it has an invalid type `{:?}` (expects `String` or `Symbol`)",
|
49
|
+
key.ty()
|
50
|
+
)));
|
51
|
+
};
|
52
|
+
|
53
|
+
if let Ok(function) = value.try_convert_to::<RubyFunction>() {
|
54
|
+
wasmer_namespace.insert(name, function.upcast().inner().clone());
|
55
|
+
} else if let Ok(memory) = value.try_convert_to::<RubyMemory>() {
|
56
|
+
wasmer_namespace.insert(name, memory.upcast().inner().clone());
|
57
|
+
} else if let Ok(global) = value.try_convert_to::<RubyGlobal>() {
|
58
|
+
wasmer_namespace.insert(name, global.upcast().inner().clone());
|
59
|
+
} else if let Ok(table) = value.try_convert_to::<RubyTable>() {
|
60
|
+
wasmer_namespace.insert(name, table.upcast().inner().clone());
|
61
|
+
} else {
|
62
|
+
return Err(to_ruby_err::<TypeError, _>(format!(
|
63
|
+
"`ImportObject` cannot register the given type `{:?}` associated to `{:?}`",
|
64
|
+
value.ty(),
|
65
|
+
name,
|
66
|
+
)));
|
67
|
+
}
|
68
|
+
|
69
|
+
Ok(())
|
70
|
+
});
|
71
|
+
});
|
72
|
+
|
73
|
+
self.inner
|
74
|
+
.register(namespace_name.to_str(), wasmer_namespace);
|
75
|
+
|
76
|
+
Ok(NilClass::new())
|
77
|
+
}
|
78
|
+
}
|
@@ -0,0 +1,45 @@
|
|
1
|
+
use crate::{
|
2
|
+
error::{to_ruby_err, RuntimeError},
|
3
|
+
exports::Exports,
|
4
|
+
import_object::RubyImportObject,
|
5
|
+
module::Module,
|
6
|
+
prelude::*,
|
7
|
+
};
|
8
|
+
use rutie::{AnyObject, Object};
|
9
|
+
|
10
|
+
#[rubyclass(module = "Wasmer")]
|
11
|
+
pub struct Instance {
|
12
|
+
_inner: wasmer::Instance,
|
13
|
+
exports: AnyObject,
|
14
|
+
}
|
15
|
+
|
16
|
+
#[rubymethods]
|
17
|
+
impl Instance {
|
18
|
+
pub fn new(module: &Module, import_object: &AnyObject) -> RubyResult<AnyObject> {
|
19
|
+
let module = module.inner();
|
20
|
+
|
21
|
+
let instance = if import_object.is_nil() {
|
22
|
+
wasmer::Instance::new(&module, &wasmer::imports! {})
|
23
|
+
} else {
|
24
|
+
wasmer::Instance::new(
|
25
|
+
&module,
|
26
|
+
import_object
|
27
|
+
.try_convert_to::<RubyImportObject>()?
|
28
|
+
.upcast()
|
29
|
+
.inner(),
|
30
|
+
)
|
31
|
+
};
|
32
|
+
|
33
|
+
let instance = instance.map_err(to_ruby_err::<RuntimeError, _>)?;
|
34
|
+
let exports = Exports::ruby_new(Exports::new(instance.exports.clone()));
|
35
|
+
|
36
|
+
Ok(Instance::ruby_new(Instance {
|
37
|
+
_inner: instance,
|
38
|
+
exports,
|
39
|
+
}))
|
40
|
+
}
|
41
|
+
|
42
|
+
pub fn exports(&self) -> RubyResult<AnyObject> {
|
43
|
+
Ok(self.exports.clone())
|
44
|
+
}
|
45
|
+
}
|
@@ -0,0 +1,307 @@
|
|
1
|
+
#![deny(warnings)]
|
2
|
+
|
3
|
+
//! # The `wasmer` Ruby package
|
4
|
+
//!
|
5
|
+
//! A complete and mature WebAssembly runtime for Ruby based on [Wasmer].
|
6
|
+
//!
|
7
|
+
//! ## Features
|
8
|
+
//!
|
9
|
+
//! * **Easy to use**: The `wasmer` API mimics the standard
|
10
|
+
//! WebAssembly API,
|
11
|
+
//! * **Fast**: `wasmer` executes the WebAssembly modules as fast as
|
12
|
+
//! possible,
|
13
|
+
//! * **Safe**: All calls to WebAssembly will be fast, but more
|
14
|
+
//! importantly, complete safe and sandboxed.
|
15
|
+
//!
|
16
|
+
//! [Wasmer]: https://github.com/wasmerio/wasmer
|
17
|
+
|
18
|
+
#[cfg(doc)]
|
19
|
+
mod doc;
|
20
|
+
mod error;
|
21
|
+
mod exports;
|
22
|
+
mod externals;
|
23
|
+
mod import_object;
|
24
|
+
mod instance;
|
25
|
+
mod memory;
|
26
|
+
mod module;
|
27
|
+
mod prelude;
|
28
|
+
mod store;
|
29
|
+
mod types;
|
30
|
+
mod values;
|
31
|
+
mod wasi;
|
32
|
+
mod wat;
|
33
|
+
|
34
|
+
#[cfg(doc)]
|
35
|
+
pub use doc::*;
|
36
|
+
|
37
|
+
use crate::memory::views::{
|
38
|
+
Int16Array, Int32Array, Int8Array, Uint16Array, Uint32Array, Uint8Array,
|
39
|
+
};
|
40
|
+
use rutie::{Class, Integer, Module, Object, RString};
|
41
|
+
|
42
|
+
macro_rules! ruby_define {
|
43
|
+
(in $module:ident
|
44
|
+
$( class ( $( $class_rust_module:path ),+ ) $class_name:ident
|
45
|
+
$( include $include_name:ident )*
|
46
|
+
{
|
47
|
+
$( @const $constant_name:ident = $constant_value:expr; )*
|
48
|
+
$( $ruby_definition:ident ($method_rust_name:ident) $method_name:expr; )*
|
49
|
+
};
|
50
|
+
)*
|
51
|
+
|
52
|
+
$( function ( $function_rust_name:path ) $function_name:expr; )*
|
53
|
+
) => {
|
54
|
+
$(
|
55
|
+
{
|
56
|
+
let data_class = Class::from_existing("Object");
|
57
|
+
|
58
|
+
$module
|
59
|
+
.define_nested_class(stringify!($class_name), Some(&data_class))
|
60
|
+
.define(|this| {
|
61
|
+
$(
|
62
|
+
#[allow(unused_imports)]
|
63
|
+
use $class_rust_module::*;
|
64
|
+
)+
|
65
|
+
|
66
|
+
$(
|
67
|
+
this.$ruby_definition($method_name, $method_rust_name);
|
68
|
+
)*
|
69
|
+
|
70
|
+
$(
|
71
|
+
this.const_set(stringify!($constant_name), &$constant_value);
|
72
|
+
)*
|
73
|
+
})
|
74
|
+
$( .include( stringify!($include_name) ) )*
|
75
|
+
;
|
76
|
+
}
|
77
|
+
)*
|
78
|
+
|
79
|
+
$( $module.define_module_function($function_name, $function_rust_name); )*
|
80
|
+
}
|
81
|
+
}
|
82
|
+
|
83
|
+
#[doc(hidden)]
|
84
|
+
#[allow(non_snake_case)]
|
85
|
+
#[no_mangle]
|
86
|
+
pub extern "C" fn init() {
|
87
|
+
let mut wasmer_module = Module::from_existing("Wasmer");
|
88
|
+
|
89
|
+
wasmer_module.const_set("VERSION", &RString::new_utf8(env!("CARGO_PKG_VERSION")));
|
90
|
+
|
91
|
+
ruby_define! {
|
92
|
+
in wasmer_module
|
93
|
+
class (store::ruby_store) Store {
|
94
|
+
def_self (new) "new";
|
95
|
+
};
|
96
|
+
|
97
|
+
class (module::ruby_module) Module {
|
98
|
+
def_self (validate) "validate";
|
99
|
+
def_self (new) "new";
|
100
|
+
def (set_name) "name=";
|
101
|
+
def (get_name) "name";
|
102
|
+
def (exports) "exports";
|
103
|
+
def (imports) "imports";
|
104
|
+
def (custom_sections) "custom_sections";
|
105
|
+
def (serialize) "serialize";
|
106
|
+
def_self (deserialize) "deserialize";
|
107
|
+
};
|
108
|
+
|
109
|
+
class (instance::ruby_instance) Instance {
|
110
|
+
def_self (new) "new";
|
111
|
+
def (exports) "exports";
|
112
|
+
};
|
113
|
+
|
114
|
+
class (exports::ruby_exports, exports::ruby_exports_extra) Exports {
|
115
|
+
def (respond_to_missing) "respond_to_missing?";
|
116
|
+
def (method_missing) "method_missing";
|
117
|
+
def (length) "length";
|
118
|
+
};
|
119
|
+
|
120
|
+
class (import_object::ruby_importobject) ImportObject {
|
121
|
+
def_self (new) "new";
|
122
|
+
def (contains_namespace) "contains_namespace?";
|
123
|
+
def (register) "register";
|
124
|
+
};
|
125
|
+
|
126
|
+
class (externals::function::ruby_function, externals::function::ruby_function_extra) Function {
|
127
|
+
def_self (new) "new";
|
128
|
+
def (call) "call";
|
129
|
+
def (r#type) "type";
|
130
|
+
};
|
131
|
+
|
132
|
+
class (externals::memory::ruby_memory) Memory {
|
133
|
+
def_self (new) "new";
|
134
|
+
def (r#type) "type";
|
135
|
+
def (size) "size";
|
136
|
+
def (data_size) "data_size";
|
137
|
+
def (grow) "grow";
|
138
|
+
def (uint8_view) "uint8_view";
|
139
|
+
def (int8_view) "int8_view";
|
140
|
+
def (uint16_view) "uint16_view";
|
141
|
+
def (int16_view) "int16_view";
|
142
|
+
def (uint32_view) "uint32_view";
|
143
|
+
def (int32_view) "int32_view";
|
144
|
+
};
|
145
|
+
|
146
|
+
class (memory::views::ruby_uint8array) Uint8Array
|
147
|
+
include Enumerable
|
148
|
+
{
|
149
|
+
@const BYTES_PER_ELEMENT = Integer::from(Uint8Array::BYTES_PER_ELEMENT);
|
150
|
+
def (length) "length";
|
151
|
+
def (set) "[]=";
|
152
|
+
def (get) "[]";
|
153
|
+
def (each) "each";
|
154
|
+
};
|
155
|
+
|
156
|
+
class (memory::views::ruby_int8array) Int8Array
|
157
|
+
include Enumerable
|
158
|
+
{
|
159
|
+
@const BYTES_PER_ELEMENT = Integer::from(Int8Array::BYTES_PER_ELEMENT);
|
160
|
+
def (length) "length";
|
161
|
+
def (set) "[]=";
|
162
|
+
def (get) "[]";
|
163
|
+
def (each) "each";
|
164
|
+
};
|
165
|
+
|
166
|
+
class (memory::views::ruby_uint16array) Uint16Array
|
167
|
+
include Enumerable
|
168
|
+
{
|
169
|
+
@const BYTES_PER_ELEMENT = Integer::from(Uint16Array::BYTES_PER_ELEMENT);
|
170
|
+
def (length) "length";
|
171
|
+
def (set) "[]=";
|
172
|
+
def (get) "[]";
|
173
|
+
def (each) "each";
|
174
|
+
};
|
175
|
+
|
176
|
+
class (memory::views::ruby_int16array) Int16Array
|
177
|
+
include Enumerable
|
178
|
+
{
|
179
|
+
@const BYTES_PER_ELEMENT = Integer::from(Int16Array::BYTES_PER_ELEMENT);
|
180
|
+
def (length) "length";
|
181
|
+
def (set) "[]=";
|
182
|
+
def (get) "[]";
|
183
|
+
def (each) "each";
|
184
|
+
};
|
185
|
+
|
186
|
+
class (memory::views::ruby_uint32array) Uint32Array
|
187
|
+
include Enumerable
|
188
|
+
{
|
189
|
+
@const BYTES_PER_ELEMENT = Integer::from(Uint32Array::BYTES_PER_ELEMENT);
|
190
|
+
def (length) "length";
|
191
|
+
def (set) "[]=";
|
192
|
+
def (get) "[]";
|
193
|
+
def (each) "each";
|
194
|
+
};
|
195
|
+
|
196
|
+
class (memory::views::ruby_int32array) Int32Array
|
197
|
+
include Enumerable
|
198
|
+
{
|
199
|
+
@const BYTES_PER_ELEMENT = Integer::from(Int32Array::BYTES_PER_ELEMENT);
|
200
|
+
def (length) "length";
|
201
|
+
def (set) "[]=";
|
202
|
+
def (get) "[]";
|
203
|
+
def (each) "each";
|
204
|
+
};
|
205
|
+
|
206
|
+
class (externals::global::ruby_global) Global {
|
207
|
+
def_self (new) "new";
|
208
|
+
def (mutable) "mutable?";
|
209
|
+
def (get_value) "value";
|
210
|
+
def (set_value) "value=";
|
211
|
+
def (r#type) "type";
|
212
|
+
};
|
213
|
+
|
214
|
+
class (externals::table::ruby_table) Table {
|
215
|
+
def_self (new) "new";
|
216
|
+
};
|
217
|
+
|
218
|
+
class (types) Type {
|
219
|
+
@const I32 = Integer::new(1);
|
220
|
+
@const I64 = Integer::new(2);
|
221
|
+
@const F32 = Integer::new(3);
|
222
|
+
@const F64 = Integer::new(4);
|
223
|
+
@const V128 = Integer::new(5);
|
224
|
+
@const EXTERN_REF = Integer::new(6);
|
225
|
+
@const FUNC_REF = Integer::new(7);
|
226
|
+
};
|
227
|
+
|
228
|
+
class (types::ruby_functiontype) FunctionType {
|
229
|
+
def_self (new) "new";
|
230
|
+
def (params) "params";
|
231
|
+
def (results) "results";
|
232
|
+
};
|
233
|
+
|
234
|
+
class (types::ruby_memorytype) MemoryType {
|
235
|
+
def_self (new) "new";
|
236
|
+
def (minimum) "minimum";
|
237
|
+
def (maximum) "maximum";
|
238
|
+
def (shared) "shared?";
|
239
|
+
};
|
240
|
+
|
241
|
+
class (types::ruby_globaltype) GlobalType {
|
242
|
+
def_self (new) "new";
|
243
|
+
def (r#type) "type";
|
244
|
+
def (mutable) "mutable?";
|
245
|
+
};
|
246
|
+
|
247
|
+
class (types::ruby_tabletype) TableType {
|
248
|
+
def_self (new) "new";
|
249
|
+
def (r#type) "type";
|
250
|
+
def (minimum) "minimum";
|
251
|
+
def (maximum) "maximum";
|
252
|
+
};
|
253
|
+
|
254
|
+
class (types::ruby_exporttype) ExportType {
|
255
|
+
def_self (new) "new";
|
256
|
+
def (name) "name";
|
257
|
+
def (r#type) "type";
|
258
|
+
};
|
259
|
+
|
260
|
+
class (types::ruby_importtype) ImportType {
|
261
|
+
def_self (new) "new";
|
262
|
+
def (module) "module";
|
263
|
+
def (name) "name";
|
264
|
+
def (r#type) "type";
|
265
|
+
};
|
266
|
+
|
267
|
+
class (values::ruby_value) Value {
|
268
|
+
def_self (i32) "i32";
|
269
|
+
def_self (i64) "i64";
|
270
|
+
def_self (f32) "f32";
|
271
|
+
def_self (f64) "f64";
|
272
|
+
};
|
273
|
+
|
274
|
+
function (wat::wat2wasm) "wat2wasm";
|
275
|
+
function (wat::wasm2wat) "wasm2wat";
|
276
|
+
};
|
277
|
+
|
278
|
+
let mut wasmer_wasi_module = wasmer_module.define_nested_module("Wasi");
|
279
|
+
|
280
|
+
ruby_define! {
|
281
|
+
in wasmer_wasi_module
|
282
|
+
class (wasi) Version {
|
283
|
+
@const LATEST = Integer::new(1);
|
284
|
+
@const SNAPSHOT0 = Integer::new(2);
|
285
|
+
@const SNAPSHOT1 = Integer::new(3);
|
286
|
+
};
|
287
|
+
|
288
|
+
class (wasi::ruby_statebuilder) StateBuilder {
|
289
|
+
def_self (new) "new";
|
290
|
+
def (arguments) "arguments";
|
291
|
+
def (argument) "argument";
|
292
|
+
def (environments) "environments";
|
293
|
+
def (environment) "environment";
|
294
|
+
def (preopen_directories) "preopen_directories";
|
295
|
+
def (preopen_directory) "preopen_directory";
|
296
|
+
def (map_directories) "map_directories";
|
297
|
+
def (map_directory) "map_directory";
|
298
|
+
def (finalize) "finalize";
|
299
|
+
};
|
300
|
+
|
301
|
+
class (wasi::ruby_environment) Environment {
|
302
|
+
def (generate_import_object) "generate_import_object";
|
303
|
+
};
|
304
|
+
|
305
|
+
function (wasi::get_version) "get_version";
|
306
|
+
};
|
307
|
+
}
|