Skip to content

Instantly share code, notes, and snippets.

@hanslovsky
Last active July 2, 2022 21:33
Show Gist options
  • Save hanslovsky/d27fd6e4a6480a103de8abfada596d06 to your computer and use it in GitHub Desktop.
Save hanslovsky/d27fd6e4a6480a103de8abfada596d06 to your computer and use it in GitHub Desktop.
package me.hanslovsky.konkorde
import com.sun.jna.Library
import com.sun.jna.Memory
import com.sun.jna.Native
import com.sun.jna.Pointer
import com.sun.jna.Structure
interface ConcordeLib : Library {
fun CCutil_sprand(seed: Int, rstate: CCrandstate): Unit
companion object {
@JvmStatic val INSTANCE = Native.load("concorde", ConcordeLib::class.java)
}
@Structure.FieldOrder("a", "b", "arr")
open class CCrandstate : Structure() {
class ByReference : CCrandstate(), Structure.ByReference
@JvmField var a: Int = 0
@JvmField var b: Int = 0
@JvmField val arr: Pointer = Memory(55L * Native.getNativeSize(Integer.TYPE))
override fun toString(): String {
return "${this::class.java}(a=$a, b=$b, arr=${arr})"
}
}
}
fun main() {
val rstate = ConcordeLib.CCrandstate()
println("before: rstate=$rstate rstate.arr[0]=${rstate.arr.getInt(0)}")
// before: rstate=class me.hanslovsky.konkorde.ConcordeLib$CCrandstate(a=0, b=0, arr=allocated@0x7f25a46eefc0 (220 bytes)) rstate.arr[0]=-1543503728
ConcordeLib.INSTANCE.CCutil_sprand(0, rstate)
// rstate.arr pointer address changes after native call
// even though CCutil_sprand does not allocate any memory
println("after: rstate=$rstate")
//after: rstate=class me.hanslovsky.konkorde.ConcordeLib$CCrandstate(a=0, b=24, arr=native@0x1b3928f93272b759)
// next line will fail with SIGSEGV
println("after: rstate=$rstate rstate.arr[0]=${rstate.arr.getInt(0)}")
//#
//# A fatal error has been detected by the Java Runtime Environment:
//#
//# SIGSEGV (0xb) at pc=0x00007f256dc09e18, pid=48562, tid=48563
}
package me.hanslovsky.konkorde
import com.sun.jna.Library
import com.sun.jna.Native
import com.sun.jna.Structure
interface ConcordeLibFixed : Library {
fun CCutil_sprand(seed: Int, rstate: CCrandstate): Unit
companion object {
@JvmStatic val INSTANCE = Native.load("concorde", ConcordeLibFixed::class.java)
}
@Structure.FieldOrder("a", "b", "arr")
open class CCrandstate : Structure() {
class ByReference : CCrandstate(), Structure.ByReference
@JvmField var a: Int = 0
@JvmField var b: Int = 0
@JvmField val arr: IntArray = IntArray(55) // Memory(55L * Native.getNativeSize(Integer.TYPE))
override fun toString(): String {
return "${this::class.java}(a=$a, b=$b, arr=${arr})"
}
}
}
fun main() {
val rstate = ConcordeLibFixed.CCrandstate()
println("before: rstate=$rstate rstate.arr[0]=${rstate.arr.get(0)}")
// before: rstate=class me.hanslovsky.konkorde.ConcordeLib$CCrandstate(a=0, b=0, arr=allocated@0x7f25a46eefc0 (220 bytes)) rstate.arr[0]=-1543503728
ConcordeLibFixed.INSTANCE.CCutil_sprand(0, rstate)
// rstate.arr pointer address changes after native call
// even though CCutil_sprand does not allocate any memory
println("after: rstate=$rstate")
//after: rstate=class me.hanslovsky.konkorde.ConcordeLib$CCrandstate(a=0, b=24, arr=native@0x1b3928f93272b759)
println("after: rstate=$rstate rstate.arr[0]=${rstate.arr.get(0)}")
}
package me.hanslovsky.konkorde
import com.sun.jna.Library
import com.sun.jna.Native
import com.sun.jna.Pointer
interface ConcordeLibPointer : Library {
fun CCutil_sprand(seed: Int, rstate: Pointer): Unit
companion object {
@JvmStatic val INSTANCE = Native.load("concorde", ConcordeLibPointer::class.java)
}
class CCRandStatePointer : Pointer(allocate()) {
val a: Int get() = getInt(0)
val b: Int get() = getInt(4)
val arr = { index: Int -> getInt(8L + 4*index) }
override fun toString() = "p($a, $b, ${arr(0)})"
companion object {
private fun allocate() = Native.malloc(4*(1 + 1 + 55))
}
}
}
fun main() {
val rstate = ConcordeLibPointer.CCRandStatePointer()
println("before: rstate=$rstate")
// before: rstate=p(-738197360, 32515, -738197360)
ConcordeLibPointer.INSTANCE.CCutil_sprand(0, rstate)
println("after: rstate=$rstate")
//after: rstate=p(0, 24, 846378841)
}
#include "machdefs.h"
#include "util.h"
typedef struct CCrandstate {
int a;
int b;
int arr[55];
} CCrandstate;
void CCutil_sprand (int seed, CCrandstate *r)
{
int i, ii;
int last, next;
int *arr = r->arr;
seed %= CC_PRANDMAX;
if (seed < 0) seed += CC_PRANDMAX;
arr[0] = last = seed;
next = 1;
for (i = 1; i < 55; i++) {
ii = (21 * i) % 55;
arr[ii] = next;
next = last - next;
if (next < 0)
next += CC_PRANDMAX;
last = arr[ii];
}
r->a = 0;
r->b = 24;
for (i = 0; i < 165; i++)
last = CCutil_lprand (r);
}
int CCutil_lprand (CCrandstate *r)
{
int t;
if (r->a-- == 0)
r->a = 54;
if (r->b-- == 0)
r->b = 54;
t = r->arr[r->a] - r->arr[r->b];
if (t < 0)
t += CC_PRANDMAX;
r->arr[r->a] = t;
return t;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment