Meta-object support. (#1451)
This commit is contained in:
+6
-4
@@ -616,7 +616,9 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
|
||||
val typeInfoPtr: LLVMValueRef = if (owner.isObjCClass()) {
|
||||
call(context.llvm.getObjCKotlinTypeInfo, listOf(receiver))
|
||||
} else {
|
||||
val typeInfoPtrPtr = LLVMBuildStructGEP(builder, receiver, 0 /* type_info */, "")!!
|
||||
val typeInfoOrMetaPtr = structGep(receiver, 0 /* typeInfoOrMeta_ */)
|
||||
val typeInfoOrMeta = load(typeInfoOrMetaPtr)
|
||||
val typeInfoPtrPtr = structGep(typeInfoOrMeta, 0 /* typeInfo */)
|
||||
load(typeInfoPtrPtr)
|
||||
}
|
||||
|
||||
@@ -655,10 +657,10 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
|
||||
|
||||
val objectPtr = codegen.getObjectInstanceStorage(descriptor, shared)
|
||||
val bbCurrent = currentBlock
|
||||
val bbInit = basicBlock("label_init", locationInfo)
|
||||
val bbExit = basicBlock("label_continue", locationInfo)
|
||||
val bbInit= basicBlock("label_init", locationInfo)
|
||||
val bbExit= basicBlock("label_continue", locationInfo)
|
||||
val objectVal = loadSlot(objectPtr, false)
|
||||
val objectInitialized = icmpUGt(ptrToInt(objectVal, codegen.intPtrType), codegen.immOneIntPtrType)
|
||||
val objectInitialized= icmpUGt(ptrToInt(objectVal, codegen.intPtrType), codegen.immOneIntPtrType)
|
||||
condBr(objectInitialized, bbExit, bbInit)
|
||||
|
||||
positionAtEnd(bbInit)
|
||||
|
||||
+3
-6
@@ -27,7 +27,6 @@ internal val LLVMValueRef.type: LLVMTypeRef
|
||||
* Represents the value which can be emitted as bitcode const value
|
||||
*/
|
||||
internal interface ConstValue {
|
||||
|
||||
val llvm: LLVMValueRef
|
||||
}
|
||||
|
||||
@@ -54,9 +53,8 @@ private class ConstGetElementPtr(val pointer: ConstPointer, val index: Int) : Co
|
||||
|
||||
internal fun ConstPointer.bitcast(toType: LLVMTypeRef) = constPointer(LLVMConstBitCast(this.llvm, toType)!!)
|
||||
|
||||
internal class ConstArray(val elemType: LLVMTypeRef?, val elements: List<ConstValue>) : ConstValue {
|
||||
|
||||
override val llvm = LLVMConstArray(elemType, elements.map { it.llvm }.toCValues(), elements.size)!!
|
||||
internal class ConstArray(elementType: LLVMTypeRef?, val elements: List<ConstValue>) : ConstValue {
|
||||
override val llvm = LLVMConstArray(elementType, elements.map { it.llvm }.toCValues(), elements.size)!!
|
||||
}
|
||||
|
||||
internal open class Struct(val type: LLVMTypeRef?, val elements: List<ConstValue?>) : ConstValue {
|
||||
@@ -108,7 +106,7 @@ internal class Zero(val type: LLVMTypeRef) : ConstValue {
|
||||
override val llvm = LLVMConstNull(type)!!
|
||||
}
|
||||
|
||||
internal class NullPointer(val pointeeType: LLVMTypeRef): ConstPointer {
|
||||
internal class NullPointer(pointeeType: LLVMTypeRef): ConstPointer {
|
||||
override val llvm = LLVMConstNull(pointerType(pointeeType))!!
|
||||
}
|
||||
|
||||
@@ -149,7 +147,6 @@ internal val kInt8Ptr = pointerType(int8Type)
|
||||
internal val kInt8PtrPtr = pointerType(kInt8Ptr)
|
||||
internal val kNullInt8Ptr = LLVMConstNull(kInt8Ptr)!!
|
||||
internal val kImmInt32One = Int32(1).llvm
|
||||
internal val kImmInt64One = Int64(1).llvm
|
||||
internal val ContextUtils.kNullObjHeaderPtr: LLVMValueRef
|
||||
get() = LLVMConstNull(this.kObjHeaderPtr)!!
|
||||
internal val ContextUtils.kNullObjHeaderPtrPtr: LLVMValueRef
|
||||
|
||||
+34
-23
@@ -35,22 +35,28 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
|
||||
inner class MethodTableRecord(val nameSignature: LocalHash, val methodEntryPoint: ConstPointer?) :
|
||||
Struct(runtime.methodTableRecordType, nameSignature, methodEntryPoint)
|
||||
|
||||
private inner class TypeInfo(val name: ConstValue, val size: Int,
|
||||
val superType: ConstValue,
|
||||
val objOffsets: ConstValue,
|
||||
val objOffsetsCount: Int,
|
||||
val interfaces: ConstValue,
|
||||
val interfacesCount: Int,
|
||||
val methods: ConstValue,
|
||||
val methodsCount: Int,
|
||||
val fields: ConstValue,
|
||||
val fieldsCount: Int,
|
||||
val packageName: String?,
|
||||
val relativeName: String?,
|
||||
val writableTypeInfo: ConstPointer?) :
|
||||
private inner class TypeInfo(
|
||||
selfPtr: ConstPointer,
|
||||
name: ConstValue,
|
||||
size: Int,
|
||||
superType: ConstValue,
|
||||
objOffsets: ConstValue,
|
||||
objOffsetsCount: Int,
|
||||
interfaces: ConstValue,
|
||||
interfacesCount: Int,
|
||||
methods: ConstValue,
|
||||
methodsCount: Int,
|
||||
fields: ConstValue,
|
||||
fieldsCount: Int,
|
||||
packageName: String?,
|
||||
relativeName: String?,
|
||||
writableTypeInfo: ConstPointer?) :
|
||||
|
||||
Struct(
|
||||
runtime.typeInfoType,
|
||||
|
||||
selfPtr,
|
||||
|
||||
name,
|
||||
Int32(size),
|
||||
|
||||
@@ -162,8 +168,11 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
|
||||
runtime.methodTableRecordType, methods)
|
||||
|
||||
val reflectionInfo = getReflectionInfo(classDesc)
|
||||
|
||||
val typeInfo = TypeInfo(name, size,
|
||||
val typeInfoGlobal = llvmDeclarations.typeInfoGlobal
|
||||
val typeInfo = TypeInfo(
|
||||
classDesc.typeInfoPtr,
|
||||
name,
|
||||
size,
|
||||
superType,
|
||||
objOffsetsPtr, objOffsets.size,
|
||||
interfacesPtr, interfaces.size,
|
||||
@@ -174,8 +183,6 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
|
||||
llvmDeclarations.writableTypeInfoGlobal?.pointer
|
||||
)
|
||||
|
||||
val typeInfoGlobal = llvmDeclarations.typeInfoGlobal
|
||||
|
||||
val typeInfoGlobalValue = if (!classDesc.typeInfoHasVtableAttached) {
|
||||
typeInfo
|
||||
} else {
|
||||
@@ -265,8 +272,12 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
|
||||
.also { it.setZeroInitializer() }
|
||||
.pointer
|
||||
}
|
||||
|
||||
val typeInfo = TypeInfo(
|
||||
val vtable = vtable(superClass)
|
||||
val typeInfoWithVtableType = structType(runtime.typeInfoType, vtable.llvmType)
|
||||
val typeInfoWithVtableGlobal = staticData.createGlobal(typeInfoWithVtableType, "", isExported = false)
|
||||
val result = typeInfoWithVtableGlobal.pointer.getElementPtr(0)
|
||||
val typeInfoWithVtable = Struct(TypeInfo(
|
||||
selfPtr = result,
|
||||
name = name,
|
||||
size = size,
|
||||
superType = superClass.typeInfoPtr,
|
||||
@@ -277,12 +288,12 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
|
||||
packageName = reflectionInfo.packageName,
|
||||
relativeName = reflectionInfo.relativeName,
|
||||
writableTypeInfo = writableTypeInfo
|
||||
)
|
||||
), vtable)
|
||||
|
||||
val vtable = vtable(superClass)
|
||||
typeInfoWithVtableGlobal.setInitializer(typeInfoWithVtable)
|
||||
typeInfoWithVtableGlobal.setConstant(true)
|
||||
|
||||
return staticData.placeGlobal("", Struct(typeInfo, vtable))
|
||||
.pointer.getElementPtr(0)
|
||||
return result
|
||||
}
|
||||
|
||||
private val OverriddenFunctionDescriptor.implementation get() = getImplementation(context)
|
||||
|
||||
Reference in New Issue
Block a user