diff --git a/src/trufflestg/data/AlgData.kt b/src/trufflestg/data/AlgData.kt index f0a624a..cf70adc 100644 --- a/src/trufflestg/data/AlgData.kt +++ b/src/trufflestg/data/AlgData.kt @@ -68,38 +68,13 @@ class ZeroArgDataCon( ) : DataCon() { override fun getInfo() = _info - override fun isDouble(slot: Slot): Boolean = false - override fun isFloat(slot: Slot): Boolean = false - override fun isInteger(slot: Slot): Boolean = false - override fun isLong(slot: Slot): Boolean = false - override fun isObject(slot: Slot): Boolean = false - override fun getValue(slot: Int) { CompilerDirectives.transferToInterpreter() throw IndexOutOfBoundsException() } - override fun getDouble(slot: Slot): Double { - CompilerDirectives.transferToInterpreter() - throw IndexOutOfBoundsException() - } - override fun getFloat(slot: Slot): Float { - CompilerDirectives.transferToInterpreter() - throw IndexOutOfBoundsException() - } - override fun getInteger(slot: Slot): Int { - CompilerDirectives.transferToInterpreter() - throw IndexOutOfBoundsException() - } - override fun getLong(slot: Slot): Long { - CompilerDirectives.transferToInterpreter() - throw IndexOutOfBoundsException() - } - override fun getObject(slot: Slot): Any? { - CompilerDirectives.transferToInterpreter() - throw IndexOutOfBoundsException() - } } +// TODO: use ArrayMappedDataFrame? class ArrayDataCon( val _info: DataConInfo, val tag: Int, @@ -107,17 +82,6 @@ class ArrayDataCon( ): DataCon() { override fun getInfo(): DataConInfo = _info override fun getValue(slot: Slot): Any? = args[slot] - override fun getObject(slot: Slot): Any? = args[slot] - override fun isObject(slot: Slot): Boolean = true - - override fun getDouble(slot: Slot): Double = throw FrameSlotTypeException() - override fun isDouble(slot: Slot): Boolean = false - override fun getFloat(slot: Slot): Float = throw FrameSlotTypeException() - override fun isFloat(slot: Slot): Boolean = false - override fun getInteger(slot: Slot): Int = throw FrameSlotTypeException() - override fun isInteger(slot: Slot): Boolean = false - override fun getLong(slot: Slot): Long = throw FrameSlotTypeException() - override fun isLong(slot: Slot): Boolean = false } abstract class DataConInfo( diff --git a/src/trufflestg/frame/ArrayMappedDataFrame.kt b/src/trufflestg/frame/ArrayMappedDataFrame.kt index c9e9336..8ef3126 100644 --- a/src/trufflestg/frame/ArrayMappedDataFrame.kt +++ b/src/trufflestg/frame/ArrayMappedDataFrame.kt @@ -24,27 +24,8 @@ class ArrayMappedDataFrame( val obj : Mask // anything in adata ) : DataFrame { val int: Mask get() = obj.inv() - override fun isInteger(slot: Slot) = slot.mask isa int - override fun isObject(slot: Slot) = slot.mask isa obj override fun getValue(slot: Slot): Any? = slot.mask.let { if (it isa obj) adata[it prefix obj] else idata[it prefix int] } - @Throws(FrameSlotTypeException::class) - override fun getInteger(slot: Slot): Int = slot.mask.let { - if (it isa obj) throw FrameSlotTypeException() - idata[it prefix int] - } - @Throws(FrameSlotTypeException::class) - override fun getObject(slot: Slot): Any? = slot.mask.let { - if (it isa int) throw FrameSlotTypeException() - idata[it prefix obj] - } - - override fun getDouble(slot: Slot) = throw FrameSlotTypeException() - override fun isDouble(slot: Slot): Boolean = false - override fun getFloat(slot: Slot): Float = throw FrameSlotTypeException() - override fun isFloat(slot: Slot): Boolean = false - override fun getLong(slot: Slot): Long = throw FrameSlotTypeException() - override fun isLong(slot: Slot): Boolean = false } \ No newline at end of file diff --git a/src/trufflestg/frame/BuildFrame.kt b/src/trufflestg/frame/BuildFrame.kt index a9f04ab..a8c9b2a 100644 --- a/src/trufflestg/frame/BuildFrame.kt +++ b/src/trufflestg/frame/BuildFrame.kt @@ -12,8 +12,8 @@ import trufflestg.array_utils.map // TODO: //interface Builder { fun build(xs: Array): T } - interface DataFrameBuilder { fun build(xs: Array): DataFrame } + fun factory(cls: Class): ByteArray = `class`( public and final, "${cls.name}Builder".replace('.','/')) { interfaces = mutableListOf(type(DataFrameBuilder::class).internalName) diff --git a/src/trufflestg/frame/DataFrame.kt b/src/trufflestg/frame/DataFrame.kt index 8fae0e9..6437292 100644 --- a/src/trufflestg/frame/DataFrame.kt +++ b/src/trufflestg/frame/DataFrame.kt @@ -7,25 +7,5 @@ typealias Slot = Int // TODO: i'm currently only using getValue, and probably won't use any of the others // TODO: make this an abstract class: casting to superclasses should be faster than casting to interfaces interface DataFrame { - abstract fun getValue(slot: Slot): Any? - - @Throws(FrameSlotTypeException::class) - abstract fun getDouble(slot: Slot): Double // D - abstract fun isDouble(slot: Slot): Boolean - - @Throws(FrameSlotTypeException::class) - abstract fun getFloat(slot: Slot): Float // F - abstract fun isFloat(slot: Slot): Boolean - - @Throws(FrameSlotTypeException::class) - abstract fun getInteger(slot: Slot): Int // I - abstract fun isInteger(slot: Slot): Boolean - - @Throws(FrameSlotTypeException::class) - abstract fun getLong(slot: Slot): Long // L - abstract fun isLong(slot: Slot): Boolean - - @Throws(FrameSlotTypeException::class) - abstract fun getObject(slot: Slot): Any? // O - abstract fun isObject(slot: Slot): Boolean + fun getValue(slot: Slot): Any? } \ No newline at end of file diff --git a/src/trufflestg/frame/FieldInfo.kt b/src/trufflestg/frame/FieldInfo.kt index 89c10cc..32eec6c 100644 --- a/src/trufflestg/frame/FieldInfo.kt +++ b/src/trufflestg/frame/FieldInfo.kt @@ -8,17 +8,9 @@ import trufflestg.data.StgWord sealed class FieldInfo(val sig: Char, val type: Type, val klass: Class<*>) { open val signature: String get() = sig.toString() - abstract fun load(asm: Block, slot: Slot) - abstract fun aload(asm: Block) abstract fun box(asm: Block) abstract fun unbox(asm: Block) - abstract fun ret(asm: Block) abstract fun matches(o: Any?): Boolean - open val isInteger: Boolean get() = false - open val isLong: Boolean get() = false - open val isFloat: Boolean get() = false - open val isDouble: Boolean get() = false - open val isObject: Boolean get() = false companion object { fun of(c: Char) = when (c) { 'I' -> intFieldInfo @@ -33,7 +25,8 @@ sealed class FieldInfo(val sig: Char, val type: Type, val klass: Class<*>) { is Float -> floatFieldInfo is Long -> longFieldInfo is Double -> doubleFieldInfo - // FIXME: StgInt, StgWord + is StgInt -> stgIntFieldInfo + is StgWord -> stgWordFieldInfo // TODO: think if i want to unbox any of the other types in stg_data.kt // also known class (to avoid isinstance checks) else -> objectFieldInfo @@ -42,72 +35,44 @@ sealed class FieldInfo(val sig: Char, val type: Type, val klass: Class<*>) { } private object intFieldInfo : FieldInfo('I', int, Int::class.java) { - override fun load(asm: Block, slot: Slot) = asm.iload(slot) - override fun aload(asm: Block) = asm.iaload override fun box(asm: Block) = asm.invokestatic(+Integer::class, +Integer::class, "valueOf", int) override fun unbox(asm: Block) = asm.invokevirtual(+Integer::class, int, "intValue") - override fun ret(asm: Block) = asm.ireturn override fun matches(o: Any?): Boolean = o is Int - override val isInteger: Boolean get() = true } private object floatFieldInfo : FieldInfo('F', float, Float::class.java) { - override fun load(asm: Block, slot: Slot) = asm.fload(slot) - override fun aload(asm: Block) = asm.faload override fun box(asm: Block) = asm.invokestatic(+Float::class, +Float::class, "valueOf", float) override fun unbox(asm: Block) = asm.invokevirtual(+Float::class, float, "floatValue") - override fun ret(asm: Block) = asm.freturn override fun matches(o: Any?): Boolean = o is Float - override val isFloat: Boolean get() = true } object objectFieldInfo : FieldInfo('O', `object`, Object::class.java) { - override fun load(asm: Block, slot: Slot) = asm.aload(slot) - override fun aload(asm: Block) = asm.aaload override fun box(asm: Block) {} override fun unbox(asm: Block) {} - override fun ret(asm: Block) = asm.areturn override fun matches(o: Any?): Boolean = true override val signature: String get() = "Ljava/lang/Object;" - override val isObject: Boolean get() = true } private object longFieldInfo : FieldInfo('L', long, Long::class.java) { - override fun load(asm: Block, slot: Slot) = asm.lload(slot) - override fun aload(asm: Block) = asm.laload override fun box(asm: Block) = asm.invokestatic(+Long::class, +Long::class, "valueOf", long) override fun unbox(asm: Block) = asm.invokevirtual(+Long::class, long, "longValue") - override fun ret(asm: Block) = asm.lreturn override fun matches(o: Any?): Boolean = o is Long - override val isLong: Boolean get() = true } private object doubleFieldInfo : FieldInfo('D', double, Double::class.java) { - override fun load(asm: Block, slot: Slot) = asm.dload(slot) - override fun aload(asm: Block) = asm.daload override fun box(asm: Block) = asm.invokestatic(+Double::class, +Double::class, "valueOf", double) override fun unbox(asm: Block) = asm.invokevirtual(+Double::class, double, "doubleValue") - override fun ret(asm: Block) = asm.dreturn override fun matches(o: Any?): Boolean = o is Double - override val isDouble: Boolean get() = true } object stgIntFieldInfo : FieldInfo('L', long, StgInt::class.java) { - override fun load(asm: Block, slot: Slot) = asm.lload(slot) - override fun aload(asm: Block) = asm.laload override fun box(asm: Block) = asm.invokestatic(+StgInt::class, +StgInt::class, "box", long) override fun unbox(asm: Block) = asm.invokevirtual(+StgInt::class, long, "unbox") - override fun ret(asm: Block) = asm.lreturn - override fun matches(o: Any?): Boolean = o is Long - override val isLong: Boolean get() = true + override fun matches(o: Any?): Boolean = o is StgInt } object stgWordFieldInfo : FieldInfo('L', long, StgWord::class.java) { - override fun load(asm: Block, slot: Slot) = asm.lload(slot) - override fun aload(asm: Block) = asm.laload override fun box(asm: Block) = asm.invokestatic(+StgWord::class, +StgWord::class, "box", long) override fun unbox(asm: Block) = asm.invokevirtual(+StgWord::class, long, "unbox") - override fun ret(asm: Block) = asm.lreturn - override fun matches(o: Any?): Boolean = o is Long - override val isLong: Boolean get() = true + override fun matches(o: Any?): Boolean = o is StgWord } diff --git a/src/trufflestg/frame/SimpleDataFrame.kt b/src/trufflestg/frame/SimpleDataFrame.kt index e7b5d9b..7554d89 100644 --- a/src/trufflestg/frame/SimpleDataFrame.kt +++ b/src/trufflestg/frame/SimpleDataFrame.kt @@ -1,25 +1,5 @@ package trufflestg.frame -import com.oracle.truffle.api.frame.FrameSlotTypeException - -class SimpleDataFrame(vararg val data: Any?) { - fun getValue(slot: Slot) = data[slot] - fun getSize() = data.size - @Throws(FrameSlotTypeException::class) - fun getDouble(slot: Slot) = data[slot] as? Double ?: throw FrameSlotTypeException() - fun isDouble(slot: Slot) = data[slot] is Double - @Throws(FrameSlotTypeException::class) - fun getFloat(slot: Slot) = data[slot] as? Float ?: throw FrameSlotTypeException() - fun isFloat(slot: Slot) = data[slot] is Float - @Throws(FrameSlotTypeException::class) - fun getInteger(slot: Slot) = data[slot] as? Int ?: throw FrameSlotTypeException() - fun isInteger(slot: Slot) = data[slot] is Int - @Throws(FrameSlotTypeException::class) - fun getLong(slot: Slot) = data[slot] as? Long ?: throw FrameSlotTypeException() - @Throws(FrameSlotTypeException::class) - fun getObject(slot: Slot) = data[slot]?.takeIf(Companion::isSimpleObject) ?: throw FrameSlotTypeException() - fun isObject(slot: Slot) = data[slot].let { it != null && isSimpleObject(it) } - companion object { - private fun isSimpleObject(it: Any): Boolean = it !is Double && it !is Long && it !is Float && it !is Int - } -} \ No newline at end of file +class SimpleDataFrame(vararg val data: Any?) : DataFrame { + override fun getValue(slot: Slot) = data[slot] +} diff --git a/src/trufflestg/frame/frame_assembly.kt b/src/trufflestg/frame/frame_assembly.kt index e605491..9386160 100644 --- a/src/trufflestg/frame/frame_assembly.kt +++ b/src/trufflestg/frame/frame_assembly.kt @@ -34,68 +34,9 @@ fun ClassNode.frameBody(types: Array, superCls: Type = type(Object::c val N = types.size val members = types.indices.map { "_$it" }.toTypedArray() - fun isMethod(name: String, predicate: (FieldInfo) -> Boolean) { - method(public and final, boolean, name, +Slot::class) { - asm { - when { - types.all(predicate) -> { iconst_1; ireturn } - !types.any(predicate) -> { iconst_0; ireturn } - else -> { - val no = LabelNode() - val yes = LabelNode() - iload_1 - lookupswitch(no, *types.mapIndexedNotNull { i, v -> if (predicate(v)) i to yes else null }.toTypedArray()) - add(no) - iconst_0 - ireturn - add(yes) - iconst_1 - ireturn - } - } - } - } - } - - fun getMethod(resultType: Type, name: String, predicate: (FieldInfo) -> Boolean) { - method(public and final, resultType, name, +Slot::class) { - throws(+FrameSlotTypeException::class) - asm { - types.mapIndexedNotNull { i, v -> if(predicate(v)) i to LabelNode() else null }.toTypedArray().let { - if (it.isNotEmpty()) { - val defaultLabel = LabelNode() - aload_0 - iload_1 - lookupswitch(defaultLabel, *it) - it.forEach { (i, label) -> - add(label) - val t = types[i] - getfield(type, members[i], t.type) - t.ret(this) - } - add(defaultLabel) - } - } - assembleThrow(this, +FrameSlotTypeException::class) - } - } - } - for (i in types.indices) field(public and final,types[i].type,members[i]) -// constructor(public, parameterTypes = *types.map{it.type}.toTypedArray()) { -// asm.`return` { -// aload_0 -// invokespecial(superCls, void, "") -// for (i in types.indices) { -// aload_0 -// types[i].load(this, i+1) -// putfield(type, members[i], types[i].type) -// } -// } -// } - constructor(public, parameterTypes = *arrayOf(`object`.array)) { asm.`return` { aload_0 @@ -118,17 +59,6 @@ fun ClassNode.frameBody(types: Array, superCls: Type = type(Object::c } } - isMethod("isInteger") { it.isInteger } - isMethod("isLong") { it.isLong } - isMethod("isFloat") { it.isFloat } - isMethod("isDouble") { it.isDouble } - - getMethod(int, "getInteger") { it.isInteger } - getMethod(long, "getLong") { it.isLong } - getMethod(float, "getFloat") { it.isFloat } - getMethod(double, "getDouble") { it.isDouble } - getMethod(`object`, "getObject") { it.isObject } - method(public and final, `object`, "getValue", +Slot::class) { if (N == 0) { asm { @@ -153,13 +83,6 @@ fun ClassNode.frameBody(types: Array, superCls: Type = type(Object::c } } - - // purely for debugging - method(public and final, int, "getSize") { - asm.ireturn { - push(types.size) - } - } } // TODO: add CompilerDirectives.ValueType to the generated class @@ -167,12 +90,6 @@ fun frame(signature: String, name: String) : ByteArray = `class`(public,name) { frameBody(signature.map { FieldInfo.of(it) }.toTypedArray()) } -val child: AnnotationNode get() = annotationNode(+Node.Child::class) - -val code = +Code::class - - - fun ByteArray.loadClassWith(className: String, lookup: (String) -> Class<*>?) : Class<*> { val classBuffer = this return object : ClassLoader(Int::class.java.classLoader) {