CODEGEN: support for instanceof for null implemented

This commit is contained in:
Konstantin Anisimov
2016-12-06 16:29:46 +03:00
committed by vvlevchenko
parent 3eec3da511
commit 3cb1dd2eb1
2 changed files with 23 additions and 1 deletions
@@ -645,6 +645,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
return valuePhi
}
//-------------------------------------------------------------------------//
private fun evaluateExpressionAndJump(expression: IrExpression, destination: ContinuationBlock) {
@@ -1242,9 +1243,29 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
val type = value.typeOperand
val srcArg = evaluateExpression(codegen.newVar(), value.argument)!! // Evaluate src expression.
return genInstanceOf(tmpVariableName, srcArg, type)
val bbNull = codegen.basicBlock()
val bbInstanceOf = codegen.basicBlock()
val bbExit = codegen.basicBlock()
val condition = codegen.icmpEq(srcArg, codegen.kNullObjHeaderPtr, codegen.newVar())
codegen.condBr(condition, bbNull, bbInstanceOf)
codegen.positionAtEnd(bbNull)
val resultNull = if (TypeUtils.isNullableType(type)) kTrue else kFalse
codegen.br(bbExit)
codegen.positionAtEnd(bbInstanceOf)
val resultInstanceOf = genInstanceOf(tmpVariableName, srcArg, type)
codegen.br(bbExit)
codegen.positionAtEnd(bbExit)
val result = codegen.phi(kBoolean, codegen.newVar())
codegen.addPhiIncoming(result, bbNull to resultNull, bbInstanceOf to resultInstanceOf)
return result
}
//-------------------------------------------------------------------------//
private fun genInstanceOf(tmpVariableName: String, obj: LLVMValueRef, type: KotlinType): LLVMValueRef {
val dstDescriptor = TypeUtils.getClassDescriptor(type) // Get class descriptor for dst type.
val dstTypeInfo = codegen.typeInfoValue(dstDescriptor!!) // Get TypeInfo for dst type.
@@ -115,6 +115,7 @@ internal val ContextUtils.kObjHeaderPtrPtr: LLVMTypeRef
internal val ContextUtils.kTypeInfoPtr: LLVMTypeRef
get() = pointerType(kTypeInfo)
internal val kInt1 = LLVMInt1Type()!!
internal val kBoolean = kInt1
internal val kInt8Ptr = pointerType(int8Type)
internal val kInt8PtrPtr = pointerType(kInt8Ptr)
internal val kImmInt32One = Int32(1).llvm