wasmer 0.3.0 → 0.4.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.
@@ -0,0 +1,141 @@
1
+ //! The `Instance` WebAssembly class.
2
+
3
+ pub mod exports;
4
+ pub mod globals;
5
+
6
+ use crate::{
7
+ error::unwrap_or_raise,
8
+ instance::{
9
+ exports::{ExportedFunctions, RubyExportedFunctions, EXPORTED_FUNCTIONS_WRAPPER},
10
+ globals::{ExportedGlobals, RubyExportedGlobals, EXPORTED_GLOBALS_WRAPPER},
11
+ },
12
+ memory::{Memory, RubyMemory, MEMORY_WRAPPER},
13
+ };
14
+ use lazy_static::lazy_static;
15
+ use rutie::{
16
+ class, methods, wrappable_struct, AnyException, AnyObject, Exception, Module, NilClass, Object,
17
+ RString,
18
+ };
19
+ use std::rc::Rc;
20
+ use wasmer_runtime::{self as runtime, imports, Export};
21
+
22
+ /// The `Instance` Ruby class.
23
+ pub struct Instance {
24
+ /// The WebAssembly instance.
25
+ instance: Rc<runtime::Instance>,
26
+ }
27
+
28
+ impl Instance {
29
+ /// Create a new instance of the `Instance` Ruby class.
30
+ /// The constructor receives bytes from a string.
31
+ pub fn new(bytes: &[u8]) -> Result<Self, AnyException> {
32
+ let import_object = imports! {};
33
+
34
+ Ok(Self {
35
+ instance: Rc::new(runtime::instantiate(bytes, &import_object).map_err(|e| {
36
+ AnyException::new(
37
+ "RuntimeError",
38
+ Some(&format!("Failed to instantiate the module:\n {}", e)),
39
+ )
40
+ })?),
41
+ })
42
+ }
43
+ }
44
+
45
+ wrappable_struct!(Instance, InstanceWrapper, INSTANCE_WRAPPER);
46
+
47
+ class!(RubyInstance);
48
+
49
+ #[rustfmt::skip]
50
+ methods!(
51
+ RubyInstance,
52
+ _itself,
53
+
54
+ // Glue code to call the `Instance.new` method.
55
+ fn ruby_instance_new(bytes: RString) -> AnyObject {
56
+ unwrap_or_raise(|| {
57
+ let instance = Instance::new(
58
+ bytes
59
+ .map_err(|_| {
60
+ AnyException::new(
61
+ "ArgumentError",
62
+ Some("WebAssembly module must be represented by Ruby bytes only."),
63
+ )
64
+ })?
65
+ .to_bytes_unchecked(),
66
+ )?;
67
+ let exported_functions = ExportedFunctions::new(instance.instance.clone());
68
+ let exported_globals = ExportedGlobals::new(instance.instance.clone());
69
+ let exported_memory =
70
+ instance
71
+ .instance
72
+ .exports()
73
+ .find_map(|(_, export)| match export {
74
+ Export::Memory(memory) => Some(Memory::new(Rc::new(memory))),
75
+ _ => None,
76
+ });
77
+
78
+ let wasmer_module = Module::from_existing("Wasmer");
79
+
80
+ let mut ruby_instance: AnyObject = wasmer_module
81
+ .get_nested_class("Instance")
82
+ .wrap_data(instance, &*INSTANCE_WRAPPER);
83
+
84
+ let ruby_exported_functions: RubyExportedFunctions = wasmer_module
85
+ .get_nested_class("ExportedFunctions")
86
+ .wrap_data(exported_functions, &*EXPORTED_FUNCTIONS_WRAPPER);
87
+
88
+ let ruby_exported_globals: RubyExportedGlobals = wasmer_module
89
+ .get_nested_class("ExportedGlobals")
90
+ .wrap_data(exported_globals, &*EXPORTED_GLOBALS_WRAPPER);
91
+
92
+ ruby_instance.instance_variable_set("@exports", ruby_exported_functions);
93
+ ruby_instance.instance_variable_set("@globals", ruby_exported_globals);
94
+
95
+ if let Some(exported_memory) = exported_memory {
96
+ let ruby_exported_memory: RubyMemory = wasmer_module
97
+ .get_nested_class("Memory")
98
+ .wrap_data(exported_memory, &*MEMORY_WRAPPER);
99
+ ruby_instance.instance_variable_set("@memory", ruby_exported_memory);
100
+ } else {
101
+ ruby_instance.instance_variable_set("@memory", NilClass::new());
102
+ }
103
+
104
+ Ok(ruby_instance)
105
+ })
106
+ }
107
+
108
+ // Glue code to call the `Instance.exports` getter method.
109
+ fn ruby_instance_exported_functions() -> RubyExportedFunctions {
110
+ unsafe {
111
+ _itself
112
+ .instance_variable_get("@exports")
113
+ .to::<RubyExportedFunctions>()
114
+ }
115
+ }
116
+
117
+ // Glue code to call the `Instance.globals` getter method.
118
+ fn ruby_instance_exported_globals() -> RubyExportedGlobals {
119
+ unsafe {
120
+ _itself
121
+ .instance_variable_get("@globals")
122
+ .to::<RubyExportedGlobals>()
123
+ }
124
+ }
125
+
126
+ // Glue code to call the `Instance.memory` getter method.
127
+ fn ruby_instance_memory() -> RubyMemory {
128
+ unwrap_or_raise(|| {
129
+ let memory = _itself.instance_variable_get("@memory");
130
+
131
+ if !memory.is_nil() {
132
+ Ok(unsafe { memory.to::<RubyMemory>() })
133
+ } else {
134
+ Err(AnyException::new(
135
+ "RuntimeError",
136
+ Some("The WebAssembly module has no exported memory."),
137
+ ))
138
+ }
139
+ })
140
+ }
141
+ );
data/src/lib.rs CHANGED
@@ -24,6 +24,9 @@ pub extern "C" fn Init_wasmer() {
24
24
  // Declare the `exports` getter method.
25
25
  itself.def("exports", instance::ruby_instance_exported_functions);
26
26
 
27
+ // Declare the `globals` getter method.
28
+ itself.def("globals", instance::ruby_instance_exported_globals);
29
+
27
30
  // Declare the `memory` getter method.
28
31
  itself.def("memory", instance::ruby_instance_memory);
29
32
  });
