  -- | Compute next prime greater than @/n/@ probalistically.
  --
 diff -X ../utils/updatePatches.excludes -Nru upstream/pkg/integer-gmp/src/GHC/Integer/Logarithms/Internals.hs boot/pkg/integer-gmp/src/GHC/Integer/Logarithms/Internals.hs
---- upstream/pkg/integer-gmp/src/GHC/Integer/Logarithms/Internals.hs	2018-12-24 07:45:51.000000000 +0100
-+++ boot/pkg/integer-gmp/src/GHC/Integer/Logarithms/Internals.hs	2018-12-24 07:45:51.676965858 +0100
+--- upstream/pkg/integer-gmp/src/GHC/Integer/Logarithms/Internals.hs	2019-05-07 22:52:34.000000000 -0700
++++ boot/pkg/integer-gmp/src/GHC/Integer/Logarithms/Internals.hs	2019-05-07 22:52:34.932871418 -0700
 @@ -2,6 +2,11 @@
  {-# LANGUAGE MagicHash #-}
  {-# LANGUAGE UnboxedTuples #-}

 testPrimeBigNat :: BigNat -> Int# -> Int#
+#ifdef ghcjs_HOST_OS
+testPrimeBigNat (BN# ba#) r# = js_testPrimeBigNat ba# r#
+foreign import javascript unsafe "h$ghcjbn_testPrime_b($1,$2)" js_testPrimeBigNat :: ByteArray# -> Int# -> Int#
+#else
 testPrimeBigNat bn@(BN# ba#) = c_integer_gmp_test_prime# ba# (sizeofBigNat# bn)
 

+  throw new Error("isPrime_s");
+}
+
+
+// fixme: seed
+function h$ghcjsbn_random_b(min, max) {
+  if(h$ghcjsbn_cmp_bb(min, max) >= 0) {
+    return min;
+  }
+  var range = h$ghcjsbn_sub_bb(max, min);
+  var size = 4 + Math.ceil(h$ghcjsbn_nbits_b(range) / 16);
+  var r = h$ghcjsbn_zero_b;
+  for(var i=0;i<size;i++) {
+    var rnd = Math.floor(Math.random()*65536);
+    r = h$ghcjsbn_or_bb(h$ghcsbn_shl_b(r, 16), h$ghcjsbn_mkBigNat_w(rnd));
+  }
+  return h$ghcjsbn_add_bb(h$ghcjsbn_rem_bb(r, range), min);
+}
+
+function h$ghcjsbn_testPrime_b(n, rounds) {
+  var r = 0, d = n;
+  var nm1 = h$ghcjsbn_sub_bw(n,1);
+  var two = h$ghcjsbn_mkBigNat_w(2);
+  while(h$ghcjsbn_testBit_b(d, 0)) {
+    d = h$ghcjsbn_shr_b(d, 1);
+    r++;
+  }
+  for(var round = 0; round < rounds; round++) {
+    var a = h$ghcjsbn_random_b(two, nm1);
+    var x = h$ghcjsbn_modPow_bbb(a, d, n);
+    if(h$ghcjsbn_eq_bw(x,1) || h$ghcjsbn_eq_bb(x,nm1)) continue;
+    var found = false;
+    for(var rr=0;rr<r;rr++) {
+      x = h$ghcjsbn_modPow_bbb(x, two, n);
+      if(h$ghcjsbn_eq_bb(x, nm1)) {
+        found = true;
+        break;
+      }
+    }
+    if(!found) return 0;
+  }
+  return 1;
+}
+
+function h$ghcjsbn_testPrime_w(w, rounds) {
+  return h$ghcjsbn_testPrime_b(h$ghcjsbn_mkBigNat_w(w), rounds);
+}
+
+function h$integer_gmp_next_prime1(w) {
+  var r = h$ghcjsbn_nextPrime_b(h$ghcjsbn_mkBigNat_w(w));
+  return h$ghcjsbn_toWord_b(r);
+}
+
+function h$ghcjsbn_nextPrime_b(bn) {
+  var rounds = 64;
+  if(h$ghcjsbn_eq_bw(bn, 2)) {
+    return h$ghcjsbn_mkBigNat_w(3);
+  }
+  var i = bn;
+  do {
+    i = h$ghcjsbn_add_bw(i, 2);
+  } while(!h$ghcjsbn_testPrime_b(i, rounds));
+  return i;
+}
+
+// BigNat -> BigNat -> Bool
