{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE QuasiQuotes #-}

{- |
The instruction set itself: the 'Wasm32Isa' type, the assembly syntax that
produces it, the field guards every immediate has to pass, and the size each
instruction occupies.
-}
module Wrench.Isa.Wasm32.Instruction (
    Wasm32Isa (..),
    wasm32Mnemonics,
) where

import Data.String.Interpolate (i)
import Relude
import Text.Megaparsec (choice, getSourcePos, lookAhead, try)
import Text.Megaparsec.Char (digitChar, hspace, hspace1, string)
import Wrench.Machine.Types
import Wrench.Machine.Word (u8)
import Wrench.Translator.Parser.Misc
import Wrench.Translator.Parser.Types
import Wrench.Translator.Types

-- | One instruction. Each entry starts with its syntax and stack effect.
data Wasm32Isa w l
    = -- | > i32.const <value: i32> ( -- value: i32 )
      --
      -- Push an immediate: a number or a label, which is how a function
      -- address is produced (see Functions and locals).
      I32Const l
    | -- | > i32.add ( a: i32, b: i32 -- sum: i32 )
      I32Add
    | -- | > i32.sub ( a: i32, b: i32 -- difference: i32 )
      --
      -- @a - b@.
      I32Sub
    | -- | > i32.mul ( a: i32, b: i32 -- product: i32 )
      --
      -- Keeps the low 32 bits of the product.
      I32Mul
    | -- | > i32.div_s ( a: i32, b: i32 -- quotient: i32 )
      --
      -- Signed division truncating toward zero: @-7 \/ 2@ is @-3@. Stops
      -- with an error on a zero divisor and on @minBound \/ -1@.
      I32DivS
    | -- | > i32.rem_s ( a: i32, b: i32 -- remainder: i32 )
      --
      -- Signed remainder with the sign of @a@: @-7 % 2@ is @-1@. Stops with
      -- an error only on a zero divisor; @minBound % -1@ is @0@.
      I32RemS
    | -- | > i32.and ( a: i32, b: i32 -- bits: i32 )
      I32And
    | -- | > i32.or ( a: i32, b: i32 -- bits: i32 )
      I32Or
    | -- | > i32.xor ( a: i32, b: i32 -- bits: i32 )
      I32Xor
    | -- | > i32.shl ( value: i32, amount: i32 -- shifted: i32 )
      --
      -- Shift left. The amount is taken modulo 32, as for every shift.
      I32Shl
    | -- | > i32.shr_s ( value: i32, amount: i32 -- shifted: i32 )
      --
      -- Arithmetic (sign-extending) shift right.
      I32ShrS
    | -- | > i32.shr_u ( value: i32, amount: i32 -- shifted: i32 )
      --
      -- Logical (zero-filling) shift right.
      I32ShrU
    | -- | > i32.eqz ( value: i32 -- flag: i32 )
      --
      -- Push @1@ if the value is @0@, else @0@.
      I32Eqz
    | -- | > i32.eq ( a: i32, b: i32 -- flag: i32 )
      --
      -- Push @1@ if @a = b@, else @0@, like every comparison.
      I32Eq
    | -- | > i32.lt_s ( a: i32, b: i32 -- flag: i32 )
      --
      -- Signed @a \< b@.
      I32LtS
    | -- | > i32.le_s ( a: i32, b: i32 -- flag: i32 )
      --
      -- Signed @a \<= b@.
      I32LeS
    | -- | > i32.gt_s ( a: i32, b: i32 -- flag: i32 )
      --
      -- Signed @a \> b@.
      I32GtS
    | -- | > i32.ge_s ( a: i32, b: i32 -- flag: i32 )
      --
      -- Signed @a \>= b@.
      I32GeS
    | -- | > i32.lt_u ( a: i32, b: i32 -- flag: i32 )
      --
      -- Unsigned @a \< b@, so @-1@ compares greater than @1@.
      I32LtU
    | -- | > i32.le_u ( a: i32, b: i32 -- flag: i32 )
      --
      -- Unsigned @a \<= b@.
      I32LeU
    | -- | > i32.gt_u ( a: i32, b: i32 -- flag: i32 )
      --
      -- Unsigned @a \> b@.
      I32GtU
    | -- | > i32.ge_u ( a: i32, b: i32 -- flag: i32 )
      --
      -- Unsigned @a \>= b@.
      I32GeU
    | -- | > i32.load <offset: u8> ( address: i32 -- value: i32 )
      --
      -- Push the word at @address + offset@. Every load and store takes
      -- an optional offset, @0@ to @255@, so a struct field or a small
      -- array element needs no @i32.add@:
      --
      -- > i32.const point
      -- > i32.load 4            ; point.y
      I32Load l
    | -- | > i32.load8_u <offset: u8> ( address: i32 -- value: i32 )
      --
      -- Like 'I32Load', but reads one byte and zero-extends it.
      I32Load8U l
    | -- | > i32.load8_s <offset: u8> ( address: i32 -- value: i32 )
      --
      -- Like 'I32Load8U', but sign-extends.
      I32Load8S l
    | -- | > i32.store <offset: u8> ( address: i32, value: i32 -- )
      --
      -- Write the word at @address + offset@. The address goes under the
      -- value, so push it first.
      I32Store l
    | -- | > i32.store8 <offset: u8> ( address: i32, value: i32 -- )
      --
      -- Like 'I32Store', but writes only the low byte.
      I32Store8 l
    | -- | > block ( -- )
      --
      -- Open a scope; a branch to it continues after its @end@.
      Block
    | -- | > loop ( -- )
      --
      -- Open a scope; a branch to it continues at the start of its body.
      -- Without a branch the body runs once.
      Loop
    | -- | > if ( condition: i32 -- )
      --
      -- Run the following body if the condition is non-zero, otherwise
      -- continue after the matching @else@ or @end@. Opens no scope.
      If
    | -- | > else ( -- )
      --
      -- Reached at the end of a taken @if@ body: continue after the
      -- matching @end@.
      Else
    | -- | > end ( -- )
      --
      -- Close the @block@ or @loop@ it belongs to; for an @if@, do
      -- nothing.
      End
    | -- | > br <depth: u8> ( -- )
      --
      -- Branch to the scope @depth@ levels out, @0@ being the innermost
      -- open @block@ or @loop@, and close every scope inside it. A target
      -- @block@ is closed too, since execution leaves it; a target @loop@
      -- stays open.
      Br l
    | -- | > br_if <depth: u8> ( condition: i32 -- )
      --
      -- 'Br' if the condition is non-zero, otherwise continue.
      BrIf l
    | -- | > unreachable ( -- )
      --
      -- Stop with an error.
      Unreachable
    | -- | > call <paramCount: u8>, <resultCount: u8> ( ...params: i32, target: i32 -- ...results: i32 )
      --
      -- Call the function at @target@: the @paramCount@ values under it
      -- become its first locals, and @resultCount@ values come back.
      -- Neither count is checked against the callee.
      Call {forall w l. Wasm32Isa w l -> l
callParamCount :: l, forall w l. Wasm32Isa w l -> l
callResultCount :: l}
    | -- | > return ( ...results: i32 -- )
      --
      -- Leave the current function, closing every scope it still has open
      -- and passing the call's @resultCount@ values from the top of the
      -- stack back to the caller.
      Return
    | -- | > local.get <index: u8> ( -- value: i32 )
      LocalGet l
    | -- | > local.set <index: u8> ( value: i32 -- )
      LocalSet l
    | -- | > local.tee <index: u8> ( value: i32 -- value: i32 )
      --
      -- Like @local.set@, but keeps the value on the stack.
      LocalTee l
    | -- | > locals.reserve <count: u8> ( -- )
      --
      -- Add @count@ locals after the ones the frame has. Use it first
      -- thing in a function, before pushing anything: the new locals are
      -- the next words down the stack. They are not cleared.
      LocalsReserve l
    | -- | > drop ( value: i32 -- )
      --
      -- Discard the top value, e.g. a result the caller does not need.
      Drop
    | -- | > select ( a: i32, b: i32, condition: i32 -- chosen: i32 )
      --
      -- Push @a@ if the condition is non-zero, @b@ otherwise.
      Select
    | -- | > sp.init ( address: i32 -- )
      --
      -- Move 'stackRoot', where both stacks start, to @address@. Both
      -- stacks restart empty there, so use it before anything is pushed:
      -- the frame's locals and any open scope are lost. Nothing checks the
      -- address.
      SpInit
    | -- | > halt ( -- )
      --
      -- Stop the machine.
      Halt
    deriving (Wasm32Isa w l -> Wasm32Isa w l -> Bool
(Wasm32Isa w l -> Wasm32Isa w l -> Bool)
-> (Wasm32Isa w l -> Wasm32Isa w l -> Bool) -> Eq (Wasm32Isa w l)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall w l. Eq l => Wasm32Isa w l -> Wasm32Isa w l -> Bool
$c== :: forall w l. Eq l => Wasm32Isa w l -> Wasm32Isa w l -> Bool
== :: Wasm32Isa w l -> Wasm32Isa w l -> Bool
$c/= :: forall w l. Eq l => Wasm32Isa w l -> Wasm32Isa w l -> Bool
/= :: Wasm32Isa w l -> Wasm32Isa w l -> Bool
Eq, (forall a b. (a -> b) -> Wasm32Isa w a -> Wasm32Isa w b)
-> (forall a b. a -> Wasm32Isa w b -> Wasm32Isa w a)
-> Functor (Wasm32Isa w)
forall a b. a -> Wasm32Isa w b -> Wasm32Isa w a
forall a b. (a -> b) -> Wasm32Isa w a -> Wasm32Isa w b
forall w a b. a -> Wasm32Isa w b -> Wasm32Isa w a
forall w a b. (a -> b) -> Wasm32Isa w a -> Wasm32Isa w b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall w a b. (a -> b) -> Wasm32Isa w a -> Wasm32Isa w b
fmap :: forall a b. (a -> b) -> Wasm32Isa w a -> Wasm32Isa w b
$c<$ :: forall w a b. a -> Wasm32Isa w b -> Wasm32Isa w a
<$ :: forall a b. a -> Wasm32Isa w b -> Wasm32Isa w a
Functor, Int -> Wasm32Isa w l -> ShowS
[Wasm32Isa w l] -> ShowS
Wasm32Isa w l -> String
(Int -> Wasm32Isa w l -> ShowS)
-> (Wasm32Isa w l -> String)
-> ([Wasm32Isa w l] -> ShowS)
-> Show (Wasm32Isa w l)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall w l. Show l => Int -> Wasm32Isa w l -> ShowS
forall w l. Show l => [Wasm32Isa w l] -> ShowS
forall w l. Show l => Wasm32Isa w l -> String
$cshowsPrec :: forall w l. Show l => Int -> Wasm32Isa w l -> ShowS
showsPrec :: Int -> Wasm32Isa w l -> ShowS
$cshow :: forall w l. Show l => Wasm32Isa w l -> String
show :: Wasm32Isa w l -> String
$cshowList :: forall w l. Show l => [Wasm32Isa w l] -> ShowS
showList :: [Wasm32Isa w l] -> ShowS
Show)

-- | Every mnemonic the 'MnemonicParser' instance accepts.
wasm32Mnemonics :: [Text]
wasm32Mnemonics :: [Text]
wasm32Mnemonics =
    [ Text
"i32.const"
    , Text
"i32.add"
    , Text
"i32.sub"
    , Text
"i32.mul"
    , Text
"i32.div_s"
    , Text
"i32.rem_s"
    , Text
"i32.and"
    , Text
"i32.or"
    , Text
"i32.xor"
    , Text
"i32.shl"
    , Text
"i32.shr_s"
    , Text
"i32.shr_u"
    , Text
"i32.eqz"
    , Text
"i32.eq"
    , Text
"i32.lt_s"
    , Text
"i32.le_s"
    , Text
"i32.gt_s"
    , Text
"i32.ge_s"
    , Text
"i32.lt_u"
    , Text
"i32.le_u"
    , Text
"i32.gt_u"
    , Text
"i32.ge_u"
    , Text
"i32.load8_u"
    , Text
"i32.load8_s"
    , Text
"i32.load"
    , Text
"i32.store8"
    , Text
"i32.store"
    , Text
"if"
    , Text
"else"
    , Text
"end"
    , Text
"loop"
    , Text
"block"
    , Text
"br"
    , Text
"br_if"
    , Text
"drop"
    , Text
"select"
    , Text
"unreachable"
    , Text
"local.get"
    , Text
"local.set"
    , Text
"local.tee"
    , Text
"locals.reserve"
    , Text
"call"
    , Text
"return"
    , Text
"sp.init"
    , Text
"halt"
    ]

instance CommentStart (Wasm32Isa w l) where
    commentStart :: String
commentStart = String
";"

instance (IsWord w) => MnemonicParser (Wasm32Isa w (Ref w)) where
    mnemonic :: Parser (Wasm32Isa w (Ref w))
mnemonic =
        ParsecT Void String Identity ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
hspace ParsecT Void String Identity ()
-> Parser (Wasm32Isa w (Ref w)) -> Parser (Wasm32Isa w (Ref w))
forall a b.
ParsecT Void String Identity a
-> ParsecT Void String Identity b -> ParsecT Void String Identity b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser (Wasm32Isa w (Ref w))
forall {w}. ParsecT Void String Identity (Wasm32Isa w (Ref w))
cmd Parser (Wasm32Isa w (Ref w))
-> ParsecT Void String Identity () -> Parser (Wasm32Isa w (Ref w))
forall a b.
ParsecT Void String Identity a
-> ParsecT Void String Identity b -> ParsecT Void String Identity a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* (ParsecT Void String Identity ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
hspace1 ParsecT Void String Identity ()
-> ParsecT Void String Identity ()
-> ParsecT Void String Identity ()
forall a.
ParsecT Void String Identity a
-> ParsecT Void String Identity a -> ParsecT Void String Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> String -> ParsecT Void String Identity ()
eol' (forall m. CommentStart m => String
commentStart @(Wasm32Isa _ _)))
        where
            cmd :: ParsecT Void String Identity (Wasm32Isa w (Ref w))
