Proper TypeInfo for arrays on stack for runtime checks

This commit is contained in:
Elena Lepilkina
2019-12-25 20:41:29 +03:00
committed by LepilkinaElena
parent 552984758e
commit 6ceef9fd53
@@ -430,15 +430,17 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
fun allocInstance(typeInfo: LLVMValueRef, lifetime: Lifetime): LLVMValueRef = fun allocInstance(typeInfo: LLVMValueRef, lifetime: Lifetime): LLVMValueRef =
call(context.llvm.allocInstanceFunction, listOf(typeInfo), lifetime) call(context.llvm.allocInstanceFunction, listOf(typeInfo), lifetime)
fun allocInstance(irClass: IrClass, lifetime: Lifetime): LLVMValueRef = fun allocInstance(irClass: IrClass, lifetime: Lifetime): LLVMValueRef {
if (lifetime == Lifetime.LOCAL) { val typeInfo = codegen.typeInfoForAllocation(irClass)
val stackSlot = alloca(context.llvmDeclarations.forClass(irClass).bodyType) return if (lifetime == Lifetime.LOCAL) {
val objectHeader = structGep(stackSlot, 0, "objHeader") val stackSlot = alloca(context.llvmDeclarations.forClass(irClass).bodyType)
setTypeInfoForLocalObject(objectHeader) val objectHeader = structGep(stackSlot, 0, "objHeader")
objectHeader setTypeInfoForLocalObject(objectHeader, typeInfo)
} else { objectHeader
allocInstance(codegen.typeInfoForAllocation(irClass), lifetime) } else {
} allocInstance(typeInfo, lifetime)
}
}
// TODO: find better place? // TODO: find better place?
val arrayToElementType = mapOf( val arrayToElementType = mapOf(
@@ -469,31 +471,32 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
fun allocArray(irClass: IrClass, fun allocArray(irClass: IrClass,
count: LLVMValueRef, count: LLVMValueRef,
lifetime: Lifetime, lifetime: Lifetime,
exceptionHandler: ExceptionHandler): LLVMValueRef = exceptionHandler: ExceptionHandler): LLVMValueRef {
if (lifetime == Lifetime.LOCAL) { val typeInfo = codegen.typeInfoValue(irClass)
val className = irClass.fqNameForIrSerialization.asString() return if (lifetime == Lifetime.LOCAL) {
assert(className in arrayToElementType) val className = irClass.fqNameForIrSerialization.asString()
allocArrayOnStack(className, count) assert(className in arrayToElementType)
} else { allocArrayOnStack(className, count, typeInfo)
call(context.llvm.allocArrayFunction, listOf(codegen.typeInfoValue(irClass), count), } else {
lifetime, exceptionHandler) call(context.llvm.allocArrayFunction, listOf(typeInfo, count), lifetime, exceptionHandler)
} }
}
fun setTypeInfoForLocalObject(objectHeader: LLVMValueRef) { fun setTypeInfoForLocalObject(objectHeader: LLVMValueRef, typeInfoPointer: LLVMValueRef) {
val typeInfo = structGep(objectHeader, 0, "typeInfoOrMeta_") val typeInfo = structGep(objectHeader, 0, "typeInfoOrMeta_")
// Set tag OBJECT_TAG_PERMANENT_CONTAINER | OBJECT_TAG_NONTRIVIAL_CONTAINER. // Set tag OBJECT_TAG_PERMANENT_CONTAINER | OBJECT_TAG_NONTRIVIAL_CONTAINER.
val typeInfoValue = intToPtr(or(ptrToInt(alloca(kTypeInfo), codegen.intPtrType), val typeInfoValue = intToPtr(or(ptrToInt(typeInfoPointer, codegen.intPtrType),
codegen.immThreeIntPtrType), kTypeInfoPtr) codegen.immThreeIntPtrType), kTypeInfoPtr)
store(typeInfoValue, typeInfo) store(typeInfoValue, typeInfo)
} }
fun allocArrayOnStack(arrayTypeName: String, count: LLVMValueRef): LLVMValueRef { fun allocArrayOnStack(arrayTypeName: String, count: LLVMValueRef, typeInfo: LLVMValueRef): LLVMValueRef {
val constCount = extractConstUnsignedInt(count).toInt() val constCount = extractConstUnsignedInt(count).toInt()
val arrayType = localArrayType(arrayTypeName, constCount) val arrayType = localArrayType(arrayTypeName, constCount)
val arraySlot = alloca(arrayType) val arraySlot = alloca(arrayType)
// Set array size in ArrayHeader. // Set array size in ArrayHeader.
val arrayHeaderSlot = structGep(arraySlot, 0, "arrayHeader") val arrayHeaderSlot = structGep(arraySlot, 0, "arrayHeader")
setTypeInfoForLocalObject(arrayHeaderSlot) setTypeInfoForLocalObject(arrayHeaderSlot, typeInfo)
val sizeField = structGep(arrayHeaderSlot, 1, "count_") val sizeField = structGep(arrayHeaderSlot, 1, "count_")
store(count, sizeField) store(count, sizeField)
call(context.llvm.memsetFunction, call(context.llvm.memsetFunction,