wasmer 0.1.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.cargo/config +1 -1
- data/.github/workflows/documentation.yml +50 -0
- data/.github/workflows/test.yml +73 -0
- data/.gitignore +3 -1
- data/CHANGELOG.md +225 -0
- data/Cargo.lock +747 -708
- data/Cargo.toml +7 -21
- data/Gemfile +2 -3
- data/LICENSE +21 -0
- data/README.md +1 -0
- data/Rakefile +4 -3
- data/bors.toml +6 -0
- 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 +229 -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 +396 -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 +20 -2
- data/lib/wasmer.rb +29 -3
- data/wasmer.gemspec +8 -12
- metadata +53 -49
- data/.circleci/config.yml +0 -70
- data/README.md +0 -279
- data/lib/wasmer/version.rb +0 -3
- data/src/instance.rs +0 -282
- data/src/lib.rs +0 -98
- data/src/memory/mod.rs +0 -120
- data/src/memory/view.rs +0 -127
- 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
|
+
}
|