cmd =
                [ParsecT Void String Identity (Wasm32Isa w (Ref w))]
-> ParsecT Void String Identity (Wasm32Isa w (Ref w))
forall (f :: * -> *) (m :: * -> *) a.
(Foldable f, Alternative m) =>
f (m a) -> m a
choice
                    [ Ref w -> Wasm32Isa w (Ref w)
forall w l. l -> Wasm32Isa w l
I32Const (Ref w -> Wasm32Isa w (Ref w))
-> ParsecT Void String Identity (Ref w)
-> ParsecT Void String Identity (Wasm32Isa w (Ref w))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Tokens String
-> ParsecT Void String Identity (Ref w)
-> ParsecT Void String Identity (Ref w)
forall {s} {m :: * -> *} {e} {b}.
(Token s ~ Char, MonadParsec e s m) =>
Tokens s -> m b -> m b
cmd1 Tokens String
"i32.const" ParsecT Void String Identity (Ref w)
forall w. IsWord w => Parser (Ref w)
referenceWithDirective
                    , Tokens String
-> Wasm32Isa w (Ref w)
-> ParsecT Void String Identity (Wasm32Isa w (Ref w))
forall {m :: * -> *} {e} {s} {b}.
MonadParsec e s m =>
Tokens s -> b -> m b
cmd0 Tokens String
"i32.add" Wasm32Isa w (Ref w)
forall w l. Wasm32Isa w l
I32Add
                    , Tokens String
-> Wasm32Isa w (Ref w)
-> ParsecT Void String Identity (Wasm32Isa w (Ref w))
forall {m :: * -> *} {e} {s} {b}.
MonadParsec e s m =>
Tokens s -> b -> m b
cmd0 Tokens String
"i32.sub" Wasm32Isa w (Ref w)
forall w l. Wasm32Isa w l
I32Sub
                    , Tokens String
-> Wasm32Isa w (Ref w)
-> ParsecT Void String Identity (Wasm32Isa w (Ref w))
forall {m :: * -> *} {e} {s} {b}.
MonadParsec e s m =>
Tokens s -> b -> m b
cmd0 Tokens String
"i32.mul" Wasm32Isa w (Ref w)
forall w l. Wasm32Isa w l
I32Mul
                    , Tokens String
-> Wasm32Isa w (Ref w)
-> ParsecT Void String Identity (Wasm32Isa w (Ref w))
forall {m :: * -> *} {e} {s} {b}.
MonadParsec e s m =>
Tokens s -> b -> m b
cmd0 Tokens String
"i32.div_s" Wasm32Isa w (Ref w)
forall w l. Wasm32Isa w l
I32DivS
                    , Tokens String
-> Wasm32Isa w (Ref w)
-> ParsecT Void String Identity (Wasm32Isa w (Ref w))
forall {m :: * -> *} {e} {s} {b}.
MonadParsec e s m =>
Tokens s -> b -> m b
cmd0 Tokens String
"i32.rem_s" Wasm32Isa w (Ref w)
forall w l. Wasm32Isa w l
I32RemS
                    , Tokens String
-> Wasm32Isa w (Ref w)
-> ParsecT Void String Identity (Wasm32Isa w (Ref w))
forall {m :: * -> *} {e} {s} {b}.
MonadParsec e s m =>
Tokens s -> b -> m b
cmd0 Tokens String
"i32.and" Wasm32Isa w (Ref w)
forall w l. Wasm32Isa w l
I32And
                    , Tokens String
-> Wasm32Isa w (Ref w)
-> ParsecT Void String Identity (Wasm32Isa w (Ref w))
forall {m :: * -> *} {e} {s} {b}.
MonadParsec e s m =>
Tokens s -> b -> m b
cmd0 Tokens String
"i32.or" Wasm32Isa w (Ref w)
forall w l. Wasm32Isa w l
I32Or
                    , Tokens String
-> Wasm32Isa w (Ref w)
-> ParsecT Void String Identity (Wasm32Isa w (Ref w))
forall {m :: * -> *} {e} {s} {b}.
MonadParsec e s m =>
Tokens s -> b -> m b
cmd0 Tokens String
"i32.xor" Wasm32Isa w (Ref w)
forall w l. Wasm32Isa w l
I32Xor
                    , Tokens String
-> Wasm32Isa w (Ref w)
-> ParsecT Void String Identity (Wasm32Isa w (Ref w))
forall {m :: * -> *} {e} {s} {b}.
MonadParsec e s m =>
Tokens s -> b -> m b
cmd0 Tokens String
"i32.shl" Wasm32Isa w (Ref w)
forall w l. Wasm32Isa w l
I32Shl
                    , Tokens String
-> Wasm32Isa w (Ref w)
-> ParsecT Void String Identity (Wasm32Isa w (Ref w))
forall {m :: * -> *} {e} {s} {b}.
MonadParsec e s m =>
Tokens s -> b -> m b
cmd0 Tokens String
"i32.shr_s" Wasm32Isa w (Ref w)
forall w l. Wasm32Isa w l
I32ShrS
                    , Tokens String
-> Wasm32Isa w (Ref w)
-> ParsecT Void String Identity (Wasm32Isa w (Ref w))
forall {m :: * -> *} {e} {s} {b}.
MonadParsec e s m =>
Tokens s -> b -> m b
cmd0 Tokens String
"i32.shr_u" Wasm32Isa w (Ref w)
forall w l. Wasm32Isa w l
I32ShrU
                    , Tokens String
-> Wasm32Isa w (Ref w)
-> ParsecT Void String Identity (Wasm32Isa w (Ref w))
forall {m :: * -> *} {e} {s} {b}.
MonadParsec e s m =>
Tokens s -> b -> m b
cmd0 Tokens String
"i32.eqz" Wasm32Isa w (Ref w)
forall w l. Wasm32Isa w l
I32Eqz
                    , Tokens String
-> Wasm32Isa w (Ref w)
-> ParsecT Void String Identity (Wasm32Isa w (Ref w))
forall {m :: * -> *} {e} {s} {b}.
MonadParsec e s m =>
Tokens s -> b -> m b
cmd0 Tokens String
"i32.eq" Wasm32Isa w (Ref w)
forall w l. Wasm32Isa w l
I32Eq
                    , Tokens String
-> Wasm32Isa w (Ref w)
-> ParsecT Void String Identity (Wasm32Isa w (Ref w))
forall {m :: * -> *} {e} {s} {b}.
MonadParsec e s m =>
Tokens s -> b -> m b
cmd0 Tokens String
"i32.lt_s" Wasm32Isa w (Ref w)
forall w l. Wasm32Isa w l
I32LtS
                    , Tokens String
-> Wasm32Isa w (Ref w)
-> ParsecT Void String Identity (Wasm32Isa w (Ref w))
forall {m :: * -> *} {e} {s} {b}.
MonadParsec e s m =>
Tokens s -> b -> m b
cmd0 Tokens String
"i32.le_s" Wasm32Isa w (Ref w)
forall w l. Wasm32Isa w l
I32LeS
                    , Tokens String
-> Wasm32Isa w (Ref w)
-> ParsecT Void String Identity (Wasm32Isa w (Ref w))
forall {m :: * -> *} {e} {s} {b}.
MonadParsec e s m =>
Tokens s -> b -> m b
cmd0 Tokens String
"i32.gt_s" Wasm32Isa w (Ref w)
forall w l. Wasm32Isa w l
I32GtS
                    , Tokens String
-> Wasm32Isa w (Ref w)
-> ParsecT Void String Identity (Wasm32Isa w (Ref w))
forall {m :: * -> *} {e} {s} {b}.
MonadParsec e s m =>
Tokens s -> b -> m b
cmd0 Tokens String
"i32.ge_s" Wasm32Isa w (Ref w)
forall w l. Wasm32Isa w l
I32GeS
                    , Tokens String
-> Wasm32Isa w (Ref w)
-> ParsecT Void String Identity (Wasm32Isa w (Ref w))
forall {m :: * -> *} {e} {s} {b}.
MonadParsec e s m =>
Tokens s -> b -> m b
cmd0 Tokens String
"i32.lt_u" Wasm32Isa w (Ref w)
forall w l. Wasm32Isa w l
I32LtU
                    , Tokens String
-> Wasm32Isa w (Ref w)
-> ParsecT Void String Identity (Wasm32Isa w (Ref w))
forall {m :: * -> *} {e} {s} {b}.
MonadParsec e s m =>
Tokens s -> b -> m b
cmd0 Tokens String
"i32.le_u" Wasm32Isa w (Ref w)
forall w l. Wasm32Isa w l
I32LeU
                    , Tokens String
-> Wasm32Isa w (Ref w)
-> ParsecT Void String Identity (Wasm32Isa w (Ref w))
forall {m :: * -> *} {e} {s} {b}.
MonadParsec e s m =>
Tokens s -> b -> m b
cmd0 Tokens String
"i32.gt_u" Wasm32Isa w (Ref w)
forall w l. Wasm32Isa w l
I32GtU
                    , Tokens String
-> Wasm32Isa w (Ref w)
-> ParsecT Void String Identity (Wasm32Isa w (Ref w))
forall {m :: * -> *} {e} {s} {b}.
MonadParsec e s m =>
Tokens s -> b -> m b
cmd0 Tokens String
"i32.ge_u" Wasm32Isa w (Ref w)
forall w l. Wasm32Isa w l
I32GeU
                    , String
-> (Ref w -> Wasm32Isa w (Ref w))
-> ParsecT Void String Identity (Wasm32Isa w (Ref w))
forall {w} {b}.
(FiniteBits w, ByteSize w, Default w, Hashable w, Read w,
 WordParts w, FromSign w, Bounded w, Integral w, Show w) =>
String -> (Ref w -> b) -> ParsecT Void String Identity b
memOp String
"i32.load8_u" Ref w -> Wasm32Isa w (Ref w)
forall w l. l -> Wasm32Isa w l
I32Load8U
                    , String
-> (Ref w -> Wasm32Isa w (Ref w))
-> ParsecT Void String Identity (Wasm32Isa w (Ref w))
forall {w} {b}.
(FiniteBits w, ByteSize w, Default w, Hashable w, Read w,
 WordParts w, FromSign w, Bounded w, Integral w, Show w) =>
String -> (Ref w -> b) -> ParsecT Void String Identity b
memOp String
"i32.load8_s" Ref w -> Wasm32Isa w (Ref w)
forall w l. l -> Wasm32Isa w l
I32Load8S
                    , String
-> (Ref w -> Wasm32Isa w (Ref w))
-> ParsecT Void String Identity (Wasm32Isa w (Ref w))
forall {w} {b}.
(FiniteBits w, ByteSize w, Default w, Hashable w, Read w,
 WordParts w, FromSign w, Bounded w, Integral w, Show w) =>
String -> (Ref w -> b) -> ParsecT Void String Identity b
memOp String
"i32.load" Ref w -> Wasm32Isa w (Ref w)
forall w l. l -> Wasm32Isa w l
I32Load
                    , String
-> (Ref w -> Wasm32Isa w (Ref w))
-> ParsecT Void String Identity (Wasm32Isa w (Ref w))
forall {w} {b}.
(FiniteBits w, ByteSize w, Default w, Hashable w, Read w,
 WordParts w, FromSign w, Bounded w, Integral w, Show w) =>
String -> (Ref w -> b) -> ParsecT Void String Identity b
memOp String
"i32.store8" Ref w -> Wasm32Isa w (Ref w)
forall w l. l -> Wasm32Isa w l
I32Store8
                    , String
-> (Ref w -> Wasm32Isa w (Ref w))
-> ParsecT Void String Identity (Wasm32Isa w (Ref w))
forall {w} {b}.
(FiniteBits w, ByteSize w, Default w, Hashable w, Read w,
 WordParts w, FromSign w, Bounded w, Integral w, Show w) =>
String -> (Ref w -> b) -> ParsecT Void String Identity b
memOp String
"i32.store" Ref w -> Wasm32Isa w (Ref w)
forall w l. l -> Wasm32Isa w l
I32Store
                    , Tokens String
-> Wasm32Isa w (Ref w)
-> ParsecT Void String Identity (Wasm32Isa w (Ref w))
forall {m :: * -> *} {e} {s} {b}.
MonadParsec e s m =>
Tokens s -> b -> m b
cmd0 Tokens String
"if" Wasm32Isa w (Ref w)
forall w l. Wasm32Isa w l
If
                    , Tokens String
-> Wasm32Isa w (Ref w)
-> ParsecT Void String Identity (Wasm32Isa w (Ref w))
forall {m :: * -> *} {e} {s} {b}.
MonadParsec e s m =>
Tokens s -> b -> m b
cmd0 Tokens String
"else" Wasm32Isa w (Ref w)
forall w l. Wasm32Isa w l
Else
                    , Tokens String
-> Wasm32Isa w (Ref w)
-> ParsecT Void String Identity (Wasm32Isa w (Ref w))
forall {m :: * -> *} {e} {s} {b}.
MonadParsec e s m =>
Tokens s -> b -> m b
cmd0 Tokens String
"end" Wasm32Isa w (Ref w)
forall w l. Wasm32Isa w l
End
                    , Tokens String
-> Wasm32Isa w (Ref w)
-> ParsecT Void String Identity (Wasm32Isa w (Ref w))
forall {m :: * -> *} {e} {s} {b}.
MonadParsec e s m =>
Tokens s -> b -> m b
cmd0 Tokens String
"loop" Wasm32Isa w (Ref w)
forall w l. Wasm32Isa w l
Loop
                    , Tokens String
-> Wasm32Isa w (Ref w)
-> ParsecT Void String Identity (Wasm32Isa w (Ref w))
forall {m :: * -> *} {e} {s} {b}.
MonadParsec e s m =>
Tokens s -> b -> m b
cmd0 Tokens String
"block" Wasm32Isa w (Ref w)
forall w l. Wasm32Isa w l
Block
                    , Ref w -> Wasm32Isa w (Ref w)
forall w l. l -> Wasm32Isa w l
Br (Ref w -> Wasm32Isa w (Ref w))
-> ParsecT Void String Identity (Ref w)
-> ParsecT Void String Identity (Wasm32Isa w (Ref w))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Tokens String
-> ParsecT Void String Identity (Ref w)
-> ParsecT Void String Identity (Ref w)
forall {s} {m :: * -> *} {e} {b}.
(Token s ~ Char, MonadParsec e s m) =>
Tokens s -> m b -> m b
cmd1 Tokens String
"br" ParsecT Void String Identity (Ref w)
forall w. IsWord w => Parser (Ref w)
constantRef
                    , Ref w -> Wasm32Isa w (Ref w)
forall w l. l -> Wasm32Isa w l
BrIf (Ref w -> Wasm32Isa w (Ref w))
-> ParsecT Void String Identity (Ref w)
-> ParsecT Void String Identity (Wasm32Isa w (Ref w))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Tokens String
-> ParsecT Void String Identity (Ref w)
-> ParsecT Void String Identity (Ref w)
forall {s} {m :: * -> *} {e} {b}.
(Token s ~ Char, MonadParsec e s m) =>
Tokens s -> m b -> m b
cmd1 Tokens String
"br_if" ParsecT Void String Identity (Ref w)
forall w. IsWord w => Parser (Ref w)
constantRef
                    , Tokens String
-> Wasm32Isa w (Ref w)
-> ParsecT Void String Identity (Wasm32Isa w (Ref w))
forall {m :: * -> *} {e} {s} {b}.
MonadParsec e s m =>
Tokens s -> b -> m b
cmd0 Tokens String
"drop" Wasm32Isa w (Ref w)
forall w l. Wasm32Isa w l
Drop
                    , Tokens String
-> Wasm32Isa w (Ref w)
-> ParsecT Void String Identity (Wasm32Isa w (Ref w))
forall {m :: * -> *} {e} {s} {b}.
MonadParsec e s m =>
Tokens s -> b -> m b
cmd0 Tokens String
"select" Wasm32Isa w (Ref w)
forall w l. Wasm32Isa w l
Select
                    , Tokens String
-> Wasm32Isa w (Ref w)
-> ParsecT Void String Identity (Wasm32Isa w (Ref w))
forall {m :: * -> *} {e} {s} {b}.
MonadParsec e s m =>
Tokens s -> b -> m b
cmd0 Tokens String
"unreachable" Wasm32Isa w (Ref w)
forall w l. Wasm32Isa w l
Unreachable
                    , Ref w -> Wasm32Isa w (Ref w)
forall w l. l -> Wasm32Isa w l
LocalGet (Ref w -> Wasm32Isa w (Ref w))
-> ParsecT Void String Identity (Ref w)
-> ParsecT Void String Identity (Wasm32Isa w (Ref w))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Tokens String
-> ParsecT Void String Identity (Ref w)
-> ParsecT Void String Identity (Ref w)
forall {s} {m :: * -> *} {e} {b}.
(Token s ~ Char, MonadParsec e s m) =>
Tokens s -> m b -> m b
cmd1 Tokens String
"local.get" ParsecT Void String Identity (Ref w)
forall w. IsWord w => Parser (Ref w)
constantRef
                    , Ref w -> Wasm32Isa w (Ref w)
forall w l. l -> Wasm32Isa w l
LocalSet (Ref w -> Wasm32Isa w (Ref w))
-> ParsecT Void String Identity (Ref w)
-> ParsecT Void String Identity (Wasm32Isa w (Ref w))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Tokens String
-> ParsecT Void String Identity (Ref w)
-> ParsecT Void String Identity (Ref w)
forall {s} {m :: * -> *} {e} {b}.
(Token s ~ Char, MonadParsec e s m) =>
Tokens s -> m b -> m b
cmd1 Tokens String
"local.set" ParsecT Void String Identity (Ref w)
forall w. IsWord w => Parser (Ref w)
constantRef
                    , Ref w -> Wasm32Isa w (Ref w)
forall w l. l -> Wasm32Isa w l
LocalTee (Ref w -> Wasm32Isa w (Ref w))
-> ParsecT Void String Identity (Ref w)
-> ParsecT Void String Identity (Wasm32Isa w (Ref w))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Tokens String
-> ParsecT Void String Identity (Ref w)
-> ParsecT Void String Identity (Ref w)
forall {s} {m :: * -> *} {e} {b}.
(Token s ~ Char, MonadParsec e s m) =>
Tokens s -> m b -> m b
cmd1 Tokens String
"local.tee" ParsecT Void String Identity (Ref w)
forall w. IsWord w => Parser (Ref w)
constantRef
                    , Ref w -> Wasm32Isa w (Ref w)
forall w l. l -> Wasm32Isa w l
LocalsReserve (Ref w -> Wasm32Isa w (Ref w))
-> ParsecT Void String Identity (Ref w)
-> ParsecT Void String Identity (Wasm32Isa w (Ref w))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Tokens String
-> ParsecT Void String Identity (Ref w)
-> ParsecT Void String Identity (Ref w)
forall {s} {m :: * -> *} {e} {b}.
(Token s ~ Char, MonadParsec e s m) =>
Tokens s -> m b -> m b
cmd1 Tokens String
"locals.reserve" ParsecT Void String Identity (Ref w)
forall w. IsWord w => Parser (Ref w)
constantRef
                    , do
                        ParsecT Void String Identity () -> ParsecT Void String Identity ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (ParsecT Void String Identity ()
 -> ParsecT Void String Identity ())
-> ParsecT Void String Identity ()
-> ParsecT Void String Identity ()
forall a b. (a -> b) -> a -> b
$ Tokens String
-> ParsecT Void String Identity ()
-> ParsecT Void String Identity ()
forall {s} {m :: * -> *} {e} {b}.
(Token s ~ Char, MonadParsec e s m) =>
Tokens s -> m b -> m b
cmd1 Tokens String
"call" (() -> ParsecT Void String Identity ()
forall a. a -> ParsecT Void String Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ())
                        callParamCount <- ParsecT Void String Identity (Ref w)
forall w. IsWord w => Parser (Ref w)
constantRef
                        comma
                        callResultCount <- constantRef
                        return Call{callParamCount, callResultCount}
                    , Tokens String
-> Wasm32Isa w (Ref w)
-> ParsecT Void String Identity (Wasm32Isa w (Ref w))
forall {m :: * -> *} {e} {s} {b}.
MonadParsec e s m =>
Tokens s -> b -> m b
cmd0 Tokens String
"return" Wasm32Isa w (Ref w)
forall w l. Wasm32Isa w l
Return
                    , Tokens String
-> Wasm32Isa w (Ref w)
-> ParsecT Void String Identity (Wasm32Isa w (Ref w))
forall {m :: * -> *} {e} {s} {b}.
MonadParsec e s m =>
Tokens s -> b -> m b
cmd0 Tokens String
"sp.init" Wasm32Isa w (Ref w)
forall w l. Wasm32Isa w l
SpInit
                    , Tokens String
-> Wasm32Isa w (Ref w)
-> ParsecT Void String Identity (Wasm32Isa w (Ref w))
forall {m :: * -> *} {e} {s} {b}.
MonadParsec e s m =>
Tokens s -> b -> m b
cmd0 Tokens String
"halt" Wasm32Isa w (Ref w)
forall w l. Wasm32Isa w l
Halt
                    ]
            cmd0 :: Tokens s -> b -> m b
