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.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/.cargo/config +1 -1
  3. data/.github/workflows/documentation.yml +50 -0
  4. data/.github/workflows/test.yml +73 -0
  5. data/.gitignore +3 -1
  6. data/CHANGELOG.md +225 -0
  7. data/Cargo.lock +747 -708
  8. data/Cargo.toml +7 -21
  9. data/Gemfile +2 -3
  10. data/LICENSE +21 -0
  11. data/README.md +1 -0
  12. data/Rakefile +4 -3
  13. data/bors.toml +6 -0
  14. data/crates/rutie-derive-macros/Cargo.toml +19 -0
  15. data/crates/rutie-derive-macros/README.md +4 -0
  16. data/crates/rutie-derive-macros/src/class.rs +156 -0
  17. data/crates/rutie-derive-macros/src/function.rs +178 -0
  18. data/crates/rutie-derive-macros/src/lib.rs +27 -0
  19. data/crates/rutie-derive-macros/src/methods.rs +282 -0
  20. data/crates/rutie-derive/Cargo.toml +14 -0
  21. data/crates/rutie-derive/README.md +97 -0
  22. data/crates/rutie-derive/src/lib.rs +4 -0
  23. data/crates/rutie-derive/src/upcast.rs +47 -0
  24. data/crates/rutie-test/Cargo.toml +10 -0
  25. data/crates/rutie-test/src/lib.rs +38 -0
  26. data/crates/wasmer/Cargo.toml +27 -0
  27. data/crates/wasmer/README.md +229 -0
  28. data/crates/wasmer/src/doc.rs +1512 -0
  29. data/crates/wasmer/src/error.rs +55 -0
  30. data/crates/wasmer/src/exports.rs +107 -0
  31. data/crates/wasmer/src/externals/function.rs +159 -0
  32. data/crates/wasmer/src/externals/global.rs +62 -0
  33. data/crates/wasmer/src/externals/memory.rs +117 -0
  34. data/crates/wasmer/src/externals/mod.rs +9 -0
  35. data/crates/wasmer/src/externals/table.rs +41 -0
  36. data/crates/wasmer/src/import_object.rs +78 -0
  37. data/crates/wasmer/src/instance.rs +45 -0
  38. data/crates/wasmer/src/lib.rs +307 -0
  39. data/crates/wasmer/src/memory/mod.rs +1 -0
  40. data/crates/wasmer/src/memory/views.rs +112 -0
  41. data/crates/wasmer/src/module.rs +106 -0
  42. data/crates/wasmer/src/prelude.rs +3 -0
  43. data/crates/wasmer/src/store.rs +22 -0
  44. data/crates/wasmer/src/types.rs +396 -0
  45. data/crates/wasmer/src/values.rs +84 -0
  46. data/crates/wasmer/src/wasi.rs +226 -0
  47. data/crates/wasmer/src/wat.rs +20 -0
  48. data/justfile +20 -2
  49. data/lib/wasmer.rb +29 -3
  50. data/wasmer.gemspec +8 -12
  51. metadata +53 -49
  52. data/.circleci/config.yml +0 -70
  53. data/README.md +0 -279
  54. data/lib/wasmer/version.rb +0 -3
  55. data/src/instance.rs +0 -282
  56. data/src/lib.rs +0 -98
  57. data/src/memory/mod.rs +0 -120
  58. data/src/memory/view.rs +0 -127
  59. data/src/module.rs +0 -28
