wasmtime 0.1.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,69 +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.funcs.each do |name, func|
64
- mod.define_singleton_method(name) { |*args| func.call(*args) }
65
- end
66
- $LOADED_FEATURES << absolute_path
67
- true
68
- end
69
- end
data/src/func.rs DELETED
@@ -1,200 +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::vm::*;
12
-
13
- pub struct Func {
14
- func: w::Func,
15
- }
16
-
17
- impl Func {
18
- pub fn new(func: w::Func) -> Self {
19
- Func { func }
20
- }
21
-
22
- pub fn call(&mut self, args: &[w::Val]) -> Vec<w::Val> {
23
- self.func.call(args).expect("failed to call func").to_vec()
24
- }
25
-
26
- pub fn into_ruby(self) -> RubyFunc {
27
- Module::from_existing("Wasmtime")
28
- .get_nested_class("Func")
29
- .wrap_data(self, &*FUNC_WRAPPER)
30
- }
31
-
32
- fn parse_param_types(&self) -> Vec<RubyType> {
33
- self.func
34
- .ty()
35
- .params()
36
- .iter()
37
- .map(|val_type| val_type_to_ruby_type(val_type))
38
- .collect()
39
- }
40
-
41
- fn parse_result_type(&self) -> RubyType {
42
- match self.func.ty().results().len() {
43
- 0 => RubyType::NilClass,
44
- 1 => val_type_to_ruby_type(self.func.ty().results().first().unwrap()),
45
- _ => raise("StandardError", "multiple return values are not supported"),
46
- }
47
- }
48
- }
49
-
50
- fn val_type_to_ruby_type(val_type: &w::ValType) -> RubyType {
51
- match val_type {
52
- w::ValType::I32 => RubyType::Integer32,
53
- w::ValType::I64 => RubyType::Integer64,
54
- w::ValType::F32 => RubyType::Float32,
55
- w::ValType::F64 => RubyType::Float64,
56
- _ => RubyType::Unsupported,
57
- }
58
- }
59
-
60
- #[derive(Debug, Copy, Clone)]
61
- enum RubyType {
62
- Integer32,
63
- Integer64,
64
- Float32,
65
- Float64,
66
- // String,
67
- // Boolean,
68
- NilClass,
69
- Unsupported,
70
- }
71
-
72
- impl Into<AnyObject> for RubyType {
73
- fn into(self) -> AnyObject {
74
- RString::new_utf8(&format!("{:?}", self)).into()
75
- }
76
- }
77
-
78
- fn translate_incoming(args: Array, param_types: &[RubyType]) -> Vec<w::Val> {
79
- if args.length() != param_types.len() {
80
- raise(
81
- "ArgumentError",
82
- &format!(
83
- "wrong number of arguments (given {}, expected {})",
84
- args.length(),
85
- param_types.len()
86
- ),
87
- )
88
- }
89
- args.into_iter()
90
- .zip(param_types)
91
- .map(|(arg, param_type)| match param_type {
92
- RubyType::Integer32 => w::Val::I32(
93
- arg.try_convert_to::<Integer>()
94
- .expect("failed to convert integer")
95
- .to_i32(),
96
- ),
97
- RubyType::Integer64 => w::Val::I64(
98
- arg.try_convert_to::<Integer>()
99
- .expect("failed to convert integer")
100
- .to_i64(),
101
- ),
102
- RubyType::Float32 => w::Val::F32(
103
- (arg.try_convert_to::<Float>()
104
- .expect("failed to convert float")
105
- .to_f64() as f32)
106
- .to_bits(),
107
- ),
108
- RubyType::Float64 => w::Val::F64(
109
- arg.try_convert_to::<Float>()
110
- .expect("failed to convert float")
111
- .to_f64()
112
- .to_bits(),
113
- ),
114
- RubyType::NilClass | RubyType::Unsupported => raise(
115
- "StandardError",
116
- &format!("unsupported arg type: {:?}", param_type),
117
- ),
118
- })
119
- .collect()
120
- }
121
-
122
- fn translate_outgoing(native_results: Vec<w::Val>) -> AnyObject {
123
- let results: Vec<AnyObject> = native_results
124
- .into_iter()
125
- .map(|r| match r {
126
- w::Val::I32(v) => Integer::new(v.into()).into(),
127
- w::Val::I64(v) => Integer::new(v).into(),
128
- w::Val::F32(v) => Float::new(f32::from_bits(v).into()).into(),
129
- w::Val::F64(v) => Float::new(f64::from_bits(v)).into(),
130
- _ => raise("StandardError", &format!("unsupported value: {:?}", r)),
131
- })
132
- .collect();
133
-
134
- match results.len() {
135
- 0 => NilClass::new().into(),
136
- 1 => results.first().unwrap().into(),
137
- _ => raise("StandardError", "multiple return values are not supported"),
138
- }
139
- }
140
-
141
- wrappable_struct!(Func, FuncWrapper, FUNC_WRAPPER);
142
- class!(RubyFunc);
143
-
144
- #[rustfmt::skip]
145
- methods!(
146
- RubyFunc,
147
- itself,
148
-
149
- fn ruby_func_signature() -> Hash {
150
- let func = itself.get_data(&*FUNC_WRAPPER);
151
-
152
- let mut param_types = Array::new();
153
- for param_type in func.parse_param_types().iter() {
154
- param_types.push(RString::new_utf8(&format!("{:?}", param_type)));
155
- }
156
-
157
- let result_type: AnyObject = func.parse_result_type().into();
158
-
159
- let mut signature = Hash::new();
160
- signature.store(Symbol::new("params"), param_types);
161
- signature.store(Symbol::new("result"), result_type);
162
-
163
- signature
164
- }
165
- );
166
-
167
- pub extern "C" fn ruby_func_call(
168
- argc: r::types::Argc,
169
- argv: *const AnyObject,
170
- mut itself: AnyObject,
171
- ) -> AnyObject {
172
- // TODO: Remove this section when rutie `methods!` macro has support for variadic functions
173
- // https://github.com/danielpclark/rutie/blob/1c951b59e00944d305ca425267c54115c8c1bb86/README.md#variadic-functions--splat-operator
174
- let args_raw = r::types::Value::from(0);
175
- unsafe {
176
- let p_argv: *const r::types::Value = mem::transmute(argv);
177
- rubysys::class::rb_scan_args(
178
- argc,
179
- p_argv,
180
- r::util::str_to_cstring("*").as_ptr(),
181
- &args_raw,
182
- )
183
- };
184
- let args = Array::from(args_raw);
185
- // ---
186
- let func = itself.get_data_mut(&*FUNC_WRAPPER);
187
-
188
- let args_native = translate_incoming(args, &func.parse_param_types());
189
- let results_native = func.call(&args_native[..]);
190
- translate_outgoing(results_native)
191
- }
192
-
193
- pub fn ruby_init() {
194
- Module::from_existing("Wasmtime").define(|module| {
195
- module.define_nested_class("Func", None).define(|class| {
196
- class.def("signature", ruby_func_signature);
197
- class.def("call", ruby_func_call);
198
- });
199
- });
200
- }
data/src/instance.rs DELETED
@@ -1,94 +0,0 @@
1
- use lazy_static::lazy_static;
2
- use rutie::{class, methods, wrappable_struct, Hash, Module, Object, RString, Symbol};
3
- use std::collections::HashMap;
4
- use std::fs;
5
- use wasmtime as w;
6
-
7
- use crate::func::Func;
8
- use crate::memory::Memory;
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, Func>, HashMap<String, Memory>) {
31
- let mut funcs = HashMap::new();
32
- let mut memories = HashMap::new();
33
-
34
- for export in self.instance.exports() {
35
- match export.ty() {
36
- w::ExternType::Func(_) => {
37
- let name = export.name().to_string();
38
- let func = Func::new(export.into_func().expect("failed to create func"));
39
- funcs.insert(name, func);
40
- }
41
- w::ExternType::Memory(_) => {
42
- let memory = Memory::new();
43
- memories.insert(export.name().to_string(), memory);
44
- }
45
- _ => {}
46
- }
47
- }
48
-
49
- (funcs, memories)
50
- }
51
-
52
- pub fn funcs(&self) -> HashMap<String, Func> {
53
- let (functions, _) = self.exports();
54
- functions
55
- }
56
-
57
- pub fn into_ruby(self) -> RubyInstance {
58
- Module::from_existing("Wasmtime")
59
- .get_nested_class("Instance")
60
- .wrap_data(self, &*INSTANCE_WRAPPER)
61
- }
62
- }
63
-
64
- wrappable_struct!(Instance, InstanceWrapper, INSTANCE_WRAPPER);
65
- class!(RubyInstance);
66
-
67
- #[rustfmt::skip]
68
- methods!(
69
- RubyInstance,
70
- itself,
71
-
72
- fn ruby_instance_new(path: RString) -> RubyInstance {
73
- Instance::new(path.expect("failed read path").to_string()).into_ruby()
74
- }
75
-
76
- fn ruby_instance_funcs() -> Hash {
77
- let mut funcs = Hash::new();
78
- for (export_name, func) in itself.get_data(&*INSTANCE_WRAPPER).funcs().into_iter() {
79
- funcs.store(Symbol::new(&export_name), func.into_ruby());
80
- }
81
- funcs
82
- }
83
- );
84
-
85
- pub fn ruby_init() {
86
- Module::from_existing("Wasmtime").define(|module| {
87
- module
88
- .define_nested_class("Instance", None)
89
- .define(|class| {
90
- class.def_self("new", ruby_instance_new);
91
- class.def("funcs", ruby_instance_funcs);
92
- });
93
- });
94
- }
data/src/lib.rs DELETED
@@ -1,19 +0,0 @@
1
- mod func;
2
- mod instance;
3
- mod memory;
4
- mod vm;
5
-
6
- #[allow(non_snake_case)]
7
- #[no_mangle]
8
- pub extern "C" fn Init_native() {
9
- std::panic::set_hook(Box::new(|panic_info| {
10
- if let Some(s) = panic_info.payload().downcast_ref::<&str>() {
11
- vm::raise("StandardError", s)
12
- } else {
13
- vm::raise("StandardError", &format!("{:?}", panic_info))
14
- }
15
- }));
16
-
17
- instance::ruby_init();
18
- func::ruby_init();
19
- }
data/src/memory.rs DELETED
@@ -1,7 +0,0 @@
1
- pub struct Memory {}
2
-
3
- impl Memory {
4
- pub fn new() -> Self {
5
- Memory {}
6
- }
7
- }
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
- }