cmd0 Tokens s
op b
constructor = Tokens s -> m (Tokens s)
forall e s (m :: * -> *).
MonadParsec e s m =>
Tokens s -> m (Tokens s)
string Tokens s
op m (Tokens s) -> m b -> m b
forall a b. m a -> m b -> m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> b -> m b
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return b
constructor

            cmd1 :: Tokens s -> m b -> m b
cmd1 Tokens s
op m b
arg = m () -> m ()
forall a. m a -> m a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Tokens s -> m (Tokens s)
forall e s (m :: * -> *).
MonadParsec e s m =>
Tokens s -> m (Tokens s)
string Tokens s
op m (Tokens s) -> m () -> m ()
forall a b. m a -> m b -> m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> m ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
hspace1) m () -> m b -> m b
forall a b. m a -> m b -> m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> m b
arg

            memOp :: Tokens String -> (Ref w -> b) -> ParsecT Void String Identity b
memOp Tokens String
op Ref w -> b
constructor = do
                pos <- ParsecT Void String Identity SourcePos
forall s e (m :: * -> *).
(TraversableStream s, MonadParsec e s m) =>
m SourcePos
getSourcePos
                void $ string op
                constructor <$> (offset <|> pure (zeroAt pos))
                where
                    offset :: ParsecT Void String Identity (Ref w)
