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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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