Project

General

Profile

Actions

Feature #22222

open

Expose a C API equivalent of `RubyVM::InstructionSequence.load_from_binary`

Feature #22222: Expose a C API equivalent of `RubyVM::InstructionSequence.load_from_binary`

Added by byroot (Jean Boussier) 1 day ago. Updated about 24 hours ago.

Status:
Open
Assignee:
-
Target version:
-
[ruby-core:126211]

Description

Currently the only API to deserialize instruction sequence is RubyVM::InstructionSequence.load_from_binary(String).

It works fine, but isn't ideal for gems like bootsnap, as it needs to allocate a fairly large string and memcpy into it.

I would like to be able to directly pass a char *ptr and size_t len pair, so that I can directly pass a internal buffer or even mmapped file.

Proposed API:

VALUE rb_iseq_load_from_binary(const char *ptr, size_t len)

Pull request: https://github.com/ruby/ruby/pull/18136

Updated by nobu (Nobuyoshi Nakada) 1 day ago Actions #1 [ruby-core:126212]

rb_str_new_static does not memcpy (of course you have the responsibility to keep the String).

Updated by byroot (Jean Boussier) 1 day ago Actions #2 [ruby-core:126213]

@nobu (Nobuyoshi Nakada) yes I know, but as you mention, it's meant to point at static C strings, not mmaped files or stack buffers, so it doesn't work for Bootsnap.

Updated by byroot (Jean Boussier) 1 day ago Actions #3

  • Description updated (diff)

Updated by nobu (Nobuyoshi Nakada) 1 day ago Actions #4 [ruby-core:126215]

The only requirements for rb_str_new_static are that the caller is responsible for freeing the allocated memory, and that the memory is not freed while the object is still in existence.
You can think of it as requiring the same level of care as when passing a buffer to a system call.
The term “static” essentially means that the memory is stable from the perspective of this function.

Updated by byroot (Jean Boussier) 1 day ago Actions #5 [ruby-core:126216]

Yes, I get that, but my point is that these constraints are very hard to ensure in my case.

Updated by Eregon (Benoit Daloze) about 24 hours ago Actions #6 [ruby-core:126217]

I guess one concrete issue here with using rb_str_new_static() is the mmaped file/stack buffer will be freed soon after the RubyVM::InstructionSequence.load_from_binary(String) call, but that String object might live longer, there is no "GC this object now" (AFAIK).
And potentially something could get that String via ObjectSpace.each_object, and then it'd segfault if the underlying buffer has been freed.

Actions

Also available in: PDF Atom