wasmtime 0.2.0-x86_64-linux → 0.3.0-x86_64-linux

Sign up to get free protection for your applications and to get access to all the features.
data/Cargo.toml DELETED
@@ -1,14 +0,0 @@
1
- [package]
2
- name = "wasmtime-ruby"
3
- version = "0.1.0"
4
- authors = ["David Cristofaro <david@dtcristo.com>"]
5
- edition = "2018"
6
- publish = false
7
-
8
- [lib]
9
- crate-type = ["cdylib"]
10
-
11
- [dependencies]
12
- lazy_static = "1.4.0"
13
- rutie = "0.7.0"
14
- wasmtime = "0.16.0"
@@ -1,5 +0,0 @@
1
- clean:
2
- rake clean
3
-
4
- install:
5
- rake compile
@@ -1,3 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- import '../../lib/tasks/compile.rake'
@@ -1,5 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- unless system('rustup --version')
4
- abort 'Building native extention requires Rust with rustup (https://rustup.rs/).'
5
- end
@@ -1,27 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'rbconfig'
4
-
5
- SOEXT = RbConfig::CONFIG['SOEXT']
6
- DLEXT = RbConfig::CONFIG['DLEXT']
7
-
8
- SO = File.expand_path("../../target/release/libwasmtime_ruby.#{SOEXT}", __dir__)
9
- DL = File.expand_path("../wasmtime/native.#{DLEXT}", __dir__)
10
-
11
- desc 'Remove compile artifacts'
12
- task :clean do
13
- sh 'cargo clean'
14
- rm_rf SO
15
- rm_rf DL
16
- end
17
-
18
- desc 'Compile native extension'
19
- task :compile do
20
- unless `rustup target list`.include?('wasm32-unknown-unknown (installed)')
21
- sh 'rustup target add wasm32-unknown-unknown'
22
- end
23
-
24
- ENV['NO_LINK_RUTIE'] = '1'
25
- sh 'cargo build --release'
26
- cp SO, DL
27
- end
Binary file
@@ -1,20 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Wasmtime
4
- module Refinements
5
- refine String do
6
- def camelize(uppercase_first_letter = true)
7
- string = self
8
- if uppercase_first_letter
9
- string = string.sub(/^[a-z\d]*/, &:capitalize)
10
- else
11
- string = string.sub(/^(?:(?=\b|[A-Z_])|\w)/, &:downcase)
12
- end
13
- string.gsub(%r{(?:_|(\/))([a-z\d]*)}) { "#{$1}#{$2.capitalize}" }.gsub(
14
- '/',
15
- '::'
16
- )
17
- end
18
- end
19
- end
20
- end
@@ -1,72 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'wasmtime'
4
-
5
- using Wasmtime::Refinements
6
-
7
- module Kernel
8
- unless defined?(wasmtime_original_require)
9
- alias_method :wasmtime_original_require, :require
10
- private :wasmtime_original_require
11
- end
12
-
13
- def require(path)
14
- wasmtime_original_require(path)
15
- rescue LoadError => load_error
16
- try_load =
17
- Proc.new do |path, extention|
18
- path_with_extention =
19
- path.end_with?(".#{extention}") ? path : "#{path}.#{extention}"
20
-
21
- if path_with_extention.start_with?('.', '/', '~')
22
- absolute_path = File.expand_path(path_with_extention)
23
- return Wasmtime.load(absolute_path) if File.file?(absolute_path)
24
- end
25
- $LOAD_PATH.each do |load_dir|
26
- absolute_path = File.expand_path(path_with_extention, load_dir)
27
- return Wasmtime.load(absolute_path) if File.file?(absolute_path)
28
- end
29
- end
30
-
31
- try_load.call(path, 'wasm')
32
- try_load.call(path, 'wat')
33
-
34
- raise load_error
35
- end
36
-
37
- unless defined?(wasmtime_original_require_relative)
38
- alias_method :wasmtime_original_require_relative, :require_relative
39
- private :wasmtime_original_require_relative
40
- end
41
-
42
- def require_relative(path)
43
- absolute_path =
44
- File.expand_path(path, File.dirname(caller_locations[0].absolute_path))
45
- require(absolute_path)
46
- end
47
- end
48
-
49
- module Wasmtime
50
- module_function
51
-
52
- def load(absolute_path)
53
- return false if $LOADED_FEATURES.include?(absolute_path)
54
- filename = absolute_path.split(File::SEPARATOR).last
55
- module_name =
56
- if filename.end_with?('.wasm')
57
- filename.delete_suffix('.wasm')
58
- else
59
- filename.delete_suffix('.wat')
60
- end
61
- mod = Object.const_set(module_name.camelize, Module.new)
62
- instance = Wasmtime::Instance.new(absolute_path)
63
- instance.exports.each do |name, export|
64
- case export
65
- when Wasmtime::Func
66
- mod.define_singleton_method(name) { |*args| export.call(*args) }
67
- end
68
- end
69
- $LOADED_FEATURES << absolute_path
70
- true
71
- end
72
- end
data/src/export.rs DELETED
@@ -1,19 +0,0 @@
1
- use rutie::{AnyObject, Object};
2
- use wasmtime as w;
3
-
4
- use crate::func::{Func, RubyFunc};
5
- use crate::memory::RubyMemory;
6
-
7
- pub enum Export {
8
- Func(Func),
9
- Memory(w::Memory),
10
- }
11
-
12
- impl From<Export> for AnyObject {
13
- fn from(export: Export) -> Self {
14
- match export {
15
- Export::Func(func) => RubyFunc::from(func).value().into(),
16
- Export::Memory(memory) => RubyMemory::from(memory).value().into(),
17
- }
18
- }
19
- }
data/src/func.rs DELETED
@@ -1,175 +0,0 @@
1
- use lazy_static::lazy_static;
2
- use rutie as r;
3
- use rutie::rubysys;
4
- use rutie::{
5
- class, methods, wrappable_struct, AnyObject, Array, Float, Hash, Integer, Module, NilClass,
6
- Object, RString, Symbol,
7
- };
8
- use std::mem;
9
- use wasmtime as w;
10
-
11
- use crate::ruby_type::RubyType;
12
- use crate::vm::raise;
13
-
14
- pub struct Func {
15
- func: w::Func,
16
- }
17
-
18
- impl Func {
19
- pub fn new(func: w::Func) -> Self {
20
- Func { func }
21
- }
22
-
23
- pub fn call(&mut self, args: &[w::Val]) -> Vec<w::Val> {
24
- self.func.call(args).expect("failed to call func").to_vec()
25
- }
26
-
27
- fn parse_param_types(&self) -> Vec<RubyType> {
28
- self.func
29
- .ty()
30
- .params()
31
- .iter()
32
- .map(|val_type| val_type.into())
33
- .collect()
34
- }
35
-
36
- fn parse_result_type(&self) -> RubyType {
37
- match self.func.ty().results().len() {
38
- 0 => RubyType::NilClass,
39
- 1 => self.func.ty().results().first().unwrap().into(),
40
- _ => raise("StandardError", "multiple return values are not supported"),
41
- }
42
- }
43
- }
44
-
45
- fn translate_incoming(args: Array, param_types: &[RubyType]) -> Vec<w::Val> {
46
- if args.length() != param_types.len() {
47
- raise(
48
- "ArgumentError",
49
- &format!(
50
- "wrong number of arguments (given {}, expected {})",
51
- args.length(),
52
- param_types.len()
53
- ),
54
- )
55
- }
56
- args.into_iter()
57
- .zip(param_types)
58
- .map(|(arg, param_type)| match param_type {
59
- RubyType::Integer32 => w::Val::I32(
60
- arg.try_convert_to::<Integer>()
61
- .expect("failed to convert integer")
62
- .to_i32(),
63
- ),
64
- RubyType::Integer64 => w::Val::I64(
65
- arg.try_convert_to::<Integer>()
66
- .expect("failed to convert integer")
67
- .to_i64(),
68
- ),
69
- RubyType::Float32 => w::Val::F32(
70
- (arg.try_convert_to::<Float>()
71
- .expect("failed to convert float")
72
- .to_f64() as f32)
73
- .to_bits(),
74
- ),
75
- RubyType::Float64 => w::Val::F64(
76
- arg.try_convert_to::<Float>()
77
- .expect("failed to convert float")
78
- .to_f64()
79
- .to_bits(),
80
- ),
81
- RubyType::NilClass | RubyType::Unsupported => raise(
82
- "StandardError",
83
- &format!("unsupported arg type: {:?}", param_type),
84
- ),
85
- })
86
- .collect()
87
- }
88
-
89
- fn translate_outgoing(native_results: Vec<w::Val>) -> AnyObject {
90
- let results: Vec<AnyObject> = native_results
91
- .into_iter()
92
- .map(|r| match r {
93
- w::Val::I32(v) => Integer::new(v.into()).into(),
94
- w::Val::I64(v) => Integer::new(v).into(),
95
- w::Val::F32(v) => Float::new(f32::from_bits(v).into()).into(),
96
- w::Val::F64(v) => Float::new(f64::from_bits(v)).into(),
97
- _ => raise("StandardError", &format!("unsupported value: {:?}", r)),
98
- })
99
- .collect();
100
-
101
- match results.len() {
102
- 0 => NilClass::new().into(),
103
- 1 => results.first().unwrap().into(),
104
- _ => raise("StandardError", "multiple return values are not supported"),
105
- }
106
- }
107
-
108
- wrappable_struct!(Func, FuncWrapper, FUNC_WRAPPER);
109
- class!(RubyFunc);
110
-
111
- impl From<Func> for RubyFunc {
112
- fn from(func: Func) -> Self {
113
- Module::from_existing("Wasmtime")
114
- .get_nested_class("Func")
115
- .wrap_data(func, &*FUNC_WRAPPER)
116
- }
117
- }
118
-
119
- #[rustfmt::skip]
120
- methods!(
121
- RubyFunc,
122
- itself,
123
-
124
- fn ruby_func_signature() -> Hash {
125
- let func = itself.get_data(&*FUNC_WRAPPER);
126
-
127
- let mut param_types = Array::new();
128
- for param_type in func.parse_param_types().iter() {
129
- param_types.push(RString::new_utf8(&format!("{:?}", param_type)));
130
- }
131
-
132
- let result_type: AnyObject = func.parse_result_type().into();
133
-
134
- let mut signature = Hash::new();
135
- signature.store(Symbol::new("params"), param_types);
136
- signature.store(Symbol::new("result"), result_type);
137
-
138
- signature
139
- }
140
- );
141
-
142
- pub extern "C" fn ruby_func_call(
143
- argc: r::types::Argc,
144
- argv: *const AnyObject,
145
- mut itself: AnyObject,
146
- ) -> AnyObject {
147
- // TODO: Remove this section when rutie `methods!` macro has support for variadic functions
148
- // https://github.com/danielpclark/rutie/blob/1c951b59e00944d305ca425267c54115c8c1bb86/README.md#variadic-functions--splat-operator
149
- let args_raw = r::types::Value::from(0);
150
- unsafe {
151
- let p_argv: *const r::types::Value = mem::transmute(argv);
152
- rubysys::class::rb_scan_args(
153
- argc,
154
- p_argv,
155
- r::util::str_to_cstring("*").as_ptr(),
156
- &args_raw,
157
- )
158
- };
159
- let args = Array::from(args_raw);
160
- // ---
161
- let func = itself.get_data_mut(&*FUNC_WRAPPER);
162
-
163
- let args_native = translate_incoming(args, &func.parse_param_types());
164
- let results_native = func.call(&args_native[..]);
165
- translate_outgoing(results_native)
166
- }
167
-
168
- pub fn ruby_init() {
169
- Module::from_existing("Wasmtime").define(|module| {
170
- module.define_nested_class("Func", None).define(|class| {
171
- class.def("signature", ruby_func_signature);
172
- class.def("call", ruby_func_call);
173
- });
174
- });
175
- }
data/src/instance.rs DELETED
@@ -1,93 +0,0 @@
1
- use lazy_static::lazy_static;
2
- use rutie::{class, methods, wrappable_struct, AnyObject, Hash, Module, Object, RString};
3
- use std::collections::HashMap;
4
- use std::fs;
5
- use wasmtime as w;
6
-
7
- use crate::export::Export;
8
- use crate::func::Func;
9
-
10
- pub struct Instance {
11
- instance: w::Instance,
12
- }
13
-
14
- impl Instance {
15
- pub fn new(path: String) -> Self {
16
- let wasm = fs::read(path).expect("failed to read wasm file");
17
-
18
- let config = w::Config::new();
19
- // config.wasm_interface_types(true);
20
-
21
- let engine = w::Engine::new(&config);
22
- let store = w::Store::new(&engine);
23
- let module = w::Module::new(&store, &wasm).expect("failed to create module");
24
- let imports: Vec<w::Extern> = Vec::new();
25
- let instance = w::Instance::new(&module, &imports).expect("failed to create instance");
26
-
27
- Instance { instance }
28
- }
29
-
30
- fn exports(&self) -> HashMap<String, Export> {
31
- let mut exports = HashMap::new();
32
-
33
- for export in self.instance.exports() {
34
- match export.ty() {
35
- w::ExternType::Func(_) => {
36
- let name = export.name().to_string();
37
- let func = Func::new(export.into_func().unwrap());
38
- exports.insert(name, Export::Func(func));
39
- }
40
- w::ExternType::Memory(_) => {
41
- let name = export.name().to_string();
42
- let memory = export.into_memory().unwrap();
43
- exports.insert(name, Export::Memory(memory));
44
- }
45
- _ => {}
46
- }
47
- }
48
-
49
- exports
50
- }
51
- }
52
-
53
- wrappable_struct!(Instance, InstanceWrapper, INSTANCE_WRAPPER);
54
- class!(RubyInstance);
55
-
56
- impl From<Instance> for RubyInstance {
57
- fn from(instance: Instance) -> Self {
58
- Module::from_existing("Wasmtime")
59
- .get_nested_class("Instance")
60
- .wrap_data(instance, &*INSTANCE_WRAPPER)
61
- }
62
- }
63
-
64
- #[rustfmt::skip]
65
- methods!(
66
- RubyInstance,
67
- itself,
68
-
69
- fn ruby_instance_new(path: RString) -> RubyInstance {
70
- Instance::new(path.expect("failed read path").to_string()).into()
71
- }
72
-
73
- fn ruby_instance_exports() -> Hash {
74
- let mut exports = Hash::new();
75
-
76
- for (export_name, export) in itself.get_data(&*INSTANCE_WRAPPER).exports().into_iter() {
77
- exports.store::<RString, AnyObject>(RString::new_utf8(&export_name), export.into());
78
- }
79
-
80
- exports
81
- }
82
- );
83
-
84
- pub fn ruby_init() {
85
- Module::from_existing("Wasmtime").define(|module| {
86
- module
87
- .define_nested_class("Instance", None)
88
- .define(|class| {
89
- class.def_self("new", ruby_instance_new);
90
- class.def("exports", ruby_instance_exports);
91
- });
92
- });
93
- }
data/src/lib.rs DELETED
@@ -1,22 +0,0 @@
1
- mod export;
2
- mod func;
3
- mod instance;
4
- mod memory;
5
- mod ruby_type;
6
- mod vm;
7
-
8
- #[allow(non_snake_case)]
9
- #[no_mangle]
10
- pub extern "C" fn Init_native() {
11
- std::panic::set_hook(Box::new(|panic_info| {
12
- if let Some(s) = panic_info.payload().downcast_ref::<&str>() {
13
- vm::raise("StandardError", s)
14
- } else {
15
- vm::raise("StandardError", &format!("{:?}", panic_info))
16
- }
17
- }));
18
-
19
- instance::ruby_init();
20
- func::ruby_init();
21
- memory::ruby_init();
22
- }
data/src/memory.rs DELETED
@@ -1,48 +0,0 @@
1
- use lazy_static::lazy_static;
2
- use rutie::{class, methods, wrappable_struct, AnyObject, Integer, Module, NilClass, Object};
3
- use wasmtime as w;
4
-
5
- wrappable_struct!(w::Memory, MemoryWrapper, MEMORY_WRAPPER);
6
- class!(RubyMemory);
7
-
8
- impl From<w::Memory> for RubyMemory {
9
- fn from(memory: w::Memory) -> Self {
10
- Module::from_existing("Wasmtime")
11
- .get_nested_class("Memory")
12
- .wrap_data(memory, &*MEMORY_WRAPPER)
13
- }
14
- }
15
-
16
- #[rustfmt::skip]
17
- methods!(
18
- RubyMemory,
19
- itself,
20
-
21
- fn ruby_instance_data_size() -> Integer {
22
- Integer::from(itself.get_data(&*MEMORY_WRAPPER).data_size() as u32)
23
- }
24
-
25
- fn ruby_instance_size() -> Integer {
26
- Integer::from(itself.get_data(&*MEMORY_WRAPPER).size())
27
- }
28
-
29
- fn ruby_instance_grow(delta: Integer) -> AnyObject {
30
- let memory = itself.get_data(&*MEMORY_WRAPPER);
31
- let delta = delta.unwrap().to_i32();
32
- if delta < 0 { return NilClass::new().into() }
33
- match memory.grow(delta as u32) {
34
- Ok(original) => Integer::from(original).into(),
35
- Err(_) => NilClass::new().into()
36
- }
37
- }
38
- );
39
-
40
- pub fn ruby_init() {
41
- Module::from_existing("Wasmtime").define(|module| {
42
- module.define_nested_class("Memory", None).define(|class| {
43
- class.def("data_size", ruby_instance_data_size);
44
- class.def("size", ruby_instance_size);
45
- class.def("grow", ruby_instance_grow);
46
- });
47
- });
48
- }
data/src/ruby_type.rs DELETED
@@ -1,32 +0,0 @@
1
- use rutie::{AnyObject, RString};
2
- use wasmtime as w;
3
-
4
- #[derive(Debug, Copy, Clone)]
5
- pub enum RubyType {
6
- Integer32,
7
- Integer64,
8
- Float32,
9
- Float64,
10
- // String,
11
- // Boolean,
12
- NilClass,
13
- Unsupported,
14
- }
15
-
16
- impl From<RubyType> for AnyObject {
17
- fn from(ruby_type: RubyType) -> AnyObject {
18
- RString::new_utf8(&format!("{:?}", ruby_type)).into()
19
- }
20
- }
21
-
22
- impl From<&w::ValType> for RubyType {
23
- fn from(val_type: &w::ValType) -> Self {
24
- match val_type {
25
- w::ValType::I32 => RubyType::Integer32,
26
- w::ValType::I64 => RubyType::Integer64,
27
- w::ValType::F32 => RubyType::Float32,
28
- w::ValType::F64 => RubyType::Float64,
29
- _ => RubyType::Unsupported,
30
- }
31
- }
32
- }
data/src/vm.rs DELETED
@@ -1,6 +0,0 @@
1
- use rutie::{Class, VM};
2
-
3
- pub fn raise(exception: &str, message: &str) -> ! {
4
- VM::raise(Class::from_existing(exception), message);
5
- loop {}
6
- }