Skip to content

Commit 6464374

Browse files
authored
Fix stack overflow in fromFoldable, fixes #3 (#6)
I had to rearrange things to remove that `where` clause in the tests because otherwise I'd get a syntax error (still not entirely sure why, but oh well). The test I've added fails on `master` with compiler v0.12.3 and node v8.10.0, but passes with the change to `fromFoldable`.
1 parent 993b44a commit 6464374

File tree

2 files changed

+18
-8
lines changed

2 files changed

+18
-8
lines changed

src/Foreign/Object.purs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ module Foreign.Object
4444
import Prelude
4545

4646
import Control.Monad.ST (ST)
47+
import Control.Monad.ST as ST
4748
import Data.Array as A
4849
import Data.Eq (class Eq1)
4950
import Data.Foldable (class Foldable, foldl, foldr, for_)
@@ -216,7 +217,7 @@ update f k m = alter (maybe Nothing f) k m
216217
fromFoldable :: forall f a. Foldable f => f (Tuple String a) -> Object a
217218
fromFoldable l = runST do
218219
s <- OST.new
219-
for_ (A.fromFoldable l) \(Tuple k v) -> OST.poke k v s
220+
ST.foreach (A.fromFoldable l) \(Tuple k v) -> void $ OST.poke k v s
220221
pure s
221222

222223
foreign import _lookupST :: forall a r z. Fn4 z (a -> z) String (STObject r a) (ST r z)

test/Test/Foreign/Object.purs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ module Test.Foreign.Object where
22

33
import Prelude
44

5-
import Effect (Effect)
6-
import Effect.Console (log)
75
import Control.Monad.Writer (runWriter, tell)
86
import Data.Array as A
97
import Data.Foldable (foldl, foldr)
@@ -13,12 +11,16 @@ import Data.List as L
1311
import Data.List.NonEmpty as NEL
1412
import Data.Maybe (Maybe(..))
1513
import Data.NonEmpty ((:|))
16-
import Foreign.Object as O
17-
import Foreign.Object.Gen (genForeignObject)
1814
import Data.Traversable (sequence, traverse)
1915
import Data.TraversableWithIndex (traverseWithIndex)
2016
import Data.Tuple (Tuple(..), fst, snd, uncurry)
17+
import Effect (Effect)
18+
import Effect.Console (log)
19+
import Foreign.Object (Object)
20+
import Foreign.Object as O
21+
import Foreign.Object.Gen (genForeignObject)
2122
import Partial.Unsafe (unsafePartial)
23+
import Test.Assert (assertEqual)
2224
import Test.QuickCheck ((<?>), quickCheck, quickCheck', (===))
2325
import Test.QuickCheck.Arbitrary (class Arbitrary, arbitrary)
2426
import Test.QuickCheck.Gen as Gen
@@ -244,7 +246,14 @@ objectTests = do
244246
quickCheck \(TestObject m) ->
245247
let lhs = go m
246248
rhs = go m
249+
go :: O.Object (Array Ordering) -> Array Ordering
250+
go = O.foldMap (const identity)
247251
in lhs == rhs <?> ("lhs: " <> show lhs <> ", rhs: " <> show rhs)
248-
where
249-
go :: O.Object (Array Ordering) -> Array Ordering
250-
go = O.foldMap \_ v -> v
252+
253+
log "fromFoldable stack safety"
254+
do
255+
let entries = 100000
256+
assertEqual
257+
{ expected: entries
258+
, actual: O.size (O.fromFoldable (map (\x -> Tuple (show x) x) (A.range 1 entries)))
259+
}

0 commit comments

Comments
 (0)