diff --git a/lvtrun/README.md b/lvtrun/README.md index 66f147e..cb22056 100644 --- a/lvtrun/README.md +++ b/lvtrun/README.md @@ -32,17 +32,21 @@ # ----------------------- 2 ----------------------- -02 +02 24 # 02 is the id of the import section -24 01 16 77 -61 73 69 5f -73 6e 61 70 -73 68 6f 74 -5f 70 72 65 -76 69 65 77 -31 09 70 72 -6f 63 5f 65 -78 69 74 00 +# 1 vector +01 +# name is 16hex = 22dec bytes long +16 +# name = "wasi_snapshot_preview1" +77 61 73 69 5f 73 6e 61 70 73 68 6f 74 5f 70 72 65 76 69 65 77 31 +# name is 09 +09 +# name = "proct_exit" +70 72 6f 63 5f 65 78 69 74 +# 00 = func = function +00 +# 00 = typeidx = 0 02 # ----------------------- 3 ----------------------- diff --git a/lvtrun/src/OpCodes.hs b/lvtrun/src/OpCodes.hs index 8ef96a7..9c2030c 100644 --- a/lvtrun/src/OpCodes.hs +++ b/lvtrun/src/OpCodes.hs @@ -57,6 +57,7 @@ extractOpCode' (0x4a:rest) = ([0x4a], BSL.pack rest) extractOpCode' (0x4c:rest) = ([0x4c], BSL.pack rest) extractOpCode' (0x4e:rest) = ([0x4e], BSL.pack rest) extractOpCode' (0x47:rest) = ([0x47], BSL.pack rest) +extractOpCode' (0x05:rest) = ([0x05], BSL.pack rest) extractOpCode' (0x3f:0x00:rest) = ([0x3f, 0x00], BSL.pack rest) extractOpCode' (0x40:0x00:rest) = ([0x40, 0x00], BSL.pack rest) extractOpCode' (0x04:0x40:rest) = ([0x04, 0x40], BSL.pack rest) @@ -72,6 +73,7 @@ createInstruction [0x00] bytes = (Unreachable, bytes) createInstruction [0x01] bytes = (Nop, bytes) createInstruction [0x02] bytes = (Block EmptyType, bytes) createInstruction [0x0b] bytes = (End, bytes) +createInstruction [0x05] bytes = (Else, bytes) createInstruction [0x48] bytes = (I32Lts, bytes) createInstruction [0x0f] bytes = (Return, bytes) createInstruction [0x4b] bytes = (I32Gtu, bytes) diff --git a/lvtrun/src/Run/Vm.hs b/lvtrun/src/Run/Vm.hs index ef0b6b1..3fc31d9 100644 --- a/lvtrun/src/Run/Vm.hs +++ b/lvtrun/src/Run/Vm.hs @@ -102,10 +102,32 @@ execCall vm cEx funcIdx = cEx { ceStack = newStack } currentStack = ceStack cEx res = ceResults (currentExec newVm) +doesElseExist' :: [Instruction] -> Bool +doesElseExist' [] = False +doesElseExist' (Else:_) = True +doesElseExist' (_:rest) = doesElseExist' rest + +doesElseExist :: CurrentExec -> Bool +doesElseExist cEx = doesElseExist' (drop (ceInstIdx cEx) (ceInstructions cEx)) + +getElseIndex' :: [Instruction] -> Int -> Int +getElseIndex' [] _ = throw $ RuntimeError "getElseIndex: missing else" +getElseIndex' (Else:_) idx = idx +getElseIndex' (_:rest) idx = getElseIndex' rest (idx + 1) + +getElseIndex :: CurrentExec -> Int +getElseIndex cEx = getElseIndex' (drop (ceInstIdx cEx) (ceInstructions cEx)) 0 + +executeElse :: CurrentExec -> CurrentExec +executeElse cEx@(CurrentExec {ceStack = stack}) = + case doesElseExist cEx of + False -> cEx + True -> cEx { ceInstIdx = getElseIndex cEx } + execIf :: CurrentExec -> CurrentExec execIf cEx@(CurrentExec {ceStack = stack}) = case stackTop stack of I_32 0 -> goToEndInstruction cEx - I_32 1 -> addLabel (cEx { crBlockIndents = (crBlockIndents cEx) + 1 }) + I_32 1 -> executeElse (addLabel (cEx { crBlockIndents = (crBlockIndents cEx) + 1 })) I_32 _ -> throw $ RuntimeError "execIf: bad if statement" _ -> throw $ RuntimeError "execIf: bad type" @@ -175,7 +197,8 @@ execOpCode _ cEx (I32Gtu) = execI32GtU cEx execOpCode _ cEx (Block _) = incrementBlockIndent (addLabel cEx) execOpCode _ cEx (Br labelIdx) = execBr cEx labelIdx execOpCode _ cEx (Loop) = incrementBlockIndent (addLabel cEx) -execOpCode _ cEx _ = cEx +execOpCode _ cEx (Else) = throw $ RuntimeError "elseWithoutIf" +execOpCode _ cEx _ = throw $ RuntimeError "execOpCode: not implemented" execOpCodes :: VM -> [Instruction] -> CurrentExec execOpCodes vm [] = currentExec vm diff --git a/lvtrun/src/Types.hs b/lvtrun/src/Types.hs index 0c2ac91..121c239 100644 --- a/lvtrun/src/Types.hs +++ b/lvtrun/src/Types.hs @@ -117,6 +117,7 @@ data Instruction = | I32Leu | I32Eq | I32Lts + | Else | I32Gts | I32Les | I32Ges