@@ -0,0 +1 @@
1
+ pub mod views;
@@ -0,0 +1,112 @@
1
+ use crate::{
2
+ error::{to_ruby_err, ArgumentError, IndexError, TypeError},
3
+ prelude::*,
4
+ };
5
+ use rutie::{Integer, NilClass, VM};
6
+ use std::{
7
+ convert::{TryFrom, TryInto},
8
+ mem::size_of,
9
+ };
10
+
11
+ macro_rules! memory_view {
12
+ ($class_name:ident over $wasm_type:ty | $bytes_per_element:expr) => {
13
+ #[rubyclass(module = "Wasmer")]
14
+ pub struct $class_name {
15
+ memory: wasmer::Memory,
16
+ offset: usize,
17
+ }
18
+
19
+ impl $class_name {
20
+ pub const BYTES_PER_ELEMENT: u32 = $bytes_per_element;
21
+
22
+ pub fn new(memory: wasmer::Memory, offset: usize) -> Self {
23
+ Self { memory, offset }
24
+ }
25
+ }
26
+
27
+ #[rubymethods]
28
+ impl $class_name {
29
+ pub fn length(&self) -> RubyResult<Integer> {
30
+ Ok(Integer::new(
31
+ (self.memory.view::<$wasm_type>()[self.offset..].len()
32
+ / size_of::<$wasm_type>())
33
+ .try_into()
34
+ .map_err(to_ruby_err::<TypeError, _>)?,
35
+ ))
36
+ }
37
+
38
+ pub fn set(&self, index: &Integer, value: &Integer) -> RubyResult<NilClass> {
39
+ let index =
40
+ isize::try_from(index.to_i32()).map_err(to_ruby_err::<ArgumentError, _>)?;
41
+ let value = <$wasm_type>::try_from(value.to_u64())
42
+ .map_err(to_ruby_err::<ArgumentError, _>)?;
43
+
44
+ let offset = self.offset;
45
+ let view = self.memory.view::<$wasm_type>();
46
+
47
+ if index < 0 {
48
+ return Err(to_ruby_err::<IndexError, _>(
49
+ "Out of bound: Index cannot be negative",
50
+ ));
51
+ }
52
+
53
+ let index = index as usize;
54
+
55
+ if view.len() <= offset + index {
56
+ return Err(to_ruby_err::<IndexError, _>(format!(
57
+ "Out of bound: Maximum index {} is larger than the memory size {}",
58
+ offset + index,
59
+ view.len()
60
+ )));
61
+ }
62
+
63
+ view[offset + index].set(value);
64
+
65
+ Ok(NilClass::new())
66
+ }
67
+
68
+ pub fn get(&self, index: &Integer) -> RubyResult<Integer> {
69
+ let index =
70
+ isize::try_from(index.to_i32()).map_err(to_ruby_err::<ArgumentError, _>)?;
71
+
72
+ let offset = self.offset;
73
+ let view = self.memory.view::<$wasm_type>();
74
+
75
+ if index < 0 {
76
+ return Err(to_ruby_err::<IndexError, _>(
77
+ "Out of bound: Index cannot be negative.",
78
+ ));
79
+ }
80
+
81
+ let index = index as usize;
82
+
83
+ if view.len() <= offset + index {
84
+ return Err(to_ruby_err::<IndexError, _>(format!(
85
+ "Out of bound: Maximum index {} is larger than the memory size {}.",
86
+ offset + index,
87
+ view.len()
88
+ )));
89
+ }
90
+
91
+ Ok(Integer::new(view[offset + index].get().into()))
92
+ }
93
+
94
+ pub fn each(&self) -> RubyResult<NilClass> {
95
+ let view = self.memory.view::<$wasm_type>();
96
+
97
+ for nth in self.offset..view.len() {
98
+ VM::yield_object(Integer::new(view[nth].get().into()));
99
+ }
100
+
101
+ Ok(NilClass::new())
102
+ }
103
+ }
104
+ };
105
+ }
106
+
107
+ memory_view!(Uint8Array over u8|1);
108
+ memory_view!(Int8Array over i8|1);
109
+ memory_view!(Uint16Array over u16|2);
110
+ memory_view!(Int16Array over i16|2);
111
+ memory_view!(Uint32Array over u32|4);
112
+ memory_view!(Int32Array over i32|4);
@@ -0,0 +1,106 @@
1
+ use crate::{
2
+ error::{to_ruby_err, RuntimeError},
3
+ prelude::*,
4
+ store::Store,
5
+ types::{ExportType, ImportType},
6
+ };
7
+ use rutie::{AnyObject, Array, Boolean, Encoding, NilClass, Object, RString};
8
+ use std::convert::TryFrom;
9
+
10
+ #[rubyclass(module = "Wasmer")]
11
+ pub struct Module {
12
+ inner: wasmer::Module,
13
+ }
14
+
15
+ impl Module {
16
+ pub(crate) fn inner(&self) -> &wasmer::Module {
17
+ &self.inner
18
+ }
19
+
20
+ fn inner_mut(&mut self) -> &mut wasmer::Module {
21
+ &mut self.inner
22
+ }
23
+ }
24
+
25
+ #[rubymethods]
26
+ impl Module {
27
+ pub fn new(store: &Store, bytes: &RString) -> RubyResult<AnyObject> {
28
+ let module = wasmer::Module::new(store.inner(), bytes.to_bytes_unchecked());
29
+
30
+ Ok(Module::ruby_new(Module {
31
+ inner: module.map_err(to_ruby_err::<RuntimeError, _>)?,
32
+ }))
33
+ }
34
+
35
+ pub fn validate(store: &Store, bytes: &AnyObject) -> RubyResult<Boolean> {
36
+ Ok(Boolean::new(match bytes.try_convert_to::<RString>() {
37
+ Ok(bytes) => {
38
+ wasmer::Module::validate(store.inner(), bytes.to_bytes_unchecked()).is_ok()
39
+ }
40
+ _ => false,
41
+ }))
42
+ }
43
+
44
+ pub fn get_name(&self) -> RubyResult<AnyObject> {
45
+ Ok(self.inner().name().map_or_else(
46
+ || NilClass::new().to_any_object(),
47
+ |name| RString::new_utf8(name).to_any_object(),
48
+ ))
49
+ }
50
+
51
+ pub fn set_name(&mut self, name: &RString) -> RubyResult<NilClass> {
52
+ self.inner_mut().set_name(name.to_str());
53
+
54
+ Ok(NilClass::new())
55
+ }
56
+
57
+ pub fn exports(&self) -> RubyResult<Array> {
58
+ let exports = self.inner.exports();
59
+ let mut array = Array::with_capacity(exports.len());
60
+
61
+ for export_type in exports.map(|export_type| ExportType::try_from(export_type)) {
62
+ array.push(ExportType::ruby_new(export_type?));
63
+ }
64
+
65
+ Ok(array)
66
+ }
67
+
68
+ pub fn imports(&self) -> RubyResult<Array> {
69
+ let imports = self.inner.imports();
70
+ let mut array = Array::with_capacity(imports.len());
71
+
72
+ for import_type in imports.map(|import_type| ImportType::try_from(import_type)) {
73
+ array.push(ImportType::ruby_new(import_type?));
74
+ }
75
+
76
+ Ok(array)
77
+ }
78
+
79
+ pub fn custom_sections(&self, name: &RString) -> RubyResult<Array> {
80
+ Ok(self
81
+ .inner()
82
+ .custom_sections(name.to_str())
83
+ .map(|custom_section| {
84
+ RString::from_bytes(&custom_section, &Encoding::us_ascii()).to_any_object()
85
+ })
86
+ .collect())
87
+ }
88
+
89
+ pub fn serialize(&self) -> RubyResult<RString> {
90
+ Ok(RString::from_bytes(
91
+ self.inner()
92
+ .serialize()
93
+ .map_err(to_ruby_err::<RuntimeError, _>)?
94
+ .as_slice(),
95
+ &Encoding::us_ascii(),
96
+ ))
97
+ }
98
+
99
+ pub fn deserialize(store: &Store, bytes: &RString) -> RubyResult<AnyObject> {
100
+ let module =
101
+ unsafe { wasmer::Module::deserialize(store.inner(), bytes.to_bytes_unchecked()) }
102
+ .map_err(to_ruby_err::<RuntimeError, _>)?;
103
+
104
+ Ok(Module::ruby_new(Module { inner: module }))
105
+ }
106
+ }
@@ -0,0 +1,3 @@
1
+ pub use crate::error::RubyResult;
2
+ pub use lazy_static::lazy_static;
3
+ pub use rutie_derive::{rubyclass, rubyfunction, rubymethods, ClassInfo, UpcastRubyClass};
@@ -0,0 +1,22 @@
1
+ use crate::prelude::*;
2
+ use rutie::AnyObject;
3
+
4
+ #[rubyclass(module = "Wasmer")]
5
+ pub struct Store {
6
+ inner: wasmer::Store,
7
+ }
8
+
9
+ impl Store {
10
+ pub(crate) fn inner(&self) -> &wasmer::Store {
11
+ &self.inner
12
+ }
13
+ }
14
+
15
+ #[rubymethods]
16
+ impl Store {
17
+ pub fn new() -> RubyResult<AnyObject> {
18
+ Ok(Store::ruby_new(Store {
19
+ inner: Default::default(),
20
+ }))
21
+ }
22
+ }
@@ -0,0 +1,396 @@
1
+ use crate::{
2
+ error::{to_ruby_err, TypeError},
3
+ prelude::*,
4
+ };
5
+ use rutie::{AnyException, AnyObject, Array, Boolean, Integer, NilClass, Object, RString};
6
+ use std::convert::TryFrom;
7
+
8
+ #[derive(Debug, Copy, Clone)]
9
+ #[repr(u8)]
10
+ pub enum Type {
11
+ I32 = 1,
12
+ I64 = 2,
13
+ F32 = 3,
14
+ F64 = 4,
15
+ V128 = 5,
16
+ ExternRef = 6,
17
+ FuncRef = 7,
18
+ }
19
+
20
+ impl Type {
21
+ fn to_integer(&self) -> Integer {
22
+ match self {
23
+ Self::I32 => Integer::new(1),
24
+ Self::I64 => Integer::new(2),
25
+ Self::F32 => Integer::new(3),
26
+ Self::F64 => Integer::new(4),
27
+ Self::V128 => Integer::new(5),
28
+ Self::ExternRef => Integer::new(6),
29
+ Self::FuncRef => Integer::new(7),
30
+ }
31
+ }
32
+ }
33
+
34
+ impl From<&wasmer::Type> for Type {
35
+ fn from(value: &wasmer::Type) -> Self {
36
+ match value {
37
+ wasmer::Type::I32 => Self::I32,
38
+ wasmer::Type::I64 => Self::I64,
39
+ wasmer::Type::F32 => Self::F32,
40
+ wasmer::Type::F64 => Self::F64,
41
+ wasmer::Type::V128 => Self::V128,
42
+ wasmer::Type::ExternRef => Self::ExternRef,
43
+ wasmer::Type::FuncRef => Self::FuncRef,
44
+ }
45
+ }
46
+ }
47
+
48
+ impl Into<wasmer::Type> for Type {
49
+ fn into(self) -> wasmer::Type {
50
+ match self {
51
+ Self::I32 => wasmer::Type::I32,
52
+ Self::I64 => wasmer::Type::I64,
53
+ Self::F32 => wasmer::Type::F32,
54
+ Self::F64 => wasmer::Type::F64,
55
+ Self::V128 => wasmer::Type::V128,
56
+ Self::ExternRef => wasmer::Type::ExternRef,
57
+ Self::FuncRef => wasmer::Type::FuncRef,
58
+ }
59
+ }
60
+ }
61
+
62
+ impl TryFrom<&Integer> for Type {
63
+ type Error = &'static str;
64
+
65
+ fn try_from(value: &Integer) -> Result<Self, Self::Error> {
66
+ Ok(match value.to_i32() {
67
+ 1 => Type::I32,
68
+ 2 => Type::I64,
69
+ 3 => Type::F32,
70
+ 4 => Type::F64,
71
+ 5 => Type::V128,
72
+ 6 => Type::ExternRef,
73
+ 7 => Type::FuncRef,
74
+ _ => return Err("Unrecognized type"),
75
+ })
76
+ }
77
+ }
78
+
79
+ #[rubyclass(module = "Wasmer")]
80
+ pub struct FunctionType {
81
+ pub params: Vec<Type>,
82
+ pub results: Vec<Type>,
83
+ }
84
+
85
+ #[rubymethods]
86
+ impl FunctionType {
87
+ pub fn new(params: &Array, results: &Array) -> RubyResult<AnyObject> {
88
+ let params = unsafe { params.to_any_object().to::<Array>() }
89
+ .into_iter()
90
+ .map(|param| {
91
+ param
92
+ .try_convert_to::<Integer>()
93
+ .and_then(|param| Type::try_from(&param).map_err(to_ruby_err::<TypeError, _>))
94
+ })
95
+ .collect::<Result<Vec<Type>, AnyException>>()?;
96
+ let results = unsafe { results.to_any_object().to::<Array>() }
97
+ .into_iter()
98
+ .map(|result| {
99
+ result
100
+ .try_convert_to::<Integer>()
101
+ .and_then(|result| Type::try_from(&result).map_err(to_ruby_err::<TypeError, _>))
102
+ })
103
+ .collect::<Result<Vec<Type>, AnyException>>()?;
104
+
105
+ Ok(FunctionType::ruby_new(FunctionType { params, results }))
106
+ }
107
+
108
+ pub fn params(&self) -> RubyResult<Array> {
109
+ Ok(self
110
+ .params
111
+ .iter()
112
+ .map(|ty| Type::to_integer(ty).to_any_object())
113
+ .collect())
114
+ }
115
+
116
+ pub fn results(&self) -> RubyResult<Array> {
117
+ Ok(self
118
+ .results
119
+ .iter()
120
+ .map(|ty| Type::to_integer(ty).to_any_object())
121
+ .collect())
122
+ }
123
+ }
124
+
125
+ impl From<&wasmer::FunctionType> for FunctionType {
126
+ fn from(value: &wasmer::FunctionType) -> Self {
127
+ Self {
128
+ params: value.params().iter().map(Into::into).collect(),
129
+ results: value.results().iter().map(Into::into).collect(),
130
+ }
131
+ }
132
+ }
133
+
134
+ impl Into<wasmer::FunctionType> for &FunctionType {
135
+ fn into(self) -> wasmer::FunctionType {
136
+ wasmer::FunctionType::new(
137
+ self.params
138
+ .iter()
139
+ .cloned()
140
+ .map(Into::into)
141
+ .collect::<Vec<_>>(),
142
+ self.results
143
+ .iter()
144
+ .cloned()
145
+ .map(Into::into)
146
+ .collect::<Vec<_>>(),
147
+ )
148
+ }
149
+ }
150
+
151
+ #[rubyclass(module = "Wasmer")]
152
+ pub struct MemoryType {
153
+ pub minimum: u32,
154
+ pub maximum: Option<u32>,
155
+ pub shared: bool,
156
+ }
157
+
158
+ #[rubymethods]
159
+ impl MemoryType {
160
+ pub fn new(minimum: &Integer, maximum: &AnyObject, shared: &Boolean) -> RubyResult<AnyObject> {
161
+ Ok(MemoryType::ruby_new(MemoryType {
162
+ minimum: minimum.to_u64() as _,
163
+ maximum: if maximum.is_nil() {
164
+ None
165
+ } else {
166
+ Some(maximum.try_convert_to::<Integer>()?.to_u64() as _)
167
+ },
168
+ shared: shared.to_bool(),
169
+ }))
170
+ }
171
+
172
+ pub fn minimum(&self) -> RubyResult<Integer> {
173
+ Ok(Integer::new(self.minimum.into()))
174
+ }
175
+
176
+ pub fn maximum(&self) -> RubyResult<AnyObject> {
177
+ Ok(match self.maximum {
178
+ Some(maximum) => Integer::new(maximum.into()).to_any_object(),
179
+ None => NilClass::new().to_any_object(),
180
+ })
181
+ }
182
+
183
+ pub fn shared(&self) -> RubyResult<Boolean> {
184
+ Ok(Boolean::new(self.shared))
185
+ }
186
+ }
187
+
188
+ impl From<wasmer::MemoryType> for MemoryType {
189
+ fn from(value: wasmer::MemoryType) -> Self {
190
+ Self::from(&value)
191
+ }
192
+ }
193
+
194
+ impl From<&wasmer::MemoryType> for MemoryType {
195
+ fn from(value: &wasmer::MemoryType) -> Self {
196
+ Self {
197
+ minimum: value.minimum.0,
198
+ maximum: value.maximum.map(|pages| pages.0),
199
+ shared: value.shared,
200
+ }
201
+ }
202
+ }
203
+
204
+ impl Into<wasmer::MemoryType> for &MemoryType {
205
+ fn into(self) -> wasmer::MemoryType {
206
+ wasmer::MemoryType::new(self.minimum, self.maximum, self.shared)
207
+ }
208
+ }
209
+
210
+ #[rubyclass(module = "Wasmer")]
211
+ pub struct GlobalType {
212
+ pub ty: Type,
213
+ pub mutable: bool,
214
+ }
215
+
216
+ #[rubymethods]
217
+ impl GlobalType {
218
+ pub fn new(ty: &Integer, mutable: &Boolean) -> RubyResult<AnyObject> {
219
+ Ok(GlobalType::ruby_new(GlobalType {
220
+ ty: Type::try_from(ty).map_err(to_ruby_err::<TypeError, _>)?,
221
+ mutable: mutable.to_bool(),
222
+ }))
223
+ }
224
+
225
+ pub fn r#type(&self) -> RubyResult<Integer> {
226
+ Ok(self.ty.to_integer())
227
+ }
228
+
229
+ pub fn mutable(&self) -> RubyResult<Boolean> {
230
+ Ok(Boolean::new(self.mutable))
231
+ }
232
+ }
233
+
234
+ impl From<&wasmer::GlobalType> for GlobalType {
235
+ fn from(value: &wasmer::GlobalType) -> Self {
236
+ Self {
237
+ ty: (&value.ty).into(),
238
+ mutable: value.mutability.is_mutable(),
239
+ }
240
+ }
241
+ }
242
+
243
+ #[rubyclass(module = "Wasmer")]
244
+ pub struct TableType {
245
+ pub ty: Type,
246
+ pub minimum: u32,
247
+ pub maximum: Option<u32>,
248
+ }
249
+
250
+ #[rubymethods]
251
+ impl TableType {
252
+ pub fn new(ty: &Integer, minimum: &Integer, maximum: &AnyObject) -> RubyResult<AnyObject> {
253
+ Ok(TableType::ruby_new(TableType {
254
+ ty: Type::try_from(ty).map_err(to_ruby_err::<TypeError, _>)?,
255
+ minimum: minimum.to_u64() as _,
256
+ maximum: if maximum.is_nil() {
257
+ None
258
+ } else {
259
+ Some(maximum.try_convert_to::<Integer>()?.to_u64() as _)
260
+ },
261
+ }))
262
+ }
263
+
264
+ pub fn r#type(&self) -> RubyResult<Integer> {
265
+ Ok(self.ty.to_integer())
266
+ }
267
+
268
+ pub fn minimum(&self) -> RubyResult<Integer> {
269
+ Ok(Integer::new(self.minimum.into()))
270
+ }
271
+
272
+ pub fn maximum(&self) -> RubyResult<AnyObject> {
273
+ Ok(match self.maximum {
274
+ Some(maximum) => Integer::new(maximum.into()).to_any_object(),
275
+ None => NilClass::new().to_any_object(),
276
+ })
277
+ }
278
+ }
279
+
280
+ impl From<&wasmer::TableType> for TableType {
281
+ fn from(value: &wasmer::TableType) -> Self {
282
+ Self {
283
+ ty: (&value.ty).into(),
284
+ minimum: value.minimum,
285
+ maximum: value.maximum,
286
+ }
287
+ }
288
+ }
289
+
290
+ impl Into<wasmer::TableType> for &TableType {
291
+ fn into(self) -> wasmer::TableType {
292
+ wasmer::TableType::new(self.ty.into(), self.minimum, self.maximum)
293
+ }
294
+ }
295
+
296
+ #[rubyclass(module = "Wasmer")]
297
+ pub struct ExportType {
298
+ pub name: String,
299
+ pub ty: AnyObject,
300
+ }
301
+
302
+ #[rubymethods]
303
+ impl ExportType {
304
+ pub fn new(name: &RString, ty: &AnyObject) -> RubyResult<AnyObject> {
305
+ Ok(ExportType::ruby_new(ExportType {
306
+ name: name.to_string(),
307
+ ty: if ty.try_convert_to::<RubyFunctionType>().is_ok()
308
+ || ty.try_convert_to::<RubyMemoryType>().is_ok()
309
+ || ty.try_convert_to::<RubyGlobalType>().is_ok()
310
+ || ty.try_convert_to::<RubyTableType>().is_ok()
311
+ {
312
+ unsafe { ty.to::<AnyObject>() }
313
+ } else {
314
+ return Err(to_ruby_err::<TypeError, _>("Argument #2 of `ExportType.new` must be of kind `FunctionType`, `MemoryType`, `GlobalType` or `TableType`"));
315
+ },
316
+ }))
317
+ }
318
+
319
+ pub fn name(&self) -> RubyResult<RString> {
320
+ Ok(RString::new_utf8(&self.name))
321
+ }
322
+
323
+ pub fn r#type(&self) -> RubyResult<AnyObject> {
324
+ Ok(self.ty.clone())
325
+ }
326
+ }
327
+
328
+ impl TryFrom<wasmer::ExportType> for ExportType {
329
+ type Error = AnyException;
330
+
331
+ fn try_from(value: wasmer::ExportType) -> Result<Self, Self::Error> {
332
+ Ok(ExportType {
333
+ name: value.name().to_string(),
334
+ ty: extern_type_to_ruby_any_object(value.ty()),
335
+ })
336
+ }
337
+ }
338
+
339
+ #[rubyclass(module = "Wasmer")]
340
+ pub struct ImportType {
341
+ pub module: String,
342
+ pub name: String,
343
+ pub ty: AnyObject,
344
+ }
345
+
346
+ #[rubymethods]
347
+ impl ImportType {
348
+ pub fn new(module: &RString, name: &RString, ty: &AnyObject) -> RubyResult<AnyObject> {
349
+ Ok(ImportType::ruby_new(ImportType {
350
+ module: module.to_string(),
351
+ name: name.to_string(),
352
+ ty: if ty.try_convert_to::<RubyFunctionType>().is_ok()
353
+ || ty.try_convert_to::<RubyMemoryType>().is_ok()
354
+ || ty.try_convert_to::<RubyGlobalType>().is_ok()
355
+ || ty.try_convert_to::<RubyTableType>().is_ok()
356
+ {
357
+ unsafe { ty.to::<AnyObject>() }
358
+ } else {
359
+ return Err(to_ruby_err::<TypeError, _>("Argument #3 of `ImportType.new` must be of kind `FunctionType`, `MemoryType`, `GlobalType` or `TableType`"));
360
+ },
361
+ }))
362
+ }
363
+
364
+ pub fn module(&self) -> RubyResult<RString> {
365
+ Ok(RString::new_utf8(&self.module))
366
+ }
367
+
368
+ pub fn name(&self) -> RubyResult<RString> {
369
+ Ok(RString::new_utf8(&self.name))
370
+ }
371
+
372
+ pub fn r#type(&self) -> RubyResult<AnyObject> {
373
+ Ok(self.ty.clone())
374
+ }
375
+ }
376
+
377
+ impl TryFrom<wasmer::ImportType> for ImportType {
378
+ type Error = AnyException;
379
+
380
+ fn try_from(value: wasmer::ImportType) -> Result<Self, Self::Error> {
381
+ Ok(ImportType {
382
+ module: value.module().to_string(),
383
+ name: value.name().to_string(),
384
+ ty: extern_type_to_ruby_any_object(value.ty()),
385
+ })
386
+ }
387
+ }
388
+
389
+ fn extern_type_to_ruby_any_object(value: &wasmer::ExternType) -> AnyObject {
390
+ match value {
391
+ wasmer::ExternType::Function(t) => FunctionType::ruby_new(FunctionType::from(t)),
392
+ wasmer::ExternType::Memory(t) => MemoryType::ruby_new(MemoryType::from(t)),
393
+ wasmer::ExternType::Global(t) => GlobalType::ruby_new(GlobalType::from(t)),
394
+ wasmer::ExternType::Table(t) => TableType::ruby_new(TableType::from(t)),
395
+ }
396
+ }