wasmer 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: /.*/