diff --git a/experiments/MemLayout/.idea/compiler.xml b/experiments/MemLayout/.idea/compiler.xml
new file mode 100644
index 00000000000..96cc43efa6a
--- /dev/null
+++ b/experiments/MemLayout/.idea/compiler.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/experiments/MemLayout/.idea/copyright/profiles_settings.xml b/experiments/MemLayout/.idea/copyright/profiles_settings.xml
new file mode 100644
index 00000000000..e7bedf3377d
--- /dev/null
+++ b/experiments/MemLayout/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/experiments/MemLayout/.idea/dictionaries/jetbrains.xml b/experiments/MemLayout/.idea/dictionaries/jetbrains.xml
new file mode 100644
index 00000000000..e74e927f28f
--- /dev/null
+++ b/experiments/MemLayout/.idea/dictionaries/jetbrains.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/experiments/MemLayout/.idea/libraries/KotlinJavaRuntime.xml b/experiments/MemLayout/.idea/libraries/KotlinJavaRuntime.xml
new file mode 100644
index 00000000000..c630c0b8796
--- /dev/null
+++ b/experiments/MemLayout/.idea/libraries/KotlinJavaRuntime.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/experiments/MemLayout/.idea/misc.xml b/experiments/MemLayout/.idea/misc.xml
new file mode 100644
index 00000000000..c6d8fb73c8c
--- /dev/null
+++ b/experiments/MemLayout/.idea/misc.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/experiments/MemLayout/.idea/modules.xml b/experiments/MemLayout/.idea/modules.xml
new file mode 100644
index 00000000000..cf169cddad6
--- /dev/null
+++ b/experiments/MemLayout/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/experiments/MemLayout/.idea/workspace.xml b/experiments/MemLayout/.idea/workspace.xml
new file mode 100644
index 00000000000..b4ab8b8ed46
--- /dev/null
+++ b/experiments/MemLayout/.idea/workspace.xml
@@ -0,0 +1,612 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Android
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1472818752311
+
+
+ 1472818752311
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No facets are configured
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1.8
+
+
+
+
+
+
+
+
+
+
+
+ MemLayout
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ KotlinJavaRuntime
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/experiments/MemLayout/MemLayout.iml b/experiments/MemLayout/MemLayout.iml
new file mode 100644
index 00000000000..245d3429faa
--- /dev/null
+++ b/experiments/MemLayout/MemLayout.iml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/experiments/MemLayout/src/app.kt b/experiments/MemLayout/src/app.kt
new file mode 100644
index 00000000000..127223c5622
--- /dev/null
+++ b/experiments/MemLayout/src/app.kt
@@ -0,0 +1,97 @@
+package kotlin_native.test
+
+import sun.misc.Unsafe
+
+class Bridge {
+ val unsafe = GetUnsafe()
+
+ fun GetUnsafe(): sun.misc.Unsafe {
+ val theUnsafe = Unsafe::class.java.getDeclaredField("theUnsafe")
+ theUnsafe.isAccessible = true
+ return theUnsafe.get(null) as Unsafe
+ }
+
+ constructor() {
+ System.loadLibrary("bridge-jni")
+ }
+
+ fun Lookup(name:String) : NativePtr;
+
+ public native fun Call(NativeFunction func, Array args)
+ public native fun Lookup(String func, String signature) : NativeFunction
+}
+
+val bridge = Bridge()
+
+class NativeFunction(name:String, val signature:String) {
+ var ptr : Long = bridge.LookupFunction(name)
+}
+
+val stat = NativeFunction("stat". "DSP")
+
+class NativePtr(size:Long) {
+ var ptr : Long = bridge.unsafe.allocateMemory(size)
+
+ fun IntAt(offset:Int):Int {
+ return bridge.unsafe.getInt(ptr+offset)
+ }
+ fun LongAt(offset:Int):Long {
+ return bridge.unsafe.getLong(ptr+offset)
+ }
+ fun Free() {
+ bridge.unsafe.freeMemory(ptr)
+ ptr = 0
+ }
+}
+
+interface Native {
+ fun ptr() : NativePtr
+}
+
+class StatInfo : Native {
+ val ptr = NativePtr(1024)
+ val size : Long
+ get() = ptr.LongAt(96)
+ val inode : Int
+ get() = ptr.IntAt(8)
+ override fun ptr() = ptr
+}
+
+fun AsCString(s:String):NativePtr {
+ val ptr = NativePtr((s.length + 1) as Long)
+ return ptr
+}
+
+class Layout {
+ fun Call(func: String, signature: String, args:Array) : Any {
+
+ when (func) {
+ "stat" -> {
+ val str = AsCString(args[0] as String)
+ val args2 = arrayOf(null, str, (args[1] as StatInfo).ptr)
+ val rv = bridge.Call(func, signature, args2)
+ str.Free()
+ return args2[0]
+ }
+ else -> assert(false)
+ }
+ return ""
+ }
+}
+
+fun Cleanup(args:Array) {
+ for (a in args) {
+ if (a is Native) {
+ a.ptr().Free()
+ }
+ }
+}
+
+fun main(args: Array) {
+ val caller = Layout()
+ val file = if (args.size > 0) args[0] else "/etc/passwd"
+ val args = arrayOf(file, StatInfo())
+ val result = caller.Call(bridge.Lookup("stat", "DSP"), args)
+ println("got " + (args[1] as StatInfo).size)
+ Cleanup(args)
+}
\ No newline at end of file