Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC

Commits:

6 changed files:

Changes:

  • changelog.d/T27788-js-selector
    1
    +section: js-backend
    
    2
    +synopsis: Fix a bug in the JavaScript backend: Entering a selector thunk whose selected field was an unevaluated thunk could duplicate work or crash the program with a type error.
    
    3
    +issues: #27788
    
    4
    +mrs: !16681

  • compiler/GHC/StgToJS/Apply.hs
    ... ... @@ -1036,7 +1036,12 @@ updates s = do
    1036 1036
                               [ si' |= ss' .! i
    
    1037 1037
                               , sir' |= (closureField2 si') `ApplExpr` [r1]
    
    1038 1038
                               , ifS (app "typeof" [sir'] .===. jTyObject)
    
    1039
    -                            (copyClosure DontCopyCC si' sir')
    
    1039
    +                            (ifS (isThunk sir' .||. isBlackhole sir')
    
    1040
    +                              (mconcat [ closureInfo   si' |= hdUpdThunkEntry
    
    1041
    +                                       , closureField1 si' |= sir'
    
    1042
    +                                       , closureField2 si' |= null_
    
    1043
    +                                       ])
    
    1044
    +                              (copyClosure DontCopyCC si' sir'))
    
    1040 1045
                                 (assignClosure si' $ unbox_closure sir')
    
    1041 1046
                               , postIncrS i
    
    1042 1047
                               ]
    
    ... ... @@ -1066,7 +1071,8 @@ updates s = do
    1066 1071
                                    , -- update selectors
    
    1067 1072
                                      jwhenS ((app typeof [closureMeta updatee] .===. jTyObject) .&&. (closureMeta updatee .^ "sel"))
    
    1068 1073
                                      ((ss |= closureMeta updatee .^ "sel")
    
    1069
    -                                  <> upd_loop)
    
    1074
    +                                  <> upd_loop
    
    1075
    +                                  <> (closureMeta updatee .^ "sel" |= null_))
    
    1070 1076
                                    , -- overwrite the object
    
    1071 1077
                                      ifS (app typeof [r1] .===. jTyObject)
    
    1072 1078
                                      (mconcat [ traceRts s (jString "$upd_frame: boxed: " + ((closureInfo r1) .^ "n"))
    

  • compiler/GHC/StgToJS/Symbols.hs
    ... ... @@ -375,6 +375,9 @@ hdCAFsResetStr = name "h$CAFsReset"
    375 375
     hdUpdThunkEntryStr :: Ident
    
    376 376
     hdUpdThunkEntryStr = name "h$upd_thunk_e"
    
    377 377
     
    
    378
    +hdUpdThunkEntry :: JStgExpr
    
    379
    +hdUpdThunkEntry = global (identFS hdUpdThunkEntryStr)
    
    380
    +
    
    378 381
     hdAp3EntryStr :: Ident
    
    379 382
     hdAp3EntryStr = name "h$ap3_e"
    
    380 383
     
    

  • testsuite/tests/javascript/T27788.hs
    1
    +module Main where
    
    2
    +
    
    3
    +import Control.Exception (evaluate)
    
    4
    +import System.Environment (getArgs)
    
    5
    +
    
    6
    +{-# NOINLINE mkInner #-}
    
    7
    +mkInner :: Int -> (Int, Int)
    
    8
    +mkInner n = (n + 1, n + 2)
    
    9
    +
    
    10
    +{-# NOINLINE mkOuter #-}
    
    11
    +mkOuter :: (Int, Int) -> Int -> ((Int, Int), Int)
    
    12
    +mkOuter a n = (a, n)
    
    13
    +
    
    14
    +main :: IO ()
    
    15
    +main = do
    
    16
    +  n <- length <$> getArgs
    
    17
    +  let inner = mkInner n
    
    18
    +      outer = mkOuter inner n
    
    19
    +      (inner', _) = outer
    
    20
    +      (p, _) = inner
    
    21
    +  _ <- evaluate inner'
    
    22
    +  print (fst inner')
    
    23
    +  print (fst inner)
    
    24
    +  print p
    
    25
    +  print (snd outer)

  • testsuite/tests/javascript/T27788.stdout
    1
    +1
    
    2
    +1
    
    3
    +1
    
    4
    +0

  • testsuite/tests/javascript/all.T
    ... ... @@ -28,3 +28,5 @@ test('T24744', normal, makefile_test, ['T24744'])
    28 28
     
    
    29 29
     test('T25633', normal, compile_and_run, [''])
    
    30 30
     test('T24886', normal, compile, [''])
    
    31
    +
    
    32
    +test('T27788', normal, compile_and_run, ['-O0'])