Skip to content
This repository has been archived by the owner on Aug 17, 2022. It is now read-only.

Discussing record.lift/lower for multi-dimensional records #108

Open
Hywan opened this issue Apr 7, 2020 · 3 comments
Open

Discussing record.lift/lower for multi-dimensional records #108

Hywan opened this issue Apr 7, 2020 · 3 comments

Comments

@Hywan
Copy link
Contributor

Hywan commented Apr 7, 2020

Discussing about this version of the proposal (the latest at the time of writing): https://github.com/WebAssembly/interface-types/blob/5af0606baceab6c5ecc8bd247fae944998c2aa61/proposals/interface-types/working-notes/Instructions.md#stringlower_memory

I want to discuss about the record.lift instruction (same ideas for record.lower). Let's assume the following type, that could represent a Point:

;; Point { x: i32, y: i32 }
(@interface type (record (field i32) (field i32)))

Then the set of instructions would look like the following:

Instruction Stack Comment
arg.get 0 [i32(7)] Load x
arg.get 1 [i32(7), i32(42)] Load y
record.lift 0 [record([7, 42])] Tada, our record

My question is what happens with a multi-dimensional record? Let's assume the Line type:

;; Line { p1: Point, p2: Point }
(@interace type
  (record
    (field
      record (field i32) (field i32))
    (field
      record (field i32) (field i32))))

Then the set of instructions would look like as follows:

Instruction Stack Comment
arg.get 0 [i32(7)] Load x for p1
arg.get 1 [i32(7), i32(42)] Load y for p1
arg.get 2 [i32(7), i32(42), i32(153)] Load x for p2
arg.get 3 [i32(7), i32(42), i32(153), i32(256)] Load y for p2
record.lift 0 [record([record([7, 42]), record([153, 256])])] Tada, our record

Is this correct? Should we have all the fields “flattened”, and the record.lift instruction rebuild everything? Or do we expect the following:

Instruction Stack Comment
arg.get 0 [i32(7)] Load x for p1
arg.get 1 [i32(7), i32(42)] Load y for p1
record.lift ?? [record([i32(7), i32(42)])] Record for p1
arg.get 2 [record([i32(7), i32(42)]), i32(153)] Load x for p2
arg.get 3 [record([i32(7), i32(42)]), i32(153), i32(256)] Load y for p2
record.lift ?? [record([i32(7), i32(42)]), record([i32(153), i32(256)])] Record for p2
record.lift 0 [record([record([7, 42]), record([153, 256])])] Tada, our final record

In this case, we load intermediate Point records. But since record.lift requires a record type index, what would it be? It would mean that record type must be flattened too, something like:

(@interface type $point (record (field i32) (field i32)))
(@interface type $line (record (field (record type $point) (record type $point))))

The same observation can be applied to record.lower.

I hope my question isn't too trivial. With the Covid-19 situation, I have difficulties to follow every discussions of this WG.

Thanks!

@fgmccabe
Copy link
Contributor

fgmccabe commented Apr 7, 2020 via email

@syrusakbary
Copy link

  1. Record.lift/lower (not my preferred names for these ops) wrap and unwrap
    interface value types. I.e., they go from a sequence of IT values on the
    stack <-> a single IT value.

Agreed, it took me some time to grasp what were the methods for.
I think record.wrap, record.unwrap might be a bit clearer. Thoughts?

@fgmccabe
Copy link
Contributor

fgmccabe commented Apr 9, 2020

Prefer pack and unpack but not super committed to that

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants