Orb icon indicating copy to clipboard operation
Orb copied to clipboard

Read memory offset, incorporating size of statically allocated pages for string constants

Open RoyalIcing opened this issue 1 year ago • 4 comments
trafficstars

Currently the string constants are just thrown into memory from offset 0xFF. You must write Memory.pages(1) for string constants to even work — this sucks!

What we should do is count how many bytes the string constants take and allocate an exact number of memory pages for them. e.g. 80 KiB of constants should allocate 2 pages. I don’t think we are so memory tight that we have to compress memory, so the left over memory on the last page for constants would just remain unused.

I intend to switch how String pointers are represented (See #7) but we’d still likely put 0x0 nul bytes between each string. This makes raw memory easier to debug, and possibly is useful for interop that expects nul-terminated strings (but I’m still learning whether these are something to avoid like the plague).

RoyalIcing avatar Mar 15 '24 08:03 RoyalIcing

Having done a little investigation this looks difficult. We calculate all the constants when compiling the entire module.

# lib/orb.ex:637
        def __wasm_module__() do
          %{body: body, constants: constants, global_definitions: global_definitions} =
            Orb.Compiler.run(__MODULE__, @wasm_globals)

          Orb.ModuleDefinition.new(…)
        end       

So if we want to use the constants size at WebAssembly compile time then we have a chicken-egg problem. We use this for SilverOrb.Arena to work out which page offset an arena has allocated. So it needs to know that at compile-time.

I don’t want to compile twice as there’s a risk that state changes between the two and it results into two slightly different compiled outputs. And knowing the size of the constants would be a state change.

RoyalIcing avatar Apr 11 '24 23:04 RoyalIcing

I'm thinking the easiest way to solve this is to have a WebAssembly global store the constant size. Operations like with arenas can just read that global.

A small pass just before assembly will set the initial value of the global. It only needs to be a read-only global.

RoyalIcing avatar Apr 19 '24 09:04 RoyalIcing

This is now implemented, and it was much easier than anticipated!

RoyalIcing avatar Jun 13 '24 12:06 RoyalIcing

SilverOrb.Arena still needs a way to read the page offset it has been allocated.

RoyalIcing avatar Jun 13 '24 12:06 RoyalIcing