@@ -37,16 +40,51 @@ pub extern "C" fn Init_wasmer() {
37
40
  // Declare the `respond_to_missing?` method.
38
41
  itself.def(
39
42
  "respond_to_missing?",
40
- instance::ruby_exported_functions_method_exists,
43
+ instance::exports::ruby_exported_functions_method_exists,
44
+ );
45
+
46
+ // Declare the `method_missing` method.
47
+ itself.def(
48
+ "method_missing",
49
+ instance::exports::ruby_exported_functions_method_missing,
50
+ );
51
+ });
52
+
53
+ let exported_globals_data_class = Class::from_existing("Object");
54
+
55
+ // Declare the `ExportedGlobals` Ruby class.
56
+ wasmer_module
57
+ .define_nested_class("ExportedGlobals", Some(&exported_globals_data_class))
58
+ .define(|itself| {
59
+ // Declare the `respond_to_missing?` method.
60
+ itself.def(
61
+ "respond_to_missing?",
62
+ instance::globals::ruby_exported_globals_method_exists,
41
63
  );
42
64
 
43
65
  // Declare the `method_missing` method.
44
66
  itself.def(
45
67
  "method_missing",
46
- instance::ruby_exported_functions_method_missing,
68
+ instance::globals::ruby_exported_globals_method_missing,
47
69
  );
48
70
  });
49
71
 
72
+ let exported_global_data_class = Class::from_existing("Object");
73
+
74
+ // Declare the `ExportedGlobal` Ruby class.
75
+ wasmer_module
76
+ .define_nested_class("ExportedGlobal", Some(&exported_global_data_class))
77
+ .define(|itself| {
78
+ // Declare the `value` getter.
79
+ itself.def("value", instance::globals::ruby_exported_global_get_value);
80
+
81
+ // Declare the `value` setter.
82
+ itself.def("value=", instance::globals::ruby_exported_global_set_value);
83
+
84
+ // Declare the `mutable` getter.
85
+ itself.def("mutable", instance::globals::ruby_exported_global_mutable);
86
+ });
87
+
50
88
  let module_data_class = Class::from_existing("Object");
51
89
 
52
90
  // Declare the `Module` Ruby class.
