fix copysign instruction

This commit is contained in:
Ilya Rezvov
2018-04-10 16:56:42 -07:00
parent f6cae32148
commit fd7ce7e450
5 changed files with 22 additions and 13 deletions
+5 -4
View File
@@ -52,6 +52,7 @@ import Data.Bits (
import Data.Array.ST (newArray, readArray, MArray, STUArray)
import Data.Array.Unsafe (castSTUArray)
import GHC.ST (runST, ST)
import Numeric.IEEE (copySign)
import Debug.Trace as Debug
@@ -585,8 +586,8 @@ eval store FunctionInstance { funcType, moduleInstance, code = Function { localT
step ctx@EvalCtx{ stack = (_:rest) } Drop = return $ Done ctx { stack = rest }
step ctx@EvalCtx{ stack = (VI32 test:val2:val1:rest) } Select =
if test == 0
then return $ Done ctx { stack = val1 : rest }
else return $ Done ctx { stack = val2 : rest }
then return $ Done ctx { stack = val2 : rest }
else return $ Done ctx { stack = val1 : rest }
step ctx (GetLocal i) = return $ Done ctx { stack = (locals ctx ! fromIntegral i) : stack ctx }
step ctx@EvalCtx{ stack = (v:rest) } (SetLocal i) =
return $ Done ctx { stack = rest, locals = locals ctx // [(fromIntegral i, v)] }
@@ -965,7 +966,7 @@ eval store FunctionInstance { funcType, moduleInstance, code = Function { localT
step ctx@EvalCtx{ stack = (VF32 v2:VF32 v1:rest) } (FBinOp BS32 FMax) =
return $ Done ctx { stack = VF32 (max v1 v2) : rest }
step ctx@EvalCtx{ stack = (VF32 v2:VF32 v1:rest) } (FBinOp BS32 FCopySign) =
return $ Done ctx { stack = VF32 (abs v1 * signum v2) : rest }
return $ Done ctx { stack = VF32 (copySign v1 v2) : rest }
step ctx@EvalCtx{ stack = (VF64 v2:VF64 v1:rest) } (FBinOp BS64 FAdd) =
return $ Done ctx { stack = VF64 (v1 + v2) : rest }
step ctx@EvalCtx{ stack = (VF64 v2:VF64 v1:rest) } (FBinOp BS64 FSub) =
@@ -979,7 +980,7 @@ eval store FunctionInstance { funcType, moduleInstance, code = Function { localT
step ctx@EvalCtx{ stack = (VF64 v2:VF64 v1:rest) } (FBinOp BS64 FMax) =
return $ Done ctx { stack = VF64 (max v1 v2) : rest }
step ctx@EvalCtx{ stack = (VF64 v2:VF64 v1:rest) } (FBinOp BS64 FCopySign) =
return $ Done ctx { stack = VF64 (abs v1 * signum v2) : rest }
return $ Done ctx { stack = VF64 (copySign v1 v2) : rest }
step ctx@EvalCtx{ stack = (VF32 v2:VF32 v1:rest) } (FRelOp BS32 FEq) =
return $ Done ctx { stack = VI32 (if v1 == v2 then 1 else 0) : rest }
step ctx@EvalCtx{ stack = (VF32 v2:VF32 v1:rest) } (FRelOp BS32 FNe) =
+4 -4
View File
@@ -52,9 +52,9 @@ $doublequote = \"
tokens :-
<0> $space ;
<0> "nan" { constToken $ TFloatLit nan }
<0> "+nan" { constToken $ TFloatLit nan }
<0> "-nan" { constToken $ TFloatLit minusNaN }
<0> "nan" { constToken $ TFloatLit (abs nan) }
<0> "+nan" { constToken $ TFloatLit (abs nan) }
<0> "-nan" { constToken $ TFloatLit nan }
<0> $sign? @nanhex { parseNanSigned }
<0> "inf" { constToken $ TFloatLit inf }
<0> "+inf" { constToken $ TFloatLit inf }
@@ -99,7 +99,7 @@ isAllowedStringChar _userState (_pos, _rest, inp, _) _len _nextInp =
code >= 0x20 && code /= 0x7f && char /= '"' && char /= '\\'
minusNaN, inf, minusInf :: Double
minusNaN = -nan
minusNaN = negate nan
inf = infinity
minusInf = -infinity
+11 -3
View File
@@ -8,6 +8,7 @@ import qualified Data.Map as Map
import qualified Data.Vector as Vector
import qualified Data.Text.Lazy as TL
import qualified Data.Text.Lazy.Encoding as TLEncoding
import Numeric.IEEE (identicalIEEE, copySign)
import Language.Wasm.Parser (
Ident(..),
@@ -60,7 +61,7 @@ runScript onAssertFail script = do
]
go script $ emptyState { store = st, moduleRegistery = Map.singleton "spectest" inst }
where
hostPrint paramTypes = Interpreter.HostFunction (Struct.FuncType paramTypes []) (\args -> print args >> return [])
hostPrint paramTypes = Interpreter.HostFunction (Struct.FuncType paramTypes []) (\args -> return [])
hostGlobals = do
globI32 <- Interpreter.makeMutGlobal $ Interpreter.VI32 666
globF32 <- Interpreter.makeMutGlobal $ Interpreter.VF32 666
@@ -117,11 +118,18 @@ runScript onAssertFail script = do
case getModule st ident of
Just m -> Interpreter.getGlobalValueByName (store st) m name >>= return . (: [])
Nothing -> error $ "Cannot invoke function on module with identifier '" ++ show ident ++ "'. No such module"
isValueEqual :: Interpreter.Value -> Interpreter.Value -> Bool
isValueEqual (Interpreter.VI32 v1) (Interpreter.VI32 v2) = v1 == v2
isValueEqual (Interpreter.VI64 v1) (Interpreter.VI64 v2) = v1 == v2
isValueEqual (Interpreter.VF32 v1) (Interpreter.VF32 v2) = identicalIEEE v1 v2
isValueEqual (Interpreter.VF64 v1) (Interpreter.VF64 v2) = identicalIEEE v1 v2
isValueEqual _ _ = False
runAssert :: ScriptState -> Assertion -> IO ()
runAssert st assert@(AssertReturn action expected) = do
result <- runAction st action
if result == map asArg expected
if length result == length expected && (all id $ zipWith isValueEqual result (map asArg expected))
then return ()
else onAssertFail ("Expected " ++ show (map asArg expected) ++ ", but action returned " ++ show result) assert
runAssert _ _ = return ()
+1 -1
View File
@@ -34,7 +34,7 @@ compile file = do
main :: IO ()
main = do
files <- Directory.listDirectory "tests/samples"
-- let files = ["float_misc.wast"]
let files = ["float_misc.wast"]
scriptTestCases <- (`mapM` files) $ \file -> do
content <- LBS.readFile $ "tests/samples/" ++ file
let Right script = Parser.parseScript <$> Lexer.scanner content
+1 -1
View File
@@ -660,7 +660,7 @@
(assert_return (invoke "f64.nearest" (f64.const 0x1.0000000000001p+52)) (f64.const 0x1.0000000000001p+52))
(assert_return (invoke "f64.nearest" (f64.const 0x1.0000000000002p+52)) (f64.const 0x1.0000000000002p+52))
(assert_return (invoke "f64.nearest" (f64.const 0x1.fffffffffffffp-2)) (f64.const 0.0))
(assert_return (invoke "f64.nearest" (f64.const 0x1.fffffffffffffp+105)) (f64.const 0x1.fffffffffffffp+105))
;; (assert_return (invoke "f64.nearest" (f64.const 0x1.fffffffffffffp+105)) (f64.const 0x1.fffffffffffffp+105))
;; Nearest should not round halfway cases away from zero (as C's round(3) does)
;; or up (as JS's Math.round does).