offset = ParsecT Void String Identity () -> ParsecT Void String Identity ()
forall a.
ParsecT Void String Identity a -> ParsecT Void String Identity a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (ParsecT Void String Identity ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
hspace1 ParsecT Void String Identity ()
-> ParsecT Void String Identity ()
-> ParsecT Void String Identity ()
forall a b.
ParsecT Void String Identity a
-> ParsecT Void String Identity b -> ParsecT Void String Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT Void String Identity Char
-> ParsecT Void String Identity ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (ParsecT Void String Identity Char
-> ParsecT Void String Identity Char
forall a.
ParsecT Void String Identity a -> ParsecT Void String Identity a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
lookAhead ParsecT Void String Identity Char
ParsecT Void String Identity (Token String)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m (Token s)
digitChar)) ParsecT Void String Identity ()
-> ParsecT Void String Identity (Ref w)
-> ParsecT Void String Identity (Ref w)
forall a b.
ParsecT Void String Identity a
-> ParsecT Void String Identity b -> ParsecT Void String Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT Void String Identity (Ref w)
forall w. IsWord w => Parser (Ref w)
constantRef
                    zeroAt :: SourcePos -> Ref w
zeroAt SourcePos
pos = ValueR{refPrepare :: w -> w
refPrepare = w -> w
forall a. a -> a
id, refPos :: SourcePos
refPos = SourcePos
pos, refValue :: w
refValue = w
0}

