fix copysign instruction
This commit is contained in:
@@ -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) =
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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).
|
||||
|
||||
Reference in New Issue
Block a user