diff --git a/src/lib.rs b/src/lib.rs index fb4ea5e..d17c3d8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -104,7 +104,11 @@ pub extern "C" fn Init_wasmer() { // Declare the `[]` (get) method. itself.def("[]", memory::view::$mod_name::ruby_memory_view_get); - }); + + // Declare the `each` method. + itself.def("each", memory::view::$mod_name::ruby_memory_view_each); + }) + .include("Enumerable"); }; } diff --git a/src/memory/view.rs b/src/memory/view.rs index 0c2d71c..56abd7e 100644 --- a/src/memory/view.rs +++ b/src/memory/view.rs @@ -9,7 +9,7 @@ macro_rules! memory_view { use lazy_static::lazy_static; use rutie::{ class, methods, wrappable_struct, AnyException, Exception, Fixnum, Integer, - NilClass, Object, + NilClass, Object, VM, }; use std::{mem::size_of, rc::Rc}; use wasmer_runtime as runtime; @@ -71,6 +71,15 @@ macro_rules! memory_view { Ok(view[offset + index].get()) } } + + pub fn each(&self) { + let view = self.memory.view::<$wasm_type>(); + + for nth in self.offset..view.len() { + let value = view[nth].get() as i64; + VM::yield_object(Integer::from(value)); + } + } } wrappable_struct!(MemoryView, MemoryViewWrapper, MEMORY_VIEW_WRAPPER); @@ -117,6 +126,12 @@ macro_rules! memory_view { )) }) } + + fn ruby_memory_view_each() -> RubyMemoryView { + let memory_view = _itself.get_data(&*MEMORY_VIEW_WRAPPER); + memory_view.each(); + _itself + } ); } }; diff --git a/tests/memory_test.rb b/tests/memory_test.rb index 507df9a..68b3e1f 100644 --- a/tests/memory_test.rb +++ b/tests/memory_test.rb @@ -99,20 +99,28 @@ def test_hello_world nth = 0 string = "" - while true - char = memory[nth] - - if 0 == char - break - end - - string += char.chr + memory.each do |char| + break if 0 == char + string << char.chr nth += 1 end + assert_equal 13, nth assert_equal "Hello, World!", string end + def test_enumerable + instance = Wasmer::Instance.new self.bytes + memory = instance.memory.int16_view + memory[0] = 1 + memory[1] = 10 + memory[2] = 100 + memory[3] = 1000 + memory[5] = 2 + sum = memory.take_while{|x| x > 0}.inject(0, &:+) + assert_equal 1111, sum + end + def test_views_share_the_same_buffer instance = Wasmer::Instance.new self.bytes int8 = instance.memory.int8_view