fix serialization/deserialization and complete saturated data conversions
This commit is contained in:
@@ -130,7 +130,10 @@ getSection sectionType parser def = do
|
||||
where
|
||||
parseSection op
|
||||
| op == 0 = skipCustomSection >> getSection sectionType parser def
|
||||
| op == fromEnum sectionType = getWord8 >> (getULEB128 32 :: Get Natural) >> parser
|
||||
| op == fromEnum sectionType = do
|
||||
getWord8
|
||||
len <- getULEB128 32
|
||||
isolate len parser
|
||||
| op > fromEnum DataSection = fail "invalid section id"
|
||||
| op > fromEnum sectionType = return def
|
||||
| otherwise =
|
||||
@@ -522,6 +525,15 @@ instance Serialize (Instruction Natural) where
|
||||
put (IUnOp BS64 IExtend16S) = putWord8 0xC3
|
||||
put (IUnOp BS64 IExtend32S) = putWord8 0xC4
|
||||
|
||||
put (ITruncSatFS BS32 BS32) = putWord8 0xFC >> putULEB128 (0x00 :: Word32)
|
||||
put (ITruncSatFU BS32 BS32) = putWord8 0xFC >> putULEB128 (0x01 :: Word32)
|
||||
put (ITruncSatFS BS32 BS64) = putWord8 0xFC >> putULEB128 (0x02 :: Word32)
|
||||
put (ITruncSatFU BS32 BS64) = putWord8 0xFC >> putULEB128 (0x03 :: Word32)
|
||||
put (ITruncSatFS BS64 BS32) = putWord8 0xFC >> putULEB128 (0x04 :: Word32)
|
||||
put (ITruncSatFU BS64 BS32) = putWord8 0xFC >> putULEB128 (0x05 :: Word32)
|
||||
put (ITruncSatFS BS64 BS64) = putWord8 0xFC >> putULEB128 (0x06 :: Word32)
|
||||
put (ITruncSatFU BS64 BS64) = putWord8 0xFC >> putULEB128 (0x07 :: Word32)
|
||||
|
||||
get = do
|
||||
op <- getWord8
|
||||
case op of
|
||||
@@ -711,6 +723,18 @@ instance Serialize (Instruction Natural) where
|
||||
0xC2 -> return $ IUnOp BS64 IExtend8S
|
||||
0xC3 -> return $ IUnOp BS64 IExtend16S
|
||||
0xC4 -> return $ IUnOp BS64 IExtend32S
|
||||
0xFC -> do -- misc
|
||||
ext <- getULEB128 32
|
||||
case (ext :: Word32) of
|
||||
0x00 -> return $ ITruncSatFS BS32 BS32
|
||||
0x01 -> return $ ITruncSatFU BS32 BS32
|
||||
0x02 -> return $ ITruncSatFS BS32 BS64
|
||||
0x03 -> return $ ITruncSatFU BS32 BS64
|
||||
0x04 -> return $ ITruncSatFS BS64 BS32
|
||||
0x05 -> return $ ITruncSatFU BS64 BS32
|
||||
0x06 -> return $ ITruncSatFS BS64 BS64
|
||||
0x07 -> return $ ITruncSatFU BS64 BS64
|
||||
_ -> fail "Unknown byte value after misc instruction byte"
|
||||
_ -> fail "Unknown byte value in place of instruction opcode"
|
||||
|
||||
putExpression :: Expression -> Put
|
||||
@@ -792,7 +816,10 @@ instance Serialize Function where
|
||||
putByteString bs
|
||||
get = do
|
||||
_size <- getULEB128 32 :: Get Natural
|
||||
locals <- concat . map (\(LocalTypeRange n val) -> replicate (fromIntegral n) val) <$> getVec
|
||||
localRanges <- getVec
|
||||
let localLen = sum $ map (\(LocalTypeRange n _) -> n) localRanges
|
||||
if localLen < 2^32 then return () else fail "too many locals"
|
||||
let locals = concat $ map (\(LocalTypeRange n val) -> replicate (fromIntegral n) val) localRanges
|
||||
body <- getExpression
|
||||
return $ Function 0 locals body
|
||||
|
||||
|
||||
@@ -1079,21 +1079,81 @@ eval budget store FunctionInstance { funcType, moduleInstance, code = Function {
|
||||
then return Trap
|
||||
else return $ Done ctx { stack = VI64 (truncate v) : rest }
|
||||
step ctx@EvalCtx{ stack = (VF32 v:rest) } (ITruncFS BS32 BS32) =
|
||||
if isNaN v || isInfinite v || v >= 2^31 || v < -2^31
|
||||
if isNaN v || isInfinite v || v >= 2^31 || v < -2^31 - 1
|
||||
then return Trap
|
||||
else return $ Done ctx { stack = VI32 (asWord32 $ truncate v) : rest }
|
||||
step ctx@EvalCtx{ stack = (VF64 v:rest) } (ITruncFS BS32 BS64) =
|
||||
if isNaN v || isInfinite v || v >= 2^31 || v < -2^31
|
||||
if isNaN v || isInfinite v || v >= 2^31 || v <= -2^31 - 1
|
||||
then return Trap
|
||||
else return $ Done ctx { stack = VI32 (asWord32 $ truncate v) : rest }
|
||||
step ctx@EvalCtx{ stack = (VF32 v:rest) } (ITruncFS BS64 BS32) =
|
||||
if isNaN v || isInfinite v || v >= 2^63 || v < -2^63
|
||||
if isNaN v || isInfinite v || v >= 2^63 || v < -2^63 - 1
|
||||
then return Trap
|
||||
else return $ Done ctx { stack = VI64 (asWord64 $ truncate v) : rest }
|
||||
step ctx@EvalCtx{ stack = (VF64 v:rest) } (ITruncFS BS64 BS64) =
|
||||
if isNaN v || isInfinite v || v >= 2^63 || v < -2^63
|
||||
if isNaN v || isInfinite v || v >= 2^63 || v < -2^63 - 1
|
||||
then return Trap
|
||||
else return $ Done ctx { stack = VI64 (asWord64 $ truncate v) : rest }
|
||||
|
||||
step ctx@EvalCtx{ stack = (VF32 v:rest) } (ITruncSatFS BS32 BS32) | isNaN v =
|
||||
return $ Done ctx { stack = VI32 0 : rest }
|
||||
step ctx@EvalCtx{ stack = (VF64 v:rest) } (ITruncSatFS BS32 BS64) | isNaN v =
|
||||
return $ Done ctx { stack = VI32 0 : rest }
|
||||
step ctx@EvalCtx{ stack = (VF32 v:rest) } (ITruncSatFS BS64 BS32) | isNaN v =
|
||||
return $ Done ctx { stack = VI64 0 : rest }
|
||||
step ctx@EvalCtx{ stack = (VF64 v:rest) } (ITruncSatFS BS64 BS64) | isNaN v =
|
||||
return $ Done ctx { stack = VI64 0 : rest }
|
||||
step ctx@EvalCtx{ stack = (VF32 v:rest) } (ITruncSatFU BS32 BS32) | v <= -1 || isNaN v =
|
||||
return $ Done ctx { stack = VI32 0 : rest }
|
||||
step ctx@EvalCtx{ stack = (VF64 v:rest) } (ITruncSatFU BS32 BS64) | v <= -1 || isNaN v =
|
||||
return $ Done ctx { stack = VI32 0 : rest }
|
||||
step ctx@EvalCtx{ stack = (VF32 v:rest) } (ITruncSatFU BS64 BS32) | v <= -1 || isNaN v =
|
||||
return $ Done ctx { stack = VI64 0 : rest }
|
||||
step ctx@EvalCtx{ stack = (VF64 v:rest) } (ITruncSatFU BS64 BS64) | v <= -1 || isNaN v =
|
||||
return $ Done ctx { stack = VI64 0 : rest }
|
||||
|
||||
step ctx@EvalCtx{ stack = (VF32 v:rest) } (ITruncSatFS BS32 BS32) | v >= 2^31 =
|
||||
return $ Done ctx { stack = VI32 0x7fffffff : rest }
|
||||
step ctx@EvalCtx{ stack = (VF64 v:rest) } (ITruncSatFS BS32 BS64) | v >= 2^31 =
|
||||
return $ Done ctx { stack = VI32 0x7fffffff : rest }
|
||||
step ctx@EvalCtx{ stack = (VF32 v:rest) } (ITruncSatFS BS64 BS32) | v >= 2^63 =
|
||||
return $ Done ctx { stack = VI64 0x7fffffffffffffff : rest }
|
||||
step ctx@EvalCtx{ stack = (VF64 v:rest) } (ITruncSatFS BS64 BS64) | v >= 2^63 =
|
||||
return $ Done ctx { stack = VI64 0x7fffffffffffffff : rest }
|
||||
step ctx@EvalCtx{ stack = (VF32 v:rest) } (ITruncSatFU BS32 BS32) | v >= 2^32 =
|
||||
return $ Done ctx { stack = VI32 0xffffffff : rest }
|
||||
step ctx@EvalCtx{ stack = (VF64 v:rest) } (ITruncSatFU BS32 BS64) | v >= 2^32 =
|
||||
return $ Done ctx { stack = VI32 0xffffffff : rest }
|
||||
step ctx@EvalCtx{ stack = (VF32 v:rest) } (ITruncSatFU BS64 BS32) | v >= 2^64 =
|
||||
return $ Done ctx { stack = VI64 0xffffffffffffffff : rest }
|
||||
step ctx@EvalCtx{ stack = (VF64 v:rest) } (ITruncSatFU BS64 BS64) | v >= 2^64 =
|
||||
return $ Done ctx { stack = VI64 0xffffffffffffffff : rest }
|
||||
|
||||
step ctx@EvalCtx{ stack = (VF32 v:rest) } (ITruncSatFS BS32 BS32) | v <= -2^31 - 1 =
|
||||
return $ Done ctx { stack = VI32 0x80000000 : rest }
|
||||
step ctx@EvalCtx{ stack = (VF64 v:rest) } (ITruncSatFS BS32 BS64) | v <= -2^31 - 1 =
|
||||
return $ Done ctx { stack = VI32 0x80000000 : rest }
|
||||
step ctx@EvalCtx{ stack = (VF32 v:rest) } (ITruncSatFS BS64 BS32) | v <= -2^63 - 1 =
|
||||
return $ Done ctx { stack = VI64 0x8000000000000000 : rest }
|
||||
step ctx@EvalCtx{ stack = (VF64 v:rest) } (ITruncSatFS BS64 BS64) | v <= -2^63 - 1 =
|
||||
return $ Done ctx { stack = VI64 0x8000000000000000 : rest }
|
||||
|
||||
step ctx@EvalCtx{ stack = (VF32 v:rest) } (ITruncSatFU BS32 BS32) =
|
||||
return $ Done ctx { stack = VI32 (truncate v) : rest }
|
||||
step ctx@EvalCtx{ stack = (VF64 v:rest) } (ITruncSatFU BS32 BS64) =
|
||||
return $ Done ctx { stack = VI32 (truncate v) : rest }
|
||||
step ctx@EvalCtx{ stack = (VF32 v:rest) } (ITruncSatFU BS64 BS32) =
|
||||
return $ Done ctx { stack = VI64 (truncate v) : rest }
|
||||
step ctx@EvalCtx{ stack = (VF64 v:rest) } (ITruncSatFU BS64 BS64) =
|
||||
return $ Done ctx { stack = VI64 (truncate v) : rest }
|
||||
step ctx@EvalCtx{ stack = (VF32 v:rest) } (ITruncSatFS BS32 BS32) =
|
||||
return $ Done ctx { stack = VI32 (asWord32 $ truncate v) : rest }
|
||||
step ctx@EvalCtx{ stack = (VF64 v:rest) } (ITruncSatFS BS32 BS64) =
|
||||
return $ Done ctx { stack = VI32 (asWord32 $ truncate v) : rest }
|
||||
step ctx@EvalCtx{ stack = (VF32 v:rest) } (ITruncSatFS BS64 BS32) =
|
||||
return $ Done ctx { stack = VI64 (asWord64 $ truncate v) : rest }
|
||||
step ctx@EvalCtx{ stack = (VF64 v:rest) } (ITruncSatFS BS64 BS64) =
|
||||
return $ Done ctx { stack = VI64 (asWord64 $ truncate v) : rest }
|
||||
step ctx@EvalCtx{ stack = (VI32 v:rest) } I64ExtendUI32 =
|
||||
return $ Done ctx { stack = VI64 (fromIntegral v) : rest }
|
||||
step ctx@EvalCtx{ stack = (VI32 v:rest) } I64ExtendSI32 =
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ import qualified Data.List as List
|
||||
main :: IO ()
|
||||
main = do
|
||||
files <- filter (List.isSuffixOf ".wast") <$> Directory.listDirectory "tests/spec"
|
||||
-- let files = ["select.wast"]
|
||||
-- let files = ["conversions.wast"]
|
||||
scriptTestCases <- (`mapM` files) $ \file -> do
|
||||
test <- LBS.readFile ("tests/spec/" ++ file)
|
||||
return $ testCase file $ do
|
||||
|
||||
Reference in New Issue
Block a user