check sign-sensitive division arguments for trap conditions

This commit is contained in:
Ilya Rezvov
2018-04-21 09:40:18 -07:00
parent 49719b64cd
commit e99c7c427b
2 changed files with 42 additions and 14 deletions
+33 -13
View File
@@ -678,11 +678,15 @@ eval store FunctionInstance { funcType, moduleInstance, code = Function { localT
let funcAddr = elements !? fromIntegral v
case funcAddr of
Just (Just addr) -> do
let args = params funcType
res <- invoke store addr (zipWith checkValType args $ reverse $ take (length args) rest)
case res of
Just res -> return $ Done ctx { stack = reverse res ++ (drop (length args) rest) }
Nothing -> return Trap
let funInst = funcInstances store ! addr
let args = params $ Language.Wasm.Interpreter.funcType funInst
if length args > length rest
then return Trap
else do
res <- eval store funInst (zipWith checkValType args $ reverse $ take (length args) rest)
case res of
Just res -> return $ Done ctx { stack = reverse res ++ (drop (length args) rest) }
Nothing -> return Trap
_ -> return Trap
step ctx@EvalCtx{ stack = (_:rest) } Drop = return $ Done ctx { stack = rest }
step ctx@EvalCtx{ stack = (VI32 test:val2:val1:rest) } Select =
@@ -941,13 +945,21 @@ eval store FunctionInstance { funcType, moduleInstance, code = Function { localT
step ctx@EvalCtx{ stack = (VI32 v2:VI32 v1:rest) } (IBinOp BS32 IMul) =
return $ Done ctx { stack = VI32 (v1 * v2) : rest }
step ctx@EvalCtx{ stack = (VI32 v2:VI32 v1:rest) } (IBinOp BS32 IDivU) =
return $ Done ctx { stack = VI32 (v1 `quot` v2) : rest }
if v2 == 0
then return Trap
else return $ Done ctx { stack = VI32 (v1 `quot` v2) : rest }
step ctx@EvalCtx{ stack = (VI32 v2:VI32 v1:rest) } (IBinOp BS32 IDivS) =
return $ Done ctx { stack = VI32 (asWord32 $ asInt32 v1 `quot` asInt32 v2) : rest }
if v2 == 0 || (v1 == 0x80000000 && v2 == 0xFFFFFFFF)
then return Trap
else return $ Done ctx { stack = VI32 (asWord32 $ asInt32 v1 `quot` asInt32 v2) : rest }
step ctx@EvalCtx{ stack = (VI32 v2:VI32 v1:rest) } (IBinOp BS32 IRemU) =
return $ Done ctx { stack = VI32 (v1 `rem` v2) : rest }
if v2 == 0
then return Trap
else return $ Done ctx { stack = VI32 (v1 `rem` v2) : rest }
step ctx@EvalCtx{ stack = (VI32 v2:VI32 v1:rest) } (IBinOp BS32 IRemS) =
return $ Done ctx { stack = VI32 (asWord32 $ asInt32 v1 `rem` asInt32 v2) : rest }
if v2 == 0
then return Trap
else return $ Done ctx { stack = VI32 (asWord32 $ asInt32 v1 `rem` asInt32 v2) : rest }
step ctx@EvalCtx{ stack = (VI32 v2:VI32 v1:rest) } (IBinOp BS32 IAnd) =
return $ Done ctx { stack = VI32 (v1 .&. v2) : rest }
step ctx@EvalCtx{ stack = (VI32 v2:VI32 v1:rest) } (IBinOp BS32 IOr) =
@@ -999,13 +1011,21 @@ eval store FunctionInstance { funcType, moduleInstance, code = Function { localT
step ctx@EvalCtx{ stack = (VI64 v2:VI64 v1:rest) } (IBinOp BS64 IMul) =
return $ Done ctx { stack = VI64 (v1 * v2) : rest }
step ctx@EvalCtx{ stack = (VI64 v2:VI64 v1:rest) } (IBinOp BS64 IDivU) =
return $ Done ctx { stack = VI64 (v1 `quot` v2) : rest }
if v2 == 0
then return Trap
else return $ Done ctx { stack = VI64 (v1 `quot` v2) : rest }
step ctx@EvalCtx{ stack = (VI64 v2:VI64 v1:rest) } (IBinOp BS64 IDivS) =
return $ Done ctx { stack = VI64 (asWord64 $ asInt64 v1 `quot` asInt64 v2) : rest }
if v2 == 0 || (v1 == 0x8000000000000000 && v2 == 0xFFFFFFFFFFFFFFFF)
then return Trap
else return $ Done ctx { stack = VI64 (asWord64 $ asInt64 v1 `quot` asInt64 v2) : rest }
step ctx@EvalCtx{ stack = (VI64 v2:VI64 v1:rest) } (IBinOp BS64 IRemU) =
return $ Done ctx { stack = VI64 (v1 `rem` v2) : rest }
if v2 == 0
then return Trap
else return $ Done ctx { stack = VI64 (v1 `rem` v2) : rest }
step ctx@EvalCtx{ stack = (VI64 v2:VI64 v1:rest) } (IBinOp BS64 IRemS) =
return $ Done ctx { stack = VI64 (asWord64 $ asInt64 v1 `rem` asInt64 v2) : rest }
if v2 == 0
then return Trap
else return $ Done ctx { stack = VI64 (asWord64 $ asInt64 v1 `rem` asInt64 v2) : rest }
step ctx@EvalCtx{ stack = (VI64 v2:VI64 v1:rest) } (IBinOp BS64 IAnd) =
return $ Done ctx { stack = VI64 (v1 .&. v2) : rest }
step ctx@EvalCtx{ stack = (VI64 v2:VI64 v1:rest) } (IBinOp BS64 IOr) =
+9 -1
View File
@@ -226,7 +226,15 @@ runScript onAssertFail script = do
if isNothing result
then return ()
else onAssertFail ("Expected trap, but action returned " ++ show (fromJust result)) assert
-- runAssert st assert@(AssertTrap (Right moduleDef) failureString) =
runAssert st assert@(AssertTrap (Right moduleDef) failureString) =
let (_, m) = buildModule moduleDef in
case Validate.validate m of
Validate.Valid -> do
res <- Interpreter.instantiate (store st) (buildImports st) m
case res of
Left "Start function terminated with trap" -> return ()
_ -> onAssertFail ("Module linking should fail with trap during execution of a start function") assert
reason -> error $ "Module linking failed dut to invalid module with reason: " ++ show reason
runAssert _ _ = return ()
runCommand :: ScriptState -> Command -> IO ScriptState