@@ -20,8 +20,7 @@ use crate::{
20
20
  use lazy_static::lazy_static;
21
21
  use rutie::{class, methods, wrappable_struct, AnyException, Exception, Integer, Module, Object};
22
22
  use std::rc::Rc;
23
- use wasmer_runtime as runtime;
24
- use wasmer_runtime_core::units::Pages;
23
+ use wasmer_runtime::{self as runtime, units::Pages};
25
24
 
26
25
  pub struct Memory {
27
26
  memory: Rc<runtime::Memory>,
@@ -22,8 +22,8 @@ Gem::Specification.new do |spec|
22
22
 
23
23
  spec.require_paths = %w(lib)
24
24
 
25
- spec.add_dependency "rutie", "~> 0.0.3"
26
- spec.add_development_dependency "bundler", "~> 2.0"
27
- spec.add_development_dependency "rake", "~> 10.0"
28
- spec.add_development_dependency "minitest", "~> 5.0"
25
+ spec.add_dependency "rutie", "~> 0.0.4"
26
+ spec.add_development_dependency "bundler", "~> 2.1"
27
+ spec.add_development_dependency "rake", "~> 13.0"
28
+ spec.add_development_dependency "minitest", "~> 5.14"
29
29
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wasmer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ivan Enderlin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-08-28 00:00:00.000000000 Z
11
+ date: 2020-03-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rutie
@@ -16,56 +16,56 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.0.3
19
+ version: 0.0.4
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.0.3
26
+ version: 0.0.4
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '2.0'
33
+ version: '2.1'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '2.0'
40
+ version: '2.1'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '10.0'
47
+ version: '13.0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '10.0'
54
+ version: '13.0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: minitest
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '5.0'
61
+ version: '5.14'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '5.0'
68
+ version: '5.14'
69
69
  description: Wasmer is a Ruby extension to run WebAssembly binaries.
70
70
  email:
71
71
  - ivan.enderlin@hoa-project.net
@@ -75,14 +75,16 @@ extensions:
75
75
  extra_rdoc_files: []
76
76
  files:
77
77
  - ".cargo/config"
78
- - ".circleci/config.yml"
79
78
  - ".github/ISSUE_TEMPLATE/---bug-report.md"
80
79
  - ".github/ISSUE_TEMPLATE/---feature-request.md"
81
80
  - ".github/ISSUE_TEMPLATE/--question.md"
81
+ - ".github/workflows/test.yml"
82
82
  - ".gitignore"
83
+ - CHANGELOG.md
83
84
  - Cargo.lock
84
85
  - Cargo.toml
85
86
  - Gemfile
87
+ - LICENSE
86
88
  - README.md
87
89
  - Rakefile
88
90
  - bors.toml
@@ -90,7 +92,9 @@ files:
90
92
  - lib/wasmer.rb
91
93
  - lib/wasmer/version.rb
92
94
  - src/error.rs
93
- - src/instance.rs
95
+ - src/instance/exports.rs
96
+ - src/instance/globals.rs
97
+ - src/instance/mod.rs
94
98
  - src/lib.rs
95
99
  - src/memory/mod.rs
96
100
  - src/memory/view.rs
@@ -1,72 +0,0 @@
1
- version: 2.1
2
-
3
- # List of all jobs.
4
- jobs:
5
- # Build and test the project the project.
6
- build-and-test:
7
- docker:
8
- - image: circleci/ruby:latest
9
- steps:
10
- # Update the project.
11
- - checkout
12
-
13
- # If the cache exists, loads it.
14
- - restore_cache:
15
- keys:
16
- - v1-linux-{{ arch }}-{{ checksum "Cargo.lock" }}
17
- - v1-linux-{{ arch }}
18
-
19
- # Install Rust.
20
- - run:
21
- name: Install Rust
22
- command: |
23
- test -d /usr/local/cargo || curl https://sh.rustup.rs -sSf | sh -s -- -y
24
-
25
- # Install `just` used to manage the project.
26
- - run:
27
- name: Install just
28
- command: |
29
- export PATH="$HOME/.cargo/bin:$PATH"
30
- test -f $HOME/.cargo/bin/just || cargo install just
31
-
32
- # Compile the Ruby extension.
33
- - run:
34
- name: Compile the Ruby extension
35
- command: |
36
- export PATH="$HOME/.cargo/bin:$PATH"
37
- just build
38
-
39
- # Save everything in the cache (except the `just` binary).
40
- - save_cache:
41
- paths:
42
- - /usr/local/cargo/registry
43
- - target/release/.fingerprint
44
- - target/release/build
45
- - target/release/deps
46
- key: v1-linux-{{ arch }}-{{ checksum "Cargo.lock" }}
47
-
48
- # Run the extension test suites.
49
- - run:
50
- name: Test the extension
51
- command: |
52
- export PATH="$HOME/.cargo/bin:$PATH"
53
- gem install bundler
54
- just test
55
-
56
-
57
- # List of workflows.
58
- workflows:
59
- version: 2
60
-
61
- # The build workflow.
62
- build:
63
- jobs:
64
- # Run the `build-and-test` job for the `trying` and `staging` branches, and all tags.
65
- - build-and-test:
66
- filters:
67
- branches:
68
- only:
69
- - trying
70
- - staging
71
- tags:
72
- only: /.*/