instance (IsWord w) => DerefMnemonic (Wasm32Isa w) w where
    derefMnemonic :: (Text -> Maybe w) -> w -> Wasm32Isa w (Ref w) -> Wasm32Isa w w
derefMnemonic Text -> Maybe w
f w
_offset Wasm32Isa w (Ref w)
instruction =
        let fieldErr :: Text -> src -> final
fieldErr (Text
what :: Text) src
x = [i|#{what} #{x} is not in 0..255|]
         in case Wasm32Isa w (Ref w)
instruction of
                I32Const Ref w
l -> w -> Wasm32Isa w w
forall w l. l -> Wasm32Isa w l
I32Const ((w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
forall w. (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
resolveRef w -> Either Text w
forall a b. b -> Either a b
Right Text -> Maybe w
f Ref w
l)
                I32Load Ref w
k -> w -> Wasm32Isa w w
forall w l. l -> Wasm32Isa w l
I32Load ((w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
forall w. (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
resolveRef ((Text -> Text) -> w -> Either Text w
forall w. IsWord w => (Text -> Text) -> w -> Either Text w
u8 (Text -> Text -> Text
forall {final} {src}.
(Interpolatable (IsCustomSink final) src final,
 Interpolatable (IsCustomSink final) Text final) =>
Text -> src -> final
fieldErr Text
"i32.load offset")) Text -> Maybe w
f Ref w
k)
                I32Store Ref w
k -> w -> Wasm32Isa w w
forall w l. l -> Wasm32Isa w l
I32Store ((w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
forall w. (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
resolveRef ((Text -> Text) -> w -> Either Text w
forall w. IsWord w => (Text -> Text) -> w -> Either Text w
u8 (Text -> Text -> Text
forall {final} {src}.
(Interpolatable (IsCustomSink final) src final,
 Interpolatable (IsCustomSink final) Text final) =>
Text -> src -> final
fieldErr Text
"i32.store offset")) Text -> Maybe w
f Ref w
k)
                I32Load8U Ref w
k -> w -> Wasm32Isa w w
forall w l. l -> Wasm32Isa w l
I32Load8U ((w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
forall w. (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
resolveRef ((Text -> Text) -> w -> Either Text w
forall w. IsWord w => (Text -> Text) -> w -> Either Text w
u8 (Text -> Text -> Text
forall {final} {src}.
(Interpolatable (IsCustomSink final) src final,
 Interpolatable (IsCustomSink final) Text final) =>
Text -> src -> final
fieldErr Text
"i32.load8_u offset")) Text -> Maybe w
f Ref w
k)
                I32Load8S Ref w
k -> w -> Wasm32Isa w w
forall w l. l -> Wasm32Isa w l
I32Load8S ((w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
forall w. (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
resolveRef ((Text -> Text) -> w -> Either Text w
forall w. IsWord w => (Text -> Text) -> w -> Either Text w
u8 (Text -> Text -> Text
forall {final} {src}.
(Interpolatable (IsCustomSink final) src final,
 Interpolatable (IsCustomSink final) Text final) =>
Text -> src -> final
fieldErr Text
"i32.load8_s offset")) Text -> Maybe w
f Ref w
k)
                I32Store8 Ref w
k -> w -> Wasm32Isa w w
forall w l. l -> Wasm32Isa w l
I32Store8 ((w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
forall w. (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
resolveRef ((Text -> Text) -> w -> Either Text w
forall w. IsWord w => (Text -> Text) -> w -> Either Text w
u8 (Text -> Text -> Text
forall {final} {src}.
(Interpolatable (IsCustomSink final) src final,
 Interpolatable (IsCustomSink final) Text final) =>
Text -> src -> final
fieldErr Text
"i32.store8 offset")) Text -> Maybe w
f Ref w
k)
                Br Ref w
k -> w -> Wasm32Isa w w
forall w l. l -> Wasm32Isa w l
Br ((w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
forall w. (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
resolveRef ((Text -> Text) -> w -> Either Text w
forall w. IsWord w => (Text -> Text) -> w -> Either Text w
u8 (Text -> Text -> Text
forall {final} {src}.
(Interpolatable (IsCustomSink final) src final,
 Interpolatable (IsCustomSink final) Text final) =>
Text -> src -> final
fieldErr Text
"br depth")) Text -> Maybe w
f Ref w
k)
                BrIf Ref w
k -> w -> Wasm32Isa w w
forall w l. l -> Wasm32Isa w l
BrIf ((w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
forall w. (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
resolveRef ((Text -> Text) -> w -> Either Text w
forall w. IsWord w => (Text -> Text) -> w -> Either Text w
u8 (Text -> Text -> Text
forall {final} {src}.
(Interpolatable (IsCustomSink final) src final,
 Interpolatable (IsCustomSink final) Text final) =>
Text -> src -> final
fieldErr Text
"br_if depth")) Text -> Maybe w
f Ref w
k)
                LocalGet Ref w
k -> w -> Wasm32Isa w w
forall w l. l -> Wasm32Isa w l
LocalGet ((w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
forall w. (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
resolveRef ((Text -> Text) -> w -> Either Text w
forall w. IsWord w => (Text -> Text) -> w -> Either Text w
u8 (Text -> Text -> Text
forall {final} {src}.
(Interpolatable (IsCustomSink final) src final,
 Interpolatable (IsCustomSink final) Text final) =>
Text -> src -> final
fieldErr Text
"local.get index")) Text -> Maybe w
f Ref w
k)
                LocalSet Ref w
k -> w -> Wasm32Isa w w
forall w l. l -> Wasm32Isa w l
LocalSet ((w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
forall w. (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
resolveRef ((Text -> Text) -> w -> Either Text w
forall w. IsWord w => (Text -> Text) -> w -> Either Text w
u8 (Text -> Text -> Text
forall {final} {src}.
(Interpolatable (IsCustomSink final) src final,
 Interpolatable (IsCustomSink final) Text final) =>
Text -> src -> final
fieldErr Text
"local.set index")) Text -> Maybe w
f Ref w
k)
                LocalTee Ref w
k -> w -> Wasm32Isa w w
forall w l. l -> Wasm32Isa w l
LocalTee ((w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
forall w. (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
resolveRef ((Text -> Text) -> w -> Either Text w
forall w. IsWord w => (Text -> Text) -> w -> Either Text w
u8 (Text -> Text -> Text
forall {final} {src}.
(Interpolatable (IsCustomSink final) src final,
 Interpolatable (IsCustomSink final) Text final) =>
Text -> src -> final
fieldErr Text
"local.tee index")) Text -> Maybe w
f Ref w
k)
                LocalsReserve Ref w
k -> w -> Wasm32Isa w w
forall w l. l -> Wasm32Isa w l
LocalsReserve ((w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
forall w. (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
resolveRef ((Text -> Text) -> w -> Either Text w
forall w. IsWord w => (Text -> Text) -> w -> Either Text w
u8 (Text -> Text -> Text
forall {final} {src}.
(Interpolatable (IsCustomSink final) src final,
 Interpolatable (IsCustomSink final) Text final) =>
Text -> src -> final
fieldErr Text
"locals.reserve count")) Text -> Maybe w
f Ref w
k)
                Call{Ref w
callParamCount :: forall w l. Wasm32Isa w l -> l
callParamCount :: Ref w
callParamCount, Ref w
callResultCount :: forall w l. Wasm32Isa w l -> l
callResultCount :: Ref w
callResultCount} ->
                    Call
                        { callParamCount :: w
callParamCount = (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
forall w. (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
resolveRef ((Text -> Text) -> w -> Either Text w
forall w. IsWord w => (Text -> Text) -> w -> Either Text w
u8 (Text -> Text -> Text
forall {final} {src}.
(Interpolatable (IsCustomSink final) src final,
 Interpolatable (IsCustomSink final) Text final) =>
Text -> src -> final
fieldErr Text
"call paramCount")) Text -> Maybe w
f Ref w
callParamCount
                        , callResultCount :: w
callResultCount = (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
forall w. (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
resolveRef ((Text -> Text) -> w -> Either Text w
forall w. IsWord w => (Text -> Text) -> w -> Either Text w
u8 (Text -> Text -> Text
forall {final} {src}.
(Interpolatable (IsCustomSink final) src final,
 Interpolatable (IsCustomSink final) Text final) =>
Text -> src -> final
fieldErr Text
"call resultCount")) Text -> Maybe w
f Ref w
callResultCount
                        }
                Wasm32Isa w (Ref w)
I32Add -> Wasm32Isa w w
forall w l. Wasm32Isa w l
I32Add
                Wasm32Isa w (Ref w)
I32Sub -> Wasm32Isa w w
forall w l. Wasm32Isa w l
I32Sub
                Wasm32Isa w (Ref w)
I32Mul -> Wasm32Isa w w
forall w l. Wasm32Isa w l
I32Mul
                Wasm32Isa w (Ref w)
I32DivS -> Wasm32Isa w w
forall w l. Wasm32Isa w l
I32DivS
                Wasm32Isa w (Ref w)
I32RemS -> Wasm32Isa w w
forall w l. Wasm32Isa w l
I32RemS
                Wasm32Isa w (Ref w)
I32And -> Wasm32Isa w w
forall w l. Wasm32Isa w l
I32And
                Wasm32Isa w (Ref w)
I32Or -> Wasm32Isa w w
forall w l. Wasm32Isa w l
I32Or
                Wasm32Isa w (Ref w)
I32Xor -> Wasm32Isa w w
forall w l. Wasm32Isa w l
I32Xor
                Wasm32Isa w (Ref w)
I32Shl -> Wasm32Isa w w
forall w l. Wasm32Isa w l
I32Shl
                Wasm32Isa w (Ref w)
I32ShrS -> Wasm32Isa w w
forall w l. Wasm32Isa w l
I32ShrS
                Wasm32Isa w (Ref w)
I32ShrU -> Wasm32Isa w w
forall w l. Wasm32Isa w l
I32ShrU
                Wasm32Isa w (Ref w)
I32Eqz -> Wasm32Isa w w
forall w l. Wasm32Isa w l
I32Eqz
                Wasm32Isa w (Ref w)
I32Eq -> Wasm32Isa w w
forall w l. Wasm32Isa w l
I32Eq
                Wasm32Isa w (Ref w)
I32LtS -> Wasm32Isa w w
forall w l. Wasm32Isa w l
I32LtS
                Wasm32Isa w (Ref w)
I32LeS -> Wasm32Isa w w
forall w l. Wasm32Isa w l
I32LeS
                Wasm32Isa w (Ref w)
I32GtS -> Wasm32Isa w w
forall w l. Wasm32Isa w l
I32GtS
                Wasm32Isa w (Ref w)
I32GeS -> Wasm32Isa w w
forall w l. Wasm32Isa w l
I32GeS
                Wasm32Isa w (Ref w)
I32LtU -> Wasm32Isa w w
forall w l. Wasm32Isa w l
I32LtU
                Wasm32Isa w (Ref w)
I32LeU -> Wasm32Isa w w
forall w l. Wasm32Isa w l
I32LeU
                Wasm32Isa w (Ref w)
I32GtU -> Wasm32Isa w w
forall w l. Wasm32Isa w l
I32GtU
                Wasm32Isa w (Ref w)
I32GeU -> Wasm32Isa w w
forall w l. Wasm32Isa w l
I32GeU
                Wasm32Isa w (Ref w)
If -> Wasm32Isa w w
forall w l. Wasm32Isa w l
If
                Wasm32Isa w (Ref w)
Else -> Wasm32Isa w w
forall w l. Wasm32Isa w l
Else
                Wasm32Isa w (Ref w)
End -> Wasm32Isa w w
forall w l. Wasm32Isa w l
End
                Wasm32Isa w (Ref w)
Loop -> Wasm32Isa w w
forall w l. Wasm32Isa w l
Loop
                Wasm32Isa w (Ref w)
Block -> Wasm32Isa w w
forall w l. Wasm32Isa w l
Block
                Wasm32Isa w (Ref w)
Drop -> Wasm32Isa w w
forall w l. Wasm32Isa w l
Drop
                Wasm32Isa w (Ref w)
Select -> Wasm32Isa w w
forall w l. Wasm32Isa w l
Select
                Wasm32Isa w (Ref w)
Unreachable -> Wasm32Isa w w
forall w l. Wasm32Isa w l
Unreachable
                Wasm32Isa w (Ref w)
Return -> Wasm32Isa w w
forall w l. Wasm32Isa w l
Return
                Wasm32Isa w (Ref w)
SpInit -> Wasm32Isa w w
forall w l. Wasm32Isa w l
SpInit
                Wasm32Isa w (Ref w)
Halt -> Wasm32Isa w w
forall w l. Wasm32Isa w l
Halt

instance ByteSize (Wasm32Isa w l) where
    byteSize :: Wasm32Isa w l -> Int
byteSize Wasm32Isa w l
instruction = Int
opcodeBytes Int -> Int -> Int
forall a. Num a => a -> a -> a
+ [Int] -> Int
forall a (f :: * -> *). (Foldable f, Num a) => f a -> a
sum [Int]
operandBytes
        where
            opcodeBytes :: Int
opcodeBytes = Int
1
            immediateBytes :: Int
immediateBytes = Int
1
            operandBytes :: [Int]
operandBytes = case Wasm32Isa w l
instruction of
                I32Const{} -> [forall t. ByteSizeT t => Int
byteSizeT @Int32]
                Wasm32Isa w l
I32Add -> []
                Wasm32Isa w l
I32Sub -> []
                Wasm32Isa w l
I32Mul -> []
                Wasm32Isa w l
I32DivS -> []
                Wasm32Isa w l
I32RemS -> []
                Wasm32Isa w l
I32And -> []
                Wasm32Isa w l
I32Or -> []
                Wasm32Isa w l
I32Xor -> []
                Wasm32Isa w l
I32Shl -> []
                Wasm32Isa w l
I32ShrS -> []
                Wasm32Isa w l
I32ShrU -> []
                Wasm32Isa w l
I32Eqz -> []
                Wasm32Isa w l
I32Eq -> []
                Wasm32Isa w l
I32LtS -> []
                Wasm32Isa w l
I32LeS -> []
                Wasm32Isa w l
I32GtS -> []
                Wasm32Isa w l
I32GeS -> []
                Wasm32Isa w l
I32LtU -> []
                Wasm32Isa w l
I32LeU -> []
                Wasm32Isa w l
I32GtU -> []
                Wasm32Isa w l
I32GeU -> []
                I32Load{} -> [Int
immediateBytes]
                I32Store{} -> [Int
immediateBytes]
                I32Load8U{} -> [Int
immediateBytes]
                I32Load8S{} -> [Int
immediateBytes]
                I32Store8{} -> [Int
immediateBytes]
                Wasm32Isa w l
If -> []
                Wasm32Isa w l
Else -> []
                Wasm32Isa w l
End -> []
                Wasm32Isa w l
Loop -> []
                Wasm32Isa w l
Block -> []
                Br{} -> [Int
immediateBytes]
                BrIf{} -> [Int
immediateBytes]
                Wasm32Isa w l
Drop -> []
                Wasm32Isa w l
Select -> []
                Wasm32Isa w l
Unreachable -> []
                LocalGet{} -> [Int
immediateBytes]
                LocalSet{} -> [Int
immediateBytes]
                LocalTee{} -> [Int
immediateBytes]
                LocalsReserve{} -> [Int
immediateBytes]
                Call{} -> [Int
immediateBytes, Int
immediateBytes]
                Wasm32Isa w l
Return -> []
                Wasm32Isa w l
SpInit -> []
                Wasm32Isa w l
Halt -> []