diff --git a/python/extism/extism.py b/python/extism/extism.py index b050c4b..6131957 100644 --- a/python/extism/extism.py +++ b/python/extism/extism.py @@ -138,11 +138,14 @@ class Plugin: raise Error(ffi.string(error).decode()) raise Error(f"Error code: {rc}") - def call(self, name: str, data: Union[str, bytes]) -> bytes: + def call(self, name: str, data: Union[str, bytes], parse=bytes) -> bytes: if isinstance(data, str): data = data.encode() self._check_error( lib.extism_call(self.plugin, name.encode(), data, len(data))) out_len = lib.extism_output_length(self.plugin) out_buf = lib.extism_output_get(self.plugin) - return ffi.string(out_buf, out_len) + buf = ffi.buffer(out_buf, out_len) + if parse is None: + return buf + return parse(buf) diff --git a/ruby/example.rb b/ruby/example.rb index 8d880ce..2b509b9 100644 --- a/ruby/example.rb +++ b/ruby/example.rb @@ -7,4 +7,3 @@ manifest = { plugin = Extism::Plugin.new(manifest) res = JSON.parse(plugin.call("count_vowels", ARGV[0] || "this is a test")) puts res['count'] - diff --git a/ruby/lib/extism.rb b/ruby/lib/extism.rb index 93e0db2..dd88e8b 100644 --- a/ruby/lib/extism.rb +++ b/ruby/lib/extism.rb @@ -58,7 +58,9 @@ module Extism return ok end - def call(name, data) + def call(name, data, &block) + # If no block was passed then use Pointer::read_string + block ||= ->(buf, len){ buf.read_string(len) } input = FFI::MemoryPointer::from_string(data) rc = C.extism_call(@plugin, name, input, data.bytesize) if rc != 0 then @@ -70,7 +72,7 @@ module Extism end out_len = C.extism_output_length(@plugin) buf = C.extism_output_get(@plugin) - return buf.read_string(out_len) + return block.call(buf, out_len) end end end diff --git a/runtime/src/memory.rs b/runtime/src/memory.rs index 4a88a8e..096976b 100644 --- a/runtime/src/memory.rs +++ b/runtime/src/memory.rs @@ -158,13 +158,13 @@ impl PluginMemory { } } + let new_offset = self.position.saturating_add(n); + // If there aren't enough bytes, try to grow the memory size - if self.position.saturating_add(n) >= self.size() { + if new_offset >= self.size() { debug!("Need more memory"); - let bytes_needed = (self.position as f64 + n as f64 - - self.memory.data_size(&self.store) as f64) - / PAGE_SIZE as f64; + let bytes_needed = (new_offset as f64 - self.size() as f64) / PAGE_SIZE as f64; let mut pages_needed = bytes_needed.ceil() as u64; if pages_needed == 0 { pages_needed = 1 @@ -180,6 +180,11 @@ impl PluginMemory { length: n, }; + info!( + "Allocated new block: {} bytes at offset {}", + mem.length, mem.offset + ); + self.live_blocks.insert(mem.offset, mem.length); self.position += n; Ok(mem) diff --git a/runtime/src/sdk.rs b/runtime/src/sdk.rs index fac55ee..e6faa68 100644 --- a/runtime/src/sdk.rs +++ b/runtime/src/sdk.rs @@ -218,7 +218,7 @@ pub unsafe extern "C" fn extism_log_file( } } } else { - "-" + "stderr" }; let level = if log_level.is_null() { @@ -242,18 +242,24 @@ pub unsafe extern "C" fn extism_log_file( let encoder = Box::new(PatternEncoder::new("{t} {l} {d} - {m}\n")); - let logfile: Box = if file == "-" { - let console = ConsoleAppender::builder().encoder(encoder); - Box::new(console.build()) - } else { - match FileAppender::builder().encoder(encoder).build(file) { - Ok(x) => Box::new(x), - Err(e) => { - error!("Unable to set up log encoder: {e:?}"); - return false; + let logfile: Box = + if file == "-" || file == "stdout" || file == "stderr" { + let target = if file == "-" || file == "stdout" { + log4rs::append::console::Target::Stdout + } else { + log4rs::append::console::Target::Stderr + }; + let console = ConsoleAppender::builder().target(target).encoder(encoder); + Box::new(console.build()) + } else { + match FileAppender::builder().encoder(encoder).build(file) { + Ok(x) => Box::new(x), + Err(e) => { + error!("Unable to set up log encoder: {e:?}"); + return false; + } } - } - }; + }; let config = match Config::builder() .appender(Appender::builder().build("logfile", logfile))